mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'bibaev/IDEA-172425-eval-expr-jdk-9'
This commit is contained in:
+15
-1
@@ -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<ExpressionEvaluator, EvaluateException>)() -> {
|
||||
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);
|
||||
}
|
||||
|
||||
+31
-17
@@ -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()),
|
||||
|
||||
+8
@@ -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 {
|
||||
}
|
||||
+86
@@ -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;
|
||||
}
|
||||
}
|
||||
+41
@@ -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<ReflectionAccessor> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
+104
@@ -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<ConstructorReflectionAccessor.ConstructorDescriptor> {
|
||||
private static final Logger LOG = Logger.getInstance(ConstructorReflectionAccessor.class);
|
||||
|
||||
protected ConstructorReflectionAccessor(@NotNull PsiClass psiClass,
|
||||
@NotNull PsiElementFactory elementFactory) {
|
||||
super(psiClass, elementFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ConstructorDescriptor> findItemsToReplace(@NotNull PsiElement element) {
|
||||
List<ConstructorDescriptor> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -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
|
||||
}
|
||||
+148
@@ -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<FieldReflectionAccessor.FieldDescriptor> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+74
@@ -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<MethodReferenceReflectionAccessor.MethodReferenceDescriptor> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+112
@@ -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<MethodReflectionAccessor.MethodCallDescriptor> {
|
||||
private static final Logger LOG = Logger.getInstance(MethodReflectionAccessor.class);
|
||||
|
||||
protected MethodReflectionAccessor(@NotNull PsiClass psiClass,
|
||||
@NotNull PsiElementFactory elementFactory) {
|
||||
super(psiClass, elementFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<MethodCallDescriptor> findItemsToReplace(@NotNull PsiElement element) {
|
||||
List<MethodCallDescriptor> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
@@ -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<T extends ItemToReplaceDescriptor> extends ReflectionAccessorBase<T> {
|
||||
public ReferenceReflectionAccessorBase(@NotNull PsiClass psiClass, @NotNull PsiElementFactory elementFactory) {
|
||||
super(psiClass, elementFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<T> findItemsToReplace(@NotNull PsiElement element) {
|
||||
List<T> 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);
|
||||
}
|
||||
+286
@@ -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<ParameterInfo> 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<String> 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<String> 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<String> getPossibleExceptions();
|
||||
}
|
||||
|
||||
|
||||
private static class MyFieldAccessor implements MyMemberAccessor {
|
||||
private static final List<String> 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<String> 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<String> 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<String> getPossibleExceptions() {
|
||||
return Collections.unmodifiableList(Collections.singletonList("java.lang.ReflectiveOperationException"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -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);
|
||||
}
|
||||
+55
@@ -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<T extends ItemToReplaceDescriptor> 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<T> toReplace = findItemsToReplace(element);
|
||||
for (T item : toReplace) {
|
||||
grantAccess(item);
|
||||
}
|
||||
|
||||
List<T> 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<T> findItemsToReplace(@NotNull PsiElement element);
|
||||
|
||||
protected abstract void grantAccess(@NotNull T descriptor);
|
||||
}
|
||||
+1
-1
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
-26
@@ -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<StreamChainWithLibrary> 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<StreamChainOption> {
|
||||
MyStreamChainChooser(@NotNull Editor editor) {
|
||||
super(editor);
|
||||
|
||||
+12
-2
@@ -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() {
|
||||
|
||||
+8
@@ -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"
|
||||
|
||||
+3
-7
@@ -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 {
|
||||
|
||||
+8
-8
@@ -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()
|
||||
}
|
||||
+7
-7
@@ -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()
|
||||
}
|
||||
+6
-6
@@ -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()
|
||||
}
|
||||
+15
-1
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 -> {});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user