diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java index a5ed7e075af7..a879c6f45535 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java @@ -3,6 +3,7 @@ package com.intellij.debugger.ui.impl.watch; import com.intellij.compiler.CompilerConfiguration; import com.intellij.compiler.server.BuildManager; +import com.intellij.debugger.engine.SuspendContextImpl; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; import com.intellij.openapi.application.ApplicationManager; @@ -26,6 +27,8 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.refactoring.extractMethod.PrepareFailedException; import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler; +import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.frame.XSuspendContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.incremental.java.JavaBuilder; @@ -140,11 +143,22 @@ public class CompilingEvaluatorImpl extends CompilingEvaluator { if (Registry.is("debugger.compiling.evaluator") && psiContext != null) { return ApplicationManager.getApplication().runReadAction((ThrowableComputable)() -> { try { + boolean useReflection = !Registry.is("debugger.compiling.evaluator.magic.accessor", true); + if (!useReflection) { + XSuspendContext suspendContext = XDebuggerManager.getInstance(project).getCurrentSession().getSuspendContext(); + if (suspendContext instanceof SuspendContextImpl) { + JavaSdkVersion version = + JavaSdkVersion.fromVersionString(((SuspendContextImpl)suspendContext).getDebugProcess().getVirtualMachineProxy().version()); + useReflection = version != null && version.isAtLeast(JavaSdkVersion.JDK_1_9); + } + } + ExtractLightMethodObjectHandler.ExtractedData data = ExtractLightMethodObjectHandler.extractLightMethodObject( project, findPhysicalContext(psiContext), fragmentFactory.apply(psiContext), - getGeneratedClassName()); + getGeneratedClassName(), + useReflection); if (data != null) { return new CompilingEvaluatorImpl(project, psiContext, data); } diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java index 94606da170a2..1ba69a12ea7e 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java @@ -29,6 +29,7 @@ import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.extractMethod.AbstractExtractDialog; import com.intellij.refactoring.extractMethod.InputVariables; import com.intellij.refactoring.extractMethod.PrepareFailedException; +import com.intellij.refactoring.extractMethodObject.reflect.CompositeReflectionAccessor; import com.intellij.refactoring.util.RefactoringUtil; import com.intellij.refactoring.util.VariableData; import com.intellij.usageView.UsageInfo; @@ -71,7 +72,8 @@ public class ExtractLightMethodObjectHandler { public static ExtractedData extractLightMethodObject(final Project project, @Nullable PsiElement originalContext, @NotNull final PsiCodeFragment fragment, - final String methodName) throws PrepareFailedException { + final String methodName, + boolean useReflection) throws PrepareFailedException { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project); PsiElement[] elements = completeToStatementArray(fragment, elementFactory); if (elements == null) { @@ -196,25 +198,27 @@ public class ExtractLightMethodObjectHandler { PsiStatement outStatement = elementFactory.createStatementFromText("System.out.println(" + outputVariables + ");", anchor); outStatement = (PsiStatement)container.addAfter(outStatement, elementsCopy[elementsCopy.length - 1]); - copy.accept(new JavaRecursiveElementWalkingVisitor() { - private void makePublic(PsiMember method) { - if (method.hasModifierProperty(PsiModifier.PRIVATE)) { - VisibilityUtil.setVisibility(method.getModifierList(), PsiModifier.PUBLIC); + if (!useReflection) { + copy.accept(new JavaRecursiveElementWalkingVisitor() { + private void makePublic(PsiMember method) { + if (method.hasModifierProperty(PsiModifier.PRIVATE)) { + VisibilityUtil.setVisibility(method.getModifierList(), PsiModifier.PUBLIC); + } } - } - @Override - public void visitMethod(PsiMethod method) { - super.visitMethod(method); - makePublic(method); - } + @Override + public void visitMethod(PsiMethod method) { + super.visitMethod(method); + makePublic(method); + } - @Override - public void visitField(PsiField field) { - super.visitField(field); - makePublic(field); - } - }); + @Override + public void visitField(PsiField field) { + super.visitField(field); + makePublic(field); + } + }); + } final ExtractMethodObjectProcessor extractMethodObjectProcessor = new ExtractMethodObjectProcessor(project, null, elementsCopy, "") { @Override @@ -253,6 +257,16 @@ public class ExtractLightMethodObjectHandler { } final int startOffset = startOffsetInContainer + container.getTextRange().getStartOffset(); + + final PsiClass inner = extractMethodObjectProcessor.getInnerClass(); + final PsiMethod[] methods = inner.findMethodsByName("invoke", false); + + if (useReflection && methods.length == 1) { + final PsiMethod method = methods[0]; + CompositeReflectionAccessor.createAccessorToEverything(inner, elementFactory) + .accessThroughReflection(method); + } + final String generatedCall = copy.getText().substring(startOffset, outStatement.getTextOffset()); return new ExtractedData(generatedCall, (PsiClass)CodeStyleManager.getInstance(project).reformat(extractMethodObjectProcessor.getInnerClass()), diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ItemToReplaceDescriptor.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ItemToReplaceDescriptor.java new file mode 100644 index 000000000000..a2252e66fd84 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ItemToReplaceDescriptor.java @@ -0,0 +1,8 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject; + +/** + * @author Vitaliy.Bibaev + */ +public interface ItemToReplaceDescriptor { +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/PsiReflectionAccessUtil.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/PsiReflectionAccessUtil.java new file mode 100644 index 000000000000..001fcde9d05b --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/PsiReflectionAccessUtil.java @@ -0,0 +1,86 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Vitaliy.Bibaev + */ +public class PsiReflectionAccessUtil { + public static boolean isAccessibleMember(@NotNull PsiMember classMember) { + return classMember.hasModifierProperty(PsiModifier.PUBLIC) && isAccessible(classMember.getContainingClass()); + } + + @Contract("null -> false") + public static boolean isAccessible(@Nullable PsiClass psiClass) { + if (psiClass == null) return false; + while (psiClass != null) { + if (!psiClass.hasModifierProperty(PsiModifier.PUBLIC)) { + return false; + } + + psiClass = psiClass.getContainingClass(); + } + + return true; + } + + @Nullable + public static String extractQualifier(@NotNull PsiReferenceExpression referenceExpression) { + PsiExpression qualifierExpression = referenceExpression.getQualifierExpression(); + PsiType expressionType = qualifierExpression != null ? qualifierExpression.getType() : null; + return expressionType == null ? null : qualifierExpression.getText(); + } + + @Contract("null -> null") + @Nullable + public static PsiClass nearestAccessedClass(@Nullable PsiClass psiClass) { + while (psiClass != null && !psiClass.hasModifierProperty(PsiModifier.PUBLIC)) { + psiClass = psiClass.getSuperClass(); + } + + return psiClass; + } + + @Nullable + public static String getAccessibleReturnType(@Nullable PsiType type) { + PsiClass psiClass = nearestAccessedClass(PsiUtil.resolveClassInType(type)); + if (psiClass != null) { + return psiClass.getQualifiedName(); + } + + return type != null ? type.getCanonicalText() : null; + } + + @Nullable + public static String getAccessibleReturnType(@Nullable PsiClass psiClass) { + psiClass = nearestAccessedClass(psiClass); + return psiClass == null ? null : psiClass.getQualifiedName(); + } + + @NotNull + @Contract(pure = true) + public static String classForName(@NotNull String typeName) { + return TypeConversionUtil.isPrimitive(typeName) ? typeName + ".class" : "java.lang.Class.forName(\"" + typeName + "\")"; + } + + @NotNull + public static String getUniqueMethodName(@NotNull PsiClass psiClass, @NotNull String prefix) { + if (!StringUtil.isJavaIdentifier(prefix)) throw new IllegalArgumentException("prefix must be a correct java identifier: " + prefix); + int i = 1; + String name; + do { + name = prefix + i; + i++; + } + while (psiClass.findMethodsByName(name, false).length != 0); + + return name; + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/CompositeReflectionAccessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/CompositeReflectionAccessor.java new file mode 100644 index 000000000000..f1a55dd0f9fb --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/CompositeReflectionAccessor.java @@ -0,0 +1,41 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject.reflect; + +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementFactory; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Vitaliy.Bibaev + */ +public class CompositeReflectionAccessor implements ReflectionAccessor { + private final List myAccessors = new ArrayList<>(); + + private CompositeReflectionAccessor() { + } + + private void registerAccessor(@NotNull ReflectionAccessor accessor) { + myAccessors.add(accessor); + } + + public static ReflectionAccessor createAccessorToEverything(@NotNull PsiClass psiClass, @NotNull PsiElementFactory elementFactory) { + CompositeReflectionAccessor compositeAccessor = new CompositeReflectionAccessor(); + compositeAccessor.registerAccessor(new FieldReflectionAccessor(psiClass, elementFactory)); + compositeAccessor.registerAccessor(new MethodReflectionAccessor(psiClass, elementFactory)); + compositeAccessor.registerAccessor(new ConstructorReflectionAccessor(psiClass, elementFactory)); + compositeAccessor.registerAccessor(new MethodReferenceReflectionAccessor(psiClass, elementFactory)); + + return compositeAccessor; + } + + @Override + public void accessThroughReflection(@NotNull PsiElement element) { + for (ReflectionAccessor accessor : myAccessors) { + accessor.accessThroughReflection(element); + } + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ConstructorReflectionAccessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ConstructorReflectionAccessor.java new file mode 100644 index 000000000000..bfe00bc7e7c5 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ConstructorReflectionAccessor.java @@ -0,0 +1,104 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject.reflect; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.*; +import com.intellij.psi.util.ClassUtil; +import com.intellij.refactoring.extractMethodObject.ItemToReplaceDescriptor; +import com.intellij.refactoring.extractMethodObject.PsiReflectionAccessUtil; +import one.util.streamex.StreamEx; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Vitaliy.Bibaev + */ +public class ConstructorReflectionAccessor extends ReflectionAccessorBase { + private static final Logger LOG = Logger.getInstance(ConstructorReflectionAccessor.class); + + protected ConstructorReflectionAccessor(@NotNull PsiClass psiClass, + @NotNull PsiElementFactory elementFactory) { + super(psiClass, elementFactory); + } + + @Override + protected List findItemsToReplace(@NotNull PsiElement element) { + List result = new ArrayList<>(); + + element.accept(new JavaRecursiveElementVisitor() { + @Override + public void visitNewExpression(PsiNewExpression expression) { + super.visitNewExpression(expression); + if (expression.getAnonymousClass() != null || expression.getArrayInitializer() != null) return; + ConstructorDescriptor descriptor = ConstructorDescriptor.createIfInaccessible(expression); + if (descriptor != null) { + result.add(descriptor); + } + } + }); + + return result; + } + + @Override + protected void grantAccess(@NotNull ConstructorDescriptor descriptor) { + String className = ClassUtil.getJVMClassName(descriptor.psiClass); + String returnType = PsiReflectionAccessUtil.getAccessibleReturnType(descriptor.psiClass); + PsiExpressionList argumentList = descriptor.newExpression.getArgumentList(); + if (className == null || argumentList == null || returnType == null) { + LOG.debug("expression is incomplete"); + return; + } + + String methodName = PsiReflectionAccessUtil.getUniqueMethodName(getOuterClass(), "new" + className); + ReflectionAccessMethodBuilder methodBuilder = new ReflectionAccessMethodBuilder(methodName); + methodBuilder.accessedConstructor(className) + .setStatic(getOuterClass().hasModifierProperty(PsiModifier.STATIC)) + .setReturnType(returnType); + if (descriptor.constructor != null) { + methodBuilder.addParameters(descriptor.constructor.getParameterList()); + } + + PsiMethod newPsiMethod = methodBuilder.build(getElementFactory(), getOuterClass()); + getOuterClass().add(newPsiMethod); + String args = StreamEx.of(argumentList.getExpressions()).map(x -> x.getText()).joining(", ", "(", ")"); + String newCallExpression = newPsiMethod.getName() + args; + descriptor.newExpression.replace(getElementFactory().createExpressionFromText(newCallExpression, descriptor.newExpression)); + } + + public static class ConstructorDescriptor implements ItemToReplaceDescriptor { + public final PsiNewExpression newExpression; + public final PsiClass psiClass; + + // null if and only if default constructor is used + @Nullable public final PsiMethod constructor; + + @Nullable + public static ConstructorDescriptor createIfInaccessible(@NotNull PsiNewExpression expression) { + PsiMethod constructor = expression.resolveConstructor(); + if (constructor != null) { + PsiClass containingClass = constructor.getContainingClass(); + if (containingClass != null && !PsiReflectionAccessUtil.isAccessibleMember(constructor)) { + return new ConstructorDescriptor(expression, constructor, containingClass); + } + } + else { + PsiJavaCodeReferenceElement classReference = expression.getClassReference(); + if (classReference instanceof PsiClass && !PsiReflectionAccessUtil.isAccessible((PsiClass)classReference)) { + return new ConstructorDescriptor(expression, null, (PsiClass)classReference); + } + } + + return null; + } + + public ConstructorDescriptor(@NotNull PsiNewExpression expression, @Nullable PsiMethod constructor, PsiClass psiClass) { + newExpression = expression; + this.constructor = constructor; + this.psiClass = psiClass; + } + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/FieldAccessType.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/FieldAccessType.java new file mode 100644 index 000000000000..cfc83c234140 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/FieldAccessType.java @@ -0,0 +1,9 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject.reflect; + +/** + * @author Vitaliy.Bibaev + */ +public enum FieldAccessType { + GET, SET +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/FieldReflectionAccessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/FieldReflectionAccessor.java new file mode 100644 index 000000000000..e1dd9d45fb05 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/FieldReflectionAccessor.java @@ -0,0 +1,148 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject.reflect; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.ClassUtil; +import com.intellij.refactoring.extractMethodObject.ItemToReplaceDescriptor; +import com.intellij.refactoring.extractMethodObject.PsiReflectionAccessUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +/** + * @author Vitaliy.Bibaev + */ +public class FieldReflectionAccessor extends ReferenceReflectionAccessorBase { + private static final Logger LOG = Logger.getInstance(FieldReflectionAccessor.class); + + public FieldReflectionAccessor(@NotNull PsiClass psiClass, + @NotNull PsiElementFactory elementFactory) { + super(psiClass, elementFactory); + } + + @Nullable + @Override + protected FieldDescriptor createDescriptor(@NotNull PsiReferenceExpression expression) { + final PsiElement resolved = expression.resolve(); + if (resolved instanceof PsiField) { + final PsiField field = (PsiField)resolved; + String name = field.getName(); + if (name != null && !Objects.equals(field.getContainingClass(), getOuterClass()) && needReplace(field)) { + return new FieldDescriptor(field, expression); + } + } + + return null; + } + + @Override + protected void grantAccess(@NotNull FieldDescriptor descriptor) { + PsiElement parent = descriptor.expression.getParent(); + if (parent instanceof PsiAssignmentExpression && + Objects.equals(descriptor.expression, ((PsiAssignmentExpression)parent).getLExpression())) { + grantUpdateAccess((PsiAssignmentExpression)parent, descriptor); + } + else { + grantReadAccess(descriptor); + } + } + + private void grantReadAccess(@NotNull FieldDescriptor descriptor) { + PsiClass outerClass = getOuterClass(); + PsiMethod newMethod = createPsiMethod(descriptor, FieldAccessType.GET); + if (newMethod == null) return; + + outerClass.add(newMethod); + + String qualifier = qualify(descriptor); + String methodCall = newMethod.getName() + "(" + (qualifier == null ? "null" : qualifier) + ", null)"; + descriptor.expression.replace(getElementFactory().createExpressionFromText(methodCall, descriptor.expression)); + } + + private void grantUpdateAccess(@NotNull PsiAssignmentExpression assignmentExpression, @NotNull FieldDescriptor descriptor) { + PsiClass outerClass = getOuterClass(); + PsiMethod newMethod = createPsiMethod(descriptor, FieldAccessType.SET); + if (newMethod == null) return; + + outerClass.add(newMethod); + PsiExpression rightExpression = assignmentExpression.getRExpression(); + if (rightExpression == null) { + LOG.warn("Expression representing a new field value not found"); + return; + } + + String newValue = rightExpression.getText(); + String qualifier = qualify(descriptor); + String args = (qualifier == null ? "null" : qualifier) + ", " + newValue; + String methodCallExpression = newMethod.getName() + "(" + args + ")"; + + PsiExpression newMethodCallExpression = getElementFactory().createExpressionFromText(methodCallExpression, descriptor.expression); + assignmentExpression.replace(newMethodCallExpression); + } + + @Nullable + private PsiMethod createPsiMethod(@NotNull FieldDescriptor descriptor, FieldAccessType accessType) { + PsiClass outerClass = getOuterClass(); + PsiClass containingClass = descriptor.field.getContainingClass(); + String returnType = PsiReflectionAccessUtil.getAccessibleReturnType(descriptor.field.getType()); + String className = containingClass == null ? null : ClassUtil.getJVMClassName(containingClass); + String fieldName = descriptor.field.getName(); + if (className == null || fieldName == null) { + LOG.warn("Code is incomplete. Class name or field name not found"); + return null; + } + if (returnType == null) { + LOG.warn("Could not resolve return type"); + return null; + } + + String methodName = PsiReflectionAccessUtil.getUniqueMethodName(outerClass, "accessToField" + StringUtil.capitalize(fieldName)); + ReflectionAccessMethodBuilder methodBuilder = new ReflectionAccessMethodBuilder(methodName); + if (FieldAccessType.GET.equals(accessType)) { + methodBuilder.accessedField(className, fieldName) + .setReturnType(returnType); + } + else { + methodBuilder.updatedField(className, fieldName) + .setReturnType("void"); + } + + methodBuilder.setStatic(outerClass.hasModifierProperty(PsiModifier.STATIC)) + .addParameter("java.lang.Object", "object") + .addParameter("java.lang.Object", "value"); + + return methodBuilder.build(getElementFactory(), outerClass); + } + + protected boolean needReplace(@NotNull PsiField field) { + return !PsiReflectionAccessUtil.isAccessibleMember(field); + } + + @Nullable + private static String qualify(@NotNull FieldDescriptor descriptor) { + String qualifier = PsiReflectionAccessUtil.extractQualifier(descriptor.expression); + if (qualifier == null) { + if (!descriptor.field.hasModifierProperty(PsiModifier.STATIC)) { + PsiClass containingClass = descriptor.field.getContainingClass(); + if (containingClass != null) { + qualifier = containingClass.getQualifiedName() + ".this"; + } + } + } + + return qualifier; + } + + public static class FieldDescriptor implements ItemToReplaceDescriptor { + public final PsiField field; + public final PsiReferenceExpression expression; + + public FieldDescriptor(@NotNull PsiField field, @NotNull PsiReferenceExpression expression) { + this.field = field; + this.expression = expression; + } + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/MethodReferenceReflectionAccessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/MethodReferenceReflectionAccessor.java new file mode 100644 index 000000000000..4875d2c69312 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/MethodReferenceReflectionAccessor.java @@ -0,0 +1,74 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject.reflect; + +import com.intellij.psi.*; +import com.intellij.refactoring.extractMethodObject.ItemToReplaceDescriptor; +import com.intellij.refactoring.extractMethodObject.PsiReflectionAccessUtil; +import com.intellij.refactoring.extractMethodObject.reflect.ConstructorReflectionAccessor.ConstructorDescriptor; +import com.intellij.refactoring.util.LambdaRefactoringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import static com.intellij.refactoring.extractMethodObject.reflect.ConstructorReflectionAccessor.ConstructorDescriptor.createIfInaccessible; + +/** + * @author Vitaliy.Bibaev + */ +public class MethodReferenceReflectionAccessor + extends ReferenceReflectionAccessorBase { + private final MethodReflectionAccessor myMethodAccessor; + private final ConstructorReflectionAccessor myConstructorReflectionAccessor; + public MethodReferenceReflectionAccessor(@NotNull PsiClass psiClass, + @NotNull PsiElementFactory elementFactory) { + super(psiClass, elementFactory); + myMethodAccessor = new MethodReflectionAccessor(psiClass, elementFactory); + myConstructorReflectionAccessor = new ConstructorReflectionAccessor(psiClass, elementFactory); + } + + @Nullable + @Override + protected MethodReferenceDescriptor createDescriptor(@NotNull PsiReferenceExpression expression) { + if (expression instanceof PsiMethodReferenceExpression) { + PsiElement resolvedElement = expression.resolve(); + if (resolvedElement instanceof PsiMethod) { + PsiMethod method = (PsiMethod)resolvedElement; + if (!PsiReflectionAccessUtil.isAccessibleMember(method)) { + return new MethodReferenceDescriptor(method, (PsiMethodReferenceExpression)expression); + } + } + } + + return null; + } + + @Override + protected void grantAccess(@NotNull MethodReferenceDescriptor descriptor) { + PsiLambdaExpression lambda = LambdaRefactoringUtil.convertMethodReferenceToLambda(descriptor.expression, false, true); + if (lambda != null) { + PsiElement lambdaBody = lambda.getBody(); + if (lambdaBody instanceof PsiNewExpression) { + ConstructorDescriptor constructorDescriptor = createIfInaccessible((PsiNewExpression)lambdaBody); + if (constructorDescriptor != null) { + myConstructorReflectionAccessor.grantAccess(constructorDescriptor); + } + } + else if (lambdaBody instanceof PsiMethodCallExpression) { + PsiMethodCallExpression callExpression = (PsiMethodCallExpression)lambdaBody; + PsiMethod method = callExpression.resolveMethod(); + if (method != null) { + myMethodAccessor.grantAccess(new MethodReflectionAccessor.MethodCallDescriptor(callExpression, method)); + } + } + } + } + + public static class MethodReferenceDescriptor implements ItemToReplaceDescriptor { + public final PsiMethod method; + public final PsiMethodReferenceExpression expression; + + public MethodReferenceDescriptor(@NotNull PsiMethod method, @NotNull PsiMethodReferenceExpression expression) { + this.method = method; + this.expression = expression; + } + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/MethodReflectionAccessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/MethodReflectionAccessor.java new file mode 100644 index 000000000000..f009161ea46b --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/MethodReflectionAccessor.java @@ -0,0 +1,112 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject.reflect; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.ClassUtil; +import com.intellij.refactoring.extractMethodObject.ItemToReplaceDescriptor; +import com.intellij.refactoring.extractMethodObject.PsiReflectionAccessUtil; +import one.util.streamex.StreamEx; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @author Vitaliy.Bibaev + */ +public class MethodReflectionAccessor extends ReflectionAccessorBase { + private static final Logger LOG = Logger.getInstance(MethodReflectionAccessor.class); + + protected MethodReflectionAccessor(@NotNull PsiClass psiClass, + @NotNull PsiElementFactory elementFactory) { + super(psiClass, elementFactory); + } + + @Override + protected List findItemsToReplace(@NotNull PsiElement element) { + List result = new ArrayList<>(); + + element.accept(new JavaRecursiveElementVisitor() { + @Override + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + super.visitMethodCallExpression(expression); + PsiMethod method = expression.resolveMethod(); + if (method != null && !Objects.equals(method.getContainingClass(), getOuterClass()) && needReplace(method)) { + result.add(new MethodCallDescriptor(expression, method)); + } + } + }); + + return result; + } + + @Override + protected void grantAccess(@NotNull MethodCallDescriptor descriptor) { + PsiClass outerClass = getOuterClass(); + String returnType = PsiReflectionAccessUtil.getAccessibleReturnType(descriptor.method.getReturnType()); + PsiClass containingClass = descriptor.method.getContainingClass(); + String containingClassName = containingClass == null ? null : ClassUtil.getJVMClassName(containingClass); + String name = descriptor.method.getName(); + if (returnType == null) { + LOG.warn("return type of" + descriptor.method.getName() + " method is null"); + return; + } + + if (containingClassName == null) { + LOG.warn("containing class for method \"" + name + "\" not found"); + return; + } + + String newMethodName = PsiReflectionAccessUtil.getUniqueMethodName(outerClass, "call" + StringUtil.capitalize(name)); + ReflectionAccessMethodBuilder methodBuilder = new ReflectionAccessMethodBuilder(newMethodName); + PsiMethod newMethod = methodBuilder.accessedMethod(containingClassName, descriptor.method.getName()) + .setStatic(outerClass.hasModifierProperty(PsiModifier.STATIC)) + .addParameter("java.lang.Object", "object") + .addParameters(descriptor.method.getParameterList()) + .setReturnType(returnType) + .build(getElementFactory(), getOuterClass()); + + outerClass.add(newMethod); + String qualifier = qualify(descriptor); + String args = StreamEx.of(descriptor.callExpression.getArgumentList().getExpressions()) + .map(x -> x.getText()) + .prepend(qualifier == null ? "null" : qualifier) + .joining(", ", "(", ")"); + String newMethodCallExpression = newMethod.getName() + args; + + descriptor.callExpression.replace(getElementFactory().createExpressionFromText(newMethodCallExpression, descriptor.callExpression)); + } + + private static boolean needReplace(@NotNull PsiMethod method) { + return !PsiReflectionAccessUtil.isAccessibleMember(method); + } + + @Nullable + private static String qualify(@NotNull MethodCallDescriptor descriptor) { + String qualifier = PsiReflectionAccessUtil.extractQualifier(descriptor.callExpression.getMethodExpression()); + if (qualifier == null) { + if (!descriptor.method.hasModifierProperty(PsiModifier.STATIC)) { + PsiClass containingClass = descriptor.method.getContainingClass(); + if (containingClass != null) { + qualifier = containingClass.getQualifiedName() + ".this"; + } + } + } + + return qualifier; + } + + public static class MethodCallDescriptor implements ItemToReplaceDescriptor { + public final PsiMethodCallExpression callExpression; + public final PsiMethod method; + + public MethodCallDescriptor(@NotNull PsiMethodCallExpression expression, @NotNull PsiMethod method) { + callExpression = expression; + this.method = method; + } + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReferenceReflectionAccessorBase.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReferenceReflectionAccessorBase.java new file mode 100644 index 000000000000..f4c2a9ad3539 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReferenceReflectionAccessorBase.java @@ -0,0 +1,39 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject.reflect; + +import com.intellij.psi.*; +import com.intellij.refactoring.extractMethodObject.ItemToReplaceDescriptor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Vitaliy.Bibaev + */ +public abstract class ReferenceReflectionAccessorBase extends ReflectionAccessorBase { + public ReferenceReflectionAccessorBase(@NotNull PsiClass psiClass, @NotNull PsiElementFactory elementFactory) { + super(psiClass, elementFactory); + } + + @Override + protected List findItemsToReplace(@NotNull PsiElement element) { + List result = new ArrayList<>(); + element.accept(new JavaRecursiveElementVisitor() { + @Override + public void visitReferenceExpression(PsiReferenceExpression expression) { + super.visitReferenceExpression(expression); + final T descriptor = createDescriptor(expression); + if (descriptor != null) { + result.add(descriptor); + } + } + }); + + return result; + } + + @Nullable + protected abstract T createDescriptor(@NotNull PsiReferenceExpression expression); +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessMethodBuilder.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessMethodBuilder.java new file mode 100644 index 000000000000..c0c101758de7 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessMethodBuilder.java @@ -0,0 +1,286 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject.reflect; + +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.ClassUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.extractMethodObject.PsiReflectionAccessUtil; +import com.intellij.util.SmartList; +import one.util.streamex.StreamEx; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; + +/** + * @author Vitaliy.Bibaev + */ +public class ReflectionAccessMethodBuilder { + private boolean myIsStatic = false; + private String myReturnType = "void"; + private final String myName; + private MyMemberAccessor myMemberAccessor; + private final List myParameters = new SmartList<>(); + + public ReflectionAccessMethodBuilder(@NotNull String name) { + myName = name; + } + + public PsiMethod build(@NotNull PsiElementFactory elementFactory, + @Nullable PsiElement context) { + checkRequirements(); + String parameters = StreamEx.of(myParameters).map(p -> p.type + " " + p.name).joining(", ", "(", ")"); + String returnExpression = + ("void".equals(myReturnType) ? "member." : "return (" + myReturnType + ")member.") + myMemberAccessor.getAccessExpression(); + String methodBody = " java.lang.Class klass = " + myMemberAccessor.getClassLookupExpression() + ";\n" + + " " + myMemberAccessor.getMemberType() + " member = null;\n" + + " int interfaceNumber = -1;\n" + + " Class[] interfaces = null;\n" + + " while (member == null) {\n" + + " try {\n" + + " member = klass." + myMemberAccessor.getMemberLookupExpression() + ";\n" + + " } catch (java.lang.ReflectiveOperationException e) {\n" + + " if (interfaceNumber == -1) {\n" + + " interfaces = klass.getInterfaces();\n" + + " interfaceNumber = 0;\n" + + " }\n" + + " if (interfaceNumber < interfaces.length) {\n" + + " klass = interfaces[interfaceNumber];\n" + + " interfaceNumber += 1;\n" + + " } else {\n" + + " klass = klass.getSuperclass();\n" + + " if (klass == null) throw e;\n" + + " interfaceNumber = -1;\n" + + " }\n" + + " }\n" + + " }\n" + + " member.setAccessible(true);\n" + + " " + returnExpression + ";\n"; + List possibleExceptions = myMemberAccessor.getPossibleExceptions(); + if (!possibleExceptions.isEmpty()) { + methodBody = "try {\n" + + methodBody + + "}" + + createCatchBlocks(possibleExceptions); + } + + String methodText = + "public" + (myIsStatic ? " static " : " ") + myReturnType + " " + myName + parameters + " { \n" + methodBody + "}\n"; + + return elementFactory.createMethodFromText(methodText, context); + } + + private void checkRequirements() { + } + + public ReflectionAccessMethodBuilder accessedMethod(@NotNull String jvmClassName, @NotNull String methodName) { + myMemberAccessor = new MyMethodAccessor(jvmClassName, methodName); + return this; + } + + public ReflectionAccessMethodBuilder accessedField(@NotNull String jvmClassName, @NotNull String fieldName) { + myMemberAccessor = new MyFieldAccessor(jvmClassName, fieldName, FieldAccessType.GET); + return this; + } + + public ReflectionAccessMethodBuilder updatedField(@NotNull String jvmClassName, @NotNull String fieldName) { + myMemberAccessor = new MyFieldAccessor(jvmClassName, fieldName, FieldAccessType.SET); + return this; + } + + public ReflectionAccessMethodBuilder accessedConstructor(@NotNull String jvmClassName) { + myMemberAccessor = new MyConstructorAccessor(jvmClassName); + return this; + } + + public ReflectionAccessMethodBuilder setReturnType(@NotNull String returnType) { + myReturnType = returnType; + return this; + } + + public ReflectionAccessMethodBuilder setStatic(boolean isStatic) { + myIsStatic = isStatic; + return this; + } + + public ReflectionAccessMethodBuilder addParameter(@NotNull String jvmType, @NotNull String name) { + myParameters.add(new ParameterInfo(jvmType.replace('$', '.'), name, jvmType)); + return this; + } + + public ReflectionAccessMethodBuilder addParameters(@NotNull PsiParameterList parameterList) { + PsiParameter[] parameters = parameterList.getParameters(); + for (int i = 0; i < parameters.length; i++) { + PsiParameter parameter = parameters[i]; + String name = parameter.getName(); + PsiType type = parameter.getType(); + myParameters.add(new ParameterInfo(type.getCanonicalText(), name == null ? "arg" + i : name, extractJvmType(type))); + } + + return this; + } + + @NotNull + private static String extractJvmType(@NotNull PsiType type) { + PsiClass psiClass = PsiUtil.resolveClassInType(type); + String canonicalText = type.getCanonicalText(); + String jvmName = psiClass == null ? canonicalText : ClassUtil.getJVMClassName(psiClass); + return jvmName == null ? canonicalText : jvmName; + } + + private static String createCatchBlocks(@NotNull List exceptions) { + return StreamEx.of(exceptions).map(x -> "catch(" + x + " e) { throw new java.lang.RuntimeException(e); }").joining("\n"); + } + + private static class ParameterInfo { + public final String type; + public final String name; + public final String jvmTypeName; + + public ParameterInfo(@NotNull String type, @NotNull String name) { + this(type, name, type); + } + + public ParameterInfo(@NotNull String type, @NotNull String name, @NotNull String jvmTypeName) { + this.type = type; + this.name = name; + this.jvmTypeName = jvmTypeName; + } + } + + private interface MyMemberAccessor { + String getMemberLookupExpression(); + + String getClassLookupExpression(); + + String getAccessExpression(); + + String getMemberType(); + + List getPossibleExceptions(); + } + + + private static class MyFieldAccessor implements MyMemberAccessor { + private static final List EXCEPTIONS = Collections.unmodifiableList( + Collections.singletonList("java.lang.ReflectiveOperationException")); + private final String myFieldName; + private final String myClassName; + private final FieldAccessType myAccessType; + + public MyFieldAccessor(@NotNull String className, + @NotNull String fieldName, + @NotNull FieldAccessType accessType) { + myFieldName = fieldName; + myClassName = className; + myAccessType = accessType; + } + + @Override + public String getClassLookupExpression() { + String classForName = PsiReflectionAccessUtil.classForName(myClassName); + // emulate applySideEffectAndReturnNull().staticField expression + return "object == null ? " + classForName + " : object.getClass()"; + } + + @Override + public String getMemberLookupExpression() { + return "getDeclaredField(" + StringUtil.wrapWithDoubleQuote(myFieldName) + ")"; + } + + @Override + public String getAccessExpression() { + return FieldAccessType.GET.equals(myAccessType) ? "get(object)" : "set(object, value)"; + } + + @Override + public String getMemberType() { + return "java.lang.reflect.Field"; + } + + @Override + public List getPossibleExceptions() { + return EXCEPTIONS; + } + } + + + private class MyMethodAccessor implements MyMemberAccessor { + private final String myClassName; + private final String myMethodName; + + public MyMethodAccessor(@NotNull String className, @NotNull String methodName) { + myClassName = className; + myMethodName = methodName; + } + + @Override + public String getMemberLookupExpression() { + String args = StreamEx.of(myParameters).skip(1).map(x -> PsiReflectionAccessUtil.classForName(x.jvmTypeName)) + .prepend(StringUtil.wrapWithDoubleQuote(myMethodName)) + .joining(", ", "(", ")"); + return "getDeclaredMethod" + args; + } + + @Override + public String getClassLookupExpression() { + String classForName = PsiReflectionAccessUtil.classForName(myClassName); + // emulate applySideEffectAndReturnNull().staticMethod() expression + return "object == null ? " + classForName + " : object.getClass()"; + } + + @Override + public String getMemberType() { + return "java.lang.reflect.Method"; + } + + @Override + public List getPossibleExceptions() { + return Collections.unmodifiableList(Collections.singletonList("java.lang.ReflectiveOperationException")); + } + + @Override + public String getAccessExpression() { + return StreamEx.of(myParameters).map(x -> x.name).joining(", ", "invoke(", ")"); + } + } + + + private class MyConstructorAccessor implements MyMemberAccessor { + private final String myClassName; + + public MyConstructorAccessor(@NotNull String className) { + myClassName = className; + } + + @Override + public String getMemberLookupExpression() { + String args = StreamEx.of(myParameters).map(x -> x.jvmTypeName).map(PsiReflectionAccessUtil::classForName).joining(", ", "(", ")"); + return "getDeclaredConstructor" + args; + } + + @Override + public String getClassLookupExpression() { + return PsiReflectionAccessUtil.classForName(myClassName); + } + + @Override + public String getAccessExpression() { + String args = StreamEx.of(myParameters).map(x -> x.name).joining(", ", "(", ")"); + return "newInstance" + args; + } + + @Override + public String getMemberType() { + return "java.lang.reflect.Constructor"; + } + + @Override + public List getPossibleExceptions() { + return Collections.unmodifiableList(Collections.singletonList("java.lang.ReflectiveOperationException" + )); + } + } +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessor.java new file mode 100644 index 000000000000..53ddb99a3046 --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessor.java @@ -0,0 +1,12 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject.reflect; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +/** + * @author Vitaliy.Bibaev + */ +public interface ReflectionAccessor { + void accessThroughReflection(@NotNull PsiElement element); +} diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessorBase.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessorBase.java new file mode 100644 index 000000000000..e627538de79b --- /dev/null +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/reflect/ReflectionAccessorBase.java @@ -0,0 +1,55 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.refactoring.extractMethodObject.reflect; + +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiElementFactory; +import com.intellij.refactoring.extractMethodObject.ItemToReplaceDescriptor; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Grants access for inaccessible members using reflection. Adds an additional method per each expression + * with inaccessible members (method calls, field references, constructor calls, etc) + * + * @author Vitaliy.Bibaev + */ +public abstract class ReflectionAccessorBase implements ReflectionAccessor { + private static final Logger LOG = Logger.getInstance(ReferenceReflectionAccessorBase.class); + private final PsiClass myPsiClass; + private final PsiElementFactory myElementFactory; + + protected ReflectionAccessorBase(@NotNull PsiClass psiClass, @NotNull PsiElementFactory elementFactory) { + myPsiClass = psiClass; + myElementFactory = elementFactory; + } + + @Override + public void accessThroughReflection(@NotNull PsiElement element) { + List toReplace = findItemsToReplace(element); + for (T item : toReplace) { + grantAccess(item); + } + + List remaining = findItemsToReplace(element); + if (!remaining.isEmpty()) { + LOG.warn("Some inaccessible items were not replaced"); + } + } + + @NotNull + protected PsiElementFactory getElementFactory() { + return myElementFactory; + } + + @NotNull + protected PsiClass getOuterClass() { + return myPsiClass; + } + + protected abstract List findItemsToReplace(@NotNull PsiElement element); + + protected abstract void grantAccess(@NotNull T descriptor); +} diff --git a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerTest.java b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerTest.java index c470370328da..dec6518bcba6 100644 --- a/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerTest.java +++ b/java/java-tests/testSrc/com/intellij/java/refactoring/ExtractMethodObject4DebuggerTest.java @@ -46,7 +46,7 @@ public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase { final JavaCodeFragmentFactory fragmentFactory = JavaCodeFragmentFactory.getInstance(getProject()); final JavaCodeFragment fragment = codeBlock ? fragmentFactory.createCodeBlockCodeFragment(evaluatedText, context, false) : fragmentFactory.createExpressionCodeFragment(evaluatedText, context, null, false); final ExtractLightMethodObjectHandler.ExtractedData extractedData = - ExtractLightMethodObjectHandler.extractLightMethodObject(getProject(), context, fragment, "test"); + ExtractLightMethodObjectHandler.extractLightMethodObject(getProject(), context, fragment, "test", false); assertNotNull(extractedData); assertEquals(expectedCallSite, extractedData.getGeneratedCallText()); final PsiClass innerClass = extractedData.getGeneratedInnerClass(); diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index dba42e8f54ca..e51f4bce9339 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -360,6 +360,7 @@ debugger.valueTooltipAutoShowOnSelection.description=Auto show tooltip when edit debugger.mayBringFrameToFrontOnBreakpoint=true debugger.batch.evaluation=false debugger.compiling.evaluator=true +debugger.compiling.evaluator.magic.accessor=true debugger.watches.in.variables=true debugger.auto.fetch.icons=true debugger.close.dialog.on.navigate=true diff --git a/plugins/stream-debugger/src/com/intellij/debugger/streams/action/TraceStreamAction.java b/plugins/stream-debugger/src/com/intellij/debugger/streams/action/TraceStreamAction.java index ded87225648e..2ccd318f1b38 100644 --- a/plugins/stream-debugger/src/com/intellij/debugger/streams/action/TraceStreamAction.java +++ b/plugins/stream-debugger/src/com/intellij/debugger/streams/action/TraceStreamAction.java @@ -16,7 +16,6 @@ import com.intellij.debugger.streams.ui.impl.EvaluationAwareTraceWindow; import com.intellij.debugger.streams.wrapper.StreamChain; import com.intellij.debugger.streams.wrapper.StreamChainBuilder; import com.intellij.internal.statistic.UsageTrigger; -import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; @@ -25,17 +24,11 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; -import com.intellij.openapi.projectRoots.JavaSdk; -import com.intellij.openapi.projectRoots.JavaSdkVersion; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiEditorUtil; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerManager; -import com.intellij.xdebugger.impl.XDebuggerManagerImpl; import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -91,13 +84,6 @@ public class TraceStreamAction extends AnAction { Extensions.getExtensions(LibrarySupportProvider.EP_NAME); final PsiElement element = session == null ? null : myPositionResolver.getNearestElementToBreakpoint(session); - if (element != null && isJdkAtLeast9(session.getProject(), element)) { - XDebuggerManagerImpl.NOTIFICATION_GROUP - .createNotification("This action does not work with JDK 9 yet", MessageType.WARNING) - .notify(session.getProject()); - return; - } - if (element != null) { final List chains = mySupportedLibraries.stream() .filter(library -> library.languageId.equals(element.getLanguage().getID())) @@ -177,18 +163,6 @@ public class TraceStreamAction extends AnAction { return project == null ? null : XDebuggerManager.getInstance(project).getCurrentSession(); } - private static boolean isJdkAtLeast9(@NotNull Project project, @NotNull PsiElement element) { - if (element.getLanguage().is(JavaLanguage.INSTANCE)) { - final Sdk sdk = ProjectRootManager.getInstance(project).getProjectSdk(); - if (sdk != null) { - final JavaSdkVersion javaVersion = JavaSdk.getInstance().getVersion(sdk); - if (javaVersion != null) return javaVersion.isAtLeast(JavaSdkVersion.JDK_1_9); - } - } - - return false; - } - private static class MyStreamChainChooser extends ElementChooserImpl { MyStreamChainChooser(@NotNull Editor editor) { super(editor); diff --git a/plugins/stream-debugger/src/com/intellij/debugger/streams/test/TraceExecutionTestCase.java b/plugins/stream-debugger/src/com/intellij/debugger/streams/test/TraceExecutionTestCase.java index f53f92a974cb..6de77acf03cf 100644 --- a/plugins/stream-debugger/src/com/intellij/debugger/streams/test/TraceExecutionTestCase.java +++ b/plugins/stream-debugger/src/com/intellij/debugger/streams/test/TraceExecutionTestCase.java @@ -42,8 +42,18 @@ public abstract class TraceExecutionTestCase extends DebuggerTestCase { private final DebuggerPositionResolver myPositionResolver = new DebuggerPositionResolverImpl(); @Override - protected OutputChecker initOutputChecker() { - return new OutputChecker(getTestAppPath(), getAppOutputPath()); + protected final OutputChecker initOutputChecker() { + return new OutputChecker(getTestAppPath(), getAppOutputPath()) { + @Override + protected String replaceAdditionalInOutput(String str) { + return TraceExecutionTestCase.this.replaceAdditionalInOutput(super.replaceAdditionalInOutput(str)); + } + }; + } + + @NotNull + protected String replaceAdditionalInOutput(@NotNull String str) { + return str; } protected LibrarySupportProvider getLibrarySupportProvider() { diff --git a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/AccessibilityFailedTest.java b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/AccessibilityFailedTest.java index 64f877a5cc59..da3bceab7643 100644 --- a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/AccessibilityFailedTest.java +++ b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/AccessibilityFailedTest.java @@ -1,10 +1,18 @@ // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.debugger.streams.exec; +import org.jetbrains.annotations.NotNull; + /** * @author Vitaliy.Bibaev */ public class AccessibilityFailedTest extends FailEvaluationTestCase { + @NotNull + @Override + protected String replaceAdditionalInOutput(@NotNull String str) { + // stack traces in jdk 9 include module name. The following code removes module name from the stack trace. + return super.replaceAdditionalInOutput(str).replace("at java.base/", "at "); + } /** * Now, evaluation of such test case is not supported. MagicAccessorImpl cannot be parent for a subclass of the class "Super" diff --git a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/LibraryTraceExecutionTestCase.kt b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/LibraryTraceExecutionTestCase.kt index 76afcb183628..d04670b59b0d 100644 --- a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/LibraryTraceExecutionTestCase.kt +++ b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/LibraryTraceExecutionTestCase.kt @@ -1,7 +1,6 @@ // Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.debugger.streams.exec -import com.intellij.debugger.impl.OutputChecker import com.intellij.debugger.streams.test.TraceExecutionTestCase import com.intellij.execution.configurations.JavaParameters import com.intellij.openapi.application.ApplicationManager @@ -23,12 +22,9 @@ abstract class LibraryTraceExecutionTestCase(private val jarName: String) : Trac } } - override fun initOutputChecker(): OutputChecker { - return object : OutputChecker(testAppPath, appOutputPath) { - override fun replaceAdditionalInOutput(str: String): String { - return str.replaceFirst("$libraryDirectory/$jarName", "!LIBRARY_JAR!") - } - } + override fun replaceAdditionalInOutput(str: String): String { + return super.replaceAdditionalInOutput(str) + .replaceFirst("$libraryDirectory/$jarName", "!LIBRARY_JAR!") } override fun createJavaParameters(mainClass: String?): JavaParameters { diff --git a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/ConcatenateOperationsTest.kt b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/ConcatenateOperationsTest.kt index 1e9153a49969..5db1377e1113 100644 --- a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/ConcatenateOperationsTest.kt +++ b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/ConcatenateOperationsTest.kt @@ -7,13 +7,13 @@ package com.intellij.debugger.streams.exec.streamex class ConcatenateOperationsTest : StreamExTestCase() { override val packageName: String = "concatenate" - fun testAppendToEmpty() = doStreamExWithResultTest() - fun testAppendNone() = doStreamExWithResultTest() - fun testAppendOne() = doStreamExWithResultTest() - fun testAppendMany() = doStreamExWithResultTest() + fun testAppendToEmpty() = doStreamExVoidTest() + fun testAppendNone() = doStreamExVoidTest() + fun testAppendOne() = doStreamExVoidTest() + fun testAppendMany() = doStreamExVoidTest() - fun testPrependToEmpty() = doStreamExWithResultTest() - fun testPrependNone() = doStreamExWithResultTest() - fun testPrependOne() = doStreamExWithResultTest() - fun testPrependMany() = doStreamExWithResultTest() + fun testPrependToEmpty() = doStreamExVoidTest() + fun testPrependNone() = doStreamExVoidTest() + fun testPrependOne() = doStreamExVoidTest() + fun testPrependMany() = doStreamExVoidTest() } \ No newline at end of file diff --git a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/MappingOperationsTest.kt b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/MappingOperationsTest.kt index e796516b3c10..d848568a230b 100644 --- a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/MappingOperationsTest.kt +++ b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/MappingOperationsTest.kt @@ -10,15 +10,15 @@ class MappingOperationsTest : StreamExTestCase() { fun testElements() = doStreamExWithResultTest() fun testMapToEntry() = doStreamExWithResultTest() - fun testMapKeys() = doStreamExWithResultTest() - fun testMapToKey() = doStreamExWithResultTest() - fun testMapValues() = doStreamExWithResultTest() - fun testMapToValue() = doStreamExWithResultTest() + fun testMapKeys() = doStreamExVoidTest() + fun testMapToKey() = doStreamExVoidTest() + fun testMapValues() = doStreamExVoidTest() + fun testMapToValue() = doStreamExVoidTest() fun testMapKeyValue() = doStreamExWithResultTest() - fun testInvert() = doStreamExWithResultTest() + fun testInvert() = doStreamExVoidTest() - fun testKeys() = doStreamExWithResultTest() + fun testKeys() = doStreamExVoidTest() fun testValues() = doStreamExWithResultTest() fun testJoin() = doStreamExVoidTest() @@ -30,5 +30,5 @@ class MappingOperationsTest : StreamExTestCase() { fun testMapFirstOrElse() = doStreamExWithResultTest() fun testMapLastOrElse() = doStreamExWithResultTest() - fun testWithFirst() = doStreamExWithResultTest() + fun testWithFirst() = doStreamExVoidTest() } \ No newline at end of file diff --git a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/MiscIntermediateOperationsTest.kt b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/MiscIntermediateOperationsTest.kt index c3ccba352a06..3287b79eec46 100644 --- a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/MiscIntermediateOperationsTest.kt +++ b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/MiscIntermediateOperationsTest.kt @@ -13,13 +13,13 @@ class MiscIntermediateOperationsTest : StreamExTestCase() { fun testSkipOrdered() = doStreamExWithResultTest() - fun testParallel() = doStreamExWithResultTest() + fun testParallel() = doStreamExVoidTest() - fun testZipWithSameSizes() = doStreamExWithResultTest() - fun testZipWithLesser() = doStreamExWithResultTest() - fun testZipWithGreater() = doStreamExWithResultTest() + fun testZipWithSameSizes() = doStreamExVoidTest() + fun testZipWithLesser() = doStreamExVoidTest() + fun testZipWithGreater() = doStreamExVoidTest() fun testPrefix() = doStreamExVoidTest() - fun testPrefixKeys() = doStreamExWithResultTest() - fun testPrefixValues() = doStreamExWithResultTest() + fun testPrefixKeys() = doStreamExVoidTest() + fun testPrefixValues() = doStreamExVoidTest() } \ No newline at end of file diff --git a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/StreamExTestCase.kt b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/StreamExTestCase.kt index 8a9f64b3ff25..58f19fcaef09 100644 --- a/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/StreamExTestCase.kt +++ b/plugins/stream-debugger/test/com/intellij/debugger/streams/exec/streamex/StreamExTestCase.kt @@ -9,12 +9,26 @@ import com.intellij.debugger.streams.lib.impl.StreamExLibrarySupportProvider * @author Vitaliy.Bibaev */ abstract class StreamExTestCase : LibraryTraceExecutionTestCase("streamex-0.6.5.jar") { - abstract protected val packageName: String + private companion object { + const val STREAM_EX_REFLECTION_WARNING_MESSAGE = + "WARNING: An illegal reflective access operation has occurred\n" + + "WARNING: Illegal reflective access by one.util.streamex.StreamExInternals (file:/C:/Projects/IDEA/community/plugins/" + + "stream-debugger/lib/streamex-0.6.5.jar) to field java.util.stream.AbstractPipeline.sourceSpliterator\n" + + "WARNING: Please consider reporting this to the maintainers of one.util.streamex.StreamExInternals\n" + + "WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations\n" + + "WARNING: All illegal access operations will be denied in a future release\n" + } + + protected abstract val packageName: String override fun getLibrarySupportProvider(): LibrarySupportProvider { return StreamExLibrarySupportProvider() } + override fun replaceAdditionalInOutput(str: String): String { + return super.replaceAdditionalInOutput(str).replace(STREAM_EX_REFLECTION_WARNING_MESSAGE, "") + } + private val className: String get() = packageName + "." + getTestName(false) diff --git a/plugins/stream-debugger/testData/debug/outs/map.out b/plugins/stream-debugger/testData/debug/outs/map.out index af17baae83ec..04a56b2226e8 100644 --- a/plugins/stream-debugger/testData/debug/outs/map.out +++ b/plugins/stream-debugger/testData/debug/outs/map.out @@ -4,13 +4,13 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke Map.java:6 Stream.of(1, 2, 3) .map(x -> x * x) -.count() +.toArray() map before: 1,3,5 after: 2,4,6 -count +toArray before: 2,4,6 - after: nothing + after: 7,8,9 mappings for map direct: 1 -> 2 @@ -20,13 +20,15 @@ mappings for map 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for toArray direct: - 2 -> nothing - 4 -> nothing - 6 -> nothing + 2 -> 7 + 4 -> 8 + 6 -> 9 reverse: - empty + 2 <- 7 + 4 <- 8 + 6 <- 9 Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 diff --git a/plugins/stream-debugger/testData/debug/outs/nulls.out b/plugins/stream-debugger/testData/debug/outs/nulls.out index 5e9a44a407e2..15ec196ea4a1 100644 --- a/plugins/stream-debugger/testData/debug/outs/nulls.out +++ b/plugins/stream-debugger/testData/debug/outs/nulls.out @@ -3,16 +3,17 @@ LineBreakpoint created at Nulls.java:6 Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Nulls.java:6 Stream.of(null, null) -.count() -count +.toArray() +toArray before: 1,2 - after: nothing -mappings for count + after: 3,4 +mappings for toArray direct: - 1 -> nothing - 2 -> nothing + 1 -> 3 + 2 -> 4 reverse: - empty + 1 <- 3 + 2 <- 4 Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 diff --git a/plugins/stream-debugger/testData/debug/outs/peek.out b/plugins/stream-debugger/testData/debug/outs/peek.out index feacb5132c0d..5d3da676fffb 100644 --- a/plugins/stream-debugger/testData/debug/outs/peek.out +++ b/plugins/stream-debugger/testData/debug/outs/peek.out @@ -4,13 +4,13 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke Peek.java:6 Stream.of(1, 2, 3) .peek(x -> {}) -.count() +.toArray() peek before: 1,3,5 after: 2,4,6 -count +toArray before: 2,4,6 - after: nothing + after: 7,8,9 mappings for peek direct: 1 -> 2 @@ -20,13 +20,15 @@ mappings for peek 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for toArray direct: - 2 -> nothing - 4 -> nothing - 6 -> nothing + 2 -> 7 + 4 -> 8 + 6 -> 9 reverse: - empty + 2 <- 7 + 4 <- 8 + 6 <- 9 Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 diff --git a/plugins/stream-debugger/testData/debug/outs/primitiveResultLong.out b/plugins/stream-debugger/testData/debug/outs/primitiveResultLong.out index d73dfc1bf7ba..cd23783beeff 100644 --- a/plugins/stream-debugger/testData/debug/outs/primitiveResultLong.out +++ b/plugins/stream-debugger/testData/debug/outs/primitiveResultLong.out @@ -2,14 +2,14 @@ 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:6 -IntStream.of(1, 2) -.count() +LongStream.of(1, 2) +.sum() Result type:long -value = 2 -count +value = 3 +sum before: 1,2 after: nothing -mappings for count +mappings for sum direct: 1 -> nothing 2 -> nothing diff --git a/plugins/stream-debugger/testData/debug/src/Map.java b/plugins/stream-debugger/testData/debug/src/Map.java index 2623a2230c49..ab201f82ccd8 100644 --- a/plugins/stream-debugger/testData/debug/src/Map.java +++ b/plugins/stream-debugger/testData/debug/src/Map.java @@ -3,6 +3,6 @@ import java.util.stream.Stream; public class Map { public static void main(String[] args) { // Breakpoint! - final long res = Stream.of(1, 2, 3).map(x -> x * x).count(); + Stream.of(1, 2, 3).map(x -> x * x).toArray(); } } diff --git a/plugins/stream-debugger/testData/debug/src/Nulls.java b/plugins/stream-debugger/testData/debug/src/Nulls.java index 8bce36b4f76e..980027928cc3 100644 --- a/plugins/stream-debugger/testData/debug/src/Nulls.java +++ b/plugins/stream-debugger/testData/debug/src/Nulls.java @@ -3,6 +3,6 @@ import java.util.stream.Stream; public class Nulls { public static void main(String[] args) { // Breakpoint! - Stream.of(null, null).count(); + Stream.of(null, null).toArray(); } } diff --git a/plugins/stream-debugger/testData/debug/src/Peek.java b/plugins/stream-debugger/testData/debug/src/Peek.java index d343e045a214..77995779db14 100644 --- a/plugins/stream-debugger/testData/debug/src/Peek.java +++ b/plugins/stream-debugger/testData/debug/src/Peek.java @@ -3,6 +3,6 @@ import java.util.stream.Stream; public class Peek { public static void main(String[] args) { // Breakpoint! - final long res = Stream.of(1, 2, 3).peek(x -> {}).count(); + Stream.of(1, 2, 3).peek(x -> {}).toArray(); } } diff --git a/plugins/stream-debugger/testData/debug/src/PrimitiveResultLong.java b/plugins/stream-debugger/testData/debug/src/PrimitiveResultLong.java index 0eabcd0bb30c..fca49b98ab5a 100644 --- a/plugins/stream-debugger/testData/debug/src/PrimitiveResultLong.java +++ b/plugins/stream-debugger/testData/debug/src/PrimitiveResultLong.java @@ -1,8 +1,8 @@ -import java.util.stream.IntStream; +import java.util.stream.LongStream; public class PrimitiveResultLong { public static void main(String[] args) { // Breakpoint! - long res = IntStream.of(1, 2).count(); + long res = LongStream.of(1, 2).sum(); } } diff --git a/plugins/stream-debugger/testData/streamex/outs/appendMany.out b/plugins/stream-debugger/testData/streamex/outs/appendMany.out index f4399a8ab116..4b4e6fbe4b58 100644 --- a/plugins/stream-debugger/testData/streamex/outs/appendMany.out +++ b/plugins/stream-debugger/testData/streamex/outs/appendMany.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke AppendMany.java:10 StreamEx.of(1, 2) .append(Stream.of(3, 4, 5)) -.count() +.forEach(x -> {}) append before: 1,3 after: 2,4,5,6,7 -count +forEach before: 2,4,5,6,7 after: nothing mappings for append @@ -21,7 +21,7 @@ mappings for append nothing <- 5 nothing <- 6 nothing <- 7 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -33,4 +33,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -5 diff --git a/plugins/stream-debugger/testData/streamex/outs/appendNone.out b/plugins/stream-debugger/testData/streamex/outs/appendNone.out index b4aaf0b40cc8..6c2a420b6dfd 100644 --- a/plugins/stream-debugger/testData/streamex/outs/appendNone.out +++ b/plugins/stream-debugger/testData/streamex/outs/appendNone.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke AppendNone.java:8 StreamEx.of(1, 2) .append() -.count() +.forEach(x -> {}) append before: 1,3 after: 2,4 -count +forEach before: 2,4 after: nothing mappings for append @@ -18,7 +18,7 @@ mappings for append reverse: 1 <- 2 3 <- 4 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -27,4 +27,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -2 diff --git a/plugins/stream-debugger/testData/streamex/outs/appendOne.out b/plugins/stream-debugger/testData/streamex/outs/appendOne.out index af05a3e91b4b..6b0a16e1fed1 100644 --- a/plugins/stream-debugger/testData/streamex/outs/appendOne.out +++ b/plugins/stream-debugger/testData/streamex/outs/appendOne.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke AppendOne.java:8 StreamEx.of(1, 2) .append(3) -.count() +.forEach(x -> {}) append before: 1,3 after: 2,4,5 -count +forEach before: 2,4,5 after: nothing mappings for append @@ -19,7 +19,7 @@ mappings for append 1 <- 2 3 <- 4 nothing <- 5 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -29,4 +29,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/appendToEmpty.out b/plugins/stream-debugger/testData/streamex/outs/appendToEmpty.out index 210b0c572a9c..7db084d04a32 100644 --- a/plugins/stream-debugger/testData/streamex/outs/appendToEmpty.out +++ b/plugins/stream-debugger/testData/streamex/outs/appendToEmpty.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke AppendToEmpty.java:8 StreamEx.empty() .append(1) -.count() +.forEach(x -> {}) append before: nothing after: 1 -count +forEach before: 1 after: nothing mappings for append @@ -16,7 +16,7 @@ mappings for append empty reverse: nothing <- 1 -mappings for count +mappings for forEach direct: 1 -> nothing reverse: @@ -24,4 +24,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -1 diff --git a/plugins/stream-debugger/testData/streamex/outs/invert.out b/plugins/stream-debugger/testData/streamex/outs/invert.out index 7c1642bd4c80..01f4d7b8e87e 100644 --- a/plugins/stream-debugger/testData/streamex/outs/invert.out +++ b/plugins/stream-debugger/testData/streamex/outs/invert.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke Invert.java:8 EntryStream.of(1, 1, 2, 4, 3, 9) .invert() -.count() +.forEach(x -> {}) invert before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for invert @@ -20,7 +20,7 @@ mappings for invert 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/keys.out b/plugins/stream-debugger/testData/streamex/outs/keys.out index 2c61a9330d33..a42c3bc7547e 100644 --- a/plugins/stream-debugger/testData/streamex/outs/keys.out +++ b/plugins/stream-debugger/testData/streamex/outs/keys.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke Keys.java:8 EntryStream.of(1, 1, 2, 4, 3, 9) .keys() -.count() +.forEach(x -> {}) keys before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for keys @@ -20,7 +20,7 @@ mappings for keys 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/mapKeys.out b/plugins/stream-debugger/testData/streamex/outs/mapKeys.out index ad6f51a953e7..80e6f6d67ae6 100644 --- a/plugins/stream-debugger/testData/streamex/outs/mapKeys.out +++ b/plugins/stream-debugger/testData/streamex/outs/mapKeys.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke MapKeys.java:8 EntryStream.of(1, 1, 2, 4, 3, 9) .mapKeys(x -> x - 1) -.count() +.forEach(x -> {}) mapKeys before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for mapKeys @@ -20,7 +20,7 @@ mappings for mapKeys 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/mapToEntry.out b/plugins/stream-debugger/testData/streamex/outs/mapToEntry.out index 18995c206a17..9a9f8d04c201 100644 --- a/plugins/stream-debugger/testData/streamex/outs/mapToEntry.out +++ b/plugins/stream-debugger/testData/streamex/outs/mapToEntry.out @@ -4,13 +4,13 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke MapToEntry.java:8 StreamEx.of(1, 2, 3) .mapToEntry(x -> x * x) -.count() +.toArray() mapToEntry before: 1,3,5 after: 2,4,6 -count +toArray before: 2,4,6 - after: nothing + after: 7,8,9 mappings for mapToEntry direct: 1 -> 2 @@ -20,13 +20,15 @@ mappings for mapToEntry 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for toArray direct: - 2 -> nothing - 4 -> nothing - 6 -> nothing + 2 -> 7 + 4 -> 8 + 6 -> 9 reverse: - empty + 2 <- 7 + 4 <- 8 + 6 <- 9 Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 diff --git a/plugins/stream-debugger/testData/streamex/outs/mapToKey.out b/plugins/stream-debugger/testData/streamex/outs/mapToKey.out index d27b0b142adf..0d7a2939e2b7 100644 --- a/plugins/stream-debugger/testData/streamex/outs/mapToKey.out +++ b/plugins/stream-debugger/testData/streamex/outs/mapToKey.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke MapToKey.java:8 EntryStream.of(1, 1, 2, 4, 3, 9) .mapToKey((k, v) -> k + v) -.count() +.forEach(x -> {}) mapToKey before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for mapToKey @@ -20,7 +20,7 @@ mappings for mapToKey 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/mapToValue.out b/plugins/stream-debugger/testData/streamex/outs/mapToValue.out index 5b689c3da074..178fc128cfb7 100644 --- a/plugins/stream-debugger/testData/streamex/outs/mapToValue.out +++ b/plugins/stream-debugger/testData/streamex/outs/mapToValue.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke MapToValue.java:8 EntryStream.of(1, 1, 2, 4, 3, 9) .mapToValue((k, v) -> k + v) -.count() +.forEach(x -> {}) mapToValue before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for mapToValue @@ -20,7 +20,7 @@ mappings for mapToValue 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/mapValues.out b/plugins/stream-debugger/testData/streamex/outs/mapValues.out index 176762951708..c3473c36bb25 100644 --- a/plugins/stream-debugger/testData/streamex/outs/mapValues.out +++ b/plugins/stream-debugger/testData/streamex/outs/mapValues.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke MapValues.java:8 EntryStream.of(1, 1, 2, 4, 3, 9) .mapValues(x -> 0) -.count() +.forEach(x -> {}) mapValues before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for mapValues @@ -20,7 +20,7 @@ mappings for mapValues 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/parallel.out b/plugins/stream-debugger/testData/streamex/outs/parallel.out index b86b45b534b4..dc7cddf1ba1c 100644 --- a/plugins/stream-debugger/testData/streamex/outs/parallel.out +++ b/plugins/stream-debugger/testData/streamex/outs/parallel.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke Parallel.java:11 StreamEx.of(1, 2, 3) .parallel((ForkJoinPool) Executors.newWorkStealingPool()) -.count() +.forEach(x -> {}) parallel before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for parallel @@ -20,7 +20,7 @@ mappings for parallel 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/prefixKeys.out b/plugins/stream-debugger/testData/streamex/outs/prefixKeys.out index 148a318e3562..07feae526387 100644 --- a/plugins/stream-debugger/testData/streamex/outs/prefixKeys.out +++ b/plugins/stream-debugger/testData/streamex/outs/prefixKeys.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke PrefixKeys.java:8 EntryStream.of(1, 1, 2, 4, 3, 9) .prefixKeys((l, r) -> l + r) -.count() +.forEach(x -> {}) prefixKeys before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for prefixKeys @@ -20,7 +20,7 @@ mappings for prefixKeys nothing <- 2 nothing <- 4 nothing <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/prefixValues.out b/plugins/stream-debugger/testData/streamex/outs/prefixValues.out index 885fbea419e1..2b480edcd3ad 100644 --- a/plugins/stream-debugger/testData/streamex/outs/prefixValues.out +++ b/plugins/stream-debugger/testData/streamex/outs/prefixValues.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke PrefixValues.java:8 EntryStream.of(1, 1, 2, 4, 3, 9) .prefixValues((l, r) -> l + r) -.count() +.forEach(x -> {}) prefixValues before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for prefixValues @@ -20,7 +20,7 @@ mappings for prefixValues nothing <- 2 nothing <- 4 nothing <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/prependMany.out b/plugins/stream-debugger/testData/streamex/outs/prependMany.out index 8cec2de1c196..e7fb25f7797a 100644 --- a/plugins/stream-debugger/testData/streamex/outs/prependMany.out +++ b/plugins/stream-debugger/testData/streamex/outs/prependMany.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke PrependMany.java:10 StreamEx.of(1, 2) .prepend(Stream.of(3, 4, 5)) -.count() +.forEach(x -> {}) prepend before: 4,6 after: 1,2,3,5,7 -count +forEach before: 1,2,3,5,7 after: nothing mappings for prepend @@ -21,7 +21,7 @@ mappings for prepend nothing <- 3 4 <- 5 6 <- 7 -mappings for count +mappings for forEach direct: 1 -> nothing 2 -> nothing @@ -33,4 +33,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -5 diff --git a/plugins/stream-debugger/testData/streamex/outs/prependNone.out b/plugins/stream-debugger/testData/streamex/outs/prependNone.out index ffa3ffee5a67..585ce7eeb0c7 100644 --- a/plugins/stream-debugger/testData/streamex/outs/prependNone.out +++ b/plugins/stream-debugger/testData/streamex/outs/prependNone.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke PrependNone.java:8 StreamEx.of(1, 2) .prepend() -.count() +.forEach(x -> {}) prepend before: 1,3 after: 2,4 -count +forEach before: 2,4 after: nothing mappings for prepend @@ -18,7 +18,7 @@ mappings for prepend reverse: 1 <- 2 3 <- 4 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -27,4 +27,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -2 diff --git a/plugins/stream-debugger/testData/streamex/outs/prependOne.out b/plugins/stream-debugger/testData/streamex/outs/prependOne.out index dd8ad83752e7..0c36c1c60c62 100644 --- a/plugins/stream-debugger/testData/streamex/outs/prependOne.out +++ b/plugins/stream-debugger/testData/streamex/outs/prependOne.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke PrependOne.java:8 StreamEx.of(1, 2) .prepend(3) -.count() +.forEach(x -> {}) prepend before: 2,4 after: 1,3,5 -count +forEach before: 1,3,5 after: nothing mappings for prepend @@ -19,7 +19,7 @@ mappings for prepend nothing <- 1 2 <- 3 4 <- 5 -mappings for count +mappings for forEach direct: 1 -> nothing 3 -> nothing @@ -29,4 +29,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/prependToEmpty.out b/plugins/stream-debugger/testData/streamex/outs/prependToEmpty.out index 42d9ca1cb0e8..1ebebf886c42 100644 --- a/plugins/stream-debugger/testData/streamex/outs/prependToEmpty.out +++ b/plugins/stream-debugger/testData/streamex/outs/prependToEmpty.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke PrependToEmpty.java:8 StreamEx.empty() .prepend(1) -.count() +.forEach(x -> {}) prepend before: nothing after: 1 -count +forEach before: 1 after: nothing mappings for prepend @@ -16,7 +16,7 @@ mappings for prepend empty reverse: nothing <- 1 -mappings for count +mappings for forEach direct: 1 -> nothing reverse: @@ -24,4 +24,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -1 diff --git a/plugins/stream-debugger/testData/streamex/outs/withFirst.out b/plugins/stream-debugger/testData/streamex/outs/withFirst.out index 01b5f295cd9f..0d54f207a13c 100644 --- a/plugins/stream-debugger/testData/streamex/outs/withFirst.out +++ b/plugins/stream-debugger/testData/streamex/outs/withFirst.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke WithFirst.java:8 StreamEx.of(10., 2., 3.) .withFirst((first, other) -> first * other) -.count() +.forEach(x -> {}) withFirst before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for withFirst @@ -20,7 +20,7 @@ mappings for withFirst 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/zipWithGreater.out b/plugins/stream-debugger/testData/streamex/outs/zipWithGreater.out index d5764fe84838..1ab20ea2d4ef 100644 --- a/plugins/stream-debugger/testData/streamex/outs/zipWithGreater.out +++ b/plugins/stream-debugger/testData/streamex/outs/zipWithGreater.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke ZipWithGreater.java:10 StreamEx.of(1, 2, 3) .zipWith(Stream.of(1, 3, 9, 16, 25)) -.count() +.forEach(x -> {}) zipWith before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for zipWith @@ -20,7 +20,7 @@ mappings for zipWith 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/zipWithLesser.out b/plugins/stream-debugger/testData/streamex/outs/zipWithLesser.out index c958f50f8872..363069320daf 100644 --- a/plugins/stream-debugger/testData/streamex/outs/zipWithLesser.out +++ b/plugins/stream-debugger/testData/streamex/outs/zipWithLesser.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke ZipWithLesser.java:10 StreamEx.of(1, 2, 3, 4, 5) .zipWith(Stream.of(1, 3, 9)) -.count() +.forEach(x -> {}) zipWith before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for zipWith @@ -20,7 +20,7 @@ mappings for zipWith 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/outs/zipWithSameSizes.out b/plugins/stream-debugger/testData/streamex/outs/zipWithSameSizes.out index 952bda792b59..66fec718f020 100644 --- a/plugins/stream-debugger/testData/streamex/outs/zipWithSameSizes.out +++ b/plugins/stream-debugger/testData/streamex/outs/zipWithSameSizes.out @@ -4,11 +4,11 @@ Connected to the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socke ZipWithSameSizes.java:10 StreamEx.of(1, 2, 3) .zipWith(Stream.of(1, 3, 9)) -.count() +.forEach(x -> {}) zipWith before: 1,3,5 after: 2,4,6 -count +forEach before: 2,4,6 after: nothing mappings for zipWith @@ -20,7 +20,7 @@ mappings for zipWith 1 <- 2 3 <- 4 5 <- 6 -mappings for count +mappings for forEach direct: 2 -> nothing 4 -> nothing @@ -30,4 +30,3 @@ mappings for count Disconnected from the target VM, address: '!HOST_NAME!:PORT_NAME!', transport: 'socket' Process finished with exit code 0 -3 diff --git a/plugins/stream-debugger/testData/streamex/src/concatenate/AppendMany.java b/plugins/stream-debugger/testData/streamex/src/concatenate/AppendMany.java index 3839860e9231..8677bce117de 100644 --- a/plugins/stream-debugger/testData/streamex/src/concatenate/AppendMany.java +++ b/plugins/stream-debugger/testData/streamex/src/concatenate/AppendMany.java @@ -7,7 +7,6 @@ import java.util.stream.Stream; public class AppendMany { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2).append(Stream.of(3, 4, 5)).count(); - System.out.println(count); + StreamEx.of(1, 2).append(Stream.of(3, 4, 5)).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/concatenate/AppendNone.java b/plugins/stream-debugger/testData/streamex/src/concatenate/AppendNone.java index bb31f39f9041..923934f1ee69 100644 --- a/plugins/stream-debugger/testData/streamex/src/concatenate/AppendNone.java +++ b/plugins/stream-debugger/testData/streamex/src/concatenate/AppendNone.java @@ -5,7 +5,6 @@ import one.util.streamex.StreamEx; public class AppendNone { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2).append().count(); - System.out.println(count); + StreamEx.of(1, 2).append().forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/concatenate/AppendOne.java b/plugins/stream-debugger/testData/streamex/src/concatenate/AppendOne.java index 8fc2efb4c256..99a27d90e48a 100644 --- a/plugins/stream-debugger/testData/streamex/src/concatenate/AppendOne.java +++ b/plugins/stream-debugger/testData/streamex/src/concatenate/AppendOne.java @@ -5,7 +5,6 @@ import one.util.streamex.StreamEx; public class AppendOne { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2).append(3).count(); - System.out.println(count); + StreamEx.of(1, 2).append(3).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/concatenate/AppendToEmpty.java b/plugins/stream-debugger/testData/streamex/src/concatenate/AppendToEmpty.java index e39b99251940..fc1e9ccd5f6f 100644 --- a/plugins/stream-debugger/testData/streamex/src/concatenate/AppendToEmpty.java +++ b/plugins/stream-debugger/testData/streamex/src/concatenate/AppendToEmpty.java @@ -5,7 +5,6 @@ import one.util.streamex.StreamEx; public class AppendToEmpty { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.empty().append(1).count(); - System.out.println(count); + StreamEx.empty().append(1).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/concatenate/PrependMany.java b/plugins/stream-debugger/testData/streamex/src/concatenate/PrependMany.java index 31366e6f6aa2..a764cc052138 100644 --- a/plugins/stream-debugger/testData/streamex/src/concatenate/PrependMany.java +++ b/plugins/stream-debugger/testData/streamex/src/concatenate/PrependMany.java @@ -7,7 +7,6 @@ import java.util.stream.Stream; public class PrependMany { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2).prepend(Stream.of(3, 4, 5)).count(); - System.out.println(count); + StreamEx.of(1, 2).prepend(Stream.of(3, 4, 5)).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/concatenate/PrependNone.java b/plugins/stream-debugger/testData/streamex/src/concatenate/PrependNone.java index 15bc51d34709..7639eb1432d6 100644 --- a/plugins/stream-debugger/testData/streamex/src/concatenate/PrependNone.java +++ b/plugins/stream-debugger/testData/streamex/src/concatenate/PrependNone.java @@ -5,7 +5,6 @@ import one.util.streamex.StreamEx; public class PrependNone { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2).prepend().count(); - System.out.println(count); + StreamEx.of(1, 2).prepend().forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/concatenate/PrependOne.java b/plugins/stream-debugger/testData/streamex/src/concatenate/PrependOne.java index cc575c92c981..163a753749e1 100644 --- a/plugins/stream-debugger/testData/streamex/src/concatenate/PrependOne.java +++ b/plugins/stream-debugger/testData/streamex/src/concatenate/PrependOne.java @@ -5,7 +5,6 @@ import one.util.streamex.StreamEx; public class PrependOne { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2).prepend(3).count(); - System.out.println(count); + StreamEx.of(1, 2).prepend(3).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/concatenate/PrependToEmpty.java b/plugins/stream-debugger/testData/streamex/src/concatenate/PrependToEmpty.java index d51430bfca12..dc1ceed8f00a 100644 --- a/plugins/stream-debugger/testData/streamex/src/concatenate/PrependToEmpty.java +++ b/plugins/stream-debugger/testData/streamex/src/concatenate/PrependToEmpty.java @@ -5,7 +5,6 @@ import one.util.streamex.StreamEx; public class PrependToEmpty { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.empty().prepend(1).count(); - System.out.println(count); + StreamEx.empty().prepend(1).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/mapping/Invert.java b/plugins/stream-debugger/testData/streamex/src/mapping/Invert.java index 3488a6e6ff7a..67bacafb2d03 100644 --- a/plugins/stream-debugger/testData/streamex/src/mapping/Invert.java +++ b/plugins/stream-debugger/testData/streamex/src/mapping/Invert.java @@ -5,7 +5,6 @@ import one.util.streamex.EntryStream; public class Invert { public static void main(String[] args) { // Breakpoint! - final long count = EntryStream.of(1, 1, 2, 4, 3, 9).invert().count(); - System.out.println(count); + EntryStream.of(1, 1, 2, 4, 3, 9).invert().forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/mapping/Keys.java b/plugins/stream-debugger/testData/streamex/src/mapping/Keys.java index 4833c01db67d..c45921c9d921 100644 --- a/plugins/stream-debugger/testData/streamex/src/mapping/Keys.java +++ b/plugins/stream-debugger/testData/streamex/src/mapping/Keys.java @@ -5,7 +5,6 @@ import one.util.streamex.EntryStream; public class Keys { public static void main(String[] args) { // Breakpoint! - final long count = EntryStream.of(1, 1, 2, 4, 3, 9).keys().count(); - System.out.println(count); + EntryStream.of(1, 1, 2, 4, 3, 9).keys().forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/mapping/MapKeys.java b/plugins/stream-debugger/testData/streamex/src/mapping/MapKeys.java index 5a5e424d814d..c72a443710c6 100644 --- a/plugins/stream-debugger/testData/streamex/src/mapping/MapKeys.java +++ b/plugins/stream-debugger/testData/streamex/src/mapping/MapKeys.java @@ -5,7 +5,6 @@ import one.util.streamex.EntryStream; public class MapKeys { public static void main(String[] args) { // Breakpoint! - final long count = EntryStream.of(1, 1, 2, 4, 3, 9).mapKeys(x -> x - 1).count(); - System.out.println(count); + EntryStream.of(1, 1, 2, 4, 3, 9).mapKeys(x -> x - 1).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/mapping/MapToEntry.java b/plugins/stream-debugger/testData/streamex/src/mapping/MapToEntry.java index 5d221c04263c..a16d2741ccba 100644 --- a/plugins/stream-debugger/testData/streamex/src/mapping/MapToEntry.java +++ b/plugins/stream-debugger/testData/streamex/src/mapping/MapToEntry.java @@ -5,7 +5,7 @@ import one.util.streamex.StreamEx; public class MapToEntry { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2, 3).mapToEntry(x -> x * x).count(); - System.out.println(count); + Object[] result = StreamEx.of(1, 2, 3).mapToEntry(x -> x * x).toArray(); + System.out.println(result.length); } } diff --git a/plugins/stream-debugger/testData/streamex/src/mapping/MapToKey.java b/plugins/stream-debugger/testData/streamex/src/mapping/MapToKey.java index 7a3c50c7cef2..7e31f4417e19 100644 --- a/plugins/stream-debugger/testData/streamex/src/mapping/MapToKey.java +++ b/plugins/stream-debugger/testData/streamex/src/mapping/MapToKey.java @@ -5,9 +5,8 @@ import one.util.streamex.EntryStream; public class MapToKey { public static void main(String[] args) { // Breakpoint! - final long count = EntryStream.of(1, 1, 2, 4, 3, 9) + EntryStream.of(1, 1, 2, 4, 3, 9) .mapToKey((k, v) -> k + v) - .count(); - System.out.println(count); + .forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/mapping/MapToValue.java b/plugins/stream-debugger/testData/streamex/src/mapping/MapToValue.java index 9da1aaf147ce..40912ed8a693 100644 --- a/plugins/stream-debugger/testData/streamex/src/mapping/MapToValue.java +++ b/plugins/stream-debugger/testData/streamex/src/mapping/MapToValue.java @@ -5,9 +5,8 @@ import one.util.streamex.EntryStream; public class MapToValue { public static void main(String[] args) { // Breakpoint! - final long count = EntryStream.of(1, 1, 2, 4, 3, 9) + EntryStream.of(1, 1, 2, 4, 3, 9) .mapToValue((k, v) -> k + v) - .count(); - System.out.println(count); + .forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/mapping/MapValues.java b/plugins/stream-debugger/testData/streamex/src/mapping/MapValues.java index 138dbd594a9e..57d75c179a91 100644 --- a/plugins/stream-debugger/testData/streamex/src/mapping/MapValues.java +++ b/plugins/stream-debugger/testData/streamex/src/mapping/MapValues.java @@ -5,9 +5,8 @@ import one.util.streamex.EntryStream; public class MapValues { public static void main(String[] args) { // Breakpoint! - final long count = EntryStream.of(1, 1, 2, 4, 3, 9) + EntryStream.of(1, 1, 2, 4, 3, 9) .mapValues(x -> 0) - .count(); - System.out.println(count); + .forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/mapping/WithFirst.java b/plugins/stream-debugger/testData/streamex/src/mapping/WithFirst.java index 354a1970e205..3bd7609d88a8 100644 --- a/plugins/stream-debugger/testData/streamex/src/mapping/WithFirst.java +++ b/plugins/stream-debugger/testData/streamex/src/mapping/WithFirst.java @@ -5,7 +5,6 @@ import one.util.streamex.StreamEx; public class WithFirst { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(10., 2., 3.).withFirst((first, other) -> first * other).count(); - System.out.println(count); + StreamEx.of(10., 2., 3.).withFirst((first, other) -> first * other).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/misc/Parallel.java b/plugins/stream-debugger/testData/streamex/src/misc/Parallel.java index 092277244f1f..9134975d6672 100644 --- a/plugins/stream-debugger/testData/streamex/src/misc/Parallel.java +++ b/plugins/stream-debugger/testData/streamex/src/misc/Parallel.java @@ -8,7 +8,6 @@ import java.util.concurrent.ForkJoinPool; public class Parallel { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2, 3).parallel((ForkJoinPool) Executors.newWorkStealingPool()).count(); - System.out.println(count); + StreamEx.of(1, 2, 3).parallel((ForkJoinPool) Executors.newWorkStealingPool()).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/misc/PrefixKeys.java b/plugins/stream-debugger/testData/streamex/src/misc/PrefixKeys.java index c161c996e67b..acf13c42baea 100644 --- a/plugins/stream-debugger/testData/streamex/src/misc/PrefixKeys.java +++ b/plugins/stream-debugger/testData/streamex/src/misc/PrefixKeys.java @@ -5,7 +5,6 @@ import one.util.streamex.EntryStream; public class PrefixKeys { public static void main(String[] args) { // Breakpoint! - final long count = EntryStream.of(1, 1, 2, 4, 3, 9).prefixKeys((l, r) -> l + r).count(); - System.out.println(count); + EntryStream.of(1, 1, 2, 4, 3, 9).prefixKeys((l, r) -> l + r).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/misc/PrefixValues.java b/plugins/stream-debugger/testData/streamex/src/misc/PrefixValues.java index d5ac4a026f13..f97cc03c4c40 100644 --- a/plugins/stream-debugger/testData/streamex/src/misc/PrefixValues.java +++ b/plugins/stream-debugger/testData/streamex/src/misc/PrefixValues.java @@ -5,7 +5,6 @@ import one.util.streamex.EntryStream; public class PrefixValues { public static void main(String[] args) { // Breakpoint! - final long count = EntryStream.of(1, 1, 2, 4, 3, 9).prefixValues((l, r) -> l + r).count(); - System.out.println(count); + EntryStream.of(1, 1, 2, 4, 3, 9).prefixValues((l, r) -> l + r).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/misc/ZipWithGreater.java b/plugins/stream-debugger/testData/streamex/src/misc/ZipWithGreater.java index aeaa9cbdcc68..f86db4521c71 100644 --- a/plugins/stream-debugger/testData/streamex/src/misc/ZipWithGreater.java +++ b/plugins/stream-debugger/testData/streamex/src/misc/ZipWithGreater.java @@ -7,7 +7,6 @@ import java.util.stream.Stream; public class ZipWithGreater { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2, 3).zipWith(Stream.of(1, 3, 9, 16, 25)).count(); - System.out.println(count); + StreamEx.of(1, 2, 3).zipWith(Stream.of(1, 3, 9, 16, 25)).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/misc/ZipWithLesser.java b/plugins/stream-debugger/testData/streamex/src/misc/ZipWithLesser.java index 0666014082c4..a2a73769830a 100644 --- a/plugins/stream-debugger/testData/streamex/src/misc/ZipWithLesser.java +++ b/plugins/stream-debugger/testData/streamex/src/misc/ZipWithLesser.java @@ -7,7 +7,6 @@ import java.util.stream.Stream; public class ZipWithLesser { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2, 3, 4, 5).zipWith(Stream.of(1, 3, 9)).count(); - System.out.println(count); + StreamEx.of(1, 2, 3, 4, 5).zipWith(Stream.of(1, 3, 9)).forEach(x -> {}); } } diff --git a/plugins/stream-debugger/testData/streamex/src/misc/ZipWithSameSizes.java b/plugins/stream-debugger/testData/streamex/src/misc/ZipWithSameSizes.java index 5dd387ec04bf..9337834c74d5 100644 --- a/plugins/stream-debugger/testData/streamex/src/misc/ZipWithSameSizes.java +++ b/plugins/stream-debugger/testData/streamex/src/misc/ZipWithSameSizes.java @@ -7,7 +7,6 @@ import java.util.stream.Stream; public class ZipWithSameSizes { public static void main(String[] args) { // Breakpoint! - final long count = StreamEx.of(1, 2, 3).zipWith(Stream.of(1, 3, 9)).count(); - System.out.println(count); + StreamEx.of(1, 2, 3).zipWith(Stream.of(1, 3, 9)).forEach(x -> {}); } }