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:
committed by
Mikhail Glukhikh
parent
8fb2383845
commit
fe328f8c7a
@@ -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"))
|
||||
|
||||
+5
-5
@@ -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)
|
||||
|
||||
|
||||
+50
-26
@@ -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)
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+2
-2
@@ -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() {
|
||||
|
||||
+21
-21
@@ -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
@@ -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?) {
|
||||
|
||||
@@ -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>()
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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")
|
||||
|
||||
Reference in New Issue
Block a user