Added possibility to define different evaluator builder for custom code fragment factory.

This commit is contained in:
Alexander.Podkhalyuzin
2011-10-11 17:58:58 +04:00
parent dc6be4b6d5
commit 0e7b74661e
15 changed files with 53 additions and 18 deletions
@@ -407,7 +407,7 @@ public class SetValueAction extends DebuggerAction {
protected Object evaluate(final EvaluationContextImpl evaluationContext) throws EvaluateException {
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(evaluationContext.getProject(), new com.intellij.debugger.EvaluatingComputable<ExpressionEvaluator>() {
public ExpressionEvaluator compute() throws EvaluateException {
return EvaluatorBuilderImpl.getInstance().build(text, ContextUtil.getContextElement(evaluationContext), ContextUtil.getSourcePosition(evaluationContext));
return EvaluatorBuilderImpl.build(text, ContextUtil.getContextElement(evaluationContext), ContextUtil.getSourcePosition(evaluationContext));
}
});
@@ -17,6 +17,8 @@ package com.intellij.debugger.engine.evaluation;
import com.intellij.debugger.DebuggerManagerEx;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder;
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
import com.intellij.openapi.fileTypes.LanguageFileType;
@@ -66,8 +68,11 @@ public class CodeFragmentFactoryContextWrapper implements CodeFragmentFactory{
public LanguageFileType getFileType() {
return myDelegate.getFileType();
}
@Override
public EvaluatorBuilder getEvaluatorBuilder() {
return myDelegate.getEvaluatorBuilder();
}
private PsiElement wrapContext(Project project, final PsiElement originalContext) {
if (project.isDefault()) return originalContext;
@@ -20,6 +20,8 @@ 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.engine.evaluation.expression.EvaluatorBuilder;
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl;
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.debugger.ui.DebuggerExpressionComboBox;
@@ -123,4 +125,9 @@ public class DefaultCodeFragmentFactory implements CodeFragmentFactory {
public LanguageFileType getFileType() {
return StdFileTypes.JAVA;
}
@Override
public EvaluatorBuilder getEvaluatorBuilder() {
return EvaluatorBuilderImpl.getInstance();
}
}
@@ -58,21 +58,24 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
return ourInstance;
}
public ExpressionEvaluator build(final TextWithImports text, final PsiElement contextElement, final SourcePosition position) throws EvaluateException {
public static ExpressionEvaluator build(final TextWithImports text, final PsiElement contextElement, final SourcePosition position) throws EvaluateException {
if (contextElement == null) {
throw EvaluateExceptionUtil.CANNOT_FIND_SOURCE_CLASS;
}
final Project project = contextElement.getProject();
PsiCodeFragment codeFragment = new CodeFragmentFactoryContextWrapper(DebuggerEditorImpl.findAppropriateFactory(text, contextElement)).createCodeFragment(text, contextElement, project);
CodeFragmentFactory factory = DebuggerEditorImpl.findAppropriateFactory(text, contextElement);
PsiCodeFragment codeFragment = new CodeFragmentFactoryContextWrapper(factory).createCodeFragment(text, contextElement, project);
if(codeFragment == null) {
throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", text.getText()));
}
codeFragment.forceResolveScope(GlobalSearchScope.allScope(project));
DebuggerUtils.checkSyntax(codeFragment);
return build(codeFragment, position);
EvaluatorBuilder evaluatorBuilder = factory.getEvaluatorBuilder();
return evaluatorBuilder.build(codeFragment, position);
}
public ExpressionEvaluator build(final PsiElement codeFragment, final SourcePosition position) throws EvaluateException {
@@ -217,7 +217,7 @@ public abstract class Breakpoint extends FilteredRequestor implements ClassPrepa
try {
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(getProject(), new EvaluatingComputable<ExpressionEvaluator>() {
public ExpressionEvaluator compute() throws EvaluateException {
return EvaluatorBuilderImpl.getInstance().build(expressionToEvaluate, ContextUtil.getContextElement(context), ContextUtil.getSourcePosition(context));
return EvaluatorBuilderImpl.build(expressionToEvaluate, ContextUtil.getContextElement(context), ContextUtil.getSourcePosition(context));
}
});
final String result = DebuggerUtils.getValueAsString(context, evaluator.evaluate(context));
@@ -180,7 +180,7 @@ public abstract class FilteredRequestor implements LocatableEventRequestor, JDOM
if (contextPsiElement == null) {
contextPsiElement = getEvaluationElement(); // as a last resort
}
return EvaluatorBuilderImpl.getInstance().build(getCondition(), contextPsiElement, contextSourcePosition);
return EvaluatorBuilderImpl.build(getCondition(), contextPsiElement, contextSourcePosition);
}
});
final Value value = evaluator.evaluate(context);
@@ -218,4 +218,4 @@ public abstract class FilteredRequestor implements LocatableEventRequestor, JDOM
public Project getProject() {
return myProject;
}
}
}
@@ -510,7 +510,7 @@ public class FrameVariablesTree extends DebuggerTree {
if (!isConstant) {
final TextWithImportsImpl textWithImports = new TextWithImportsImpl(reference);
try {
final ExpressionEvaluator evaluator = EvaluatorBuilderImpl.getInstance().build(textWithImports, reference, myPosition);
final ExpressionEvaluator evaluator = EvaluatorBuilderImpl.build(textWithImports, reference, myPosition);
evaluator.evaluate(myEvalContext);
//collect only expressions that do not produce any exceptions on evaluation
myExpressions.add(textWithImports);
@@ -561,4 +561,4 @@ public class FrameVariablesTree extends DebuggerTree {
// Do not step in to local and anonymous classes...
}
}
}
}
@@ -26,6 +26,7 @@ import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl;
import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
import com.intellij.debugger.engine.evaluation.expression.Modifier;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.impl.PositionUtil;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
@@ -87,13 +88,15 @@ public abstract class EvaluationDescriptor extends ValueDescriptorImpl{
protected abstract PsiCodeFragment getEvaluationCode(StackFrameContext context) throws EvaluateException;
public final Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
public final Value calcValue(final EvaluationContextImpl evaluationContext) throws EvaluateException {
try {
final EvaluationContextImpl thisEvaluationContext = getEvaluationContext(evaluationContext);
final ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, new EvaluatingComputable<ExpressionEvaluator>() {
public ExpressionEvaluator compute() throws EvaluateException {
return EvaluatorBuilderImpl.getInstance().build(getEvaluationCode(thisEvaluationContext), ContextUtil.getSourcePosition(thisEvaluationContext));
final PsiElement psiContext = PositionUtil.getContextElement(evaluationContext);
return getEffectiveCodeFragmentFactory(psiContext).getEvaluatorBuilder().build(getEvaluationCode(thisEvaluationContext),
ContextUtil.getSourcePosition(thisEvaluationContext));
}
});
@@ -77,7 +77,7 @@ public abstract class CachedEvaluator {
codeFragment.setThisType(contextType);
DebuggerUtils.checkSyntax(codeFragment);
cache.myPsiChildrenExpression = ((PsiExpressionCodeFragment)codeFragment).getExpression();
cache.myEvaluator = ((DebuggerUtilsEx)DebuggerUtils.getInstance()).getEvaluatorBuilder().build(cache.myPsiChildrenExpression, null);
cache.myEvaluator = myDefaultFragmentFactory.getEvaluatorBuilder().build(cache.myPsiChildrenExpression, null);
}
catch (EvaluateException e) {
cache.myException = e;
@@ -15,6 +15,7 @@
*/
package com.intellij.debugger.engine.evaluation;
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
@@ -31,4 +32,11 @@ public interface CodeFragmentFactory {
boolean isContextAccepted(PsiElement contextElement);
LanguageFileType getFileType();
/**
* In case if createCodeFragment returns java code use
* com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl#getInstance()
* @return builder, which can evaluate expression for your code fragment
*/
EvaluatorBuilder getEvaluatorBuilder();
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2011 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.
@@ -20,8 +20,10 @@ import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.TextWithImports;
import com.intellij.psi.PsiElement;
/**
* Main interface to extend evaluation for different JVM languages.
* @see com.intellij.debugger.engine.evaluation.CodeFragmentFactory
*/
public interface EvaluatorBuilder {
ExpressionEvaluator build(TextWithImports text, PsiElement contextElement, final SourcePosition position) throws EvaluateException;
ExpressionEvaluator build(PsiElement codeFragment, final SourcePosition position) throws EvaluateException;
}
@@ -43,4 +43,4 @@ public interface Modifier {
Type getExpectedType() throws ClassNotLoadedException, EvaluateException;
NodeDescriptor getInspectItem(Project project);
}
}
@@ -17,6 +17,8 @@ package org.jetbrains.plugins.groovy.debugger;
import com.intellij.debugger.engine.evaluation.CodeFragmentFactory;
import com.intellij.debugger.engine.evaluation.TextWithImports;
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder;
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
@@ -262,4 +264,9 @@ public class GroovyCodeFragmentFactory implements CodeFragmentFactory {
public LanguageFileType getFileType() {
return GroovyFileType.GROOVY_FILE_TYPE;
}
@Override
public EvaluatorBuilder getEvaluatorBuilder() {
return EvaluatorBuilderImpl.getInstance();
}
}