Add some additional information to psi renderer

1) Trim unused spaces in annotations
2) Rewrote fq name rendering
3) Added annotations to for loop variable
4) Added type arguments render along to type parameters in functions
This commit is contained in:
Ivan Cilcic
2019-08-23 11:46:53 +03:00
committed by Mikhail Glukhikh
parent 8fb2383845
commit fe328f8c7a
36 changed files with 284 additions and 223 deletions
+1
View File
@@ -4,6 +4,7 @@ plugins {
dependencies {
testRuntime(intellijDep())
testCompile(intellijCoreDep()) { includeJars("intellij-core") }
testCompile(project(":compiler:visualizer:render-psi"))
testCompile(project(":compiler:visualizer:render-fir"))
@@ -12,9 +12,9 @@ object Annotator {
private const val verticalLine = ""
private const val comment = "//"
class AnnotationInfo(val text: String, val range: TextRange)
data class AnnotationInfo(val text: String, val range: TextRange)
private fun putAnnotationToLines(annotations: List<AnnotationInfo>, lineStart: Int, lineSize: Int): List<StringBuilder> {
private fun putAnnotationToLines(annotations: List<AnnotationInfo>, lineStart: Int, lineSize: Int): List<String> {
val annotationLines = mutableListOf(StringBuilder(comment + " ".repeat(lineSize - comment.length)))
val levelToOffset = mutableMapOf(0 to 0)
@@ -40,10 +40,10 @@ object Annotator {
}
}
return annotationLines
return annotationLines.map { it.trim().toString() }
}
fun annotate(text: String, annotation: List<AnnotationInfo>): List<String> {
fun annotate(text: String, annotation: Set<AnnotationInfo>): List<String> {
val lines = text.lines()
val resultLines = mutableListOf<String>()
var lineStartOffset = 0
@@ -55,7 +55,7 @@ object Annotator {
if (annotations.isNotEmpty()) {
val annotationLines = putAnnotationToLines(annotations, lineStartOffset, line.length)
annotationLines.asReversed().mapTo(resultLines) { it.toString() }
resultLines += annotationLines.asReversed()
}
resultLines.add(line)
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.compiler.visualizer.Annotator.annotate
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.descriptors.impl.LazyPackageViewDescriptorImpl
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getChildOfType
@@ -24,6 +25,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.bindingContextUtil.getAbbreviatedTypeOrType
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue
@@ -34,14 +36,14 @@ import org.jetbrains.kotlin.types.*
import java.util.ArrayList
class PsiRenderer(private val file: KtFile, analysisResult: AnalysisResult) : BaseRenderer {
val bindingContext = analysisResult.bindingContext
private val annotations = mutableListOf<Annotator.AnnotationInfo>()
private val bindingContext = analysisResult.bindingContext
private val annotations = mutableSetOf<Annotator.AnnotationInfo>()
private val filePackage = file.packageFqName.toString().replace(".", "/")
private val argumentsLabel = "<PLACE-FOR-ARGUMENTS>"
val descriptorRenderer = PsiDescriptorRenderer()
private val unnecessaryData = mapOf(
"kotlin." to "",
"kotlin/" to ""
)
@@ -98,6 +100,13 @@ class PsiRenderer(private val file: KtFile, analysisResult: AnalysisResult) : Ba
//don't resolve this expression
}
override fun visitNamedFunction(function: KtNamedFunction) {
if (function.bodyExpression != null && function.equalsToken != null) {
addAnnotation(renderType(function.bodyExpression!!.getType(bindingContext)), function.equalsToken!!)
}
super.visitNamedFunction(function)
}
private fun renderVariableType(variable: KtVariableDeclaration) {
val descriptor = bindingContext[VARIABLE, variable]
addAnnotation(renderType(descriptor), variable.nameIdentifier!!)
@@ -110,6 +119,13 @@ class PsiRenderer(private val file: KtFile, analysisResult: AnalysisResult) : Ba
override fun visitDestructuringDeclarationEntry(multiDeclarationEntry: KtDestructuringDeclarationEntry) =
renderVariableType(multiDeclarationEntry)
override fun visitParameter(parameter: KtParameter) {
if ((parameter.isLoopParameter && parameter.destructuringDeclaration == null) || parameter.ownerFunction is KtPropertyAccessor) {
addAnnotation(renderType(bindingContext[VALUE_PARAMETER, parameter]?.returnType), parameter.nameIdentifier!!)
}
super.visitParameter(parameter)
}
override fun visitTypeReference(typeReference: KtTypeReference) {
if (typeReference.text.isNotEmpty()) {
val hasResolvedCall = with(object : KtVisitorVoid() {
@@ -148,7 +164,10 @@ class PsiRenderer(private val file: KtFile, analysisResult: AnalysisResult) : Ba
}
val descriptor = resolvedCall.resultingDescriptor
val annotation = descriptorRenderer.render(descriptor)
val typeArguments = if (resolvedCall.typeArguments.isNotEmpty()) {
buildString { resolvedCall.typeArguments.values.joinTo(this, ", ", "<", ">") { renderType(it) } }
} else ""
val annotation = descriptorRenderer.render(descriptor).replace(argumentsLabel, typeArguments)
addAnnotation(annotation, expression, deleteDuplicate = false)
fun addReceiverAnnotation(receiver: ReceiverValue?, receiverKind: ExplicitReceiverKind) {
@@ -214,16 +233,15 @@ class PsiRenderer(private val file: KtFile, analysisResult: AnalysisResult) : Ba
}
}
inner class PsiDescriptorRenderer : DeclarationDescriptorVisitor<Unit, StringBuilder> {
inner class PsiDescriptorRenderer(
private val needToRenderSpecialFun: Boolean = false
) : DeclarationDescriptorVisitor<Unit, StringBuilder> {
private val typeRenderer: DescriptorRenderer = DescriptorRenderer.withOptions {
withDefinedIn = false
modifiers = emptySet()
classifierNamePolicy = object : ClassifierNamePolicy {
override fun renderClassifier(classifier: ClassifierDescriptor, renderer: DescriptorRenderer): String {
val fqName = (if (classifier is TypeParameterDescriptor) renderer.renderName(classifier.name, false)
else renderer.renderFqName(DescriptorUtils.getFqName(classifier))).replace(".", "/")
return removeCurrentFilePackage(fqName)
return renderFqName(classifier)
}
}
includeAdditionalModifiers = false
@@ -238,7 +256,7 @@ class PsiRenderer(private val file: KtFile, analysisResult: AnalysisResult) : Ba
fun render(declarationDescriptor: DeclarationDescriptor): String {
if (declarationDescriptor is CallableDescriptor && declarationDescriptor.isSpecial()) {
return this.renderSpecialFunction(declarationDescriptor)
return if (needToRenderSpecialFun) this.renderSpecialFunction(declarationDescriptor) else ""
}
return buildString {
declarationDescriptor.accept(this@PsiDescriptorRenderer, this)
@@ -258,25 +276,28 @@ class PsiRenderer(private val file: KtFile, analysisResult: AnalysisResult) : Ba
}
private fun renderFqName(descriptor: DeclarationDescriptor, removeCurrentPackage: Boolean = true): String {
val fqName = generateSequence(descriptor) { it.containingDeclaration }
.fold("") { acc, desc ->
val name = when (desc) {
is LazyPackageDescriptor -> desc.fqName.toString().replace(".", "/")
else -> desc.name.asString()
}
val separator = when {
acc.isEmpty() -> ""
else -> if (desc is PackageFragmentDescriptor || desc is PackageViewDescriptor) "/" else "."
}
if (name == FqName.ROOT.toString() || desc is ModuleDescriptor) {
return@fold acc
}
return@fold "$name$separator$acc"
}
if (descriptor is TypeParameterDescriptor) return descriptor.name.render()
val fqName = qualifierNameCombine(descriptor)
return if (removeCurrentPackage) removeCurrentFilePackage(fqName) else fqName
}
private fun qualifierNameCombine(descriptor: DeclarationDescriptor): String {
val nameString = descriptor.name.render()
if (nameString == FqName.ROOT.toString()) return ""
val containingDeclaration = descriptor.containingDeclaration
val qualifier = qualifierName(containingDeclaration)
val separator =
if (containingDeclaration is PackageFragmentDescriptor || containingDeclaration is PackageViewDescriptor) "/" else "."
return if (qualifier != "") qualifier + separator + nameString else nameString
}
private fun qualifierName(descriptor: DeclarationDescriptor?): String = when (descriptor) {
is ModuleDescriptor, null -> ""
is PackageFragmentDescriptor, is PackageViewDescriptor -> descriptor.fqNameUnsafe.render().replace(".", "/")
else -> qualifierNameCombine(descriptor)
}
private fun removeCurrentFilePackage(fqName: String): String {
return if (fqName.startsWith(filePackage) && !fqName.substring(filePackage.length + 1).contains("/")) {
fqName.replaceFirst("$filePackage/", "")
@@ -367,6 +388,9 @@ class PsiRenderer(private val file: KtFile, analysisResult: AnalysisResult) : Ba
//render name
data.append(renderName(function, receiver != null))
//render type arguments
data.append(argumentsLabel)
//render value parameters
visitValueParameters(function.valueParameters, data)
@@ -10,4 +10,4 @@ class B : TA() {
// constructor A.Nested()
// │
class NestedInB : Nested()
}
}
@@ -13,4 +13,4 @@ interface Test {
// │ │ │ class C<T, S> collections/List<*>
// │ │ │ │ │
val x: a.b.C<out CharSequence, *>.D<in List<*>, *>
}
}
@@ -5,7 +5,8 @@ open class Base<T>(val x: T)
// │ │
class Derived<T : Any>(x: T) : Base<T>(x)
// constructor Derived<T : Any>(T)
// │ create.x: T
//
// Derived<T>
// │ constructor Derived<T : Any>(T)
// create.x: T
// │ │ │
fun <T : Any> create(x: T): Derived<T> = Derived(x)
@@ -41,7 +41,7 @@ enum class Planet(val m: Double, internal val r: Double) {
}
};
// val (Planet/Companion).G: Double
// val (Planet.Companion).G: Double
// │ fun (Double).times(Double): Double
// │ │ val (Planet).m: Double
// │ │ │ fun (Double).div(Double): Double
@@ -59,4 +59,4 @@ enum class Planet(val m: Double, internal val r: Double) {
// │ │
const val G = 6.67e-11
}
}
}
@@ -7,20 +7,22 @@ object O2 : Some
enum class SomeEnum(val x: Some) {
// constructor SomeEnum(Some)
// │object O1: Some
// ││
// ││
FIRST(O1) {
// Boolean
//
// Boolean
// │ Boolean
// │ │
override fun check(y: Some): Boolean = true
},
// constructor SomeEnum(Some)
// │object O2: Some
// ││
// ││
SECOND(O2) {
// SomeEnum.SECOND.check.y: Some
// │ fun (Any).equals(Any?): Boolean
// │ │ object O2: Some
// │ │
// Boolean
// │ SomeEnum.SECOND.check.y: Some
// │ │ fun (Any).equals(Any?): Boolean
// │ │ object O2: Some
// │ │ │ │
override fun check(y: Some): Boolean = y == O2
};
@@ -8,6 +8,8 @@ expect val x: Int
actual class MyClass
// String
// │
actual fun foo() = "Hello"
// Int Int
@@ -1,5 +1,6 @@
// fun ((T) -> Unit).invoke(T): Unit
//
// Unit
// │ fun ((T) -> Unit).invoke(T): Unit
// │ │
fun <T> simpleRun(f: (T) -> Unit): Unit = f()
// collections/List<T>
@@ -8,8 +9,8 @@ fun <T, R> List<T>.simpleMap(f: (T) -> R): R {
}
// simpleWith.t: T
// │ fun T.invoke(): Unit
// │ │
// Unit
// │ simpleWith.t: T
// │ │ fun T.invoke(): Unit
// │ │ │
fun <T> simpleWith(t: T, f: T.() -> Unit): Unit = t.f()
@@ -1,7 +1,9 @@
interface Any
// T?
// │
inline fun <reified T : Any> Any.safeAs(): T? = this as? T
abstract class Summator {
abstract fun <T> plus(first: T, second: T): T
}
}
@@ -1,7 +1,8 @@
// fun TODO(): Nothing
//
// Nothing
// │ fun TODO(): Nothing
// │ │
fun <T> genericFoo(): T = TODO()
// T fun <T> genericFoo(): T
// │ │
// T fun <T> genericFoo<T>(): T
// │ │
val <T> T.generic: T get() = genericFoo()
@@ -3,10 +3,10 @@ abstract class Base(val s: String)
class Outer {
// constructor Base(String)
// │ Outer.Derived.<init>.s: String
// │ │
// │ │
class Derived(s: String) : Base(s)
// constructor Base(String)
// │
// │
object Obj : Base("")
}
@@ -17,21 +17,23 @@ class SomeClass : SomeInterface {
// │ │ SomeClass.foo.x: Int
// │ │ │ fun (String).plus(Any?): String
// │ │ │ │ val (SomeClass).baz: Int
// │ │ │ │ │
// │ │ │ │ │
return y + x + baz
}
// Boolean
// │
// Boolean
// │
override var bar: Boolean
// Boolean
// │
// │
get() = true
// Boolean
// │
set(value) {}
// Double
// │
// Double
// │
lateinit var fau: Double
}
inline class InlineClass
inline class InlineClass
@@ -4,4 +4,4 @@ typealias C = B
// C /* = B */
// │
class D : C
class D : C
@@ -13,13 +13,13 @@ abstract class My<T : Some> {
// [ERROR : T]
// │ class My<T : Some>
// │ │
// │ │
abstract val y: My.T
// [ERROR : T]
// │ package test
// │ │ class My<T : Some>
// │ │ │
// │ │ │
abstract val z: test.My.T
// [ERROR : T]
@@ -10,11 +10,14 @@ typealias AnyList = List<*>
abstract class AbstractList<out T : Any> : List<T>
// constructor AbstractList<T : Any>()
// │
// │
class SomeList : AbstractList<Int>() {
// Int
//
// Int
// │ Int
// │ │
override fun get(index: Int): Int = 42
// SomeList
// │
override fun concat(other: List<Int>): List<Int> = this
}
@@ -1,23 +1,25 @@
// Int Int
// │ │
val p = 0
// Int
//
// Int
// │ Int
// │ │
fun foo() = 1
class Wrapper(val v: IntArray)
// test.a: IntArray
// │ Int
// │ │ fun (Int).plus(Int): Int
// │ │ │ test.a: IntArray
// │ │ │ │ val p: Int
// │ │ │ │ │ fun (Int).plus(Int): Int
// │ │ │ │ │ │ test.a: IntArray
// │ │ │ │ │ │ │ fun foo(): Int
// │ │ │ │ │ │ │ │ fun (Int).plus(Int): Int
// │ │ │ │ │ │ │ │ │ test.w: Wrapper
// │ │ │ │ │ │ │ │ │ │ val (Wrapper).v: IntArray
// │ │ │ │ │ │ │ │ │ │ │ Int
// │ │ │ │ │ │ │ │ │ │ │
// Int
// │ test.a: IntArray
// │ │ Int
// │ │ fun (Int).plus(Int): Int
// │ │ │ test.a: IntArray
// │ │ │ │ val p: Int
// │ │ │ │ │ fun (Int).plus(Int): Int
// │ │ │ │ │ │ test.a: IntArray
// │ │ │ │ │ │ │ fun foo(): Int
// │ │ │ │ │ │ │ │ fun (Int).plus(Int): Int
// │ │ │ │ │ │ │ │ │ test.w: Wrapper
// │ │ │ │ │ │ │ │ │ │ val (Wrapper).v: IntArray
// │ │ │ │ │ │ │ │ │ │ │ Int
// │ │ │ │ │ │ │ │ │ │ │ │ │
fun test(a: IntArray, w: Wrapper) = a[0] + a[p] + a[foo()] + w.v[0]
@@ -12,8 +12,9 @@ fun test() {
x[1] = 0
}
// Int
//
// Int
// │ Int
// │ │
fun foo() = 1
fun test2() {
@@ -1,9 +1,9 @@
// foo.a: Int
// │ fun (Int).compareTo(Int): Int
// │ │ foo.b: Int
// │ │ │ foo.a: Int
// Int │ │ │ │ foo.b: Int
// │ │ │ │ │ │
// Int │ │ │ foo.a: Int
// Int │ │ │ │ foo.b: Int
// │ │ │ │ │ │
fun foo(a: Int, b: Int) = if (a > b) a else b
fun bar(a: Double, b: Double): Double {
@@ -43,13 +43,13 @@ fun baz(a: Long, b: Long): Long {
a > b -> {
// fun io/println(Long): Unit
// │ baz.a: Long
// │ │
// │ │
println(a)
// baz.a: Long
// │
return a
}
// Nothing
// Nothing
// │ baz.b: Long
// │ │
else -> return b
@@ -57,34 +57,34 @@ fun baz(a: Long, b: Long): Long {
}
fun grade(g: Int): String {
// String
// String
// │ grade.g: Int
// │ │
// │ │
return when (g) {
// Int
// │ Int String
// │ │ │
// Int
// │ Int String
// │ │ │
6, 7 -> "Outstanding"
// Int String
// │ │
// Int String
// │ │
5 -> "Excellent"
// Int String
// │ │
// │ │
4 -> "Good"
// Int String
// │ │
// Int String
// │ │
3 -> "Mediocre"
// fun (ranges/IntRange).contains(Int): Boolean
// │ Int
// │ Int
// │ │fun (Int).rangeTo(Int): ranges/IntRange
// │ ││ Int String
// │ ││ │ │
// │ ││ │ │
in 1..2 -> "Fail"
// String
// │
// String
// │
is Number -> "Number"
// String
// │
// String
// │
else -> "Unknown"
}
}
+27 -21
View File
@@ -1,38 +1,44 @@
// distance.x: Int
// │ fun (Int).plus(Int): Int
// │ distance.y: Int
// │ │
// Int
// │ distance.x: Int
// fun (Int).plus(Int): Int
// │ │ distance.y: Int
// │ │ │ │
infix fun distance(x: Int, y: Int) = x + y
// Int
// │ [ERROR: not resolved]
// │ │ Int
// │ │
// [ERROR: unknown type]
// │ Int
// │ │ [ERROR: not resolved]
// │ │ Int
// │ │ │ │
fun test(): Int = 3 distance 4
// fun distance(Int, Int): Int
// Int
// Int
// │ │
// Int
// │ fun distance(Int, Int): Int
// │ Int
// │ │ Int
// │ │ │ │
fun testRegular(): Int = distance(3, 4)
class My(var x: Int) {
// var (My).x: Int
//
// Int
// │ var (My).x: Int
// │ │
operator fun invoke() = x
fun foo() {}
// constructor My(Int)
// │ var (My).x: Int
//
// My
// │ constructor My(Int)
// var (My).x: Int
// │ │ │
fun copy() = My(x)
}
// constructor My(Int)
// fun (My).invoke(): Int
// │ Int
//
// Int
// │ constructor My(Int)
// │ fun (My).invoke(): Int
// Int
// │ │ │
fun testInvoke(): Int = My(13)()
fun testQualified(first: My, second: My?) {
+6 -6
View File
@@ -1,8 +1,8 @@
fun foo() {
// Int
// │fun (Int).rangeTo(Int): ranges/IntRange
// ││ Int
// ││ │
// Int ││ Int
// ││ │
for (i in 1..10) {
// fun io/println(Int): Unit
// │ val foo.i: Int
@@ -17,8 +17,8 @@ fun bar(list: List<String>) {
// bar.list: collections/List<String>
// │ fun (collections/List<String>).subList(Int, Int): collections/List<String>
// │ │ Int
// │ │ │ Int
// │ │ │ │
// String │ │ │ Int
// │ │ │ │
for (element in list.subList(0, 10)) {
// fun io/println(Any?): Unit
// │ val bar.element: String
@@ -28,8 +28,8 @@ fun bar(list: List<String>) {
// bar.list: collections/List<String>
// │ fun (collections/List<String>).subList(Int, Int): collections/List<String>
// │ │ fun io/println(Any?): Unit
// │ │ Int Int │ val bar.element: String
// │ │ │ │ │ │
// String │ │ Int Int │ val bar.element: String
// │ │ │ │ │ │
for (element in list.subList(10, 20)) println(element)
}
@@ -1,18 +1,19 @@
// Nothing?
//
// Nothing?
// │ Nothing?
// │ │
fun <T> nullableValue(): T? = null
fun test() {
// Int?
// │ fun <T> nullableValue(): Int?
// │ fun <T> nullableValue<Int>(): Int?
// │ │
val n = nullableValue<Int>()
// Double?
// │ fun <T> nullableValue(): Double?
// │ fun <T> nullableValue<Double>(): Double?
// │ │
val x = nullableValue<Double>()
// String?
// │ fun <T> nullableValue(): String?
// │ fun <T> nullableValue<String>(): String?
// │ │
val s = nullableValue<String>()
}
+3 -2
View File
@@ -1,5 +1,6 @@
// collections/Collection<Int>
// │
// │ Boolean
// │ │
fun foo(x: Int, y: Int, c: Collection<Int>) =
// foo.x: Int
// │ fun (collections/Collection<Int>).contains(Int): Boolean
@@ -8,4 +9,4 @@ fun foo(x: Int, y: Int, c: Collection<Int>) =
// │ │ │ │ fun (collections/Collection<Int>).contains(Int): Boolean
// │ │ │ │ │ foo.c: collections/Collection<Int>
// │ │ │ │ │ │
x in c && y !in c
x in c && y !in c
@@ -9,4 +9,4 @@ class WithInit(x: Int) {
// │ │
this.x = x
}
}
}
+24 -23
View File
@@ -1,15 +1,16 @@
data class Tuple(val x: Int, val y: Int)
// fun ((Tuple) -> Int).invoke(Tuple): Int
// │ constructor Tuple(Int, Int)
// │ │ Int
// │ │ Int
// │ │ │
// Int
// │ fun ((Tuple) -> Int).invoke(Tuple): Int
// │ │ constructor Tuple(Int, Int)
// │ │ Int
// │ │ │ Int
// │ │ │ │ │
inline fun use(f: (Tuple) -> Int) = f(Tuple(1, 2))
fun foo(): Int {
// (Tuple) -> Int
// │
// (Tuple) -> Int
// │
val l1 = { t: Tuple ->
// foo.<anonymous>.t: Tuple
// Int │ val (Tuple).x: Int
@@ -29,13 +30,13 @@ fun foo(): Int {
// │ val foo.<anonymous>.x: Int
// │ Int │ fun (Int).plus(Int): Int
// │ │ Int │ │ val foo.<anonymous>.y: Int
// │ │ │ │ │ │
// │ │ │ │ │ │
use { (x, y) -> x + y }
// fun use((Tuple) -> Int): Int
// │
// │
return use {
// Unit
// Unit
// │ foo.<anonymous>.it: Tuple
// │ │ val (Tuple).x: Int
// │ │ │ fun (Any).equals(Any?): Boolean
@@ -51,9 +52,9 @@ fun foo(): Int {
fun bar(): Int {
// fun use((Tuple) -> Int): Int
// │
// │
return use lambda@{
// Unit
// Unit
// │ bar.<anonymous>.it: Tuple
// │ │ val (Tuple).x: Int
// │ │ │ fun (Any).equals(Any?): Boolean
@@ -71,24 +72,24 @@ fun bar(): Int {
// │
fun test(list: List<Int>) {
// collections/MutableMap<Int, String>
// │ fun <K, V> collections/mutableMapOf(): collections/MutableMap<Int, String>
// │ │
// │ fun <K, V> collections/mutableMapOf<Int, String>(): collections/MutableMap<Int, String>
// │ │
val map = mutableMapOf<Int, String>()
// test.list: collections/List<Int>
// │ fun <T> collections/Iterable<Int>.forEach((Int) -> Unit): Unit
// │ fun <T> collections/Iterable<Int>.forEach<Int>((Int) -> Unit): Unit
// │ │ val test.map: collections/MutableMap<Int, String>
// │ │ │ fun <K, V> collections/MutableMap<Int, String>.getOrPut(Int, () -> String): String
// │ │ │ fun <K, V> collections/MutableMap<Int, String>.getOrPut<Int, String>(Int, () -> String): String
// │ │ │ │ test.<anonymous>.it: Int
// │ │ │ │ │ fun <T> collections/mutableListOf(): collections/MutableList<???>
// │ │ │ │ │ fun <T> collections/mutableListOf<???>(): collections/MutableList<???>
// │ │ │ │ │ │ fun (String).plus(Any?): String
// │ │ │ │ │ │ │
// │ │ │ │ │ │ │
list.forEach { map.getOrPut(it, { mutableListOf() }) += "" }
}
// () -> Unit
// │
// () -> Unit
// │
val simple = { }
// () -> Int Int
// │ │
val another = { 42 }
// () -> Int Int
// │ │
val another = { 42 }
+16 -13
View File
@@ -1,14 +1,15 @@
fun withLocals(p: Int): Int {
class Local(val pp: Int) {
// val (withLocals/Local).pp: Int
// │ fun (Int).minus(Int): Int
// │ withLocals.p: Int
// │ │
// Int
// │ val (withLocals.Local).pp: Int
// fun (Int).minus(Int): Int
// │ │ withLocals.p: Int
// │ │ │ │
fun diff() = pp - p
}
// constructor withLocals.Local(Int)
// Int │ Int fun (withLocals/Local).diff(): Int
// Int │ Int fun (withLocals.Local).diff(): Int
// │ │ │ │
val x = Local(42).diff()
@@ -26,10 +27,11 @@ fun withLocals(p: Int): Int {
// Int constructor Any()
// │ │
val code = (object : Any() {
// fun (Any).hashCode(): Int
//
// Int
// │ fun (Any).hashCode(): Int
// │ │
fun foo() = hashCode()
// fun (withLocals/<no name provided>).foo(): Int
// fun (withLocals.<no name provided>).foo(): Int
// │
}).foo()
@@ -37,10 +39,11 @@ fun withLocals(p: Int): Int {
// │ val withLocals.code: Int
// │ │ constructor withLocals.Local(Int)
// │ │ │ Int
// │ │ │ │ fun (withLocals/Local).diff(): Int
// │ │ │ │ │ withLocals.<no name provided>.x: Int
// │ │ │ │ │ │ fun (Int).plus(Int): Int
// │ │ │ │ │ │ │ withLocals.<no name provided>.y: Int
// │ │ │ │ │ │ │ │
// │ │ │ │ fun (withLocals.Local).diff(): Int
// │ │ │ │ │ Int
// │ │ │ │ │ │ withLocals.<no name provided>.x: Int
// │ │ │ │ │ │ │ fun (Int).plus(Int): Int
// │ │ │ │ │ │ │ │ withLocals.<no name provided>.y: Int
// │ │ │ │ │ │ │ │ │
return sum(code, Local(1).diff(), fun(x: Int, y: Int) = x + y)
}
@@ -27,18 +27,18 @@ fun simple() {
// collections/List<String>
// │
fun List<String>.modify() {
// fun <T> collections/Collection<String>.plus(String): collections/List<String>
// fun <T> collections/Collection<String>.plus<String>(String): collections/List<String>
// │
this += "Alpha"
// fun <T> collections/Collection<String>.plus(String): collections/List<String>
// fun <T> collections/Collection<String>.plus<String>(String): collections/List<String>
// │
this += "Omega"
}
fun Any.modify() {
// collections/List<Int>
// │ fun <T> collections/Collection<Int>.plus(Int): collections/List<Int>
// │ fun <T> collections/Collection<Int>.plus<Int>(Int): collections/List<Int>
// │ │ Int
// │ │ │
(this as List<Int>) += 42
}
}
@@ -1,10 +1,10 @@
// orFourtyTwo.arg: Int?
// │ fun ?: (Int?, Int): Int
// Int
//
// Int
// │ orFourtyTwo.arg: Int?
// Int
//
fun orFourtyTwo(arg: Int?) = arg ?: 42
// bang.arg: Int?
// │ fun !! (Int?): Int
//
fun bang(arg: Int?) = arg!!
// Int
// │ bang.arg: Int?
//
fun bang(arg: Int?) = arg!!
@@ -22,4 +22,4 @@ class C : A, B {
// │
super<B>.foo()
}
}
}
@@ -1,6 +1,7 @@
class Some {
// Int
//
// Int
// │ Int
// │ │
fun foo(): Int = 1
fun bar(): Int {
@@ -23,12 +24,12 @@ class Some {
}
}
// fun (Some).bar(): Int
//
// Int fun (Some).bar(): Int
//
fun Some.extension() = this.bar()
fun test(some: Some): Int {
// fun <T, R> with(Some, Some.() -> Int): Int
// fun <T, R> with<Some, Int>(Some, Some.() -> Int): Int
// │ test.some: Some
// │ │ with@0
// │ │ │
@@ -39,4 +40,4 @@ fun test(some: Some): Int {
// │ │ │
this.foo() + this@with.extension()
}
}
}
@@ -1,14 +1,18 @@
interface IThing
// test1.x: Any
//
// Boolean
// │ test1.x: Any
// │ │
fun test1(x: Any) = x is IThing
// test2.x: Any
//
// Boolean
// │ test2.x: Any
// │ │
fun test2(x: Any) = x !is IThing
// test3.x: Any
//
// IThing
// │ test3.x: Any
// │ │
fun test3(x: Any) = x as IThing
// test4.x: Any
//
// IThing?
// │ test4.x: Any
// │ │
fun test4(x: Any) = x as? IThing
@@ -13,7 +13,7 @@ class B {
}
fun foo(a: Int, b: Int): Int {
// fun <T, R> with(A, A.() -> Int): Int
// fun <T, R> with<A, Int>(A, A.() -> Int): Int
// │ constructor A()
// │ │ with@0
// │ │ │
@@ -23,7 +23,7 @@ fun foo(a: Int, b: Int): Int {
// │
aProp
// fun <T, R> with(B, B.() -> Int): Int
// fun <T, R> with<B, Int>(B, B.() -> Int): Int
// │ constructor B()
// │ │ with@1
// │ │ │
@@ -43,7 +43,7 @@ fun foo(a: Int, b: Int): Int {
}
}
// fun <T, R> with(A, A.() -> Int): Int
// fun <T, R> with<A, Int>(A, A.() -> Int): Int
// │ constructor A()
// │ │ with@0
// │ │ │
@@ -53,7 +53,7 @@ fun foo(a: Int, b: Int): Int {
// │
aProp
// fun <T, R> with(B, B.() -> Int): Int
// fun <T, R> with<B, Int>(B, B.() -> Int): Int
// │ constructor B()
// │ │ with@1
// │ │ │
@@ -68,7 +68,7 @@ fun foo(a: Int, b: Int): Int {
bProp
}
// fun <T, R> with(B, B.() -> Int): Int
// fun <T, R> with<B, Int>(B, B.() -> Int): Int
// │ constructor B()
// │ │ with@1
// │ │ │
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.test
// collections/List<Int>
// │ fun <T> collections/listOf(vararg Int): collections/List<Int>
// │ fun <T> collections/listOf<Int>(vararg Int): collections/List<Int>
// │ │ Int
// │ │ │ Int
// │ │ │ │ Int
@@ -9,7 +9,7 @@ package org.jetbrains.kotlin.test
val listOfInt = listOf(1, 2, 3)
// java/util/ArrayList<Int>
// │ package java
// │ │ constructor util/ArrayList<E : Any!>()
// │ │ constructor java/util/ArrayList<E : Any!>()
// │ │ │
val javaList = java.util.ArrayList<Int>()
@@ -17,8 +17,8 @@ val javaList = java.util.ArrayList<Int>()
// │ package java/util
// │ │
fun move(): java.util.ArrayList<Int> {
// val listOfInt: collections/List<Int>
//
// Int val listOfInt: collections/List<Int>
//
for (elem in listOfInt) {
// val javaList: java/util/ArrayList<Int>
// │ fun (java/util/ArrayList<Int>).add(Int): Boolean
@@ -45,8 +45,8 @@ var withSetter
// val p4: String
// │
get() = p4
// <set-withSetter>.value: String
//
// String <set-withSetter>.value: String
//
set(value) = value
// Boolean
@@ -62,6 +62,8 @@ val withGetter2: Boolean
// │
var withSetter2: String
get() = "1"
// String
// │
set(value) {
// var <set-withSetter2>.field: String
// │ <set-withSetter2>.value: String
@@ -4,11 +4,11 @@ fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
where T : CharSequence,
T : Comparable<T> {
// copyWhenGreater.list: collections/List<T>
// │ fun <T> collections/Iterable<T>.filter((T) -> Boolean): collections/List<T>
// │ fun <T> collections/Iterable<T>.filter<T>((T) -> Boolean): collections/List<T>
// │ │ copyWhenGreater.<anonymous>.it: T
// │ │ │ fun (Comparable<T>).compareTo(T): Int
// │ │ │ │ copyWhenGreater.threshold: T
// │ │ │ │ │ fun <T, R> collections/Iterable<T>.map((T) -> String): collections/List<String>
// │ │ │ │ │ fun <T, R> collections/Iterable<T>.map<T, String>((T) -> String): collections/List<String>
// │ │ │ │ │ │ copyWhenGreater.<anonymous>.it: T
// │ │ │ │ │ │ │ fun (Any).toString(): String
// │ │ │ │ │ │ │ │
@@ -17,11 +17,11 @@ fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
fun main() {
// collections/List<String>
// │ fun <T> collections/listOf(vararg String): collections/List<String>
// │ fun <T> collections/listOf<String>(vararg String): collections/List<String>
// │ │
val list = listOf("1", "2", "3")
// collections/List<String>
// │ fun <T : CharSequence> copyWhenGreater(collections/List<String>, String): collections/List<String> where copyWhenGreater.T : Comparable<String>
// │ fun <T : CharSequence> copyWhenGreater<String>(collections/List<String>, String): collections/List<String> where T : Comparable<String>
// │ │ val main.list: collections/List<String>
// │ │ │
val copy = copyWhenGreater(list, "2")