Minor: KotlinCodeFragmentFactory.kt cleanup
This commit is contained in:
+30
-31
@@ -59,9 +59,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
import java.util.concurrent.atomic.AtomicReference
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
class KotlinCodeFragmentFactory : CodeFragmentFactory() {
|
||||||
private val LOG = Logger.getInstance(this::class.java)
|
|
||||||
|
|
||||||
override fun createCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment {
|
override fun createCodeFragment(item: TextWithImports, context: PsiElement?, project: Project): JavaCodeFragment {
|
||||||
val contextElement = getWrappedContextElement(project, context)
|
val contextElement = getWrappedContextElement(project, context)
|
||||||
if (contextElement == null) {
|
if (contextElement == null) {
|
||||||
@@ -75,8 +73,7 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
initImports(item.imports),
|
initImports(item.imports),
|
||||||
contextElement
|
contextElement
|
||||||
)
|
)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
KtBlockCodeFragment(
|
KtBlockCodeFragment(
|
||||||
project,
|
project,
|
||||||
"fragment.kt",
|
"fragment.kt",
|
||||||
@@ -86,19 +83,18 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
codeFragment.putCopyableUserData(KtCodeFragment.RUNTIME_TYPE_EVALUATOR, {
|
codeFragment.putCopyableUserData(KtCodeFragment.RUNTIME_TYPE_EVALUATOR, { expression: KtExpression ->
|
||||||
expression: KtExpression ->
|
|
||||||
|
|
||||||
val debuggerContext = DebuggerManagerEx.getInstanceEx(project).context
|
val debuggerContext = DebuggerManagerEx.getInstanceEx(project).context
|
||||||
val debuggerSession = debuggerContext.debuggerSession
|
val debuggerSession = debuggerContext.debuggerSession
|
||||||
if (debuggerSession == null || debuggerContext.suspendContext == null) {
|
if (debuggerSession == null || debuggerContext.suspendContext == null) {
|
||||||
null
|
null
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val semaphore = Semaphore()
|
val semaphore = Semaphore()
|
||||||
semaphore.down()
|
semaphore.down()
|
||||||
val nameRef = AtomicReference<KotlinType>()
|
val nameRef = AtomicReference<KotlinType>()
|
||||||
val worker = object : KotlinRuntimeTypeEvaluator(null, expression, debuggerContext, ProgressManager.getInstance().progressIndicator) {
|
val worker = object : KotlinRuntimeTypeEvaluator(
|
||||||
|
null, expression, debuggerContext, ProgressManager.getInstance().progressIndicator
|
||||||
|
) {
|
||||||
override fun typeCalculationFinished(type: KotlinType?) {
|
override fun typeCalculationFinished(type: KotlinType?) {
|
||||||
nameRef.set(type)
|
nameRef.set(type)
|
||||||
semaphore.up()
|
semaphore.up()
|
||||||
@@ -133,10 +129,12 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
return@putCopyableUserData emptyFile
|
return@putCopyableUserData emptyFile
|
||||||
}
|
}
|
||||||
|
|
||||||
val receiverTypeReference = frameDescriptor.thisObject?.let { createKotlinProperty(project, "this_0", it.type().name(), it) }?.typeReference
|
val receiverTypeReference =
|
||||||
|
frameDescriptor.thisObject?.let { createKotlinProperty(project, "this_0", it.type().name(), it) }?.typeReference
|
||||||
val receiverTypeText = receiverTypeReference?.let { "${it.text}." } ?: ""
|
val receiverTypeText = receiverTypeReference?.let { "${it.text}." } ?: ""
|
||||||
|
|
||||||
val kotlinVariablesText = frameDescriptor.visibleVariables.entries.associate { it.key.name() to it.value }.kotlinVariablesAsText(project)
|
val kotlinVariablesText =
|
||||||
|
frameDescriptor.visibleVariables.entries.associate { it.key.name() to it.value }.kotlinVariablesAsText(project)
|
||||||
|
|
||||||
val fakeFunctionText = "fun ${receiverTypeText}_java_locals_debug_fun_() {\n$kotlinVariablesText\n}"
|
val fakeFunctionText = "fun ${receiverTypeText}_java_locals_debug_fun_() {\n$kotlinVariablesText\n}"
|
||||||
|
|
||||||
@@ -145,7 +143,6 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
val fakeContext = (fakeFunction?.bodyExpression as? KtBlockExpression)?.statements?.lastOrNull()
|
val fakeContext = (fakeFunction?.bodyExpression as? KtBlockExpression)?.statements?.lastOrNull()
|
||||||
|
|
||||||
return@putCopyableUserData wrapContextIfNeeded(project, contextElement, fakeContext) ?: emptyFile
|
return@putCopyableUserData wrapContextIfNeeded(project, contextElement, fakeContext) ?: emptyFile
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,11 +169,9 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
} ?: emptyMap()
|
} ?: emptyMap()
|
||||||
|
|
||||||
frameInfo = FrameInfo(frame?.thisObject(), visibleVariables)
|
frameInfo = FrameInfo(frame?.thisObject(), visibleVariables)
|
||||||
}
|
} catch (ignored: AbsentInformationException) {
|
||||||
catch(ignored: AbsentInformationException) {
|
|
||||||
// Debug info unavailable
|
// Debug info unavailable
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
semaphore.up()
|
semaphore.up()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,8 +221,7 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
if (PsiTreeUtil.hasErrorElements(kotlinCodeFragment) && kotlinCodeFragment is KtExpressionCodeFragment) {
|
if (PsiTreeUtil.hasErrorElements(kotlinCodeFragment) && kotlinCodeFragment is KtExpressionCodeFragment) {
|
||||||
val javaExpression = try {
|
val javaExpression = try {
|
||||||
PsiElementFactory.SERVICE.getInstance(project).createExpressionFromText(item.text, context)
|
PsiElementFactory.SERVICE.getInstance(project).createExpressionFromText(item.text, context)
|
||||||
}
|
} catch (e: IncorrectOperationException) {
|
||||||
catch(e: IncorrectOperationException) {
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,8 +231,7 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
"dummy.java", JavaFileType.INSTANCE, it.text
|
"dummy.java", JavaFileType.INSTANCE, it.text
|
||||||
) as? PsiJavaFile)?.importList
|
) as? PsiJavaFile)?.importList
|
||||||
}
|
}
|
||||||
}
|
} catch (e: IncorrectOperationException) {
|
||||||
catch(e: IncorrectOperationException) {
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,8 +252,7 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
|
|
||||||
AfterConversionPass(project, J2kPostProcessor(formatCode = false)).run(convertedFragment!!, range = null)
|
AfterConversionPass(project, J2kPostProcessor(formatCode = false)).run(convertedFragment!!, range = null)
|
||||||
}
|
}
|
||||||
}
|
} catch (e: Throwable) {
|
||||||
catch (e: Throwable) {
|
|
||||||
// ignored because text can be invalid
|
// ignored because text can be invalid
|
||||||
LOG.error("Couldn't convert expression:\n`${javaExpression.text}`", e)
|
LOG.error("Couldn't convert expression:\n`${javaExpression.text}`", e)
|
||||||
}
|
}
|
||||||
@@ -284,14 +276,19 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFileType() = KotlinFileType.INSTANCE
|
override fun getFileType(): KotlinFileType = KotlinFileType.INSTANCE
|
||||||
|
|
||||||
override fun getEvaluatorBuilder() = KotlinEvaluationBuilder
|
override fun getEvaluatorBuilder() = KotlinEvaluationBuilder
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private val LOG = Logger.getInstance(this::class.java)
|
||||||
|
|
||||||
val LABEL_VARIABLE_VALUE_KEY: Key<Value> = Key.create<Value>("_label_variable_value_key_")
|
val LABEL_VARIABLE_VALUE_KEY: Key<Value> = Key.create<Value>("_label_variable_value_key_")
|
||||||
val DEBUG_LABEL_SUFFIX: String = "_DebugLabel"
|
|
||||||
@TestOnly val DEBUG_CONTEXT_FOR_TESTS: Key<DebuggerContextImpl> = Key.create("DEBUG_CONTEXT_FOR_TESTS")
|
private const val DEBUG_LABEL_SUFFIX: String = "_DebugLabel"
|
||||||
|
|
||||||
|
@TestOnly
|
||||||
|
val DEBUG_CONTEXT_FOR_TESTS: Key<DebuggerContextImpl> = Key.create("DEBUG_CONTEXT_FOR_TESTS")
|
||||||
|
|
||||||
fun getContextElement(elementAt: PsiElement?): PsiElement? {
|
fun getContextElement(elementAt: PsiElement?): PsiElement? {
|
||||||
if (elementAt == null) return null
|
if (elementAt == null) return null
|
||||||
@@ -310,7 +307,8 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
|
|
||||||
// elementAt can be PsiWhiteSpace when codeFragment is created from line start offset (in case of first opening EE window)
|
// elementAt can be PsiWhiteSpace when codeFragment is created from line start offset (in case of first opening EE window)
|
||||||
val lineStartOffset = if (elementAt is PsiWhiteSpace || elementAt is PsiComment) {
|
val lineStartOffset = if (elementAt is PsiWhiteSpace || elementAt is PsiComment) {
|
||||||
PsiTreeUtil.skipSiblingsForward(elementAt, PsiWhiteSpace::class.java, PsiComment::class.java)?.textOffset ?: elementAt.textOffset
|
PsiTreeUtil.skipSiblingsForward(elementAt, PsiWhiteSpace::class.java, PsiComment::class.java)?.textOffset
|
||||||
|
?: elementAt.textOffset
|
||||||
} else {
|
} else {
|
||||||
elementAt.textOffset
|
elementAt.textOffset
|
||||||
}
|
}
|
||||||
@@ -374,7 +372,8 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
else
|
else
|
||||||
className).addArraySuffix()
|
className).addArraySuffix()
|
||||||
|
|
||||||
val field = PsiElementFactory.SERVICE.getInstance(project).createField(variableName, PsiType.getTypeByName(type, project, GlobalSearchScope.allScope(project)))
|
val field = PsiElementFactory.SERVICE.getInstance(project)
|
||||||
|
.createField(variableName, PsiType.getTypeByName(type, project, GlobalSearchScope.allScope(project)))
|
||||||
val ktField = field.j2k() as? KtProperty
|
val ktField = field.j2k() as? KtProperty
|
||||||
ktField?.modifierList?.delete()
|
ktField?.modifierList?.delete()
|
||||||
return ktField
|
return ktField
|
||||||
@@ -413,7 +412,7 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// internal for test
|
// internal for test
|
||||||
fun createWrappingContext(
|
private fun createWrappingContext(
|
||||||
newFragmentText: String,
|
newFragmentText: String,
|
||||||
labels: Map<String, Value>,
|
labels: Map<String, Value>,
|
||||||
originalContext: KtElement?,
|
originalContext: KtElement?,
|
||||||
@@ -423,7 +422,7 @@ class KotlinCodeFragmentFactory: CodeFragmentFactory() {
|
|||||||
|
|
||||||
codeFragment.accept(object : KtTreeVisitorVoid() {
|
codeFragment.accept(object : KtTreeVisitorVoid() {
|
||||||
override fun visitProperty(property: KtProperty) {
|
override fun visitProperty(property: KtProperty) {
|
||||||
val reference = labels.get(property.name)
|
val reference = labels[property.name]
|
||||||
if (reference != null) {
|
if (reference != null) {
|
||||||
property.putUserData(LABEL_VARIABLE_VALUE_KEY, reference)
|
property.putUserData(LABEL_VARIABLE_VALUE_KEY, reference)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user