IDEA-144666 Surround with runtime type doesn't work for array types

This commit is contained in:
Egor.Ushakov
2015-09-02 13:58:34 +03:00
parent d222f61d8e
commit 4f22cc16f6
4 changed files with 31 additions and 32 deletions
@@ -71,7 +71,7 @@ public class JavaWithRuntimeCastSurrounder extends JavaExpressionSurrounder {
return null;
}
private class SurroundWithCastWorker extends RuntimeTypeEvaluator {
private static class SurroundWithCastWorker extends RuntimeTypeEvaluator {
private final Editor myEditor;
public SurroundWithCastWorker(Editor editor, PsiExpression expression, DebuggerContextImpl context, final ProgressIndicator indicator) {
@@ -80,7 +80,7 @@ public class JavaWithRuntimeCastSurrounder extends JavaExpressionSurrounder {
}
@Override
protected void typeCalculationFinished(@Nullable final PsiClass type) {
protected void typeCalculationFinished(@Nullable final PsiType type) {
if (type == null) {
return;
}
@@ -94,9 +94,9 @@ public class JavaWithRuntimeCastSurrounder extends JavaExpressionSurrounder {
try {
PsiElementFactory factory = JavaPsiFacade.getInstance(myElement.getProject()).getElementFactory();
PsiParenthesizedExpression parenth =
(PsiParenthesizedExpression)factory.createExpressionFromText("((" + type.getQualifiedName() + ")expr)", null);
PsiTypeCastExpression cast = (PsiTypeCastExpression)parenth.getExpression();
cast.getOperand().replace(myElement);
(PsiParenthesizedExpression)factory.createExpressionFromText("((" + type.getCanonicalText() + ")expr)", null);
//noinspection ConstantConditions
((PsiTypeCastExpression)parenth.getExpression()).getOperand().replace(myElement);
parenth = (PsiParenthesizedExpression)JavaCodeStyleManager.getInstance(project).shortenClassReferences(parenth);
PsiExpression expr = (PsiExpression)myElement.replace(parenth);
TextRange range = expr.getTextRange();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@ import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.DebuggerInvocationUtil;
import com.intellij.debugger.EvaluatingComputable;
import com.intellij.debugger.engine.ContextUtil;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
@@ -33,7 +34,6 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.sun.jdi.ClassType;
import com.sun.jdi.InterfaceType;
import com.sun.jdi.Type;
@@ -43,13 +43,13 @@ import org.jetbrains.annotations.Nullable;
/**
* @author peter
*/
public abstract class RuntimeTypeEvaluator extends EditorEvaluationCommand<PsiClass> {
public abstract class RuntimeTypeEvaluator extends EditorEvaluationCommand<PsiType> {
public RuntimeTypeEvaluator(@Nullable Editor editor, PsiElement expression, DebuggerContextImpl context, final ProgressIndicator indicator) {
super(editor, expression, context, indicator);
}
public void threadAction() {
PsiClass type = null;
PsiType type = null;
try {
type = evaluate();
}
@@ -62,10 +62,10 @@ public abstract class RuntimeTypeEvaluator extends EditorEvaluationCommand<PsiCl
}
}
protected abstract void typeCalculationFinished(@Nullable PsiClass type);
protected abstract void typeCalculationFinished(@Nullable PsiType type);
@Nullable
protected PsiClass evaluate(final EvaluationContextImpl evaluationContext) throws EvaluateException {
protected PsiType evaluate(final EvaluationContextImpl evaluationContext) throws EvaluateException {
final Project project = evaluationContext.getProject();
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(project, new EvaluatingComputable<ExpressionEvaluator>() {
@@ -82,36 +82,37 @@ public abstract class RuntimeTypeEvaluator extends EditorEvaluationCommand<PsiCl
throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.surrounded.expression.null"));
}
public static PsiClass getCastableRuntimeType(Project project, Value value) {
@Nullable
public static PsiType getCastableRuntimeType(Project project, Value value) {
Type type = value.type();
PsiClass psiClass = findPsiClass(project, type);
if (psiClass != null) {
return psiClass;
PsiType psiType = findPsiType(project, type);
if (psiType != null) {
return psiType;
}
if (type instanceof ClassType) {
ClassType superclass = ((ClassType)type).superclass();
if (superclass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(superclass.name())) {
psiClass = findPsiClass(project, superclass);
if (psiClass != null) {
return psiClass;
psiType = findPsiType(project, superclass);
if (psiType != null) {
return psiType;
}
}
for (InterfaceType interfaceType : ((ClassType)type).interfaces()) {
psiClass = findPsiClass(project, interfaceType);
if (psiClass != null) {
return psiClass;
psiType = findPsiType(project, interfaceType);
if (psiType != null) {
return psiType;
}
}
}
return null;
}
private static PsiClass findPsiClass(Project project, Type type) {
private static PsiType findPsiType(Project project, Type type) {
AccessToken token = ReadAction.start();
try {
return JavaPsiFacade.getInstance(project).findClass(type.name().replace('$', '.'), GlobalSearchScope.allScope(project));
return DebuggerUtils.getType(type.name().replace('$', '.'), project);
}
finally {
token.finish();
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -92,11 +92,11 @@ public class DefaultCodeFragmentFactory extends CodeFragmentFactory {
if (debuggerSession != null) {
final Semaphore semaphore = new Semaphore();
semaphore.down();
final AtomicReference<PsiClass> nameRef = new AtomicReference<PsiClass>();
final AtomicReference<PsiType> nameRef = new AtomicReference<PsiType>();
final RuntimeTypeEvaluator worker =
new RuntimeTypeEvaluator(null, expression, debuggerContext, ProgressManager.getInstance().getProgressIndicator()) {
@Override
protected void typeCalculationFinished(@Nullable PsiClass type) {
protected void typeCalculationFinished(@Nullable PsiType type) {
nameRef.set(type);
semaphore.up();
}
@@ -106,10 +106,7 @@ public class DefaultCodeFragmentFactory extends CodeFragmentFactory {
ProgressManager.checkCanceled();
if (semaphore.waitFor(20)) break;
}
final PsiClass psiClass = nameRef.get();
if (psiClass != null) {
return JavaPsiFacade.getElementFactory(project).createType(psiClass);
}
return nameRef.get();
}
return null;
}
@@ -219,16 +219,17 @@ public class DebuggerTreeNodeExpression {
Project project = expression.getProject();
PsiClass type = RuntimeTypeEvaluator.getCastableRuntimeType(project, value);
PsiType type = RuntimeTypeEvaluator.getCastableRuntimeType(project, value);
if (type == null) {
return expression;
}
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
String typeName = type.getQualifiedName();
String typeName = type.getCanonicalText();
try {
PsiParenthesizedExpression parenthExpression = (PsiParenthesizedExpression)elementFactory.createExpressionFromText(
"((" + typeName + ")expression)", null);
//noinspection ConstantConditions
((PsiTypeCastExpression)parenthExpression.getExpression()).getOperand().replace(expression);
Set<String> imports = expression.getUserData(ADDITIONAL_IMPORTS_KEY);
if (imports == null) {