mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
cast to runtime type for anonymous classes
This commit is contained in:
+2
-6
@@ -25,7 +25,6 @@ import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.ui.DebuggerExpressionComboBox;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
@@ -43,7 +42,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
* Time: 7:51:01 PM
|
||||
*/
|
||||
public class JavaWithRuntimeCastSurrounder extends JavaExpressionSurrounder {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.codeinsight.SurroundWithRuntimeCastHandler");
|
||||
|
||||
public String getTemplateDescription() {
|
||||
return CodeInsightBundle.message("surround.with.runtime.type.template");
|
||||
@@ -81,7 +79,7 @@ public class JavaWithRuntimeCastSurrounder extends JavaExpressionSurrounder {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void typeCalculationFinished(@Nullable final String type) {
|
||||
protected void typeCalculationFinished(@Nullable final PsiClass type) {
|
||||
if (type == null) {
|
||||
return;
|
||||
}
|
||||
@@ -93,11 +91,9 @@ public class JavaWithRuntimeCastSurrounder extends JavaExpressionSurrounder {
|
||||
new WriteCommandAction(project, CodeInsightBundle.message("command.name.surround.with.runtime.cast")) {
|
||||
protected void run(Result result) throws Throwable {
|
||||
try {
|
||||
LOG.assertTrue(type != null);
|
||||
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(myElement.getProject()).getElementFactory();
|
||||
PsiParenthesizedExpression parenth =
|
||||
(PsiParenthesizedExpression)factory.createExpressionFromText("((" + type + ")expr)", null);
|
||||
(PsiParenthesizedExpression)factory.createExpressionFromText("((" + type.getQualifiedName() + ")expr)", null);
|
||||
PsiTypeCastExpression cast = (PsiTypeCastExpression)parenth.getExpression();
|
||||
cast.getOperand().replace(myElement);
|
||||
parenth = (PsiParenthesizedExpression)JavaCodeStyleManager.getInstance(project).shortenClassReferences(parenth);
|
||||
|
||||
+59
-24
@@ -15,38 +15,41 @@
|
||||
*/
|
||||
package com.intellij.debugger.codeinsight;
|
||||
|
||||
import com.intellij.debugger.ui.EditorEvaluationCommand;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
|
||||
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl;
|
||||
import com.intellij.debugger.engine.ContextUtil;
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerInvocationUtil;
|
||||
import com.intellij.debugger.EvaluatingComputable;
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.engine.ContextUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl;
|
||||
import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.ui.EditorEvaluationCommand;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
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;
|
||||
import com.sun.jdi.Value;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class RuntimeTypeEvaluator extends EditorEvaluationCommand<String> {
|
||||
public abstract class RuntimeTypeEvaluator extends EditorEvaluationCommand<PsiClass> {
|
||||
public RuntimeTypeEvaluator(@Nullable Editor editor, PsiElement expression, DebuggerContextImpl context, final ProgressIndicator indicator) {
|
||||
super(editor, expression, context, indicator);
|
||||
}
|
||||
|
||||
public void threadAction() {
|
||||
String type = null;
|
||||
PsiClass type = null;
|
||||
try {
|
||||
type = evaluate();
|
||||
}
|
||||
@@ -59,9 +62,10 @@ public abstract class RuntimeTypeEvaluator extends EditorEvaluationCommand<Strin
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract void typeCalculationFinished(@Nullable String type);
|
||||
protected abstract void typeCalculationFinished(@Nullable PsiClass type);
|
||||
|
||||
protected String evaluate(final EvaluationContextImpl evaluationContext) throws EvaluateException {
|
||||
@Nullable
|
||||
protected PsiClass evaluate(final EvaluationContextImpl evaluationContext) throws EvaluateException {
|
||||
final Project project = evaluationContext.getProject();
|
||||
|
||||
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(project, new EvaluatingComputable<ExpressionEvaluator>() {
|
||||
@@ -72,14 +76,45 @@ public abstract class RuntimeTypeEvaluator extends EditorEvaluationCommand<Strin
|
||||
|
||||
final Value value = evaluator.evaluate(evaluationContext);
|
||||
if(value != null){
|
||||
return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
|
||||
public String compute() {
|
||||
return DebuggerUtilsEx.getQualifiedClassName(value.type().name(), project);
|
||||
}
|
||||
});
|
||||
return getCastableRuntimeType(project, value);
|
||||
}
|
||||
else {
|
||||
throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.surrounded.expression.null"));
|
||||
|
||||
throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.surrounded.expression.null"));
|
||||
}
|
||||
|
||||
public static PsiClass getCastableRuntimeType(Project project, Value value) {
|
||||
Type type = value.type();
|
||||
PsiClass psiClass = findPsiClass(project, type);
|
||||
if (psiClass != null) {
|
||||
return psiClass;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
for (InterfaceType interfaceType : ((ClassType)type).interfaces()) {
|
||||
psiClass = findPsiClass(project, interfaceType);
|
||||
if (psiClass != null) {
|
||||
return psiClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PsiClass findPsiClass(Project project, Type type) {
|
||||
AccessToken token = ReadAction.start();
|
||||
try {
|
||||
return JavaPsiFacade.getInstance(project).findClass(type.name().replace('$', '.'), GlobalSearchScope.allScope(project));
|
||||
}
|
||||
finally {
|
||||
token.finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-10
@@ -16,8 +16,8 @@
|
||||
package com.intellij.debugger.engine.evaluation;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionParameters;
|
||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||
import com.intellij.codeInsight.completion.CompletionService;
|
||||
import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.codeinsight.RuntimeTypeEvaluator;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
@@ -29,7 +29,6 @@ import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.util.PairFunction;
|
||||
import com.intellij.util.concurrency.Semaphore;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -91,11 +90,11 @@ public class DefaultCodeFragmentFactory implements CodeFragmentFactory {
|
||||
if (debuggerSession != null) {
|
||||
final Semaphore semaphore = new Semaphore();
|
||||
semaphore.down();
|
||||
final AtomicReference<String> nameRef = new AtomicReference<String>();
|
||||
final AtomicReference<PsiClass> nameRef = new AtomicReference<PsiClass>();
|
||||
final RuntimeTypeEvaluator worker =
|
||||
new RuntimeTypeEvaluator(null, expression, debuggerContext, ProgressManager.getInstance().getProgressIndicator()) {
|
||||
@Override
|
||||
protected void typeCalculationFinished(@Nullable String type) {
|
||||
protected void typeCalculationFinished(@Nullable PsiClass type) {
|
||||
nameRef.set(type);
|
||||
semaphore.up();
|
||||
}
|
||||
@@ -105,12 +104,9 @@ public class DefaultCodeFragmentFactory implements CodeFragmentFactory {
|
||||
ProgressManager.checkCanceled();
|
||||
if (semaphore.waitFor(20)) break;
|
||||
}
|
||||
final String className = nameRef.get();
|
||||
if (className != null) {
|
||||
final PsiClass psiClass = JavaPsiFacade.getInstance(project).findClass(className, GlobalSearchScope.allScope(project));
|
||||
if (psiClass != null) {
|
||||
return JavaPsiFacade.getElementFactory(project).createType(psiClass);
|
||||
}
|
||||
final PsiClass psiClass = nameRef.get();
|
||||
if (psiClass != null) {
|
||||
return JavaPsiFacade.getElementFactory(project).createType(psiClass);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
+23
-28
@@ -17,11 +17,11 @@ package com.intellij.debugger.ui.impl.watch;
|
||||
|
||||
import com.intellij.codeInsight.ChangeContextUtil;
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.codeinsight.RuntimeTypeEvaluator;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
@@ -197,37 +197,32 @@ public class DebuggerTreeNodeExpression {
|
||||
}
|
||||
|
||||
public static PsiExpression castToRuntimeType(PsiExpression expression, Value value, PsiElement contextElement) throws EvaluateException {
|
||||
if (value instanceof ObjectReference) {
|
||||
return castToType(expression, ((ObjectReference)value).referenceType(), contextElement);
|
||||
}
|
||||
else {
|
||||
if (!(value instanceof ObjectReference)) {
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
|
||||
private static PsiExpression castToType(PsiExpression expression, ReferenceType valueType, PsiElement contextElement) throws EvaluateException{
|
||||
if (valueType != null) {
|
||||
Project project = expression.getProject();
|
||||
|
||||
String typeName = DebuggerUtilsEx.getQualifiedClassName(valueType.name(), project);
|
||||
PsiManager manager = PsiManager.getInstance(project);
|
||||
|
||||
typeName = normalize(typeName, contextElement, project);
|
||||
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
|
||||
try {
|
||||
PsiParenthesizedExpression parenthExpression = (PsiParenthesizedExpression)elementFactory.createExpressionFromText(
|
||||
"((" + typeName + ")expression)", null);
|
||||
((PsiTypeCastExpression)parenthExpression.getExpression()).getOperand().replace(expression);
|
||||
return parenthExpression;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
throw new EvaluateException(DebuggerBundle.message("error.invalid.type.name", typeName), e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
ReferenceType valueType = ((ObjectReference)value).referenceType();
|
||||
if (valueType == null) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
Project project = expression.getProject();
|
||||
|
||||
PsiClass type = RuntimeTypeEvaluator.getCastableRuntimeType(project, value);
|
||||
if (type == null) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
try {
|
||||
PsiParenthesizedExpression parenthExpression = (PsiParenthesizedExpression)elementFactory.createExpressionFromText(
|
||||
"((" + type.getQualifiedName() + ")expression)", null);
|
||||
((PsiTypeCastExpression)parenthExpression.getExpression()).getOperand().replace(expression);
|
||||
return parenthExpression;
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
throw new EvaluateException(DebuggerBundle.message("error.invalid.type.name", type.getQualifiedName()), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user