mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[debugger] CodeFragmentFactory can produce PsiCodeFragment
* broaden code fragment type to be able to implement non-java evaluators Merge-request: IJ-MR-145790 Merged-by: Maksim Zuev <Maksim.Zuev@jetbrains.com> GitOrigin-RevId: 096badbd7e76b2c8065867349e0839452b683ab4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
08b5c4605c
commit
e046e5c6a5
+42
@@ -0,0 +1,42 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.debugger.engine
|
||||
|
||||
import com.intellij.debugger.engine.evaluation.CodeFragmentFactory
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports
|
||||
import com.intellij.debugger.impl.DebuggerUtilsImpl
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
|
||||
abstract class JavaDebuggerCodeFragmentFactory : CodeFragmentFactory() {
|
||||
final override fun createPsiCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment? {
|
||||
val codeFragment = createPsiCodeFragmentImpl(item, context, project) ?: return null
|
||||
if (context != null) {
|
||||
setThisType(context, codeFragment)
|
||||
}
|
||||
return codeFragment
|
||||
}
|
||||
|
||||
|
||||
final override fun createPresentationPsiCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment? {
|
||||
val codeFragment = createPresentationPsiCodeFragmentImpl(item, context, project) ?: return null
|
||||
if (context != null) {
|
||||
setThisType(context, codeFragment)
|
||||
}
|
||||
return codeFragment
|
||||
}
|
||||
|
||||
protected abstract fun createPresentationPsiCodeFragmentImpl(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment?
|
||||
protected abstract fun createPsiCodeFragmentImpl(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment?
|
||||
|
||||
private fun setThisType(context: PsiElement, codeFragment: JavaCodeFragment) {
|
||||
var contextType = context.getUserData(DebuggerUtilsImpl.PSI_TYPE_KEY)
|
||||
if (contextType == null) {
|
||||
val contextClass = PsiTreeUtil.getNonStrictParentOfType(context, PsiClass::class.java)
|
||||
if (contextClass != null) {
|
||||
contextType = JavaPsiFacade.getElementFactory(codeFragment.getProject()).createType(contextClass)
|
||||
}
|
||||
}
|
||||
codeFragment.setThisType(contextType)
|
||||
}
|
||||
}
|
||||
@@ -148,7 +148,7 @@ public class JavaDebuggerEvaluator extends XDebuggerEvaluator implements XDebugg
|
||||
catch (UnsupportedExpressionException ex) {
|
||||
PsiElement context = PositionUtil.getContextElement(debuggerContext);
|
||||
ExpressionEvaluator eval = CompilingEvaluatorImpl.create(project, context, e ->
|
||||
factory.createCodeFragment(text.get(), context, project));
|
||||
factory.createPsiCodeFragment(text.get(), context, project));
|
||||
if (eval != null) {
|
||||
return eval;
|
||||
}
|
||||
|
||||
+5
-5
@@ -28,13 +28,13 @@ public class CodeFragmentFactoryContextWrapper extends CodeFragmentFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaCodeFragment createCodeFragment(TextWithImports item, PsiElement context, Project project) {
|
||||
return prepareResolveScope(myDelegate.createCodeFragment(item, wrapContext(project, context), project));
|
||||
public PsiCodeFragment createPsiCodeFragment(TextWithImports item, PsiElement context, Project project) {
|
||||
return prepareResolveScope(myDelegate.createPsiCodeFragment(item, wrapContext(project, context), project));
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaCodeFragment createPresentationCodeFragment(TextWithImports item, PsiElement context, Project project) {
|
||||
return prepareResolveScope(myDelegate.createPresentationCodeFragment(item, wrapContext(project, context), project));
|
||||
public PsiCodeFragment createPresentationPsiCodeFragment(TextWithImports item, PsiElement context, Project project) {
|
||||
return prepareResolveScope(myDelegate.createPresentationPsiCodeFragment(item, wrapContext(project, context), project));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -53,7 +53,7 @@ public class CodeFragmentFactoryContextWrapper extends CodeFragmentFactory {
|
||||
return myDelegate.getEvaluatorBuilder();
|
||||
}
|
||||
|
||||
private static JavaCodeFragment prepareResolveScope(JavaCodeFragment codeFragment) {
|
||||
private static PsiCodeFragment prepareResolveScope(PsiCodeFragment codeFragment) {
|
||||
GlobalSearchScope originalResolveScope = codeFragment.getResolveScope();
|
||||
codeFragment.forceResolveScope(new DelegatingGlobalSearchScope(GlobalSearchScope.allScope(codeFragment.getProject())) {
|
||||
final Comparator<VirtualFile> myScopeComparator = Comparator.comparing(originalResolveScope::contains).thenComparing(super::compare);
|
||||
|
||||
+7
-4
@@ -6,6 +6,7 @@ import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.JavaDebuggerBundle;
|
||||
import com.intellij.debugger.codeinsight.RuntimeTypeEvaluator;
|
||||
import com.intellij.debugger.engine.JavaDebuggerCodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder;
|
||||
import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilderImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
@@ -27,7 +28,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
*/
|
||||
public class DefaultCodeFragmentFactory extends CodeFragmentFactory {
|
||||
public class DefaultCodeFragmentFactory extends JavaDebuggerCodeFragmentFactory {
|
||||
private static final class SingletonHolder {
|
||||
public static final DefaultCodeFragmentFactory ourInstance = new DefaultCodeFragmentFactory();
|
||||
}
|
||||
@@ -37,12 +38,14 @@ public class DefaultCodeFragmentFactory extends CodeFragmentFactory {
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaCodeFragment createPresentationCodeFragment(final TextWithImports item, final PsiElement context, final Project project) {
|
||||
return createCodeFragment(item, context, project);
|
||||
protected JavaCodeFragment createPresentationPsiCodeFragmentImpl(final @NotNull TextWithImports item,
|
||||
final PsiElement context,
|
||||
final @NotNull Project project) {
|
||||
return createPsiCodeFragment(item, context, project);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaCodeFragment createCodeFragment(TextWithImports item, PsiElement context, final Project project) {
|
||||
public JavaCodeFragment createPsiCodeFragmentImpl(TextWithImports item, PsiElement context, final @NotNull Project project) {
|
||||
final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(project);
|
||||
final String text = item.getText();
|
||||
|
||||
|
||||
+2
-2
@@ -60,7 +60,7 @@ public final class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
@Nullable final SourcePosition position,
|
||||
@NotNull Project project) throws EvaluateException {
|
||||
CodeFragmentFactory factory = DebuggerUtilsEx.findAppropriateCodeFragmentFactory(text, contextElement);
|
||||
PsiCodeFragment codeFragment = factory.createCodeFragment(text, contextElement, project);
|
||||
PsiCodeFragment codeFragment = factory.createPsiCodeFragment(text, contextElement, project);
|
||||
if (codeFragment == null) {
|
||||
throw EvaluateExceptionUtil.createEvaluateException(JavaDebuggerBundle.message("evaluation.error.invalid.expression", text.getText()));
|
||||
}
|
||||
@@ -1516,7 +1516,7 @@ public final class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
|
||||
private Evaluator buildFromJavaCode(String code, String imports, @NotNull PsiElement context) {
|
||||
TextWithImportsImpl text = new TextWithImportsImpl(CodeFragmentKind.CODE_BLOCK, code, imports, JavaFileType.INSTANCE);
|
||||
JavaCodeFragment codeFragment = DefaultCodeFragmentFactory.getInstance().createCodeFragment(text, context, context.getProject());
|
||||
JavaCodeFragment codeFragment = DefaultCodeFragmentFactory.getInstance().createPsiCodeFragment(text, context, context.getProject());
|
||||
return accept(codeFragment);
|
||||
}
|
||||
|
||||
|
||||
@@ -555,7 +555,7 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements
|
||||
}
|
||||
|
||||
private static PsiCodeFragment createCodeFragment(Project project, TextWithImports text, PsiElement context) {
|
||||
return DebuggerUtilsEx.findAppropriateCodeFragmentFactory(text, context).createCodeFragment(text, context, project);
|
||||
return DebuggerUtilsEx.findAppropriateCodeFragmentFactory(text, context).createPsiCodeFragment(text, context, project);
|
||||
}
|
||||
|
||||
protected String calculateEventClass(EvaluationContextImpl context, LocatableEvent event) throws EvaluateException {
|
||||
|
||||
@@ -70,7 +70,7 @@ public abstract class CompilingEvaluator implements ExpressionEvaluator {
|
||||
TextWithImports callCode = getCallCode();
|
||||
PsiElement copyContext = myData.getAnchor();
|
||||
CodeFragmentFactory factory = DebuggerUtilsEx.findAppropriateCodeFragmentFactory(callCode, copyContext);
|
||||
return factory.getEvaluatorBuilder().build(factory.createCodeFragment(callCode, copyContext, myProject),
|
||||
return factory.getEvaluatorBuilder().build(factory.createPsiCodeFragment(callCode, copyContext, myProject),
|
||||
// can not use evaluation position here, it does not match classes then
|
||||
SourcePosition.createFromElement(copyContext));
|
||||
}
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ public abstract class EvaluationDescriptor extends ValueDescriptorImpl {
|
||||
|
||||
public PsiCodeFragment createCodeFragment(PsiElement context) {
|
||||
TextWithImports text = getEvaluationText();
|
||||
return DebuggerUtilsEx.findAppropriateCodeFragmentFactory(text, context).createCodeFragment(text, context, myProject);
|
||||
return DebuggerUtilsEx.findAppropriateCodeFragmentFactory(text, context).createPsiCodeFragment(text, context, myProject);
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
|
||||
@@ -54,8 +54,7 @@ public abstract class CachedEvaluator {
|
||||
throw EvaluateExceptionUtil.createEvaluateException(JavaDebuggerBundle.message("evaluation.error.cannot.find.source", className));
|
||||
}
|
||||
CodeFragmentFactory factory = DebuggerUtilsEx.findAppropriateCodeFragmentFactory(myReferenceExpression, context);
|
||||
JavaCodeFragment codeFragment = factory.createCodeFragment(myReferenceExpression, overrideContext(context), project);
|
||||
codeFragment.setThisType(psiClassAndType.second);
|
||||
PsiCodeFragment codeFragment = factory.createPsiCodeFragment(myReferenceExpression, overrideContext(context), project);
|
||||
DebuggerUtils.checkSyntax(codeFragment);
|
||||
cache.myPsiChildrenExpression = codeFragment instanceof PsiExpressionCodeFragment ? ((PsiExpressionCodeFragment)codeFragment).getExpression() : null;
|
||||
|
||||
|
||||
+1
-16
@@ -5,7 +5,6 @@ import com.intellij.debugger.engine.evaluation.CodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsImpl;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
@@ -13,7 +12,6 @@ import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.xdebugger.XExpression;
|
||||
import com.intellij.xdebugger.XSourcePosition;
|
||||
@@ -74,20 +72,7 @@ public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase {
|
||||
TextWithImports text = TextWithImportsImpl.fromXExpression(expression);
|
||||
if (text != null) {
|
||||
CodeFragmentFactory factory = DebuggerUtilsEx.findAppropriateCodeFragmentFactory(text, context);
|
||||
JavaCodeFragment codeFragment = factory.createPresentationCodeFragment(text, context, project);
|
||||
|
||||
if (context != null) {
|
||||
PsiType contextType = context.getUserData(DebuggerUtilsImpl.PSI_TYPE_KEY);
|
||||
if (contextType == null) {
|
||||
PsiClass contextClass = PsiTreeUtil.getNonStrictParentOfType(context, PsiClass.class);
|
||||
if (contextClass != null) {
|
||||
contextType = JavaPsiFacade.getElementFactory(codeFragment.getProject()).createType(contextClass);
|
||||
}
|
||||
}
|
||||
codeFragment.setThisType(contextType);
|
||||
}
|
||||
|
||||
return codeFragment;
|
||||
return factory.createPresentationPsiCodeFragment(text, context, project);
|
||||
}
|
||||
else {
|
||||
return super.createExpressionCodeFragment(project, expression, context, isPhysical);
|
||||
|
||||
+23
-2
@@ -6,6 +6,7 @@ import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.JavaCodeFragment;
|
||||
import com.intellij.psi.PsiCodeFragment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -17,9 +18,29 @@ public abstract class CodeFragmentFactory {
|
||||
public static final ExtensionPointName<CodeFragmentFactory> EXTENSION_POINT_NAME =
|
||||
ExtensionPointName.create("com.intellij.debugger.codeFragmentFactory");
|
||||
|
||||
public abstract JavaCodeFragment createCodeFragment(TextWithImports item, PsiElement context, Project project);
|
||||
/**
|
||||
* @deprecated Use {@link CodeFragmentFactory#createPsiCodeFragment} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public JavaCodeFragment createCodeFragment(TextWithImports item, PsiElement context, Project project) {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
public abstract JavaCodeFragment createPresentationCodeFragment(TextWithImports item, PsiElement context, Project project);
|
||||
/**
|
||||
* @deprecated Use {@link CodeFragmentFactory#createPresentationPsiCodeFragment(TextWithImports, PsiElement, Project)} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public JavaCodeFragment createPresentationCodeFragment(TextWithImports item, PsiElement context, Project project) {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
|
||||
public PsiCodeFragment createPsiCodeFragment(TextWithImports item, PsiElement context, Project project) {
|
||||
return createCodeFragment(item, context, project);
|
||||
}
|
||||
|
||||
public PsiCodeFragment createPresentationPsiCodeFragment(TextWithImports item, PsiElement context, Project project) {
|
||||
return createPresentationCodeFragment(item, context, project);
|
||||
}
|
||||
|
||||
public abstract boolean isContextAccepted(PsiElement contextElement);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user