Added extra stepping filter

This commit is contained in:
Michael Bogdanov
2015-02-10 15:10:38 +03:00
parent 126de2ce27
commit b58cdae0c5
3 changed files with 94 additions and 9 deletions
+1
View File
@@ -386,6 +386,7 @@
<debugger.nodeRenderer implementation="org.jetbrains.kotlin.idea.debugger.render.KotlinClassWithDelegatedPropertyRenderer"/> <debugger.nodeRenderer implementation="org.jetbrains.kotlin.idea.debugger.render.KotlinClassWithDelegatedPropertyRenderer"/>
<debugger.sourcePositionProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinSourcePositionProvider"/> <debugger.sourcePositionProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinSourcePositionProvider"/>
<debugger.frameExtraVarsProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinFrameExtraVariablesProvider"/> <debugger.frameExtraVarsProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinFrameExtraVariablesProvider"/>
<debugger.extraSteppingFilter implementation="org.jetbrains.kotlin.idea.ExtraSteppingFilter"/>
<xdebugger.settings implementation="org.jetbrains.kotlin.idea.debugger.KotlinDebuggerSettings"/> <xdebugger.settings implementation="org.jetbrains.kotlin.idea.debugger.KotlinDebuggerSettings"/>
<codeInsight.implementMethod language="jet" implementationClass="org.jetbrains.kotlin.idea.codeInsight.ImplementMethodsHandler"/> <codeInsight.implementMethod language="jet" implementationClass="org.jetbrains.kotlin.idea.codeInsight.ImplementMethodsHandler"/>
@@ -0,0 +1,84 @@
/*
* Copyright 2010-2015 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.kotlin.idea
import com.intellij.debugger.engine
import com.intellij.debugger.engine.SuspendContext
import org.jetbrains.kotlin.idea.debugger.JetPositionManager
import com.sun.jdi.Location
import org.jetbrains.kotlin.idea.util.application.runReadAction
import com.intellij.debugger.NoDataException
import com.sun.jdi.request.StepRequest
import java.util.regex.Pattern
import java.util.WeakHashMap
import com.intellij.openapi.extensions.Extensions
import com.intellij.ui.classFilter.DebuggerClassFilterProvider
import com.intellij.debugger.settings.DebuggerSettings
public class ExtraSteppingFilter : engine.ExtraSteppingFilter {
override fun isApplicable(context: SuspendContext?): Boolean {
if (context == null) {
return false;
}
val debugProcess = context.getDebugProcess()
val positionManager = JetPositionManager(debugProcess)
val location = context.getFrameProxy().location()
return runReadAction {
shouldFilter(positionManager, location)
}
}
private fun shouldFilter(positionManager: JetPositionManager, location: Location): Boolean {
val defaultStrata = location.declaringType().defaultStratum()
if ("Kotlin" != defaultStrata) {
return false;
}
val sourcePosition =
try {
positionManager.getSourcePosition(location)
}
catch(e: NoDataException) {
return false
}
if (sourcePosition == null) return false
val className = positionManager.classNameForPosition(sourcePosition)?.replace('/', '.') ?: return false
val settings = DebuggerSettings.getInstance()
if (settings.TRACING_FILTERS_ENABLED) {
for (filter in settings.getSteppingFilters()) {
if (filter.isEnabled()) {
if (filter.matches(className)) {
return true;
}
}
}
}
return false;
}
override fun getStepRequestDepth(context: SuspendContext?): Int {
return StepRequest.STEP_INTO
}
}
@@ -119,7 +119,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
continue continue
} }
val internalClassName = getClassNameForElement(literal.getFirstChild(), typeMapper, file, isInLibrary).className val internalClassName = getInternalClassNameForElement(literal.getFirstChild(), typeMapper, file, isInLibrary).className
if (internalClassName == currentLocationClassName) { if (internalClassName == currentLocationClassName) {
return functionLiteral return functionLiteral
} }
@@ -191,7 +191,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
return result; return result;
} }
private fun classNameForPosition(sourcePosition: SourcePosition): String? { public fun classNameForPosition(sourcePosition: SourcePosition): String? {
val psiElement = sourcePosition.getElementAt() val psiElement = sourcePosition.getElementAt()
if (psiElement == null) { if (psiElement == null) {
return null return null
@@ -204,7 +204,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
val file = element.getContainingFile() as JetFile val file = element.getContainingFile() as JetFile
val isInLibrary = LibraryUtil.findLibraryEntry(file.getVirtualFile(), file.getProject()) != null val isInLibrary = LibraryUtil.findLibraryEntry(file.getVirtualFile(), file.getProject()) != null
val typeMapper = if (!isInLibrary) prepareTypeMapper(file) else createTypeMapperForLibraryFile(element, file) val typeMapper = if (!isInLibrary) prepareTypeMapper(file) else createTypeMapperForLibraryFile(element, file)
getClassNameForElement(element, typeMapper, file, isInLibrary).className getInternalClassNameForElement(element, typeMapper, file, isInLibrary).className
} }
} }
@@ -293,13 +293,13 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
return state.getTypeMapper() return state.getTypeMapper()
} }
public fun getClassNameForElement(notPositionedElement: PsiElement?, typeMapper: JetTypeMapper, file: JetFile, isInLibrary: Boolean): PositionedElement { public fun getInternalClassNameForElement(notPositionedElement: PsiElement?, typeMapper: JetTypeMapper, file: JetFile, isInLibrary: Boolean): PositionedElement {
val element = getElementToCalculateClassName(notPositionedElement) val element = getElementToCalculateClassName(notPositionedElement)
when { when {
element is JetClassOrObject -> return PositionedElement(getJvmInternalNameForImpl(typeMapper, element), element) element is JetClassOrObject -> return PositionedElement(getJvmInternalNameForImpl(typeMapper, element), element)
element is JetFunctionLiteral -> { element is JetFunctionLiteral -> {
if (isInlinedLambda(element, typeMapper.getBindingContext())) { if (isInlinedLambda(element, typeMapper.getBindingContext())) {
return getClassNameForElement(element.getParent(), typeMapper, file, isInLibrary) return getInternalClassNameForElement(element.getParent(), typeMapper, file, isInLibrary)
} }
else { else {
val asmType = CodegenBinding.asmTypeForAnonymousClass(typeMapper.getBindingContext(), element) val asmType = CodegenBinding.asmTypeForAnonymousClass(typeMapper.getBindingContext(), element)
@@ -310,9 +310,9 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
val parent = getElementToCalculateClassName(element.getParent()) val parent = getElementToCalculateClassName(element.getParent())
// Class-object initializer // Class-object initializer
if (parent is JetObjectDeclaration && parent.isDefault()) { if (parent is JetObjectDeclaration && parent.isDefault()) {
return PositionedElement(getClassNameForElement(parent.getParent(), typeMapper, file, isInLibrary).className, parent) return PositionedElement(getInternalClassNameForElement(parent.getParent(), typeMapper, file, isInLibrary).className, parent)
} }
return getClassNameForElement(element, typeMapper, file, isInLibrary) return getInternalClassNameForElement(element, typeMapper, file, isInLibrary)
} }
element is JetProperty && (!element.isTopLevel() || !isInLibrary) -> { element is JetProperty && (!element.isTopLevel() || !isInLibrary) -> {
if (isInPropertyAccessor(notPositionedElement)) { if (isInPropertyAccessor(notPositionedElement)) {
@@ -324,7 +324,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
val descriptor = typeMapper.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, element) val descriptor = typeMapper.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, element)
if (descriptor !is PropertyDescriptor) { if (descriptor !is PropertyDescriptor) {
return getClassNameForElement(element.getParent(), typeMapper, file, isInLibrary) return getInternalClassNameForElement(element.getParent(), typeMapper, file, isInLibrary)
} }
return PositionedElement(getJvmInternalNameForPropertyOwner(typeMapper, descriptor), element) return PositionedElement(getJvmInternalNameForPropertyOwner(typeMapper, descriptor), element)
@@ -441,7 +441,7 @@ public class JetPositionManager(private val myDebugProcess: DebugProcess) : Mult
if (element != null && jetFile is JetFile) { if (element != null && jetFile is JetFile) {
val isInLibrary = LibraryUtil.findLibraryEntry(jetFile.getVirtualFile(), jetFile.getProject()) != null val isInLibrary = LibraryUtil.findLibraryEntry(jetFile.getVirtualFile(), jetFile.getProject()) != null
val typeMapper = if (!isInLibrary) prepareTypeMapper(jetFile) else createTypeMapperForLibraryFile(element, jetFile) val typeMapper = if (!isInLibrary) prepareTypeMapper(jetFile) else createTypeMapperForLibraryFile(element, jetFile)
val psiElement = getClassNameForElement(element, typeMapper, jetFile, isInLibrary).element; val psiElement = getInternalClassNameForElement(element, typeMapper, jetFile, isInLibrary).element;
if (psiElement is JetNamedFunction) { if (psiElement is JetNamedFunction) {
val descriptor = typeMapper.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement) val descriptor = typeMapper.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement)