Support filter and filterNotOperations
This commit is contained in:
committed by
Yan Zhulanow
parent
6be340f079
commit
86ec8eab6e
+6
-5
@@ -1,11 +1,11 @@
|
||||
package com.intellij.debugger.streams.kotlin.lib
|
||||
|
||||
import com.intellij.debugger.streams.kotlin.resolve.FilterOrderResolver
|
||||
import com.intellij.debugger.streams.kotlin.trace.impl.handler.collections.*
|
||||
import com.intellij.debugger.streams.kotlin.trace.impl.interpret.FilterTraceInterpreter
|
||||
import com.intellij.debugger.streams.lib.IntermediateOperation
|
||||
import com.intellij.debugger.streams.lib.TerminalOperation
|
||||
import com.intellij.debugger.streams.lib.impl.LibrarySupportBase
|
||||
import com.intellij.debugger.streams.resolve.FilterResolver
|
||||
import com.intellij.debugger.streams.resolve.ValuesOrderResolver
|
||||
import com.intellij.debugger.streams.trace.CallTraceInterpreter
|
||||
import com.intellij.debugger.streams.trace.IntermediateCallHandler
|
||||
@@ -19,7 +19,8 @@ import com.intellij.debugger.streams.wrapper.TerminatorStreamCall
|
||||
*/
|
||||
class KotlinCollectionLibrarySupport : LibrarySupportBase() {
|
||||
init {
|
||||
addOperation(FilterOperation("filter", FilterCallHandler()))
|
||||
addOperation(FilterOperation("filter", FilterCallHandler(), true))
|
||||
addOperation(FilterOperation("filterNot", FilterCallHandler(), false))
|
||||
}
|
||||
|
||||
private fun addOperation(operation: CollectionOperation) {
|
||||
@@ -40,9 +41,9 @@ class KotlinCollectionLibrarySupport : LibrarySupportBase() {
|
||||
wrapper.createTerminatorHandler(call, resultExpression, dsl)
|
||||
}
|
||||
|
||||
private class FilterOperation(name: String, handler: BothSemanticsHandler)
|
||||
private class FilterOperation(name: String, handler: BothSemanticsHandler, valueToAccept: Boolean)
|
||||
: CollectionOperation(name, handler) {
|
||||
override val traceInterpreter: CallTraceInterpreter = FilterTraceInterpreter()
|
||||
override val valuesOrderResolver: ValuesOrderResolver = FilterOrderResolver()
|
||||
override val traceInterpreter: CallTraceInterpreter = FilterTraceInterpreter(valueToAccept)
|
||||
override val valuesOrderResolver: ValuesOrderResolver = FilterResolver()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
package com.intellij.debugger.streams.kotlin.resolve
|
||||
|
||||
import com.intellij.debugger.streams.resolve.ValuesOrderResolver
|
||||
import com.intellij.debugger.streams.trace.TraceInfo
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class FilterOrderResolver : ValuesOrderResolver {
|
||||
override fun resolve(info: TraceInfo): ValuesOrderResolver.Result {
|
||||
return ValuesOrderResolver.Result.of(emptyMap(), emptyMap())
|
||||
}
|
||||
}
|
||||
+50
-6
@@ -1,22 +1,66 @@
|
||||
package com.intellij.debugger.streams.kotlin.trace.impl.interpret
|
||||
|
||||
import com.intellij.debugger.streams.trace.CallTraceInterpreter
|
||||
import com.intellij.debugger.streams.trace.TraceElement
|
||||
import com.intellij.debugger.streams.trace.TraceInfo
|
||||
import com.intellij.debugger.streams.trace.impl.interpret.ValuesOrderInfo
|
||||
import com.intellij.debugger.streams.trace.impl.TraceElementImpl
|
||||
import com.intellij.debugger.streams.trace.impl.interpret.ex.UnexpectedValueTypeException
|
||||
import com.intellij.debugger.streams.wrapper.StreamCall
|
||||
import com.sun.jdi.ArrayReference
|
||||
import com.sun.jdi.BooleanValue
|
||||
import com.sun.jdi.IntegerValue
|
||||
import com.sun.jdi.Value
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class FilterTraceInterpreter : CallTraceInterpreter {
|
||||
class FilterTraceInterpreter(private val predicateValueToAccept: Boolean) : CallTraceInterpreter {
|
||||
override fun resolve(call: StreamCall, value: Value): TraceInfo {
|
||||
if (value !is ArrayReference) throw UnexpectedValueTypeException("array reference excepted, but actual: ${value.type().name()}")
|
||||
val times = value.getValue(0)
|
||||
val values = value.getValue(1)
|
||||
val predicateResults = value.getValue(0)
|
||||
return ValuesOrderInfo.empty(call)
|
||||
val before = resolveValuesBefore(value.getValue(0))
|
||||
val filteringMap = value.getValue(1)
|
||||
val after = resolveValuesAfter(before, filteringMap)
|
||||
|
||||
return ValuesOrder(call, before, after)
|
||||
}
|
||||
|
||||
private fun resolveValuesBefore(map: Value): Map<Int, TraceElement> {
|
||||
val (keys, objects) = InterpreterUtil.extractMap(map)
|
||||
val result: MutableList<TraceElement> = mutableListOf()
|
||||
for (i in 0.until(keys.length())) {
|
||||
val time = keys.getValue(i)
|
||||
val value = objects.getValue(i)
|
||||
if (time !is IntegerValue) throw UnexpectedValueTypeException("time should be represented by integer value")
|
||||
result.add(TraceElementImpl(time.value(), value))
|
||||
}
|
||||
|
||||
return InterpreterUtil.createIndexByTime(result)
|
||||
}
|
||||
|
||||
private fun resolveValuesAfter(before: Map<Int, TraceElement>, filteringMap: Value): Map<Int, TraceElement> {
|
||||
val predicateValues = extractPredicateValues(filteringMap)
|
||||
val result = linkedMapOf<Int, TraceElement>()
|
||||
for ((beforeTime, value) in before) {
|
||||
val predicateValue = predicateValues[beforeTime]
|
||||
if (predicateValue == predicateValueToAccept) {
|
||||
result[beforeTime + 1] = value
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun extractPredicateValues(filteringMap: Value): Map<Int, Boolean> {
|
||||
val (keys, values) = InterpreterUtil.extractMap(filteringMap)
|
||||
val result = mutableMapOf<Int, Boolean>()
|
||||
for (i in 0.until(keys.length())) {
|
||||
val time = keys.getValue(i)
|
||||
val value = values.getValue(i)
|
||||
if (time !is IntegerValue) throw UnexpectedValueTypeException("time should be represented by integer value")
|
||||
if (value !is BooleanValue) throw UnexpectedValueTypeException("predicate value should be represented by boolean value")
|
||||
result[time.value()] = value.value()
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.intellij.debugger.streams.kotlin.trace.impl.interpret
|
||||
|
||||
import com.intellij.debugger.streams.trace.TraceElement
|
||||
import com.intellij.debugger.streams.trace.impl.interpret.ex.UnexpectedValueException
|
||||
import com.sun.jdi.ArrayReference
|
||||
import com.sun.jdi.Value
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
object InterpreterUtil {
|
||||
|
||||
fun extractMap(value: Value): MapRepresentation {
|
||||
if (value !is ArrayReference || value.length() != 2) {
|
||||
throw UnexpectedValueException("Map should be represented by array with two nested arrays: keys and values")
|
||||
}
|
||||
|
||||
val keys = value.getValue(0)
|
||||
val values = value.getValue(1)
|
||||
|
||||
if (keys !is ArrayReference || values !is ArrayReference || keys.length() != values.length()) {
|
||||
throw UnexpectedValueException("Keys and values should be arrays with equal counts of elements")
|
||||
}
|
||||
|
||||
return MapRepresentation(keys, values)
|
||||
}
|
||||
|
||||
fun createIndexByTime(elements: List<TraceElement>): Map<Int, TraceElement> =
|
||||
elements.associate { elem -> elem.time to elem }
|
||||
|
||||
data class MapRepresentation(val keys: ArrayReference, val values: ArrayReference)
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.intellij.debugger.streams.kotlin.trace.impl.interpret
|
||||
|
||||
import com.intellij.debugger.streams.trace.TraceElement
|
||||
import com.intellij.debugger.streams.trace.TraceInfo
|
||||
import com.intellij.debugger.streams.wrapper.StreamCall
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class ValuesOrder(private val call: StreamCall,
|
||||
private val before: Map<Int, TraceElement>,
|
||||
private val after: Map<Int, TraceElement>)
|
||||
: TraceInfo {
|
||||
override fun getValuesOrderBefore(): Map<Int, TraceElement> = before
|
||||
|
||||
override fun getCall(): StreamCall = call
|
||||
|
||||
override fun getValuesOrderAfter(): Map<Int, TraceElement> = after
|
||||
|
||||
override fun getDirectTrace(): MutableMap<TraceElement, MutableList<TraceElement>>? = null
|
||||
|
||||
override fun getReverseTrace(): MutableMap<TraceElement, MutableList<TraceElement>>? = null
|
||||
}
|
||||
Reference in New Issue
Block a user