Debugger: change usage of getSourcePosition method to SourcePositionManager
(cherry picked from commit f1c4e36)
This commit is contained in:
committed by
Zalim Bashorov
parent
c6777db64f
commit
c6d134d63c
@@ -372,7 +372,7 @@
|
|||||||
<debuggerEditorTextProvider language="jet" implementationClass="org.jetbrains.jet.plugin.debugger.KotlinEditorTextProvider"/>
|
<debuggerEditorTextProvider language="jet" implementationClass="org.jetbrains.jet.plugin.debugger.KotlinEditorTextProvider"/>
|
||||||
<debuggerClassFilterProvider implementation="org.jetbrains.jet.plugin.debugger.filter.KotlinDebuggerInternalClassesFilterProvider"/>
|
<debuggerClassFilterProvider implementation="org.jetbrains.jet.plugin.debugger.filter.KotlinDebuggerInternalClassesFilterProvider"/>
|
||||||
<debugger.nodeRenderer implementation="org.jetbrains.jet.plugin.debugger.render.KotlinClassWithDelegatedPropertyRenderer"/>
|
<debugger.nodeRenderer implementation="org.jetbrains.jet.plugin.debugger.render.KotlinClassWithDelegatedPropertyRenderer"/>
|
||||||
<debugger.nodeRenderer implementation="org.jetbrains.jet.plugin.debugger.render.KotlinObjectRenderer"/>
|
<debugger.sourcePositionProvider implementation="org.jetbrains.jet.plugin.debugger.KotlinSourcePositionProvider"/>
|
||||||
<xdebugger.settings implementation="org.jetbrains.jet.plugin.debugger.KotlinDebuggerSettings"/>
|
<xdebugger.settings implementation="org.jetbrains.jet.plugin.debugger.KotlinDebuggerSettings"/>
|
||||||
|
|
||||||
<codeInsight.implementMethod language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.ImplementMethodsHandler"/>
|
<codeInsight.implementMethod language="jet" implementationClass="org.jetbrains.jet.plugin.codeInsight.ImplementMethodsHandler"/>
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 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.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.plugin.debugger
|
||||||
|
|
||||||
|
import com.intellij.debugger.engine.SourcePositionProvider
|
||||||
|
import com.intellij.debugger.ui.tree.NodeDescriptor
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.debugger.impl.DebuggerContextImpl
|
||||||
|
import com.intellij.debugger.SourcePosition
|
||||||
|
import org.jetbrains.jet.codegen.AsmUtil
|
||||||
|
import org.jetbrains.jet.lang.psi.JetClassOrObject
|
||||||
|
import com.intellij.debugger.impl.DebuggerContextUtil
|
||||||
|
import com.sun.jdi.ReferenceType
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmClassName
|
||||||
|
import com.intellij.psi.JavaPsiFacade
|
||||||
|
import org.jetbrains.jet.lang.psi.psiUtil.getStrictParentOfType
|
||||||
|
import com.sun.jdi.AbsentInformationException
|
||||||
|
import com.sun.jdi.ClassNotPreparedException
|
||||||
|
import com.intellij.debugger.ui.tree.FieldDescriptor
|
||||||
|
|
||||||
|
public class KotlinSourcePositionProvider: SourcePositionProvider() {
|
||||||
|
override fun computeSourcePosition(descriptor: NodeDescriptor, project: Project, context: DebuggerContextImpl, nearest: Boolean): SourcePosition? {
|
||||||
|
if (context.getFrameProxy() == null) return null
|
||||||
|
|
||||||
|
if (descriptor is FieldDescriptor) {
|
||||||
|
return computeSourcePosition(descriptor, project, context, nearest)
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun computeSourcePosition(descriptor: FieldDescriptor, project: Project, context: DebuggerContextImpl, nearest: Boolean): SourcePosition? {
|
||||||
|
val fieldName = descriptor.getField().name()
|
||||||
|
if (fieldName == AsmUtil.CAPTURED_THIS_FIELD || fieldName == AsmUtil.CAPTURED_RECEIVER_FIELD) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val type = descriptor.getField().declaringType()
|
||||||
|
val myClass = findClassByType(project, type, context)?.getNavigationElement()
|
||||||
|
if (myClass !is JetClassOrObject) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val field = myClass.getDeclarations().firstOrNull { fieldName == it.getName() }
|
||||||
|
if (field == null) return null
|
||||||
|
|
||||||
|
if (nearest) {
|
||||||
|
return DebuggerContextUtil.findNearest(context, field, myClass.getContainingFile())
|
||||||
|
}
|
||||||
|
return SourcePosition.createFromOffset(field.getContainingFile(), field.getTextOffset())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findClassByType(project: Project, type: ReferenceType, context: DebuggerContextImpl): PsiElement? {
|
||||||
|
val session = context.getDebuggerSession()
|
||||||
|
val scope = if (session != null) session.getSearchScope() else GlobalSearchScope.allScope(project)
|
||||||
|
val className = JvmClassName.byInternalName(type.name()).getFqNameForClassNameWithoutDollars().asString()
|
||||||
|
|
||||||
|
val myClass = JavaPsiFacade.getInstance(project).findClass(className, scope)
|
||||||
|
if (myClass != null) return myClass
|
||||||
|
|
||||||
|
val position = getLastSourcePosition(type, context)
|
||||||
|
if (position != null) {
|
||||||
|
val element = position.getElementAt()
|
||||||
|
if (element != null) {
|
||||||
|
return element.getStrictParentOfType<JetClassOrObject>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getLastSourcePosition(type: ReferenceType, context: DebuggerContextImpl): SourcePosition? {
|
||||||
|
val debugProcess = context.getDebugProcess()
|
||||||
|
if (debugProcess != null) {
|
||||||
|
try {
|
||||||
|
val locations = type.allLineLocations()
|
||||||
|
if (!locations.isEmpty()) {
|
||||||
|
val lastLocation = locations.get(locations.size() - 1)
|
||||||
|
return debugProcess.getPositionManager().getSourcePosition(lastLocation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ignored: AbsentInformationException) {
|
||||||
|
}
|
||||||
|
catch (ignored: ClassNotPreparedException) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-3
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.plugin.debugger.render
|
package org.jetbrains.jet.plugin.debugger.render
|
||||||
|
|
||||||
|
import com.intellij.debugger.ui.tree.render.ClassRenderer
|
||||||
import com.sun.jdi.Type as JdiType
|
import com.sun.jdi.Type as JdiType
|
||||||
import com.sun.jdi.Value
|
import com.sun.jdi.Value
|
||||||
import com.intellij.debugger.ui.tree.render.ChildrenBuilder
|
import com.intellij.debugger.ui.tree.render.ChildrenBuilder
|
||||||
@@ -36,9 +37,8 @@ import com.sun.jdi.InvocationException
|
|||||||
import com.sun.jdi.Method
|
import com.sun.jdi.Method
|
||||||
import org.jetbrains.jet.codegen.PropertyCodegen
|
import org.jetbrains.jet.codegen.PropertyCodegen
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name
|
import org.jetbrains.jet.lang.resolve.name.Name
|
||||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl
|
|
||||||
|
|
||||||
public class KotlinClassWithDelegatedPropertyRenderer : KotlinObjectRenderer() {
|
public class KotlinClassWithDelegatedPropertyRenderer : ClassRenderer() {
|
||||||
|
|
||||||
override fun isApplicable(jdiType: Type?): Boolean {
|
override fun isApplicable(jdiType: Type?): Boolean {
|
||||||
if (!super.isApplicable(jdiType)) return false
|
if (!super.isApplicable(jdiType)) return false
|
||||||
@@ -68,7 +68,7 @@ public class KotlinClassWithDelegatedPropertyRenderer : KotlinObjectRenderer() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val fieldDescriptor = createFieldDescriptor(builder.getParentDescriptor() as ValueDescriptorImpl, nodeDescriptorFactory, value, field, context)
|
val fieldDescriptor = nodeDescriptorFactory.getFieldDescriptor(builder.getParentDescriptor(), value, field)
|
||||||
children.add(nodeManager.createNode(fieldDescriptor, context))
|
children.add(nodeManager.createNode(fieldDescriptor, context))
|
||||||
|
|
||||||
if (field.name().endsWith(JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX)) {
|
if (field.name().endsWith(JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX)) {
|
||||||
|
|||||||
@@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2014 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.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.jet.plugin.debugger.render
|
|
||||||
|
|
||||||
import com.intellij.debugger.ui.tree.render.ClassRenderer
|
|
||||||
import com.sun.jdi.Type
|
|
||||||
import com.intellij.debugger.engine.evaluation.EvaluationContext
|
|
||||||
import com.sun.jdi.ObjectReference
|
|
||||||
import com.sun.jdi.Field
|
|
||||||
import com.sun.jdi.ClassType
|
|
||||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl
|
|
||||||
import com.intellij.debugger.ui.tree.NodeDescriptorFactory
|
|
||||||
import com.intellij.debugger.ui.tree.FieldDescriptor
|
|
||||||
import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.debugger.impl.DebuggerContextImpl
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmAbi
|
|
||||||
import com.intellij.debugger.ui.tree.ValueDescriptor
|
|
||||||
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener
|
|
||||||
import com.intellij.debugger.settings.NodeRendererSettings
|
|
||||||
import com.intellij.psi.PsiClass
|
|
||||||
import com.intellij.psi.JavaPsiFacade
|
|
||||||
import com.intellij.debugger.SourcePosition
|
|
||||||
import com.intellij.debugger.impl.DebuggerContextUtil
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
|
||||||
import com.sun.jdi.AbsentInformationException
|
|
||||||
import com.sun.jdi.ClassNotPreparedException
|
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import org.jetbrains.jet.lang.psi.JetClass
|
|
||||||
import org.jetbrains.jet.lang.resolve.java.JvmClassName
|
|
||||||
import com.sun.jdi.ReferenceType
|
|
||||||
import org.jetbrains.jet.codegen.AsmUtil
|
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject
|
|
||||||
import org.jetbrains.jet.lang.psi.psiUtil.getStrictParentOfType
|
|
||||||
|
|
||||||
public open class KotlinObjectRenderer : ClassRenderer() {
|
|
||||||
|
|
||||||
override fun isApplicable(jdiType: Type?): Boolean {
|
|
||||||
if (!super.isApplicable(jdiType)) return false
|
|
||||||
|
|
||||||
var isCustomRendererApplicable = false
|
|
||||||
NodeRendererSettings.getInstance().getCustomRenderers().iterateRenderers {
|
|
||||||
isCustomRendererApplicable = it.isApplicable(jdiType)
|
|
||||||
!isCustomRendererApplicable
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isCustomRendererApplicable) return false
|
|
||||||
|
|
||||||
return jdiType.isKotlinClass()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun createFieldDescriptor(
|
|
||||||
parentDescriptor: ValueDescriptorImpl?,
|
|
||||||
nodeDescriptorFactory: NodeDescriptorFactory?,
|
|
||||||
objRef: ObjectReference?,
|
|
||||||
field: Field?,
|
|
||||||
evaluationContext: EvaluationContext?
|
|
||||||
): FieldDescriptor {
|
|
||||||
if (field?.declaringType().isKotlinClass()) {
|
|
||||||
return KotlinObjectFieldDescriptor(evaluationContext?.getProject(), objRef, field)
|
|
||||||
}
|
|
||||||
return super.createFieldDescriptor(parentDescriptor, nodeDescriptorFactory, objRef, field, evaluationContext)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun calcLabel(
|
|
||||||
descriptor: ValueDescriptor?,
|
|
||||||
evaluationContext: EvaluationContext?,
|
|
||||||
labelListener: DescriptorLabelListener?
|
|
||||||
): String? {
|
|
||||||
val toStringRenderer = NodeRendererSettings.getInstance().getToStringRenderer()
|
|
||||||
if (toStringRenderer.isApplicable(descriptor?.getValue()?.type())) {
|
|
||||||
return toStringRenderer.calcLabel(descriptor, evaluationContext, labelListener)
|
|
||||||
}
|
|
||||||
return super.calcLabel(descriptor, evaluationContext, labelListener)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class KotlinObjectFieldDescriptor(
|
|
||||||
project: Project?,
|
|
||||||
objRef: ObjectReference?,
|
|
||||||
field: Field?
|
|
||||||
) : FieldDescriptorImpl(project, objRef, field) {
|
|
||||||
override fun getSourcePosition(project: Project?, context: DebuggerContextImpl?, nearest: Boolean): SourcePosition? {
|
|
||||||
if (context == null || context.getFrameProxy() == null) return null
|
|
||||||
|
|
||||||
val fieldName = getField().name()
|
|
||||||
if (fieldName == AsmUtil.CAPTURED_THIS_FIELD || fieldName == AsmUtil.CAPTURED_RECEIVER_FIELD) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val type = getField().declaringType()
|
|
||||||
val myClass = findClassByType(type, context)?.getNavigationElement()
|
|
||||||
if (myClass !is JetClassOrObject) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
val field = myClass.getDeclarations().firstOrNull { fieldName == it.getName() }
|
|
||||||
if (field == null) return null
|
|
||||||
|
|
||||||
if (nearest) {
|
|
||||||
return DebuggerContextUtil.findNearest(context, field, myClass.getContainingFile())
|
|
||||||
}
|
|
||||||
return SourcePosition.createFromOffset(field.getContainingFile(), field.getTextOffset())
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun findClassByType(type: ReferenceType, context: DebuggerContextImpl): PsiElement? {
|
|
||||||
val session = context.getDebuggerSession()
|
|
||||||
val scope = if (session != null) session.getSearchScope() else GlobalSearchScope.allScope(myProject)
|
|
||||||
val className = JvmClassName.byInternalName(type.name()).getFqNameForClassNameWithoutDollars().asString()
|
|
||||||
|
|
||||||
val myClass = JavaPsiFacade.getInstance(myProject).findClass(className, scope)
|
|
||||||
if (myClass != null) return myClass
|
|
||||||
|
|
||||||
val position = getLastSourcePosition(type, context)
|
|
||||||
if (position != null) {
|
|
||||||
val element = position.getElementAt()
|
|
||||||
if (element != null) {
|
|
||||||
return element.getStrictParentOfType<JetClassOrObject>()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun getLastSourcePosition(type: ReferenceType, context: DebuggerContextImpl): SourcePosition? {
|
|
||||||
val debugProcess = context.getDebugProcess()
|
|
||||||
if (debugProcess != null) {
|
|
||||||
try {
|
|
||||||
val locations = type.allLineLocations()
|
|
||||||
if (!locations.isEmpty()) {
|
|
||||||
val lastLocation = locations.get(locations.size() - 1)
|
|
||||||
return debugProcess.getPositionManager().getSourcePosition(lastLocation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (ignored: AbsentInformationException) {
|
|
||||||
}
|
|
||||||
catch (ignored: ClassNotPreparedException) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Type?.isKotlinClass(): Boolean {
|
|
||||||
return this is ClassType && this.allInterfaces().any { it.name() == JvmAbi.K_OBJECT.asString() }
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -30,10 +30,10 @@ class MyDelegateThrowsException {
|
|||||||
static = static = delegatedPropertyInClass.DelegatedPropertyInClassPackage$@packagePartHASH
|
static = static = delegatedPropertyInClass.DelegatedPropertyInClassPackage$@packagePartHASH
|
||||||
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID}
|
local = args: java.lang.String[] = {java.lang.String[0]@uniqueID}
|
||||||
local = a: delegatedPropertyInClass.A = {delegatedPropertyInClass.A@uniqueID}
|
local = a: delegatedPropertyInClass.A = {delegatedPropertyInClass.A@uniqueID}
|
||||||
field = prop$delegate: delegatedPropertyInClass.MyDelegate = {delegatedPropertyInClass.MyDelegate@uniqueID} (sp = null)
|
field = prop$delegate: delegatedPropertyInClass.MyDelegate = {delegatedPropertyInClass.MyDelegate@uniqueID} (sp = delegatedPropertyInClass.kt, 12)
|
||||||
field = prop: int = 1
|
field = prop: int = 1 (sp = delegatedPropertyInClass.kt, 12)
|
||||||
field = propEx$delegate: delegatedPropertyInClass.MyDelegateThrowsException = {delegatedPropertyInClass.MyDelegateThrowsException@uniqueID} (sp = null)
|
field = propEx$delegate: delegatedPropertyInClass.MyDelegateThrowsException = {delegatedPropertyInClass.MyDelegateThrowsException@uniqueID} (sp = delegatedPropertyInClass.kt, 13)
|
||||||
field = propEx: java.lang.IllegalStateException = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException
|
field = propEx: java.lang.IllegalStateException = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException (sp = delegatedPropertyInClass.kt, 13)
|
||||||
field = detailMessage: java.lang.String = null (sp = Throwable.!EXT!)
|
field = detailMessage: java.lang.String = null (sp = Throwable.!EXT!)
|
||||||
field = cause: java.lang.Throwable = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException (sp = Throwable.!EXT!)
|
field = cause: java.lang.Throwable = {java.lang.IllegalStateException@uniqueID}java.lang.IllegalStateException (sp = Throwable.!EXT!)
|
||||||
field = stackTrace: java.lang.StackTraceElement[] = null (sp = Throwable.!EXT!)
|
field = stackTrace: java.lang.StackTraceElement[] = null (sp = Throwable.!EXT!)
|
||||||
|
|||||||
+3
-3
@@ -62,6 +62,7 @@ import com.intellij.debugger.settings.NodeRendererSettings
|
|||||||
import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl
|
import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl
|
||||||
import com.intellij.debugger.impl.DebuggerContextImpl
|
import com.intellij.debugger.impl.DebuggerContextImpl
|
||||||
import com.intellij.debugger.SourcePosition
|
import com.intellij.debugger.SourcePosition
|
||||||
|
import com.intellij.debugger.engine.SourcePositionProvider
|
||||||
|
|
||||||
public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestBase() {
|
public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestBase() {
|
||||||
private val logger = Logger.getLogger(javaClass<KotlinEvaluateExpressionCache>())!!
|
private val logger = Logger.getLogger(javaClass<KotlinEvaluateExpressionCache>())!!
|
||||||
@@ -252,9 +253,8 @@ public abstract class AbstractKotlinEvaluateExpressionTest : KotlinDebuggerTestB
|
|||||||
is LocalVariableDescriptor -> logDescriptor(descriptor, "$curIndent local = $label\n")
|
is LocalVariableDescriptor -> logDescriptor(descriptor, "$curIndent local = $label\n")
|
||||||
is StaticDescriptor -> logDescriptor(descriptor, "$curIndent static = $label\n")
|
is StaticDescriptor -> logDescriptor(descriptor, "$curIndent static = $label\n")
|
||||||
is ThisDescriptorImpl -> logDescriptor(descriptor, "$curIndent this = $label\n")
|
is ThisDescriptorImpl -> logDescriptor(descriptor, "$curIndent this = $label\n")
|
||||||
is FieldDescriptorImpl -> logDescriptor(descriptor, "$curIndent field = $label"
|
is FieldDescriptor -> logDescriptor(descriptor, "$curIndent field = $label"
|
||||||
+ " (sp = ${render(descriptor.getSourcePosition(myProject, debuggerContext))})\n")
|
+ " (sp = ${render(SourcePositionProvider.getSourcePosition(descriptor, myProject, debuggerContext))})\n")
|
||||||
is FieldDescriptor -> logDescriptor(descriptor, "$curIndent field = $label\n")
|
|
||||||
else -> logDescriptor(descriptor, "$curIndent unknown = $label\n")
|
else -> logDescriptor(descriptor, "$curIndent unknown = $label\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user