Implement handler for filter call for kotlin collections
This commit is contained in:
committed by
Yan Zhulanow
parent
3b14ed9ae8
commit
246f79ab86
+21
@@ -0,0 +1,21 @@
|
|||||||
|
package com.intellij.debugger.streams.kotlin.trace.impl.handler.collections
|
||||||
|
|
||||||
|
import com.intellij.debugger.streams.kotlin.trace.dsl.KotlinTypes
|
||||||
|
import com.intellij.debugger.streams.wrapper.*
|
||||||
|
import com.intellij.debugger.streams.wrapper.impl.IntermediateStreamCallImpl
|
||||||
|
import com.intellij.debugger.streams.wrapper.impl.TerminatorStreamCallImpl
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Vitaliy.Bibaev
|
||||||
|
*/
|
||||||
|
fun IntermediateStreamCall.withArgs(args: List<CallArgument>) =
|
||||||
|
IntermediateStreamCallImpl(name, args, typeBefore, typeAfter, textRange)
|
||||||
|
|
||||||
|
fun TerminatorStreamCall.withArgs(args: List<CallArgument>) =
|
||||||
|
TerminatorStreamCallImpl(name, args, typeBefore, resultType, textRange)
|
||||||
|
|
||||||
|
fun StreamCall.typeBefore() =
|
||||||
|
if (StreamCall@ this is TypeBeforeAware) StreamCall@ this.typeBefore else KotlinTypes.ANY
|
||||||
|
|
||||||
|
fun StreamCall.typeAfter() =
|
||||||
|
if (StreamCall@ this is TypeAfterAware) StreamCall@ this.typeAfter else KotlinTypes.ANY
|
||||||
+69
@@ -1,7 +1,76 @@
|
|||||||
package com.intellij.debugger.streams.kotlin.trace.impl.handler.collections
|
package com.intellij.debugger.streams.kotlin.trace.impl.handler.collections
|
||||||
|
|
||||||
|
import com.intellij.debugger.streams.trace.dsl.*
|
||||||
|
import com.intellij.debugger.streams.trace.dsl.impl.TextExpression
|
||||||
|
import com.intellij.debugger.streams.trace.impl.handler.type.ClassTypeImpl
|
||||||
|
import com.intellij.debugger.streams.wrapper.CallArgument
|
||||||
|
import com.intellij.debugger.streams.wrapper.IntermediateStreamCall
|
||||||
|
import com.intellij.debugger.streams.wrapper.StreamCall
|
||||||
|
import com.intellij.debugger.streams.wrapper.TerminatorStreamCall
|
||||||
|
import com.intellij.debugger.streams.wrapper.impl.CallArgumentImpl
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Vitaliy.Bibaev
|
* @author Vitaliy.Bibaev
|
||||||
*/
|
*/
|
||||||
class FilterCallHandler : BothSemanticsHandler {
|
class FilterCallHandler : BothSemanticsHandler {
|
||||||
|
private companion object {
|
||||||
|
val VALUES_ARRAY_NAME = "objectsInPredicate"
|
||||||
|
val PREDICATE_RESULT_ARRAY_NAME = "filteringResults"
|
||||||
|
|
||||||
|
fun oldPredicateVariableName(order: Int): String = "filterPredicate" + order
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun variablesDeclaration(call: StreamCall, order: Int, dsl: Dsl): List<VariableDeclaration> {
|
||||||
|
val types = dsl.types
|
||||||
|
|
||||||
|
val timeToObjectMap = dsl.linkedMap(types.INT, call.typeBefore(), call.name + "Values" + order)
|
||||||
|
val predicateResultMap = dsl.linkedMap(types.INT, types.BOOLEAN, call.name + "PredicateValue" + order)
|
||||||
|
val predicate = call.arguments[0]
|
||||||
|
// TODO: use generic types in CallArgument
|
||||||
|
val oldFilterPredicate = dsl.variable(ClassTypeImpl(predicate.type), oldPredicateVariableName(order))
|
||||||
|
|
||||||
|
return listOf(timeToObjectMap.defaultDeclaration(), predicateResultMap.defaultDeclaration(),
|
||||||
|
dsl.declaration(oldFilterPredicate, TextExpression(predicate.text), false))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun prepareResult(dsl: Dsl, variables: List<Variable>): CodeBlock {
|
||||||
|
val values = variables[0] as MapVariable
|
||||||
|
val filterResult = variables[1] as MapVariable
|
||||||
|
return dsl.block {
|
||||||
|
add(values.convertToArray(dsl, VALUES_ARRAY_NAME))
|
||||||
|
add(filterResult.convertToArray(dsl, PREDICATE_RESULT_ARRAY_NAME))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun additionalCallsBefore(call: StreamCall, dsl: Dsl): List<IntermediateStreamCall> = emptyList()
|
||||||
|
|
||||||
|
override fun additionalCallsAfter(call: StreamCall, dsl: Dsl): List<IntermediateStreamCall> = emptyList()
|
||||||
|
|
||||||
|
override fun getResultExpression(call: StreamCall, dsl: Dsl, variables: List<Variable>): Expression {
|
||||||
|
return dsl.newArray(dsl.types.ANY, TextExpression(VALUES_ARRAY_NAME), TextExpression(PREDICATE_RESULT_ARRAY_NAME))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformAsIntermediateCall(call: IntermediateStreamCall, variables: List<Variable>, dsl: Dsl): IntermediateStreamCall {
|
||||||
|
return call.withArgs(listOf(createNewPredicate(variables, dsl)))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transformAsTerminalCall(call: TerminatorStreamCall, variables: List<Variable>, dsl: Dsl): TerminatorStreamCall {
|
||||||
|
return call.withArgs(listOf(createNewPredicate(variables, dsl)))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNewPredicate(variables: List<Variable>, dsl: Dsl): CallArgument {
|
||||||
|
val valuesMap = variables[0] as MapVariable
|
||||||
|
val filteringMap = variables[1] as MapVariable
|
||||||
|
val oldPredicate = variables[2]
|
||||||
|
val newPredicate = dsl.lambda("value") {
|
||||||
|
+dsl.updateTime()
|
||||||
|
+valuesMap.set(dsl.currentTime(), lambdaArg)
|
||||||
|
val filterResult = dsl.variable(dsl.types.BOOLEAN, "result")
|
||||||
|
declare(filterResult, oldPredicate.call("invoke", lambdaArg), false)
|
||||||
|
+filteringMap.set(dsl.currentTime(), filterResult)
|
||||||
|
doReturn(filterResult)
|
||||||
|
}.toCode()
|
||||||
|
|
||||||
|
return CallArgumentImpl(oldPredicate.type.genericTypeName, newPredicate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user