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