Evaluate: Use '<name>_field' syntax for field value evaluation (KT-14075)
This commit is contained in:
@@ -1881,7 +1881,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private ClassDescriptor getSuperCallTarget(@NotNull Call call) {
|
public ClassDescriptor getSuperCallTarget(@NotNull Call call) {
|
||||||
KtSuperExpression superExpression = CallResolverUtilKt.getSuperCallExpression(call);
|
KtSuperExpression superExpression = CallResolverUtilKt.getSuperCallExpression(call);
|
||||||
return superExpression == null ? null : getSuperCallLabelTarget(context, superExpression);
|
return superExpression == null ? null : getSuperCallLabelTarget(context, superExpression);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,25 +16,46 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.synthetic
|
package org.jetbrains.kotlin.synthetic
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
|
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.load.java.components.SamConversionResolver
|
import org.jetbrains.kotlin.load.java.components.SamConversionResolver
|
||||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
class JavaSyntheticScopes(
|
class JavaSyntheticScopes(
|
||||||
|
private val project: Project,
|
||||||
|
private val moduleDescriptor: ModuleDescriptor,
|
||||||
storageManager: StorageManager,
|
storageManager: StorageManager,
|
||||||
lookupTracker: LookupTracker,
|
lookupTracker: LookupTracker,
|
||||||
languageVersionSettings: LanguageVersionSettings,
|
languageVersionSettings: LanguageVersionSettings,
|
||||||
samConventionResolver: SamConversionResolver,
|
samConventionResolver: SamConversionResolver,
|
||||||
deprecationResolver: DeprecationResolver
|
deprecationResolver: DeprecationResolver
|
||||||
): SyntheticScopes {
|
): SyntheticScopes {
|
||||||
override val scopes = listOf(
|
override val scopes = run {
|
||||||
JavaSyntheticPropertiesScope(storageManager, lookupTracker),
|
val javaSyntheticPropertiesScope = JavaSyntheticPropertiesScope(storageManager, lookupTracker)
|
||||||
|
|
||||||
|
val scopesFromExtensions = SyntheticScopeProviderExtension
|
||||||
|
.getInstances(project)
|
||||||
|
.flatMap { it.getScopes(moduleDescriptor, javaSyntheticPropertiesScope) }
|
||||||
|
|
||||||
|
listOf(
|
||||||
|
javaSyntheticPropertiesScope,
|
||||||
SamAdapterFunctionsScope(
|
SamAdapterFunctionsScope(
|
||||||
storageManager, languageVersionSettings, samConventionResolver, deprecationResolver,
|
storageManager, languageVersionSettings, samConventionResolver, deprecationResolver,
|
||||||
lookupTracker
|
lookupTracker
|
||||||
)
|
)
|
||||||
)
|
) + scopesFromExtensions
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SyntheticScopeProviderExtension {
|
||||||
|
companion object : ProjectExtensionDescriptor<SyntheticScopeProviderExtension>(
|
||||||
|
"org.jetbrains.kotlin.syntheticScopeProviderExtension", SyntheticScopeProviderExtension::class.java)
|
||||||
|
|
||||||
|
fun getScopes(moduleDescriptor: ModuleDescriptor, javaSyntheticPropertiesScope: JavaSyntheticPropertiesScope): List<SyntheticScope>
|
||||||
|
}
|
||||||
+2
-2
@@ -39,9 +39,9 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class LazyJavaClassDescriptor(
|
class LazyJavaClassDescriptor(
|
||||||
outerContext: LazyJavaResolverContext,
|
val outerContext: LazyJavaResolverContext,
|
||||||
containingDeclaration: DeclarationDescriptor,
|
containingDeclaration: DeclarationDescriptor,
|
||||||
private val jClass: JavaClass,
|
val jClass: JavaClass,
|
||||||
private val additionalSupertypeClassDescriptor: ClassDescriptor? = null
|
private val additionalSupertypeClassDescriptor: ClassDescriptor? = null
|
||||||
) : ClassDescriptorBase(outerContext.storageManager, containingDeclaration, jClass.name,
|
) : ClassDescriptorBase(outerContext.storageManager, containingDeclaration, jClass.name,
|
||||||
outerContext.components.sourceElementFactory.source(jClass),
|
outerContext.components.sourceElementFactory.source(jClass),
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ internal val ClassDescriptor.internalName: String
|
|||||||
return computeInternalName(this, isIrBackend = false)
|
return computeInternalName(this, isIrBackend = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val ClassId.internalName: String
|
val ClassId.internalName: String
|
||||||
get() {
|
get() {
|
||||||
return JvmClassName.byClassId(JavaToKotlinClassMap.mapKotlinToJava(asSingleFqName().toUnsafe()) ?: this).internalName
|
return JvmClassName.byClassId(JavaToKotlinClassMap.mapKotlinToJava(asSingleFqName().toUnsafe()) ?: this).internalName
|
||||||
}
|
}
|
||||||
|
|||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.debugger.evaluate
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.completion.CompletionInformationProvider
|
||||||
|
|
||||||
|
class DebuggerFieldCompletionInformationProvider : CompletionInformationProvider {
|
||||||
|
override fun getContainerAndReceiverInformation(descriptor: DeclarationDescriptor) =
|
||||||
|
(descriptor as? DebuggerFieldPropertyDescriptor)?.description?.let { " $it" }
|
||||||
|
}
|
||||||
+51
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.debugger.evaluate
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
|
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||||
|
import org.jetbrains.kotlin.synthetic.JavaSyntheticPropertiesScope
|
||||||
|
|
||||||
|
class DebuggerFieldExpressionCodegenExtension : ExpressionCodegenExtension {
|
||||||
|
override fun applyProperty(receiver: StackValue, resolvedCall: ResolvedCall<*>, c: ExpressionCodegenExtension.Context): StackValue? {
|
||||||
|
val propertyDescriptor = resolvedCall.resultingDescriptor as? PropertyDescriptor ?: return null
|
||||||
|
|
||||||
|
if (propertyDescriptor is DebuggerFieldPropertyDescriptor) {
|
||||||
|
return StackValue.StackValueWithSimpleReceiver.field(
|
||||||
|
c.typeMapper.mapType(propertyDescriptor.type),
|
||||||
|
propertyDescriptor.ownerType(c.codegen.state),
|
||||||
|
propertyDescriptor.fieldName,
|
||||||
|
false,
|
||||||
|
receiver
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propertyDescriptor is JavaPropertyDescriptor) {
|
||||||
|
val containingClass = propertyDescriptor.containingDeclaration as? JavaClassDescriptor
|
||||||
|
if (containingClass != null) {
|
||||||
|
val correspondingGetter = JavaSyntheticPropertiesScope(LockBasedStorageManager.NO_LOCKS, LookupTracker.DO_NOTHING)
|
||||||
|
.getSyntheticExtensionProperties(listOf(containingClass.defaultType))
|
||||||
|
.firstOrNull { it.name == propertyDescriptor.name }
|
||||||
|
|
||||||
|
if (correspondingGetter != null) {
|
||||||
|
return c.codegen.intermediateValueForProperty(
|
||||||
|
correspondingGetter, false, false,
|
||||||
|
c.codegen.getSuperCallTarget(resolvedCall.call),
|
||||||
|
false, receiver, resolvedCall, false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
+193
@@ -0,0 +1,193 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.debugger.evaluate
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||||
|
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||||
|
import org.jetbrains.kotlin.load.java.components.JavaSourceElementFactoryImpl
|
||||||
|
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.classId
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.internalName
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||||
|
import org.jetbrains.kotlin.synthetic.JavaSyntheticPropertiesScope
|
||||||
|
import org.jetbrains.kotlin.synthetic.SyntheticScopeProviderExtension
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.replaceArgumentsWithStarProjections
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
|
class DebuggerFieldSyntheticScopeProvider : SyntheticScopeProviderExtension {
|
||||||
|
override fun getScopes(
|
||||||
|
moduleDescriptor: ModuleDescriptor,
|
||||||
|
javaSyntheticPropertiesScope: JavaSyntheticPropertiesScope
|
||||||
|
): List<SyntheticScope> {
|
||||||
|
return listOf<SyntheticScope>(DebuggerFieldSyntheticScope(javaSyntheticPropertiesScope))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DebuggerFieldSyntheticScope(val javaSyntheticPropertiesScope: JavaSyntheticPropertiesScope) : SyntheticScope.Default() {
|
||||||
|
private val javaSourceElementFactory = JavaSourceElementFactoryImpl()
|
||||||
|
|
||||||
|
override fun getSyntheticExtensionProperties(
|
||||||
|
receiverTypes: Collection<KotlinType>,
|
||||||
|
name: Name,
|
||||||
|
location: LookupLocation
|
||||||
|
): Collection<PropertyDescriptor> {
|
||||||
|
if (!isInEvaluator(location)) {
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
return getSyntheticExtensionProperties(receiverTypes).filter { it.name == name }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isInEvaluator(location: LookupLocation): Boolean {
|
||||||
|
val element = (location as? KotlinLookupLocation)?.element ?: return false
|
||||||
|
val containingFile = element.containingFile?.takeIf { it.isValid } as? KtFile ?: return false
|
||||||
|
return containingFile.suppressDiagnosticsInDebugMode
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> {
|
||||||
|
val result = mutableListOf<PropertyDescriptor>()
|
||||||
|
for (type in receiverTypes) {
|
||||||
|
val clazz = type.constructor.declarationDescriptor as? ClassDescriptor ?: continue
|
||||||
|
result += getSyntheticPropertiesForClass(clazz)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getSyntheticPropertiesForClass(clazz: ClassDescriptor): Collection<PropertyDescriptor> {
|
||||||
|
val collected = mutableMapOf<Name, PropertyDescriptor>()
|
||||||
|
|
||||||
|
val syntheticPropertyNames = javaSyntheticPropertiesScope
|
||||||
|
.getSyntheticExtensionProperties(listOf(clazz.defaultType))
|
||||||
|
.mapTo(mutableSetOf()) { it.name }
|
||||||
|
|
||||||
|
collectPropertiesWithParent(clazz, syntheticPropertyNames, collected)
|
||||||
|
return collected.values
|
||||||
|
}
|
||||||
|
|
||||||
|
private tailrec fun collectPropertiesWithParent(
|
||||||
|
clazz: ClassDescriptor,
|
||||||
|
syntheticNames: Set<Name>,
|
||||||
|
consumer: MutableMap<Name, PropertyDescriptor>
|
||||||
|
) {
|
||||||
|
when (clazz) {
|
||||||
|
is LazyJavaClassDescriptor -> collectJavaProperties(clazz, syntheticNames, consumer)
|
||||||
|
is JavaClassDescriptor -> error("Unsupported Java class type")
|
||||||
|
else -> collectKotlinProperties(clazz, consumer)
|
||||||
|
}
|
||||||
|
|
||||||
|
val superClass = clazz.getSuperClassNotAny()
|
||||||
|
if (superClass != null) {
|
||||||
|
collectPropertiesWithParent(superClass, syntheticNames, consumer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectKotlinProperties(clazz: ClassDescriptor, consumer: MutableMap<Name, PropertyDescriptor>) {
|
||||||
|
for (descriptor in clazz.unsubstitutedMemberScope.getDescriptorsFiltered(DescriptorKindFilter.VARIABLES)) {
|
||||||
|
val propertyDescriptor = descriptor as? PropertyDescriptor ?: continue
|
||||||
|
val name = propertyDescriptor.name
|
||||||
|
if (propertyDescriptor.backingField == null || name in consumer) continue
|
||||||
|
|
||||||
|
val type = propertyDescriptor.type
|
||||||
|
val sourceElement = propertyDescriptor.source
|
||||||
|
|
||||||
|
consumer[name] = createSyntheticPropertyDescriptor(clazz, type, name.asString(), "Backing field", sourceElement) { state ->
|
||||||
|
state.typeMapper.mapType(clazz.defaultType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectJavaProperties(
|
||||||
|
clazz: LazyJavaClassDescriptor,
|
||||||
|
syntheticNames: Set<Name>,
|
||||||
|
consumer: MutableMap<Name, PropertyDescriptor>
|
||||||
|
) {
|
||||||
|
val javaClass = clazz.jClass
|
||||||
|
|
||||||
|
for (field in javaClass.fields) {
|
||||||
|
val fieldName = field.name
|
||||||
|
if (field.isEnumEntry || field.isStatic || fieldName in consumer || fieldName !in syntheticNames) continue
|
||||||
|
|
||||||
|
val ownerClassName = javaClass.classId?.internalName ?: continue
|
||||||
|
val typeResolver = clazz.outerContext.typeResolver
|
||||||
|
|
||||||
|
val type = typeResolver.transformJavaType(field.type, TypeUsage.COMMON.toAttributes()).replaceArgumentsWithStarProjections()
|
||||||
|
val sourceElement = javaSourceElementFactory.source(field)
|
||||||
|
|
||||||
|
consumer[fieldName] = createSyntheticPropertyDescriptor(clazz, type, fieldName.asString(), "Java field", sourceElement) {
|
||||||
|
Type.getObjectType(ownerClassName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createSyntheticPropertyDescriptor(
|
||||||
|
clazz: ClassDescriptor,
|
||||||
|
type: KotlinType,
|
||||||
|
fieldName: String,
|
||||||
|
description: String,
|
||||||
|
getterSource: SourceElement,
|
||||||
|
ownerType: (GenerationState) -> Type
|
||||||
|
): PropertyDescriptor {
|
||||||
|
val propertyDescriptor = DebuggerFieldPropertyDescriptor(clazz, fieldName, description, ownerType)
|
||||||
|
|
||||||
|
val extensionReceiverParameter = DescriptorFactory.createExtensionReceiverParameterForCallable(
|
||||||
|
propertyDescriptor,
|
||||||
|
clazz.defaultType.replaceArgumentsWithStarProjections(),
|
||||||
|
Annotations.EMPTY
|
||||||
|
)
|
||||||
|
|
||||||
|
propertyDescriptor.setType(type, emptyList(), null, extensionReceiverParameter)
|
||||||
|
|
||||||
|
val getter = PropertyGetterDescriptorImpl(
|
||||||
|
propertyDescriptor, Annotations.EMPTY, Modality.FINAL,
|
||||||
|
Visibilities.PUBLIC, false, false, false,
|
||||||
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
|
null, getterSource
|
||||||
|
)
|
||||||
|
|
||||||
|
propertyDescriptor.initialize(getter, null)
|
||||||
|
|
||||||
|
return propertyDescriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class DebuggerFieldPropertyDescriptor(
|
||||||
|
containingDeclaration: DeclarationDescriptor,
|
||||||
|
val fieldName: String,
|
||||||
|
val description: String,
|
||||||
|
val ownerType: (GenerationState) -> Type
|
||||||
|
) : PropertyDescriptorImpl(
|
||||||
|
containingDeclaration,
|
||||||
|
null,
|
||||||
|
Annotations.EMPTY,
|
||||||
|
Modality.FINAL,
|
||||||
|
Visibilities.PUBLIC,
|
||||||
|
/*isVar = */true,
|
||||||
|
Name.identifier(fieldName + "_field"),
|
||||||
|
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||||
|
SourceElement.NO_SOURCE,
|
||||||
|
/*lateInit = */false,
|
||||||
|
/*isConst = */false,
|
||||||
|
/*isExpect = */false,
|
||||||
|
/*isActual = */false,
|
||||||
|
/*isExternal = */false,
|
||||||
|
/*isDelegated = */false
|
||||||
|
)
|
||||||
@@ -50,6 +50,10 @@
|
|||||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptDefinitionsProvider"
|
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptDefinitionsProvider"
|
||||||
interface="kotlin.script.experimental.intellij.ScriptDefinitionsProvider"
|
interface="kotlin.script.experimental.intellij.ScriptDefinitionsProvider"
|
||||||
area="IDEA_PROJECT"/>
|
area="IDEA_PROJECT"/>
|
||||||
|
|
||||||
|
<extensionPoint qualifiedName="org.jetbrains.kotlin.syntheticScopeProviderExtension"
|
||||||
|
interface="org.jetbrains.kotlin.synthetic.SyntheticScopeProviderExtension"
|
||||||
|
area="IDEA_PROJECT"/>
|
||||||
</extensionPoints>
|
</extensionPoints>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||||
|
|||||||
@@ -42,6 +42,10 @@
|
|||||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptDefinitionsProvider"
|
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptDefinitionsProvider"
|
||||||
interface="kotlin.script.experimental.intellij.ScriptDefinitionsProvider"
|
interface="kotlin.script.experimental.intellij.ScriptDefinitionsProvider"
|
||||||
area="IDEA_PROJECT"/>
|
area="IDEA_PROJECT"/>
|
||||||
|
|
||||||
|
<extensionPoint qualifiedName="org.jetbrains.kotlin.syntheticScopeProviderExtension"
|
||||||
|
interface="org.jetbrains.kotlin.synthetic.SyntheticScopeProviderExtension"
|
||||||
|
area="IDEA_PROJECT"/>
|
||||||
</extensionPoints>
|
</extensionPoints>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||||
|
|||||||
@@ -42,6 +42,10 @@
|
|||||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptDefinitionsProvider"
|
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptDefinitionsProvider"
|
||||||
interface="kotlin.script.experimental.intellij.ScriptDefinitionsProvider"
|
interface="kotlin.script.experimental.intellij.ScriptDefinitionsProvider"
|
||||||
area="IDEA_PROJECT"/>
|
area="IDEA_PROJECT"/>
|
||||||
|
|
||||||
|
<extensionPoint qualifiedName="org.jetbrains.kotlin.syntheticScopeProviderExtension"
|
||||||
|
interface="org.jetbrains.kotlin.synthetic.SyntheticScopeProviderExtension"
|
||||||
|
area="IDEA_PROJECT"/>
|
||||||
</extensionPoints>
|
</extensionPoints>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||||
|
|||||||
@@ -179,5 +179,9 @@
|
|||||||
|
|
||||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JvmIdePlatformKindTooling"/>
|
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JvmIdePlatformKindTooling"/>
|
||||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JsIdePlatformKindTooling"/>
|
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JsIdePlatformKindTooling"/>
|
||||||
|
|
||||||
|
<syntheticScopeProviderExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldSyntheticScopeProvider"/>
|
||||||
|
<expressionCodegenExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldExpressionCodegenExtension"/>
|
||||||
|
<completionInformationProvider implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldCompletionInformationProvider" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
|||||||
@@ -167,5 +167,9 @@
|
|||||||
|
|
||||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JvmIdePlatformKindTooling"/>
|
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JvmIdePlatformKindTooling"/>
|
||||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JsIdePlatformKindTooling"/>
|
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JsIdePlatformKindTooling"/>
|
||||||
|
|
||||||
|
<syntheticScopeProviderExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldSyntheticScopeProvider"/>
|
||||||
|
<expressionCodegenExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldExpressionCodegenExtension"/>
|
||||||
|
<completionInformationProvider implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldCompletionInformationProvider" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
||||||
|
|||||||
+105
@@ -0,0 +1,105 @@
|
|||||||
|
package fieldGetters
|
||||||
|
|
||||||
|
import forTests.FieldsGetters
|
||||||
|
import forTests.FieldsGetters.*
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
//Breakpoint!
|
||||||
|
val a = 5
|
||||||
|
}
|
||||||
|
|
||||||
|
class K1 {
|
||||||
|
val a: Int = 0
|
||||||
|
get() = field + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
class K2 {
|
||||||
|
@JvmField
|
||||||
|
val a: Int = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXPRESSION: K1().a
|
||||||
|
// RESULT: 1: I
|
||||||
|
|
||||||
|
// EXPRESSION: K1().a_field
|
||||||
|
// RESULT: 0: I
|
||||||
|
|
||||||
|
// EXPRESSION: K2().a
|
||||||
|
// RESULT: 0: I
|
||||||
|
|
||||||
|
// EXPRESSION: K2().a_field
|
||||||
|
// RESULT: 0: I
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// EXPRESSION: PublicField().foo
|
||||||
|
// RESULT: "a": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PublicField().foo_field
|
||||||
|
// RESULT: Unresolved reference: foo_field
|
||||||
|
|
||||||
|
// EXPRESSION: PackagePrivateField().foo
|
||||||
|
// RESULT: "b": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PackagePrivateField().foo_field
|
||||||
|
// RESULT: Unresolved reference: foo_field
|
||||||
|
|
||||||
|
// EXPRESSION: ProtectedField().foo
|
||||||
|
// RESULT: "c": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: ProtectedField().foo_field
|
||||||
|
// RESULT: Unresolved reference: foo_field
|
||||||
|
|
||||||
|
// EXPRESSION: PrivateField().foo
|
||||||
|
// RESULT: "d": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PrivateField().foo_field
|
||||||
|
// RESULT: Unresolved reference: foo_field
|
||||||
|
|
||||||
|
// EXPRESSION: PublicFieldGetter().foo
|
||||||
|
// RESULT: "b": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PublicFieldGetter().foo_field
|
||||||
|
// RESULT: "a": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PrivateFieldPublicGetter().foo
|
||||||
|
// RESULT: "d": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PrivateFieldPublicGetter().foo_field
|
||||||
|
// RESULT: "c": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PrivateFieldPrivateGetter().foo
|
||||||
|
// RESULT: "f": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PrivateFieldPrivateGetter().foo_field
|
||||||
|
// RESULT: "e": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PublicGetter1().foo
|
||||||
|
// RESULT: "g": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PublicGetter1().foo_field
|
||||||
|
// RESULT: "a": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PublicGetter2().foo
|
||||||
|
// RESULT: "h": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PublicGetter2().foo_field
|
||||||
|
// RESULT: "b": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PrivateGetter1().foo
|
||||||
|
// RESULT: "d": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PrivateGetter1().foo_field
|
||||||
|
// RESULT: Unresolved reference: foo_field
|
||||||
|
|
||||||
|
// EXPRESSION: PublicGetterOnly().foo
|
||||||
|
// RESULT: "a": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PublicGetterOnly().foo_field
|
||||||
|
// RESULT: Unresolved reference: foo_field
|
||||||
|
|
||||||
|
// EXPRESSION: PublicFieldAndGetterInParent().foo
|
||||||
|
// RESULT: "a": Ljava/lang/String;
|
||||||
|
|
||||||
|
// EXPRESSION: PublicFieldAndGetterInParent().foo_field
|
||||||
|
// RESULT: "b": Ljava/lang/String;
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
LineBreakpoint created at fieldGetters.kt:8
|
||||||
|
Run Java
|
||||||
|
Connected to the target VM
|
||||||
|
fieldGetters.kt:8
|
||||||
|
Compile bytecode for K1().a
|
||||||
|
Compile bytecode for K1().a_field
|
||||||
|
Compile bytecode for K2().a
|
||||||
|
Compile bytecode for K2().a_field
|
||||||
|
Compile bytecode for PublicField().foo
|
||||||
|
Compile bytecode for PackagePrivateField().foo
|
||||||
|
Compile bytecode for ProtectedField().foo
|
||||||
|
Compile bytecode for PrivateField().foo
|
||||||
|
Compile bytecode for PublicFieldGetter().foo
|
||||||
|
Compile bytecode for PublicFieldGetter().foo_field
|
||||||
|
Compile bytecode for PrivateFieldPublicGetter().foo
|
||||||
|
Compile bytecode for PrivateFieldPublicGetter().foo_field
|
||||||
|
Compile bytecode for PrivateFieldPrivateGetter().foo
|
||||||
|
Compile bytecode for PrivateFieldPrivateGetter().foo_field
|
||||||
|
Compile bytecode for PublicGetter1().foo
|
||||||
|
Compile bytecode for PublicGetter1().foo_field
|
||||||
|
Compile bytecode for PublicGetter2().foo
|
||||||
|
Compile bytecode for PublicGetter2().foo_field
|
||||||
|
Compile bytecode for PrivateGetter1().foo
|
||||||
|
Compile bytecode for PublicGetterOnly().foo
|
||||||
|
Compile bytecode for PublicFieldAndGetterInParent().foo
|
||||||
|
Compile bytecode for PublicFieldAndGetterInParent().foo_field
|
||||||
|
Disconnected from the target VM
|
||||||
|
|
||||||
|
Process finished with exit code 0
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package forTests;
|
||||||
|
|
||||||
|
public class FieldsGetters {
|
||||||
|
public static class PublicField {
|
||||||
|
public String foo = "a";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PackagePrivateField {
|
||||||
|
String foo = "b";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ProtectedField {
|
||||||
|
protected String foo = "c";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PrivateField {
|
||||||
|
private String foo = "d";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PublicFieldGetter {
|
||||||
|
public final String foo = "a";
|
||||||
|
|
||||||
|
public String getFoo() {
|
||||||
|
return "b";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PrivateFieldPublicGetter {
|
||||||
|
private final String foo = "c";
|
||||||
|
|
||||||
|
public String getFoo() {
|
||||||
|
return "d";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PrivateFieldPrivateGetter {
|
||||||
|
private final String foo = "e";
|
||||||
|
|
||||||
|
public String getFoo() {
|
||||||
|
return "f";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PublicGetter1 extends PublicField {
|
||||||
|
public String getFoo() {
|
||||||
|
return "g";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PublicGetter2 extends PackagePrivateField {
|
||||||
|
public String getFoo() {
|
||||||
|
return "h";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PrivateGetter1 extends PrivateField {
|
||||||
|
private String getFoo() {
|
||||||
|
return "g";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PublicGetterOnly {
|
||||||
|
public String getFoo() {
|
||||||
|
return "a";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PublicFieldAndGetterInParent extends PublicGetterOnly {
|
||||||
|
public String foo = "b";
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class AbstractGetter {
|
||||||
|
public String foo = "c";
|
||||||
|
public abstract String getFoo();
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+5
@@ -136,6 +136,11 @@ public class KotlinEvaluateExpressionTestGenerated extends AbstractKotlinEvaluat
|
|||||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/extractVariablesFromCall.kt");
|
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/extractVariablesFromCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("fieldGetters.kt")
|
||||||
|
public void testFieldGetters() throws Exception {
|
||||||
|
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/fieldGetters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("fileWithError.kt")
|
@TestMetadata("fileWithError.kt")
|
||||||
public void testFileWithError() throws Exception {
|
public void testFileWithError() throws Exception {
|
||||||
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/fileWithError.kt");
|
runTest("idea/testData/debugger/tinyApp/src/evaluate/singleBreakpoint/fileWithError.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user