From f89435405541aef93d2c8b4ae9080796e66bec5d Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 16:39:05 +0300 Subject: [PATCH 01/11] Add default size of the trace window --- .../debugger/streams/ui/impl/EvaluationAwareTraceWindow.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/intellij/debugger/streams/ui/impl/EvaluationAwareTraceWindow.java b/src/main/java/com/intellij/debugger/streams/ui/impl/EvaluationAwareTraceWindow.java index 928f95f..64db871 100644 --- a/src/main/java/com/intellij/debugger/streams/ui/impl/EvaluationAwareTraceWindow.java +++ b/src/main/java/com/intellij/debugger/streams/ui/impl/EvaluationAwareTraceWindow.java @@ -27,6 +27,7 @@ import com.intellij.ui.JBCardLayout; import com.intellij.ui.JBTabsPaneImpl; import com.intellij.ui.components.JBLabel; +import com.intellij.util.ui.JBDimension; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebugSessionListener; import com.sun.jdi.Value; @@ -47,6 +48,8 @@ * @author Vitaliy.Bibaev */ public class EvaluationAwareTraceWindow extends DialogWrapper { + private static final int DEFAULT_WIDTH = 870; + private static final int DEFAULT_HEIGHT = 400; private static final String FLAT_MODE_NAME = "Flat Mode"; private static final String TABBED_MODE_NAME = "Split Mode"; private final JPanel myCenterPane; @@ -81,6 +84,7 @@ public void sessionStopped() { myFlatContent = new MyPlaceholder(); myCenterPane.add(myFlatContent); + myCenterPane.setPreferredSize(new JBDimension(DEFAULT_WIDTH, DEFAULT_HEIGHT)); init(); } From 5010cf43bef171582e5dd3854b753dcc084a2871 Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 17:40:50 +0300 Subject: [PATCH 02/11] Add info to chain about return type of the termination call --- .../impl/TraceExpressionBuilderImpl.java | 5 +-- .../trace/impl/handler/type/GenericType.java | 1 + .../impl/handler/type/GenericTypeUtil.java | 34 +++++++++++++++++++ .../streams/wrapper/TerminatorStreamCall.java | 6 +++- .../wrapper/impl/StreamChainBuilderImpl.java | 15 ++++++-- .../impl/TerminatorStreamCallImpl.java | 11 +++--- 6 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericTypeUtil.java diff --git a/src/main/java/com/intellij/debugger/streams/trace/impl/TraceExpressionBuilderImpl.java b/src/main/java/com/intellij/debugger/streams/trace/impl/TraceExpressionBuilderImpl.java index f3f642c..3cbdae7 100644 --- a/src/main/java/com/intellij/debugger/streams/trace/impl/TraceExpressionBuilderImpl.java +++ b/src/main/java/com/intellij/debugger/streams/trace/impl/TraceExpressionBuilderImpl.java @@ -150,12 +150,13 @@ private static String buildDeclarations(@NotNull StreamCallTraceHandler producer @NotNull private static String buildStreamExpression(@NotNull StreamChain chain) { - if (chain.getTerminationCall().isVoid()) { + final GenericType resultType = chain.getTerminationCall().getResultType(); + if (resultType.equals(GenericType.VOID)) { final String resultInitialization = "final Object streamResult = null;" + LINE_SEPARATOR; return resultInitialization + chain.getText() + ";" + LINE_SEPARATOR; } else { - return "final Object streamResult = " + chain.getText() + ";" + LINE_SEPARATOR; + return "final " + resultType.getVariableTypeName() + " streamResult = " + chain.getText() + ";" + LINE_SEPARATOR; } } diff --git a/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericType.java b/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericType.java index 6a7ea99..2cfc609 100644 --- a/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericType.java +++ b/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericType.java @@ -27,6 +27,7 @@ public interface GenericType { @NotNull String getGenericTypeName(); + GenericType BOOLEAN = new GenericTypeImpl("boolean", "java.lang.Boolean"); GenericType INT = new GenericTypeImpl("int", "java.lang.Integer"); GenericType DOUBLE = new GenericTypeImpl("double", "java.lang.Double"); GenericType LONG = new GenericTypeImpl("long", "java.lang.Long"); diff --git a/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericTypeUtil.java b/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericTypeUtil.java new file mode 100644 index 0000000..03f8ee1 --- /dev/null +++ b/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericTypeUtil.java @@ -0,0 +1,34 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.streams.trace.impl.handler.type; + +import com.intellij.psi.PsiType; +import org.jetbrains.annotations.NotNull; + +/** + * @author Vitaliy.Bibaev + */ +public class GenericTypeUtil { + + public static GenericType fromPsiType(@NotNull PsiType type) { + if (PsiType.VOID.equals(type)) return GenericType.VOID; + if (PsiType.INT.equals(type)) return GenericType.INT; + if (PsiType.DOUBLE.equals(type)) return GenericType.DOUBLE; + if (PsiType.LONG.equals(type)) return GenericType.LONG; + if (PsiType.BOOLEAN.equals(type)) return GenericType.BOOLEAN; + return GenericType.OBJECT; + } +} diff --git a/src/main/java/com/intellij/debugger/streams/wrapper/TerminatorStreamCall.java b/src/main/java/com/intellij/debugger/streams/wrapper/TerminatorStreamCall.java index c663c20..ce7ad58 100644 --- a/src/main/java/com/intellij/debugger/streams/wrapper/TerminatorStreamCall.java +++ b/src/main/java/com/intellij/debugger/streams/wrapper/TerminatorStreamCall.java @@ -15,9 +15,13 @@ */ package com.intellij.debugger.streams.wrapper; +import com.intellij.debugger.streams.trace.impl.handler.type.GenericType; +import org.jetbrains.annotations.NotNull; + /** * @author Vitaliy.Bibaev */ public interface TerminatorStreamCall extends StreamCall, TypeBeforeAwareCall { - boolean isVoid(); + @NotNull + GenericType getResultType(); } diff --git a/src/main/java/com/intellij/debugger/streams/wrapper/impl/StreamChainBuilderImpl.java b/src/main/java/com/intellij/debugger/streams/wrapper/impl/StreamChainBuilderImpl.java index 0f866fd..35ce585 100644 --- a/src/main/java/com/intellij/debugger/streams/wrapper/impl/StreamChainBuilderImpl.java +++ b/src/main/java/com/intellij/debugger/streams/wrapper/impl/StreamChainBuilderImpl.java @@ -16,6 +16,7 @@ package com.intellij.debugger.streams.wrapper.impl; import com.intellij.debugger.streams.trace.impl.handler.type.GenericType; +import com.intellij.debugger.streams.trace.impl.handler.type.GenericTypeUtil; import com.intellij.debugger.streams.wrapper.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Computable; @@ -106,8 +107,8 @@ public StreamChain build(@NotNull PsiElement startElement) { prevCallType = currentType; } else if (StreamCallType.TERMINATOR.equals(type)) { - final TerminatorStreamCallImpl terminator = - new TerminatorStreamCallImpl(callName, callArgs, prevCallType, currentType.equals(GenericType.VOID)); + final GenericType genericType = resolveTerminationCallType(methodCall); + final TerminatorStreamCallImpl terminator = new TerminatorStreamCallImpl(callName, callArgs, prevCallType, genericType); return new StreamChainImpl(producer, intermediateStreamCalls, terminator, startElement); } else { @@ -150,6 +151,16 @@ private static GenericType resolveType(@NotNull PsiMethodCallExpression call) { }); } + private static GenericType resolveTerminationCallType(@NotNull PsiMethodCallExpression call) { + return ApplicationManager.getApplication().runReadAction((Computable)() -> { + final PsiMethod method = call.resolveMethod(); + if (method == null) return null; + final PsiType returnType = method.getReturnType(); + if (returnType == null) return null; + return GenericTypeUtil.fromPsiType(returnType); + }); + } + @Nullable private static PsiMethodCallExpression tryFindStreamCall(@NotNull PsiElement startElement) { PsiElement current = startElement; diff --git a/src/main/java/com/intellij/debugger/streams/wrapper/impl/TerminatorStreamCallImpl.java b/src/main/java/com/intellij/debugger/streams/wrapper/impl/TerminatorStreamCallImpl.java index 1ee318d..68258e0 100644 --- a/src/main/java/com/intellij/debugger/streams/wrapper/impl/TerminatorStreamCallImpl.java +++ b/src/main/java/com/intellij/debugger/streams/wrapper/impl/TerminatorStreamCallImpl.java @@ -25,12 +25,12 @@ */ public class TerminatorStreamCallImpl extends StreamCallImpl implements TerminatorStreamCall { private final GenericType myTypeBefore; - private final boolean myIsVoid; + private final GenericType myReturnType; - TerminatorStreamCallImpl(@NotNull String name, @NotNull String args, @NotNull GenericType typeBefore, boolean isVoid) { + TerminatorStreamCallImpl(@NotNull String name, @NotNull String args, @NotNull GenericType typeBefore, GenericType resultType) { super(name, args, StreamCallType.TERMINATOR); myTypeBefore = typeBefore; - myIsVoid = isVoid; + myReturnType = resultType; } @NotNull @@ -39,8 +39,9 @@ public GenericType getTypeBefore() { return myTypeBefore; } + @NotNull @Override - public boolean isVoid() { - return myIsVoid; + public GenericType getResultType() { + return myReturnType; } } From 4fe93f62f29ab4e71f43044cf57543b8345ea093 Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 17:55:17 +0300 Subject: [PATCH 03/11] Add tests for detection primitive types in the termination call --- .../positive/TerminationCallTypeTest.java | 68 +++++++++++++++++++ .../positive/terminationType/BooleanType.java | 7 ++ .../positive/terminationType/DoubleType.java | 7 ++ .../positive/terminationType/IntType.java | 7 ++ .../positive/terminationType/LongType.java | 7 ++ .../terminationType/ReferenceType.java | 7 ++ .../positive/terminationType/VoidType.java | 8 +++ 7 files changed, 111 insertions(+) create mode 100644 src/test/java/com/intellij/debugger/streams/chain/positive/TerminationCallTypeTest.java create mode 100644 testData/chain/positive/terminationType/BooleanType.java create mode 100644 testData/chain/positive/terminationType/DoubleType.java create mode 100644 testData/chain/positive/terminationType/IntType.java create mode 100644 testData/chain/positive/terminationType/LongType.java create mode 100644 testData/chain/positive/terminationType/ReferenceType.java create mode 100644 testData/chain/positive/terminationType/VoidType.java diff --git a/src/test/java/com/intellij/debugger/streams/chain/positive/TerminationCallTypeTest.java b/src/test/java/com/intellij/debugger/streams/chain/positive/TerminationCallTypeTest.java new file mode 100644 index 0000000..2e36ece --- /dev/null +++ b/src/test/java/com/intellij/debugger/streams/chain/positive/TerminationCallTypeTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.streams.chain.positive; + +import com.intellij.debugger.streams.trace.impl.handler.type.GenericType; +import com.intellij.debugger.streams.wrapper.StreamChain; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +/** + * @author Vitaliy.Bibaev + */ +public class TerminationCallTypeTest extends StreamChainBuilderPositiveTestBase { + public void testVoidType() throws Exception { + doTest(GenericType.VOID); + } + + public void testBooleanType() throws Exception { + doTest(GenericType.BOOLEAN); + } + + public void testIntType() throws Exception { + doTest(GenericType.INT); + } + + public void testDoubleType() throws Exception { + doTest(GenericType.DOUBLE); + } + + public void testLongType() throws Exception { + doTest(GenericType.LONG); + } + + public void testReferenceType() throws Exception { + doTest(GenericType.OBJECT); + } + + @NotNull + @Override + protected String getDirectoryName() { + return "terminationType"; + } + + protected void doTest(@NotNull GenericType returnType) throws Exception { + final PsiElement elementAtCaret = configureAndGetElementAtCaret(); + assertNotNull(elementAtCaret); + final StreamChain chain = getChainBuilder().build(elementAtCaret); + assertNotNull(chain); + assertEquals(returnType, chain.getTerminationCall().getResultType()); + } + + @Override + protected void checkResultChain(StreamChain chain) { + } +} diff --git a/testData/chain/positive/terminationType/BooleanType.java b/testData/chain/positive/terminationType/BooleanType.java new file mode 100644 index 0000000..a6c9346 --- /dev/null +++ b/testData/chain/positive/terminationType/BooleanType.java @@ -0,0 +1,7 @@ +import java.util.stream.IntStream; + +public class Baz { + public static void bar() { + IntStream.of(1, 3).anyMatch(x -> x % 2 == 0); + } +} diff --git a/testData/chain/positive/terminationType/DoubleType.java b/testData/chain/positive/terminationType/DoubleType.java new file mode 100644 index 0000000..725cff6 --- /dev/null +++ b/testData/chain/positive/terminationType/DoubleType.java @@ -0,0 +1,7 @@ +import java.util.stream.DoubleStream; + +public class Baz { + public static void bar() { + DoubleStream.of(1, 2, 3).sum(); + } +} diff --git a/testData/chain/positive/terminationType/IntType.java b/testData/chain/positive/terminationType/IntType.java new file mode 100644 index 0000000..86558fd --- /dev/null +++ b/testData/chain/positive/terminationType/IntType.java @@ -0,0 +1,7 @@ +import java.util.stream.IntStream; + +public class Baz { + public static void bar() { + IntStream.of(1, 2, 3).sum(); + } +} diff --git a/testData/chain/positive/terminationType/LongType.java b/testData/chain/positive/terminationType/LongType.java new file mode 100644 index 0000000..3ec8a7a --- /dev/null +++ b/testData/chain/positive/terminationType/LongType.java @@ -0,0 +1,7 @@ +import java.util.stream.LongStream; + +public class Baz { + public static void bar() { + LongStream.of(1, 2, 3).sum(); + } +} diff --git a/testData/chain/positive/terminationType/ReferenceType.java b/testData/chain/positive/terminationType/ReferenceType.java new file mode 100644 index 0000000..146eff0 --- /dev/null +++ b/testData/chain/positive/terminationType/ReferenceType.java @@ -0,0 +1,7 @@ +import java.util.stream.IntStream; + +public class Baz { + public static void bar() { + final int[] res = IntStream.of(1, 2).toArray(); + } +} diff --git a/testData/chain/positive/terminationType/VoidType.java b/testData/chain/positive/terminationType/VoidType.java new file mode 100644 index 0000000..51277e8 --- /dev/null +++ b/testData/chain/positive/terminationType/VoidType.java @@ -0,0 +1,8 @@ +import java.util.stream.Stream; + +public class Baz { + public static void bar() { + Stream.of(1).forEach(x -> { + }); + } +} From 3c23b76a4c4313c0c2cfcd81db16a42055373b95 Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 18:15:18 +0300 Subject: [PATCH 04/11] Minor: remove empty lines --- .../chain/positive/StreamChainBuilderPositiveTestBase.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/com/intellij/debugger/streams/chain/positive/StreamChainBuilderPositiveTestBase.java b/src/test/java/com/intellij/debugger/streams/chain/positive/StreamChainBuilderPositiveTestBase.java index b088dea..1f91f59 100644 --- a/src/test/java/com/intellij/debugger/streams/chain/positive/StreamChainBuilderPositiveTestBase.java +++ b/src/test/java/com/intellij/debugger/streams/chain/positive/StreamChainBuilderPositiveTestBase.java @@ -40,8 +40,6 @@ void doTest() throws Exception { checkResultChain(chain); } - - @NotNull protected abstract String getDirectoryName(); From 9b4187867139c375bd2a0f5afad53121ff0b114b Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 18:15:46 +0300 Subject: [PATCH 05/11] Minor: extract code to utility method --- .../impl/handler/type/GenericTypeUtil.java | 11 ++++++++ .../wrapper/impl/StreamChainBuilderImpl.java | 25 +++---------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericTypeUtil.java b/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericTypeUtil.java index 03f8ee1..62f377f 100644 --- a/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericTypeUtil.java +++ b/src/main/java/com/intellij/debugger/streams/trace/impl/handler/type/GenericTypeUtil.java @@ -15,7 +15,9 @@ */ package com.intellij.debugger.streams.trace.impl.handler.type; +import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiType; +import com.intellij.psi.util.InheritanceUtil; import org.jetbrains.annotations.NotNull; /** @@ -23,6 +25,15 @@ */ public class GenericTypeUtil { + public static GenericType fromStreamPsiType(@NotNull PsiType streamPsiType) { + if (InheritanceUtil.isInheritor(streamPsiType, CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM)) return GenericType.INT; + if (InheritanceUtil.isInheritor(streamPsiType, CommonClassNames.JAVA_UTIL_STREAM_LONG_STREAM)) return GenericType.LONG; + if (InheritanceUtil.isInheritor(streamPsiType, CommonClassNames.JAVA_UTIL_STREAM_DOUBLE_STREAM)) return GenericType.DOUBLE; + if (PsiType.VOID.equals(streamPsiType)) return GenericType.VOID; + + return GenericType.OBJECT; + } + public static GenericType fromPsiType(@NotNull PsiType type) { if (PsiType.VOID.equals(type)) return GenericType.VOID; if (PsiType.INT.equals(type)) return GenericType.INT; diff --git a/src/main/java/com/intellij/debugger/streams/wrapper/impl/StreamChainBuilderImpl.java b/src/main/java/com/intellij/debugger/streams/wrapper/impl/StreamChainBuilderImpl.java index 35ce585..4490b41 100644 --- a/src/main/java/com/intellij/debugger/streams/wrapper/impl/StreamChainBuilderImpl.java +++ b/src/main/java/com/intellij/debugger/streams/wrapper/impl/StreamChainBuilderImpl.java @@ -127,27 +127,10 @@ else if (StreamCallType.TERMINATOR.equals(type)) { private static GenericType resolveType(@NotNull PsiMethodCallExpression call) { return ApplicationManager.getApplication().runReadAction((Computable)() -> { final PsiMethod method = call.resolveMethod(); - if (method != null) { - final PsiType returnType = method.getReturnType(); - if (returnType != null) { - if (InheritanceUtil.isInheritor(returnType, CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM)) { - return GenericType.INT; - } - if (InheritanceUtil.isInheritor(returnType, CommonClassNames.JAVA_UTIL_STREAM_LONG_STREAM)) { - return GenericType.LONG; - } - if (InheritanceUtil.isInheritor(returnType, CommonClassNames.JAVA_UTIL_STREAM_DOUBLE_STREAM)) { - return GenericType.DOUBLE; - } - - if (returnType.equals(PsiType.VOID)) { - return GenericType.VOID; - } - - return GenericType.OBJECT; - } - } - return null; + if (method == null) return null; + final PsiType returnType = method.getReturnType(); + if (returnType == null) return null; + return GenericTypeUtil.fromStreamPsiType(returnType); }); } From 802689c8d5517902eefd50a572d5b055ccc74c6c Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 18:32:02 +0300 Subject: [PATCH 06/11] Support primitive results in expression and in interpretation logic --- .../streams/trace/impl/TraceExpressionBuilderImpl.java | 4 ++-- .../streams/trace/impl/TraceResultInterpreterImpl.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/intellij/debugger/streams/trace/impl/TraceExpressionBuilderImpl.java b/src/main/java/com/intellij/debugger/streams/trace/impl/TraceExpressionBuilderImpl.java index 3cbdae7..69ed41b 100644 --- a/src/main/java/com/intellij/debugger/streams/trace/impl/TraceExpressionBuilderImpl.java +++ b/src/main/java/com/intellij/debugger/streams/trace/impl/TraceExpressionBuilderImpl.java @@ -152,11 +152,11 @@ private static String buildDeclarations(@NotNull StreamCallTraceHandler producer private static String buildStreamExpression(@NotNull StreamChain chain) { final GenericType resultType = chain.getTerminationCall().getResultType(); if (resultType.equals(GenericType.VOID)) { - final String resultInitialization = "final Object streamResult = null;" + LINE_SEPARATOR; + final String resultInitialization = "final Object streamResult = new Object[1];" + LINE_SEPARATOR; return resultInitialization + chain.getText() + ";" + LINE_SEPARATOR; } else { - return "final " + resultType.getVariableTypeName() + " streamResult = " + chain.getText() + ";" + LINE_SEPARATOR; + return "final Object streamResult = new " + resultType.getVariableTypeName() + "[] { " + chain.getText() + " };" + LINE_SEPARATOR; } } diff --git a/src/main/java/com/intellij/debugger/streams/trace/impl/TraceResultInterpreterImpl.java b/src/main/java/com/intellij/debugger/streams/trace/impl/TraceResultInterpreterImpl.java index 4400ff4..b724875 100644 --- a/src/main/java/com/intellij/debugger/streams/trace/impl/TraceResultInterpreterImpl.java +++ b/src/main/java/com/intellij/debugger/streams/trace/impl/TraceResultInterpreterImpl.java @@ -43,7 +43,7 @@ public class TraceResultInterpreterImpl implements TraceResultInterpreter { @Override public TracingResult interpret(@NotNull StreamChain chain, @NotNull ArrayReference resultArray) { final ArrayReference info = (ArrayReference)resultArray.getValue(0); - final Value streamResult = resultArray.getValue(1); + final Value streamResult = ((ArrayReference)resultArray.getValue(1)).getValue(0); final Value time = resultArray.getValue(2); logTime(time); final List trace = getTrace(chain, info); From 7d228c91d0a5fcc41e4e8f6a6971c38c4128cd58 Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 19:17:59 +0300 Subject: [PATCH 07/11] Fix bug when result of stream evaluation checks two times --- .../intellij/debugger/streams/exec/TraceExecutionTestCase.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/com/intellij/debugger/streams/exec/TraceExecutionTestCase.java b/src/test/java/com/intellij/debugger/streams/exec/TraceExecutionTestCase.java index 6dcb5da..79e7256 100644 --- a/src/test/java/com/intellij/debugger/streams/exec/TraceExecutionTestCase.java +++ b/src/test/java/com/intellij/debugger/streams/exec/TraceExecutionTestCase.java @@ -144,7 +144,6 @@ protected void handleResults(@Nullable StreamChain chain, handleTrace(trace); final ResolvedTracingResult resolvedTrace = result.resolve(); - handleResultValue(resolvedTrace.getResult(), resultMustBeNull); handleResolvedTrace(resolvedTrace); } From c2dc4f3ce6d76d06b073fc641687d52b6792fcc2 Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 19:18:22 +0300 Subject: [PATCH 08/11] Add tests to check evaluation with primitive type as result --- .../exec/PrimitiveTerminalOperationTest.java | 54 +++++++++++++++++++ .../debug/outs/primitiveResultBoolean.out | 19 +++++++ testData/debug/outs/primitiveResultDouble.out | 21 ++++++++ testData/debug/outs/primitiveResultInt.out | 20 +++++++ testData/debug/outs/primitiveResultLong.out | 20 +++++++ .../debug/src/PrimitiveResultBoolean.java | 8 +++ testData/debug/src/PrimitiveResultDouble.java | 8 +++ testData/debug/src/PrimitiveResultInt.java | 8 +++ testData/debug/src/PrimitiveResultLong.java | 8 +++ 9 files changed, 166 insertions(+) create mode 100644 src/test/java/com/intellij/debugger/streams/exec/PrimitiveTerminalOperationTest.java create mode 100644 testData/debug/outs/primitiveResultBoolean.out create mode 100644 testData/debug/outs/primitiveResultDouble.out create mode 100644 testData/debug/outs/primitiveResultInt.out create mode 100644 testData/debug/outs/primitiveResultLong.out create mode 100644 testData/debug/src/PrimitiveResultBoolean.java create mode 100644 testData/debug/src/PrimitiveResultDouble.java create mode 100644 testData/debug/src/PrimitiveResultInt.java create mode 100644 testData/debug/src/PrimitiveResultLong.java diff --git a/src/test/java/com/intellij/debugger/streams/exec/PrimitiveTerminalOperationTest.java b/src/test/java/com/intellij/debugger/streams/exec/PrimitiveTerminalOperationTest.java new file mode 100644 index 0000000..b7c285a --- /dev/null +++ b/src/test/java/com/intellij/debugger/streams/exec/PrimitiveTerminalOperationTest.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.streams.exec; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.process.ProcessOutputTypes; +import com.sun.jdi.PrimitiveValue; +import com.sun.jdi.Value; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.InvocationTargetException; + +/** + * @author Vitaliy.Bibaev + */ +public class PrimitiveTerminalOperationTest extends TraceExecutionTestCase { + public void testPrimitiveResultBoolean() throws InterruptedException, ExecutionException, InvocationTargetException { + doTest(false); + } + + public void testPrimitiveResultInt() throws InterruptedException, ExecutionException, InvocationTargetException { + doTest(false); + } + + public void testPrimitiveResultDouble() throws InterruptedException, ExecutionException, InvocationTargetException { + doTest(false); + } + + public void testPrimitiveResultLong() throws InterruptedException, ExecutionException, InvocationTargetException { + doTest(false); + } + + @Override + protected void handleResultValue(@Nullable Value result, boolean mustBeNull) { + assertFalse(mustBeNull); + assertNotNull(result); + assertInstanceOf(result, PrimitiveValue.class); + println("Result type:" + result.type().name(), ProcessOutputTypes.SYSTEM); + println("value = " + result.toString(), ProcessOutputTypes.SYSTEM); + } +} diff --git a/testData/debug/outs/primitiveResultBoolean.out b/testData/debug/outs/primitiveResultBoolean.out new file mode 100644 index 0000000..a59897e --- /dev/null +++ b/testData/debug/outs/primitiveResultBoolean.out @@ -0,0 +1,19 @@ +LineBreakpoint created at PrimitiveResultBoolean.java:6 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!RT_JAR! PrimitiveResultBoolean +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +PrimitiveResultBoolean.java:5 +Stream.of(1) +.anyMatch(x -> x == 2) +Result type:boolean +value = false +Stream.of + before: nothing + after: 1 +anyMatch + before: 1 + after: nothing +mappings for anyMatch + nothing -> 1 -> nothing +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/testData/debug/outs/primitiveResultDouble.out b/testData/debug/outs/primitiveResultDouble.out new file mode 100644 index 0000000..bdfc1a9 --- /dev/null +++ b/testData/debug/outs/primitiveResultDouble.out @@ -0,0 +1,21 @@ +LineBreakpoint created at PrimitiveResultDouble.java:6 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!RT_JAR! PrimitiveResultDouble +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +PrimitiveResultDouble.java:5 +DoubleStream.of(1, 2, 3) +.sum() +Result type:double +value = 6.0 +DoubleStream.of + before: nothing + after: 1,2,3 +sum + before: 1,2,3 + after: nothing +mappings for sum + nothing -> 1 -> nothing + nothing -> 2 -> nothing + nothing -> 3 -> nothing +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/testData/debug/outs/primitiveResultInt.out b/testData/debug/outs/primitiveResultInt.out new file mode 100644 index 0000000..ba88205 --- /dev/null +++ b/testData/debug/outs/primitiveResultInt.out @@ -0,0 +1,20 @@ +LineBreakpoint created at PrimitiveResultInt.java:6 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!RT_JAR! PrimitiveResultInt +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +PrimitiveResultInt.java:5 +IntStream.of(1, 2) +.sum() +Result type:int +value = 3 +IntStream.of + before: nothing + after: 1,2 +sum + before: 1,2 + after: nothing +mappings for sum + nothing -> 1 -> nothing + nothing -> 2 -> nothing +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/testData/debug/outs/primitiveResultLong.out b/testData/debug/outs/primitiveResultLong.out new file mode 100644 index 0000000..1cff32b --- /dev/null +++ b/testData/debug/outs/primitiveResultLong.out @@ -0,0 +1,20 @@ +LineBreakpoint created at PrimitiveResultLong.java:6 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!RT_JAR! PrimitiveResultLong +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +PrimitiveResultLong.java:5 +IntStream.of(1, 2) +.count() +Result type:long +value = 2 +IntStream.of + before: nothing + after: 1,2 +count + before: 1,2 + after: nothing +mappings for count + nothing -> 1 -> nothing + nothing -> 2 -> nothing +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/testData/debug/src/PrimitiveResultBoolean.java b/testData/debug/src/PrimitiveResultBoolean.java new file mode 100644 index 0000000..cdc88f9 --- /dev/null +++ b/testData/debug/src/PrimitiveResultBoolean.java @@ -0,0 +1,8 @@ +import java.util.stream.Stream; + +public class PrimitiveResultBoolean { + public static void main(String[] args) { + // Breakpoint! + boolean res = Stream.of(1).anyMatch(x -> x == 2); + } +} diff --git a/testData/debug/src/PrimitiveResultDouble.java b/testData/debug/src/PrimitiveResultDouble.java new file mode 100644 index 0000000..00d21de --- /dev/null +++ b/testData/debug/src/PrimitiveResultDouble.java @@ -0,0 +1,8 @@ +import java.util.stream.DoubleStream; + +public class PrimitiveResultDouble { + public static void main(String[] args) { + // Breakpoint! + double res = DoubleStream.of(1, 2, 3).sum(); + } +} diff --git a/testData/debug/src/PrimitiveResultInt.java b/testData/debug/src/PrimitiveResultInt.java new file mode 100644 index 0000000..a756ea8 --- /dev/null +++ b/testData/debug/src/PrimitiveResultInt.java @@ -0,0 +1,8 @@ +import java.util.stream.IntStream; + +public class PrimitiveResultInt { + public static void main(String[] args) { + // Breakpoint! + int res = IntStream.of(1, 2).sum(); + } +} diff --git a/testData/debug/src/PrimitiveResultLong.java b/testData/debug/src/PrimitiveResultLong.java new file mode 100644 index 0000000..0eabcd0 --- /dev/null +++ b/testData/debug/src/PrimitiveResultLong.java @@ -0,0 +1,8 @@ +import java.util.stream.IntStream; + +public class PrimitiveResultLong { + public static void main(String[] args) { + // Breakpoint! + long res = IntStream.of(1, 2).count(); + } +} From e9e7f967a72d51f984e27b9b2e0615d902451fec Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 19:34:38 +0300 Subject: [PATCH 09/11] Add test to check that resolving sorted call for signed zeros is correct --- .../streams/exec/SpecialCasesTest.java | 29 +++++++++++++++++++ .../debug/outs/sortedSignedDoubleZeros.out | 25 ++++++++++++++++ .../debug/src/SortedSignedDoubleZeros.java | 8 +++++ 3 files changed, 62 insertions(+) create mode 100644 src/test/java/com/intellij/debugger/streams/exec/SpecialCasesTest.java create mode 100644 testData/debug/outs/sortedSignedDoubleZeros.out create mode 100644 testData/debug/src/SortedSignedDoubleZeros.java diff --git a/src/test/java/com/intellij/debugger/streams/exec/SpecialCasesTest.java b/src/test/java/com/intellij/debugger/streams/exec/SpecialCasesTest.java new file mode 100644 index 0000000..9da17c8 --- /dev/null +++ b/src/test/java/com/intellij/debugger/streams/exec/SpecialCasesTest.java @@ -0,0 +1,29 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.debugger.streams.exec; + +import com.intellij.execution.ExecutionException; + +import java.lang.reflect.InvocationTargetException; + +/** + * @author Vitaliy.Bibaev + */ +public class SpecialCasesTest extends TraceExecutionTestCase { + public void testSortedSignedDoubleZeros() throws InterruptedException, ExecutionException, InvocationTargetException { + doTest(false); + } +} diff --git a/testData/debug/outs/sortedSignedDoubleZeros.out b/testData/debug/outs/sortedSignedDoubleZeros.out new file mode 100644 index 0000000..a96273b --- /dev/null +++ b/testData/debug/outs/sortedSignedDoubleZeros.out @@ -0,0 +1,25 @@ +LineBreakpoint created at SortedSignedDoubleZeros.java:6 +!JDK_HOME!\bin\java -agentlib:jdwp=transport=dt_socket,address=!HOST_NAME!:!HOST_PORT!,suspend=y,server=n -Dfile.encoding=!FILE_ENCODING! -classpath !OUTPUT_PATH!;!RT_JAR! SortedSignedDoubleZeros +Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' +SortedSignedDoubleZeros.java:5 +DoubleStream.of(0., -0.) +.sorted() +.sum() +DoubleStream.of + before: nothing + after: 1,2 +sorted + before: 1,2 + after: 3,4 +sum + before: 3,4 + after: nothing +mappings for sorted + nothing -> 1 -> 4 + nothing -> 2 -> 3 +mappings for sum + 1 -> 3 -> nothing + 2 -> 4 -> nothing +Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' + +Process finished with exit code 0 diff --git a/testData/debug/src/SortedSignedDoubleZeros.java b/testData/debug/src/SortedSignedDoubleZeros.java new file mode 100644 index 0000000..d425fac --- /dev/null +++ b/testData/debug/src/SortedSignedDoubleZeros.java @@ -0,0 +1,8 @@ +import java.util.stream.DoubleStream; + +public class SortedSignedDoubleZeros { + public static void main(String[] args) { + // Breakpoint! + double sum = DoubleStream.of(0., -0.).sorted().sum(); + } +} From a08ea2678ddbd9da3808d02b561cb6085370879d Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 20:23:17 +0300 Subject: [PATCH 10/11] Fix wrong transitions for resolving of sorting of signed zeros --- .../streams/resolve/IdentityResolver.java | 33 ++++++++++++++----- .../debug/outs/sortedSignedDoubleZeros.out | 4 +-- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/intellij/debugger/streams/resolve/IdentityResolver.java b/src/main/java/com/intellij/debugger/streams/resolve/IdentityResolver.java index 2ad5643..5f88e95 100644 --- a/src/main/java/com/intellij/debugger/streams/resolve/IdentityResolver.java +++ b/src/main/java/com/intellij/debugger/streams/resolve/IdentityResolver.java @@ -17,7 +17,8 @@ import com.intellij.debugger.streams.trace.TraceElement; import com.intellij.debugger.streams.trace.TraceInfo; -import com.sun.jdi.Value; +import com.intellij.openapi.diagnostic.Logger; +import com.sun.jdi.*; import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; @@ -30,6 +31,8 @@ * @author Vitaliy.Bibaev */ public class IdentityResolver implements ValuesOrderResolver { + private static final Logger LOG = Logger.getInstance(IdentityResolver.class); + @NotNull @Override public Result resolve(@NotNull TraceInfo info) { @@ -39,15 +42,14 @@ public Result resolve(@NotNull TraceInfo info) { final Map> direct = new HashMap<>(); final Map> reverse = new HashMap<>(); - final Map> grouped = new HashMap<>( - StreamEx.of(after.keySet()) - .sorted() - .map(after::get) - .groupingBy(TraceElement::getValue) - ); + final Map> grouped = StreamEx + .of(after.keySet()) + .sorted() + .map(after::get) + .groupingBy(IdentityResolver::extractKey); for (final TraceElement element : before.values()) { - final Value value = element.getValue(); + final Object value = extractKey(element); final List elements = grouped.get(value); final TraceElement afterItem = elements.get(0); @@ -60,4 +62,19 @@ public Result resolve(@NotNull TraceInfo info) { return Result.of(direct, reverse); } + + private static Object extractKey(@NotNull TraceElement element) { + final Value value = element.getValue(); + if (!(value instanceof PrimitiveValue)) return value; + if (value instanceof IntegerValue) return ((IntegerValue)value).value(); + if (value instanceof DoubleValue) return ((DoubleValue)value).value(); + if (value instanceof LongValue) return ((LongValue)value).value(); + if (value instanceof BooleanValue) return ((BooleanValue)value).value(); + if (value instanceof ByteValue) return ((ByteValue)value).value(); + if (value instanceof CharValue) return ((CharValue)value).value(); + if (value instanceof FloatValue) return ((FloatValue)value).value(); + + LOG.error("unknown primitive value: " + value.type().name()); + return null; + } } diff --git a/testData/debug/outs/sortedSignedDoubleZeros.out b/testData/debug/outs/sortedSignedDoubleZeros.out index a96273b..5972b09 100644 --- a/testData/debug/outs/sortedSignedDoubleZeros.out +++ b/testData/debug/outs/sortedSignedDoubleZeros.out @@ -18,8 +18,8 @@ mappings for sorted nothing -> 1 -> 4 nothing -> 2 -> 3 mappings for sum - 1 -> 3 -> nothing - 2 -> 4 -> nothing + 2 -> 3 -> nothing + 1 -> 4 -> nothing Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 From a25e0028621d7206f1a0552473d7808e99402e23 Mon Sep 17 00:00:00 2001 From: "Vitaliy.Bibaev" Date: Thu, 20 Apr 2017 20:46:54 +0300 Subject: [PATCH 11/11] Update version: 0.0.9 --- build.gradle | 2 +- src/main/resources/META-INF/plugin.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index de1b9aa..4cc9d87 100644 --- a/build.gradle +++ b/build.gradle @@ -28,7 +28,7 @@ apply plugin: 'java' apply plugin: "kotlin" group 'com.intellij.debugger.stream' -version '0.0.8' +version '0.0.9' intellij { type = 'IC' diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 5b7603f..fcc180c 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -1,7 +1,7 @@ org.jetbrains.debugger.streams Java Streams Debugger - 0.0.8 + 0.0.9 JetBrains