mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-157321 Debugger and Runtime Java Varargs inconsistent
This commit is contained in:
@@ -1041,20 +1041,37 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
|
||||
// See IDEA-63581
|
||||
// if vararg parameter array is of interface type and Object[] is expected, JDI wrap it into another array,
|
||||
// in this case we have to unroll the array manually and pass its elements to the method instead of array object
|
||||
int lastIndex = myArgs.size() - 1;
|
||||
if (lastIndex >= 0) {
|
||||
final Object lastArg = myArgs.get(lastIndex);
|
||||
if (lastArg instanceof ArrayReference) {
|
||||
final ArrayReference arrayRef = (ArrayReference)lastArg;
|
||||
if (((ArrayType)arrayRef.referenceType()).componentType() instanceof InterfaceType) {
|
||||
List<String> argTypes = myMethod.argumentTypeNames();
|
||||
if (argTypes.size() > lastIndex && argTypes.get(lastIndex).startsWith(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
// unwrap array of interfaces for vararg param
|
||||
myArgs.remove(lastIndex);
|
||||
myArgs.addAll(arrayRef.getValues());
|
||||
int lastIndex = myMethod.argumentTypeNames().size() - 1;
|
||||
if (lastIndex >= 0 && myArgs.size() > lastIndex) { // at least one varargs param
|
||||
Object firstVararg = myArgs.get(lastIndex);
|
||||
if (myArgs.size() == lastIndex + 1) { // only one vararg param
|
||||
if (firstVararg instanceof ArrayReference) {
|
||||
ArrayReference arrayRef = (ArrayReference)firstVararg;
|
||||
if (((ArrayType)arrayRef.referenceType()).componentType() instanceof InterfaceType) {
|
||||
List<String> argTypes = myMethod.argumentTypeNames();
|
||||
if (argTypes.size() > lastIndex && argTypes.get(lastIndex).startsWith(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
// unwrap array of interfaces for vararg param
|
||||
myArgs.remove(lastIndex);
|
||||
myArgs.addAll(arrayRef.getValues());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (firstVararg == null) { // more than one vararg params and the first one is null
|
||||
// this is a workaround for a bug in jdi, see IDEA-157321
|
||||
int argCount = myArgs.size();
|
||||
List<Type> paramTypes = myMethod.argumentTypes();
|
||||
int paramCount = paramTypes.size();
|
||||
ArrayType lastParamType = (ArrayType)paramTypes.get(paramTypes.size() - 1);
|
||||
|
||||
int count = argCount - paramCount + 1;
|
||||
ArrayReference argArray = lastParamType.newInstance(count);
|
||||
argArray.setValues(0, myArgs, paramCount - 1, count);
|
||||
myArgs.set(paramCount - 1, argArray);
|
||||
for (int ii = paramCount; ii < argCount; ii++) {
|
||||
myArgs.remove(paramCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-30
@@ -1089,7 +1089,6 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
|
||||
if (psiMethod != null) {
|
||||
processBoxingConversions(psiMethod.getParameterList().getParameters(), argExpressions, resolveResult.getSubstitutor(), argumentEvaluators);
|
||||
argumentEvaluators = wrapVarargs(psiMethod.getParameterList().getParameters(), argExpressions, resolveResult.getSubstitutor(), argumentEvaluators);
|
||||
defaultInterfaceMethod = psiMethod.hasModifierProperty(PsiModifier.DEFAULT);
|
||||
mustBeVararg = psiMethod.isVarArgs();
|
||||
}
|
||||
@@ -1319,7 +1318,6 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
|
||||
if (constructor != null) {
|
||||
processBoxingConversions(constructor.getParameterList().getParameters(), argExpressions, constructorResolveResult.getSubstitutor(), argumentEvaluators);
|
||||
argumentEvaluators = wrapVarargs(constructor.getParameterList().getParameters(), argExpressions, constructorResolveResult.getSubstitutor(), argumentEvaluators);
|
||||
}
|
||||
|
||||
if (aClass != null && aClass.getContainingClass() != null && !aClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
@@ -1410,34 +1408,6 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private static Evaluator[] wrapVarargs(final PsiParameter[] declaredParams,
|
||||
final PsiExpression[] actualArgumentExpressions,
|
||||
final PsiSubstitutor methodResolveSubstitutor,
|
||||
final Evaluator[] argumentEvaluators) {
|
||||
int lastParam = declaredParams.length - 1;
|
||||
if (lastParam >= 0 && declaredParams[lastParam].isVarArgs() && argumentEvaluators.length > lastParam) {
|
||||
// only wrap if the first varargs parameter is null for now
|
||||
if (!TypeConversionUtil.isNullType(actualArgumentExpressions[lastParam].getType())) {
|
||||
return argumentEvaluators;
|
||||
}
|
||||
// do not wrap arrays twice
|
||||
if (argumentEvaluators.length - lastParam == 1 && actualArgumentExpressions[lastParam].getType() instanceof PsiArrayType) {
|
||||
return argumentEvaluators;
|
||||
}
|
||||
PsiEllipsisType declaredParamType = (PsiEllipsisType)methodResolveSubstitutor.substitute(declaredParams[lastParam].getType());
|
||||
ArrayInitializerEvaluator varargArrayEvaluator =
|
||||
new ArrayInitializerEvaluator(Arrays.copyOfRange(argumentEvaluators, lastParam, argumentEvaluators.length));
|
||||
NewArrayInstanceEvaluator evaluator =
|
||||
new NewArrayInstanceEvaluator(new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(declaredParamType.toArrayType())), null,
|
||||
varargArrayEvaluator);
|
||||
Evaluator[] res = new Evaluator[declaredParams.length];
|
||||
System.arraycopy(argumentEvaluators, 0, res, 0, lastParam);
|
||||
res[lastParam] = new DisableGC(evaluator);
|
||||
return res;
|
||||
}
|
||||
return argumentEvaluators;
|
||||
}
|
||||
|
||||
private static void processBoxingConversions(final PsiParameter[] declaredParams,
|
||||
final PsiExpression[] actualArgumentExpressions,
|
||||
final PsiSubstitutor methodResolveSubstitutor,
|
||||
|
||||
Reference in New Issue
Block a user