convert LazyVariablesGroup to kotlin
[idea/community.git] / platform / script-debugger / debugger-ui / src / org / jetbrains / debugger / LazyVariablesGroup.kt
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.jetbrains.debugger
17
18 import com.intellij.xdebugger.frame.XCompositeNode
19 import com.intellij.xdebugger.frame.XValueChildrenList
20 import com.intellij.xdebugger.frame.XValueGroup
21 import org.jetbrains.debugger.values.ObjectValue
22 import org.jetbrains.debugger.values.ValueType
23 import java.util.*
24
25 internal fun lazyVariablesGroup(variables: ObjectValue, start: Int, end: Int, context: VariableContext) = LazyVariablesGroup(variables, start, end, context)
26
27 class LazyVariablesGroup(private val value: ObjectValue, private val startInclusive: Int, private val endInclusive: Int, private val context: VariableContext, private val componentType: ValueType? = null, private val sparse: Boolean = true) : XValueGroup(String.format("[%,d \u2026 %,d]", startInclusive, endInclusive)) {
28   override fun computeChildren(node: XCompositeNode) {
29     node.setAlreadySorted(true)
30
31     val bucketThreshold = XCompositeNode.MAX_CHILDREN_TO_SHOW
32     if (!sparse && endInclusive - startInclusive > bucketThreshold) {
33       node.addChildren(XValueChildrenList.topGroups(computeNotSparseGroups(value, context, startInclusive, endInclusive + 1, bucketThreshold)), true)
34       return
35     }
36
37     value.getIndexedProperties(startInclusive, endInclusive + 1, bucketThreshold, object : VariableView.ObsolescentIndexedVariablesConsumer(node) {
38       override fun consumeRanges(ranges: IntArray?) {
39         if (ranges == null) {
40           val groupList = XValueChildrenList()
41           addGroups(value, ::lazyVariablesGroup, groupList, startInclusive, endInclusive, XCompositeNode.MAX_CHILDREN_TO_SHOW, context)
42           node.addChildren(groupList, true)
43         }
44         else {
45           addRanges(value, ranges, node, context, true)
46         }
47       }
48
49       override fun consumeVariables(variables: List<Variable>) {
50         node.addChildren(createVariablesList(variables, context, null), true)
51       }
52     }, componentType)
53   }
54 }
55
56 fun computeNotSparseGroups(value: ObjectValue, context: VariableContext, _fromInclusive: Int, toExclusive: Int, bucketThreshold: Int): List<XValueGroup> {
57   var fromInclusive = _fromInclusive
58   val size = toExclusive - fromInclusive
59   val bucketSize = Math.pow(bucketThreshold.toDouble(), Math.ceil(Math.log(size.toDouble()) / Math.log(bucketThreshold.toDouble())) - 1).toInt()
60   val groupList = ArrayList<XValueGroup>(Math.ceil((size / bucketSize).toDouble()).toInt())
61   while (fromInclusive < toExclusive) {
62     groupList.add(LazyVariablesGroup(value, fromInclusive, fromInclusive + (Math.min(bucketSize, toExclusive - fromInclusive) - 1), context, ValueType.NUMBER, false))
63     fromInclusive += bucketSize
64   }
65   return groupList
66 }
67
68 fun addRanges(value: ObjectValue, ranges: IntArray, node: XCompositeNode, context: VariableContext, isLast: Boolean) {
69   val groupList = XValueChildrenList(ranges.size / 2)
70   var i = 0
71   val n = ranges.size
72   while (i < n) {
73     groupList.addTopGroup(LazyVariablesGroup(value, ranges[i], ranges[i + 1], context))
74     i += 2
75   }
76   node.addChildren(groupList, isLast)
77 }
78
79 internal fun <T> addGroups(data: T,
80                   groupFactory: (data: T, start: Int, end: Int, context: VariableContext) -> XValueGroup,
81                   groupList: XValueChildrenList,
82                   _from: Int,
83                   limit: Int,
84                   bucketSize: Int,
85                   context: VariableContext) {
86   var from = _from
87   var to = Math.min(bucketSize, limit)
88   var done = false
89   do {
90     val groupFrom = from
91     var groupTo = to
92
93     from += bucketSize
94     to = from + Math.min(bucketSize, limit - from)
95
96     // don't create group for only one member
97     if (to - from == 1) {
98       groupTo++
99       done = true
100     }
101     groupList.addTopGroup(groupFactory(data, groupFrom, groupTo, context))
102     if (from >= limit) {
103       break
104     }
105   }
106   while (!done)
107 }