Add source files
This commit is contained in:
committed by
Yan Zhulanow
parent
8f566132e4
commit
957f9a7e14
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.psi
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
|
||||
fun KtExpression.resolveType(): KotlinType =
|
||||
this.analyze().getType(this)!!
|
||||
|
||||
fun KtValueArgument.resolveType(): KotlinType = getArgumentExpression()!!.resolveType()
|
||||
|
||||
fun KotlinType.getPackage(withGenerics: Boolean): String = StringUtil.getPackageName(getJetTypeFqName(withGenerics))
|
||||
|
||||
fun KtCallExpression.callName(): String = this.calleeExpression!!.text
|
||||
|
||||
fun KtCallExpression.receiverType(): KotlinType? {
|
||||
val resolvedCall = getResolvedCall(analyze())
|
||||
return resolvedCall?.dispatchReceiver?.type
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.intellij.debugger.streams.kotlin.psi
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
object StreamApiUtil {
|
||||
fun isStreamCall(expression: KtCallExpression): Boolean {
|
||||
return isIntermediateStreamCall(expression) || isProducerStreamCall(expression) || isTerminationStreamCall(expression)
|
||||
}
|
||||
|
||||
fun isProducerStreamCall(expression: KtCallExpression): Boolean {
|
||||
return checkCallSupported(expression, false, true)
|
||||
}
|
||||
|
||||
private fun isIntermediateStreamCall(expression: KtCallExpression): Boolean {
|
||||
return checkCallSupported(expression, true, true)
|
||||
}
|
||||
|
||||
fun isTerminationStreamCall(expression: KtCallExpression): Boolean {
|
||||
return checkCallSupported(expression, true, false)
|
||||
}
|
||||
|
||||
private fun checkCallSupported(expression: KtCallExpression,
|
||||
shouldSupportReceiver: Boolean,
|
||||
shouldSupportResult: Boolean): Boolean {
|
||||
val receiverType = expression.receiverType()
|
||||
val resultType = expression.resolveType()
|
||||
|
||||
return (receiverType == null || // there is no producer or producer is a static method
|
||||
shouldSupportReceiver == isSupportedType(receiverType)) && shouldSupportResult == isSupportedType(resultType)
|
||||
}
|
||||
|
||||
private fun isSupportedType(type: KotlinType?): Boolean {
|
||||
if (type == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
val typeName = type.getJetTypeFqName(false)
|
||||
return StringUtil.getPackageName(typeName).startsWith("java.util.stream")
|
||||
}
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.psi.impl
|
||||
|
||||
import com.intellij.debugger.streams.psi.ChainTransformer
|
||||
import com.intellij.debugger.streams.psi.PsiUtil
|
||||
import com.intellij.debugger.streams.wrapper.StreamChain
|
||||
import com.intellij.debugger.streams.wrapper.StreamChainBuilder
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
abstract class KotlinChainBuilderBase(private val transformer: ChainTransformer<KtCallExpression>) : StreamChainBuilder {
|
||||
protected abstract val existenceChecker: ExistenceChecker
|
||||
|
||||
override fun isChainExists(startElement: PsiElement): Boolean {
|
||||
var element: PsiElement? = PsiUtil.ignoreWhiteSpaces(startElement)
|
||||
while (element != null && !existenceChecker.isFound()) {
|
||||
existenceChecker.reset()
|
||||
element.accept(existenceChecker)
|
||||
element = toUpperLevel(element)
|
||||
}
|
||||
|
||||
return existenceChecker.isFound()
|
||||
}
|
||||
|
||||
override fun build(startElement: PsiElement): List<StreamChain> {
|
||||
val visitor = createChainsBuilder()
|
||||
var element = getLatestElementInScope(PsiUtil.ignoreWhiteSpaces(startElement))
|
||||
while (element != null) {
|
||||
element.accept(visitor)
|
||||
element = getLatestElementInScope(toUpperLevel(element))
|
||||
}
|
||||
|
||||
return visitor.chains().map { transformer.transform(it, startElement) }
|
||||
}
|
||||
|
||||
private fun toUpperLevel(element: PsiElement): PsiElement? {
|
||||
var current = element.parent
|
||||
|
||||
while (current != null && !(current is KtLambdaExpression || current is KtAnonymousInitializer)) {
|
||||
current = current.parent
|
||||
}
|
||||
|
||||
return current
|
||||
}
|
||||
|
||||
protected abstract fun createChainsBuilder(): ChainBuilder
|
||||
|
||||
private fun getLatestElementInScope(element: PsiElement?): PsiElement? {
|
||||
var current = element
|
||||
while (current != null) {
|
||||
val parent = current.parent
|
||||
if (parent is KtBlockExpression || parent is KtLambdaExpression || parent is KtStatementExpression) {
|
||||
break
|
||||
}
|
||||
|
||||
current = parent
|
||||
}
|
||||
|
||||
return current
|
||||
}
|
||||
|
||||
protected abstract class ExistenceChecker : MyTreeVisitor() {
|
||||
private var myIsFound: Boolean = false
|
||||
fun isFound(): Boolean = myIsFound
|
||||
fun reset() = setFound(false)
|
||||
protected fun fireElementFound() = setFound(true)
|
||||
|
||||
private fun setFound(value: Boolean) {
|
||||
myIsFound = value
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract class ChainBuilder : MyTreeVisitor() {
|
||||
abstract fun chains(): List<List<KtCallExpression>>
|
||||
}
|
||||
|
||||
protected abstract class MyTreeVisitor : KtTreeVisitorVoid() {
|
||||
override fun visitLambdaExpression(lambdaExpression: KtLambdaExpression) {}
|
||||
override fun visitBlockExpression(expression: KtBlockExpression) {}
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.psi.impl
|
||||
|
||||
import com.intellij.debugger.streams.kotlin.psi.callName
|
||||
import com.intellij.debugger.streams.kotlin.psi.getPackage
|
||||
import com.intellij.debugger.streams.kotlin.psi.receiverType
|
||||
import com.intellij.debugger.streams.kotlin.psi.resolveType
|
||||
import com.intellij.debugger.streams.psi.*
|
||||
import com.intellij.debugger.streams.kotlin.trace.dsl.KotlinTypes
|
||||
import com.intellij.debugger.streams.wrapper.CallArgument
|
||||
import com.intellij.debugger.streams.wrapper.IntermediateStreamCall
|
||||
import com.intellij.debugger.streams.wrapper.StreamChain
|
||||
import com.intellij.debugger.streams.wrapper.impl.*
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.psi.KtValueArgument
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinChainTransformerImpl : ChainTransformer<KtCallExpression> {
|
||||
override fun transform(callChain: List<KtCallExpression>, context: PsiElement): StreamChain {
|
||||
val firstCall = callChain.first()
|
||||
val parent = firstCall.parent
|
||||
val qualifier = if (parent is KtDotQualifiedExpression)
|
||||
QualifierExpressionImpl(parent.receiverExpression.text, parent.receiverExpression.textRange, KotlinTypes.ANY)
|
||||
else
|
||||
QualifierExpressionImpl("", TextRange.EMPTY_RANGE, KotlinTypes.ANY) // This possible only when this inherits Stream
|
||||
|
||||
val intermediateCalls = mutableListOf<IntermediateStreamCall>()
|
||||
for (call in callChain.subList(0, callChain.size - 1)) {
|
||||
intermediateCalls += IntermediateStreamCallImpl(call.callName(),
|
||||
call.valueArguments.map { it.toCallArgument() },
|
||||
KotlinTypes.ANY, KotlinTypes.ANY,
|
||||
call.textRange,
|
||||
call.receiverType()!!.getPackage(false))
|
||||
}
|
||||
|
||||
val terminationsPsiCall = callChain.last()
|
||||
// TODO: infer true types
|
||||
val terminationCall = TerminatorStreamCallImpl(terminationsPsiCall.callName(), emptyList(),
|
||||
KotlinTypes.ANY, KotlinTypes.ANY,
|
||||
terminationsPsiCall.textRange,
|
||||
terminationsPsiCall.receiverType()!!.getPackage(false))
|
||||
|
||||
return StreamChainImpl(qualifier, intermediateCalls, terminationCall, context)
|
||||
}
|
||||
|
||||
private fun KtValueArgument.toCallArgument(): CallArgument {
|
||||
val argExpression = getArgumentExpression()!!
|
||||
return CallArgumentImpl(argExpression.resolveType().getJetTypeFqName(true), argExpression.text)
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.psi.impl
|
||||
|
||||
import com.intellij.debugger.streams.kotlin.psi.impl.KotlinChainBuilderBase
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinCollectionChainBuilder : KotlinChainBuilderBase(TODO("transmit here a correct transformer")) {
|
||||
override val existenceChecker: ExistenceChecker
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
|
||||
override fun createChainsBuilder(): ChainBuilder {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.psi.impl
|
||||
|
||||
import com.intellij.debugger.streams.kotlin.psi.StreamApiUtil
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.js.descriptorUtils.getJetTypeFqName
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinJavaStreamChainBuilder : KotlinChainBuilderBase(KotlinChainTransformerImpl()) {
|
||||
override val existenceChecker: ExistenceChecker = MyExistenceChecker()
|
||||
|
||||
override fun createChainsBuilder(): ChainBuilder = MyBuilderVisitor()
|
||||
|
||||
private class MyExistenceChecker : ExistenceChecker() {
|
||||
override fun visitCallExpression(expression: KtCallExpression) {
|
||||
// TODO: make the check more sophisticated
|
||||
val type = expression.analyze().getType(expression) ?: return
|
||||
|
||||
val name = type.getJetTypeFqName(false)
|
||||
if (StringUtil.getPackageName(name).startsWith("java.util.stream")) {
|
||||
fireElementFound()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MyBuilderVisitor : ChainBuilder() {
|
||||
private val myTerminationCalls = mutableSetOf<KtCallExpression>()
|
||||
private val myPreviousCalls = mutableMapOf<KtCallExpression, KtCallExpression>()
|
||||
|
||||
override fun visitCallExpression(expression: KtCallExpression) {
|
||||
super.visitCallExpression(expression)
|
||||
if (!myPreviousCalls.containsKey(expression) && StreamApiUtil.isStreamCall(expression)) {
|
||||
updateCallTree(expression)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateCallTree(expression: KtCallExpression) {
|
||||
if (StreamApiUtil.isTerminationStreamCall(expression)) {
|
||||
myTerminationCalls.add(expression)
|
||||
}
|
||||
|
||||
val parent = expression.parent as? KtDotQualifiedExpression ?: return
|
||||
val parentCall = (parent.receiverExpression as? KtDotQualifiedExpression)?.selectorExpression
|
||||
if (parentCall is KtCallExpression && StreamApiUtil.isStreamCall(parentCall)) {
|
||||
myPreviousCalls.put(expression, parentCall)
|
||||
updateCallTree(parentCall)
|
||||
}
|
||||
}
|
||||
|
||||
override fun chains(): List<List<KtCallExpression>> {
|
||||
val chains = ArrayList<List<KtCallExpression>>()
|
||||
for (terminationCall in myTerminationCalls) {
|
||||
val chain = ArrayList<KtCallExpression>()
|
||||
var current: KtCallExpression? = terminationCall
|
||||
while (current != null) {
|
||||
if (StreamApiUtil.isProducerStreamCall(current)) {
|
||||
break
|
||||
}
|
||||
chain.add(current)
|
||||
current = myPreviousCalls[current]
|
||||
}
|
||||
|
||||
Collections.reverse(chain)
|
||||
chains.add(chain)
|
||||
}
|
||||
|
||||
return chains
|
||||
}
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.psi.impl
|
||||
|
||||
import com.intellij.debugger.streams.kotlin.psi.impl.KotlinChainBuilderBase
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinSequenceChainBuilder : KotlinChainBuilderBase(TODO("transmit here a correct transformer")) {
|
||||
override fun createChainsBuilder(): ChainBuilder {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
override val existenceChecker: ExistenceChecker
|
||||
get() = TODO("not implemented") //To change initializer of created properties use File | Settings | File Templates.
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.kotlin.trace.dsl.KotlinVariableDeclaration
|
||||
import com.intellij.debugger.streams.trace.dsl.ArrayVariable
|
||||
import com.intellij.debugger.streams.trace.dsl.Expression
|
||||
import com.intellij.debugger.streams.trace.dsl.VariableDeclaration
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.TextExpression
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.VariableImpl
|
||||
import com.intellij.debugger.streams.trace.impl.handler.type.ArrayType
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinArrayVariable(override val type: ArrayType, override val name: String)
|
||||
: VariableImpl(type, name), ArrayVariable {
|
||||
override fun get(index: Expression): Expression = TextExpression("$name[${index.toCode()}]!!")
|
||||
|
||||
override fun set(index: Expression, value: Expression): Expression = TextExpression("$name[${index.toCode()}] = ${value.toCode()}")
|
||||
|
||||
override fun defaultDeclaration(size: Expression): VariableDeclaration =
|
||||
KotlinVariableDeclaration(this, false, type.sizedDeclaration(size.toCode()))
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.Expression
|
||||
import com.intellij.debugger.streams.trace.dsl.Variable
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.AssignmentStatement
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinAssignmentStatement(override val variable: Variable, override val expression: Expression) : AssignmentStatement {
|
||||
override fun toCode(indent: Int): String = "${variable.toCode()} = ${expression.toCode()}".withIndent(indent)
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.Expression
|
||||
import com.intellij.debugger.streams.trace.dsl.StatementFactory
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.LineSeparatedCodeBlock
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
open class KotlinCodeBlock(statementFactory: StatementFactory) : LineSeparatedCodeBlock(statementFactory) {
|
||||
override fun doReturn(expression: Expression) = addStatement(expression)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.*
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinForEachLoop(private val iterateVariable: Variable,
|
||||
private val collection: Expression,
|
||||
private val loopBody: ForLoopBody) : Convertable {
|
||||
override fun toCode(indent: Int): String =
|
||||
"for (${iterateVariable.name} in ${collection.toCode()}) {\n".withIndent(indent) +
|
||||
loopBody.toCode(indent + 1) +
|
||||
"}".withIndent(indent)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.*
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinForLoop(private val initialization: VariableDeclaration,
|
||||
private val condition: Expression,
|
||||
private val afterThought: Expression,
|
||||
private val loopBody: ForLoopBody) : Convertable {
|
||||
override fun toCode(indent: Int): String =
|
||||
initialization.toCode(indent) + "\n" +
|
||||
"while (${condition.toCode()}) {\n".withIndent(indent) +
|
||||
loopBody.toCode(indent + 1) +
|
||||
afterThought.toCode(indent + 1) + "\n" +
|
||||
"}".withIndent(indent)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.*
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.TextExpression
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinForLoopBody(override val loopVariable: Variable,
|
||||
statementFactory: StatementFactory) : KotlinCodeBlock(statementFactory), ForLoopBody {
|
||||
private companion object {
|
||||
val BREAK = TextExpression("break")
|
||||
}
|
||||
|
||||
override fun breakIteration(): Expression = BREAK
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.CodeBlock
|
||||
import com.intellij.debugger.streams.trace.dsl.Expression
|
||||
import com.intellij.debugger.streams.trace.dsl.StatementFactory
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.common.IfBranchBase
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinIfBranch(condition: Expression, thenBlock: CodeBlock, statementFactory: StatementFactory)
|
||||
: IfBranchBase(condition, thenBlock, statementFactory) {
|
||||
override fun toCode(indent: Int): String {
|
||||
val elseBlockVar = elseBlock
|
||||
val ifThen = "if (${condition.toCode(0)}) {\n".withIndent(indent) +
|
||||
thenBlock.toCode(indent + 1) +
|
||||
"}".withIndent(indent)
|
||||
if (elseBlockVar != null) {
|
||||
return ifThen + " else { \n" +
|
||||
elseBlockVar.toCode(indent + 1) +
|
||||
"}".withIndent(indent)
|
||||
}
|
||||
|
||||
return ifThen
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.CodeBlock
|
||||
import com.intellij.debugger.streams.trace.dsl.Expression
|
||||
import com.intellij.debugger.streams.trace.dsl.Lambda
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.TextExpression
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinLambda(override val variableName: String, override val body: CodeBlock) : Lambda {
|
||||
override fun call(callName: String, vararg args: Expression): Expression = TextExpression("(${toCode()})").call(callName, *args)
|
||||
|
||||
override fun toCode(indent: Int): String =
|
||||
"{ $variableName -> \n".withIndent(indent) +
|
||||
body.toCode(indent + 1) +
|
||||
"}"
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.kotlin.trace.dsl.KotlinCodeBlock
|
||||
import com.intellij.debugger.streams.trace.dsl.Expression
|
||||
import com.intellij.debugger.streams.trace.dsl.LambdaBody
|
||||
import com.intellij.debugger.streams.trace.dsl.StatementFactory
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinLambdaBody(override val lambdaArg: Expression, statementFactory: StatementFactory)
|
||||
: KotlinCodeBlock(statementFactory), LambdaBody
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.kotlin.trace.dsl.KotlinVariableDeclaration
|
||||
import com.intellij.debugger.streams.trace.dsl.Expression
|
||||
import com.intellij.debugger.streams.trace.dsl.ListVariable
|
||||
import com.intellij.debugger.streams.trace.dsl.VariableDeclaration
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.VariableImpl
|
||||
import com.intellij.debugger.streams.trace.impl.handler.type.ListType
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinListVariable(override val type: ListType, name: String)
|
||||
: VariableImpl(type, name), ListVariable {
|
||||
override fun get(index: Expression): Expression = call("get", index)
|
||||
override fun set(index: Expression, newValue: Expression): Expression = call("set", index, newValue)
|
||||
override fun add(element: Expression): Expression = call("add", element)
|
||||
|
||||
override fun contains(element: Expression): Expression = call("contains", element)
|
||||
|
||||
override fun size(): Expression = property("size")
|
||||
|
||||
override fun defaultDeclaration(): VariableDeclaration =
|
||||
KotlinVariableDeclaration(this, false, type.defaultValue)
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.Expression
|
||||
import com.intellij.debugger.streams.trace.dsl.Lambda
|
||||
import com.intellij.debugger.streams.trace.dsl.VariableDeclaration
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.TextExpression
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.common.MapVariableBase
|
||||
import com.intellij.debugger.streams.trace.impl.handler.type.MapType
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinMapVariable(type: MapType, name: String) : MapVariableBase(type, name) {
|
||||
override fun get(key: Expression): Expression = TextExpression("${toCode()}[${key.toCode()}]")
|
||||
|
||||
override fun set(key: Expression, newValue: Expression): Expression =
|
||||
TextExpression("${toCode()}[${key.toCode()}] = ${newValue.toCode()}")
|
||||
|
||||
override fun contains(key: Expression): Expression = TextExpression("${key.toCode()} in ${toCode()}")
|
||||
|
||||
override fun size(): Expression = TextExpression("${toCode()}.size")
|
||||
|
||||
override fun keys(): Expression = TextExpression("${toCode()}.keys")
|
||||
|
||||
override fun computeIfAbsent(key: Expression, supplier: Lambda): Expression =
|
||||
TextExpression("${toCode()}.getOrPut(${key.toCode()}, ${supplier.toCode()}")
|
||||
|
||||
override fun defaultDeclaration(isMutable: Boolean): VariableDeclaration =
|
||||
KotlinVariableDeclaration(this, false, type.defaultValue)
|
||||
}
|
||||
+113
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.*
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.AssignmentStatement
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.TextExpression
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.VariableImpl
|
||||
import com.intellij.debugger.streams.trace.impl.handler.PeekCall
|
||||
import com.intellij.debugger.streams.trace.impl.handler.type.GenericType
|
||||
import com.intellij.debugger.streams.wrapper.IntermediateStreamCall
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinStatementFactory : StatementFactory {
|
||||
override fun createNewListExpression(elementType: GenericType, vararg args: Expression): Expression =
|
||||
TextExpression("kotlin.collections.mutableListOf<${elementType.genericTypeName}>(${StatementFactory.commaSeparate(*args)})")
|
||||
|
||||
override fun createListVariable(elementType: GenericType, name: String): ListVariable = KotlinListVariable(types.list(elementType), name)
|
||||
|
||||
override fun not(expression: Expression): Expression = TextExpression("!${expression.toCode()}")
|
||||
|
||||
override val types: Types = KotlinTypes
|
||||
|
||||
override fun createEmptyCompositeCodeBlock(): CompositeCodeBlock = KotlinCodeBlock(this)
|
||||
|
||||
override fun createEmptyCodeBlock(): CodeBlock = KotlinCodeBlock(this)
|
||||
|
||||
override fun createVariableDeclaration(variable: Variable, isMutable: Boolean): VariableDeclaration =
|
||||
KotlinVariableDeclaration(variable, isMutable)
|
||||
|
||||
override fun createVariableDeclaration(variable: Variable, init: Expression, isMutable: Boolean): VariableDeclaration =
|
||||
KotlinVariableDeclaration(variable, isMutable, init.toCode())
|
||||
|
||||
override fun createEmptyForLoopBody(iterateVariable: Variable): ForLoopBody = KotlinForLoopBody(iterateVariable, this)
|
||||
|
||||
override fun createForEachLoop(iterateVariable: Variable, collection: Expression, loopBody: ForLoopBody): Convertable =
|
||||
KotlinForEachLoop(iterateVariable, collection, loopBody)
|
||||
|
||||
override fun createForLoop(initialization: VariableDeclaration, condition: Expression,
|
||||
afterThought: Expression, loopBody: ForLoopBody): Convertable =
|
||||
KotlinForLoop(initialization, condition, afterThought, loopBody)
|
||||
|
||||
override fun createEmptyLambdaBody(argName: String): LambdaBody = KotlinLambdaBody(TextExpression(argName), this)
|
||||
|
||||
override fun createLambda(argName: String, lambdaBody: LambdaBody): Lambda = KotlinLambda(argName, lambdaBody)
|
||||
|
||||
override fun createVariable(type: GenericType, name: String): Variable = VariableImpl(type, name)
|
||||
|
||||
override fun and(left: Expression, right: Expression): Expression = TextExpression("${left.toCode()} && ${right.toCode()}")
|
||||
|
||||
override fun equals(left: Expression, right: Expression): Expression = TextExpression("${left.toCode()} == ${right.toCode()}")
|
||||
|
||||
override fun same(left: Expression, right: Expression): Expression = TextExpression("${left.toCode()} === ${right.toCode()}")
|
||||
|
||||
override fun createIfBranch(condition: Expression, thenBlock: CodeBlock): IfBranch =
|
||||
KotlinIfBranch(condition, thenBlock, this)
|
||||
|
||||
override fun createAssignmentStatement(variable: Variable, expression: Expression): AssignmentStatement =
|
||||
KotlinAssignmentStatement(variable, expression)
|
||||
|
||||
override fun createMapVariable(keyType: GenericType, valueType: GenericType, name: String, linked: Boolean): MapVariable =
|
||||
KotlinMapVariable(if (linked) types.linkedMap(keyType, valueType) else types.map(keyType, valueType), name)
|
||||
|
||||
override fun createArrayVariable(elementType: GenericType, name: String): ArrayVariable =
|
||||
KotlinArrayVariable(types.array(elementType), name)
|
||||
|
||||
override fun createScope(codeBlock: CodeBlock): Convertable =
|
||||
object : Convertable {
|
||||
override fun toCode(indent: Int): String =
|
||||
"run {\n".withIndent(indent) +
|
||||
codeBlock.toCode(indent + 1) +
|
||||
"}".withIndent(indent)
|
||||
}
|
||||
|
||||
override fun createTryBlock(block: CodeBlock): TryBlock = KotlinTryBlock(block, this)
|
||||
|
||||
override fun createTimeVariableDeclaration(): VariableDeclaration =
|
||||
KotlinVariableDeclaration(createVariable(types.TIME, "time"), false, types.TIME.defaultValue)
|
||||
|
||||
override fun currentTimeExpression(): Expression = TextExpression("time.get()")
|
||||
|
||||
override fun updateCurrentTimeExpression(): Expression = TextExpression("time.incrementAndGet()")
|
||||
|
||||
override fun createNewArrayExpression(elementType: GenericType, vararg args: Expression): Expression {
|
||||
val arguments = args.joinToString { it.toCode() }
|
||||
return when (elementType) {
|
||||
types.INT -> TextExpression("kotlin.intArrayOf($arguments)")
|
||||
types.LONG -> TextExpression("kotlin.longArrayOf($arguments)")
|
||||
types.DOUBLE -> TextExpression("kotlin.doubleArrayOf($arguments)")
|
||||
else -> TextExpression("kotlin.arrayOf<${types.nullable { elementType }.genericTypeName}>($arguments)")
|
||||
}
|
||||
}
|
||||
|
||||
override fun createNewSizedArray(elementType: GenericType, size: Expression): Expression =
|
||||
TextExpression("arrayOfNulls<${elementType.genericTypeName}>(${size.toCode()})")
|
||||
|
||||
override fun createPeekCall(elementsType: GenericType, lambda: String): IntermediateStreamCall = PeekCall(lambda, elementsType)
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.CodeBlock
|
||||
import com.intellij.debugger.streams.trace.dsl.StatementFactory
|
||||
import com.intellij.debugger.streams.trace.dsl.impl.common.TryBlockBase
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinTryBlock(private val block: CodeBlock, statementFactory: StatementFactory) : TryBlockBase(statementFactory) {
|
||||
override fun toCode(indent: Int): String {
|
||||
val descriptor = myCatchDescriptor ?: error("catch block must be specified")
|
||||
return "try {\n".withIndent(indent) +
|
||||
block.toCode(indent + 1) +
|
||||
"} catch(${descriptor.variable.name} : ${descriptor.variable.type.variableTypeName}) {\n" +
|
||||
descriptor.block.toCode(indent + 1) +
|
||||
"}".withIndent(indent)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.Types
|
||||
import com.intellij.debugger.streams.trace.impl.handler.type.*
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
object KotlinTypes : Types {
|
||||
override val ANY: GenericType = ClassTypeImpl("kotlin.Any", "kotlin.Any()")
|
||||
override val INT: GenericType = ClassTypeImpl("kotlin.Int", "0")
|
||||
override val LONG: GenericType = ClassTypeImpl("kotlin.Long", "0L")
|
||||
override val BOOLEAN: GenericType = ClassTypeImpl("kotlin.Boolean", "false")
|
||||
override val DOUBLE: GenericType = ClassTypeImpl("kotlin.Double", "0.")
|
||||
override val STRING: GenericType = ClassTypeImpl("kotlin.String", "\"\"")
|
||||
override val EXCEPTION: GenericType = ClassTypeImpl("kotlin.Throwable", "kotlin.Throwable()")
|
||||
override val VOID: GenericType = ClassTypeImpl("kotlin.Unit", "Unit")
|
||||
|
||||
override val TIME: GenericType = ClassTypeImpl("java.util.concurrent.atomic.AtomicInteger",
|
||||
"java.util.concurrent.atomic.AtomicInteger()")
|
||||
|
||||
override fun list(elementsType: GenericType): ListType =
|
||||
ListTypeImpl(elementsType, { "kotlin.collections.MutableList<$it>" }, "kotlin.collections.mutableListOf()")
|
||||
|
||||
override fun array(elementType: GenericType): ArrayType = when (elementType) {
|
||||
INT -> ArrayTypeImpl(INT, { "kotlin.IntArray" }, { "kotlin.IntArray($it)" })
|
||||
LONG -> ArrayTypeImpl(LONG, { "kotlin.LongArray" }, { "kotlin.LongArray($it)" })
|
||||
DOUBLE -> ArrayTypeImpl(DOUBLE, { "kotlin.DoubleArray" }, { "kotlin.DoubleArray($it)" })
|
||||
else -> ArrayTypeImpl(nullable { elementType }, { "kotlin.Array<$it>" }, { "kotlin.arrayOfNulls($it)" })
|
||||
}
|
||||
|
||||
override fun map(keyType: GenericType, valueType: GenericType): MapType =
|
||||
MapTypeImpl(keyType, valueType,
|
||||
{ keys, values -> "kotlin.collections.MutableMap<$keys, $values>" },
|
||||
"kotlin.collections.mutableMapOf()")
|
||||
|
||||
override fun linkedMap(keyType: GenericType, valueType: GenericType): MapType =
|
||||
MapTypeImpl(keyType, valueType,
|
||||
{ keys, values -> "kotlin.collections.MutableMap<$keys, $values>" },
|
||||
"kotlin.collections.linkedMapOf()")
|
||||
|
||||
override fun nullable(typeSelector: Types.() -> GenericType): GenericType {
|
||||
val type = this.typeSelector()
|
||||
if (type.genericTypeName.last() == '?') return type
|
||||
return when (type) {
|
||||
is ArrayType -> ArrayTypeImpl(type.elementType, { "kotlin.Array<$it>?" }, { type.sizedDeclaration(it) })
|
||||
is ListType -> ListTypeImpl(type.elementType, { "kotlin.collections.MutableList<$it>?" }, type.defaultValue)
|
||||
is MapType -> MapTypeImpl(type.keyType, type.valueType, { keys, values -> "kotlin.collections.MutableMap<$keys, $values>?" },
|
||||
type.defaultValue)
|
||||
else -> ClassTypeImpl(type.genericTypeName + '?', type.defaultValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.dsl
|
||||
|
||||
import com.intellij.debugger.streams.trace.dsl.Variable
|
||||
import com.intellij.debugger.streams.trace.dsl.VariableDeclaration
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinVariableDeclaration(override val variable: Variable,
|
||||
override val isMutable: Boolean,
|
||||
private val init: String = "") : VariableDeclaration {
|
||||
override fun toCode(indent: Int): String {
|
||||
val prefix = if (isMutable) "var" else "val"
|
||||
val suffix = if (init.trim().isEmpty()) "" else " = $init"
|
||||
return "$prefix ${variable.name}: ${variable.type.variableTypeName}$suffix".withIndent(indent)
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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 com.intellij.debugger.streams.kotlin.trace.impl
|
||||
|
||||
import com.intellij.debugger.streams.lib.HandlerFactory
|
||||
import com.intellij.debugger.streams.trace.dsl.Dsl
|
||||
import com.intellij.debugger.streams.trace.impl.TraceExpressionBuilderBase
|
||||
import com.intellij.debugger.streams.wrapper.StreamChain
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
|
||||
/**
|
||||
* @author Vitaliy.Bibaev
|
||||
*/
|
||||
class KotlinTraceExpressionBuilder(dsl: Dsl, handlerFactory: HandlerFactory) : TraceExpressionBuilderBase(dsl, handlerFactory) {
|
||||
private companion object {
|
||||
private val LOG = Logger.getInstance(KotlinTraceExpressionBuilder::class.java)
|
||||
}
|
||||
|
||||
override fun createTraceExpression(chain: StreamChain): String {
|
||||
val expression = super.createTraceExpression(chain)
|
||||
val resultDeclaration = dsl.declaration(dsl.variable(dsl.types.nullable { ANY }, resultVariableName), dsl.nullExpression, true)
|
||||
val result = "${resultDeclaration.toCode()}\n " +
|
||||
"$expression\n" +
|
||||
resultVariableName
|
||||
|
||||
LOG.info("trace expression: \n$result")
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user