Skip to content

Commit c55ae27

Browse files
committed
number library constructor overloads like scip-java. Expand constructor aliases
1 parent 93dbc5f commit c55ae27

6 files changed

Lines changed: 217 additions & 3 deletions

File tree

‎scip-kotlin-analysis/src/main/kotlin/org/scip_code/scip_java/kotlin_analysis/SymbolsCache.kt‎

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.scip_code.scip_java.kotlin_analysis
22

33
import com.intellij.psi.PsiElement
44
import java.lang.System.err
5+
import org.jetbrains.kotlin.analysis.api.KaExperimentalApi
56
import org.jetbrains.kotlin.analysis.api.KaSession
67
import org.jetbrains.kotlin.analysis.api.symbols.KaCallableSymbol
78
import org.jetbrains.kotlin.analysis.api.symbols.KaClassLikeSymbol
@@ -139,7 +140,9 @@ class SymbolsCache(private val session: KaSession) {
139140
)
140141

141142
/** The class symbol owning a constructor reference (`class Seagull : Bird()` → `Bird#`). */
142-
fun constructorOwnerSymbol(session: KaSession, target: KaConstructorSymbol): Symbol {
143+
@OptIn(KaExperimentalApi::class)
144+
fun constructorOwnerSymbol(session: KaSession, constructor: KaConstructorSymbol): Symbol {
145+
val target = with(session) { constructor.originalConstructorIfTypeAliased } ?: constructor
143146
when (val psi = target.psi) {
144147
is KtClassOrObject -> return symbolForDeclaration(psi)
145148
is KtConstructor<*> ->
@@ -197,7 +200,16 @@ class SymbolsCache(private val session: KaSession) {
197200
fun implicitItSymbol(literal: KtFunctionLiteral): Symbol = syntheticLocalSymbol(literal)
198201

199202
/** The SCIP symbol for the target of a resolved reference. */
203+
@OptIn(KaExperimentalApi::class)
200204
fun symbolForReference(session: KaSession, target: KaSymbol): Symbol {
205+
// A constructor call through a type alias (`HashMap()`) references the aliased
206+
// class's constructor, like javac and scip-kotlinc.
207+
if (target is KaConstructorSymbol) {
208+
with(session) { target.originalConstructorIfTypeAliased }
209+
?.let {
210+
return symbolForReference(session, it)
211+
}
212+
}
201213
val psi = target.psi
202214
if (psi is KtDeclaration) {
203215
// A constructor symbol whose PSI is the class itself is an implicit primary.
@@ -244,7 +256,11 @@ class SymbolsCache(private val session: KaSession) {
244256
target.containingClassId?.let { classId ->
245257
Symbol.createGlobal(
246258
classSymbol(classId),
247-
ScipSymbolDescriptor(Kind.METHOD, "<init>"),
259+
ScipSymbolDescriptor(
260+
Kind.METHOD,
261+
"<init>",
262+
externalConstructorDisambiguator(session, classId, target),
263+
),
248264
)
249265
} ?: Symbol.NONE
250266
// Library type aliases are expanded to the aliased class (`AutoCloseable`
@@ -496,6 +512,19 @@ class SymbolsCache(private val session: KaSession) {
496512
return Symbol.createGlobal(owner, descriptor)
497513
}
498514

515+
/** Like javac: constructors in declaration order, private ones included. */
516+
private fun externalConstructorDisambiguator(
517+
session: KaSession,
518+
classId: ClassId,
519+
target: KaConstructorSymbol,
520+
): String {
521+
val constructors =
522+
with(session) { findClass(classId)?.declaredMemberScope?.constructors?.toList() }
523+
?: return "()"
524+
val index = constructors.indexOf(target)
525+
return if (index <= 0) "()" else "(+$index)"
526+
}
527+
499528
private fun externalMethodDisambiguator(session: KaSession, target: KaCallableSymbol): String {
500529
val callableId = target.callableId ?: return "()"
501530
val overloads: List<KaCallableSymbol> =
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package snapshots;
2+
3+
public class ConstructorsConsumer {
4+
public static void run() {
5+
new java.io.File("a", "b");
6+
new kotlin.text.Regex("a");
7+
new StringBuilder("x");
8+
new java.util.HashMap<String, Integer>();
9+
new Overloaded(1);
10+
}
11+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package snapshots
2+
3+
class Overloaded(val s: String) {
4+
constructor(i: Int) : this(i.toString())
5+
}
6+
7+
typealias OverloadedAlias = Overloaded
8+
9+
typealias StringIntMap = HashMap<String, Int>
10+
11+
// Each call references the same symbol as its counterpart in ConstructorsConsumer.java.
12+
fun constructors() {
13+
// Library constructors are numbered like javac, private ones included.
14+
java.io.File("a", "b")
15+
Regex("a")
16+
// Calls through type aliases reference the aliased class's constructor.
17+
StringBuilder("x")
18+
StringIntMap()
19+
OverloadedAlias(1)
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package snapshots;
2+
3+
//⌄ enclosing_range_start scip-java maven . . snapshots/ConstructorsConsumer#
4+
public class ConstructorsConsumer {
5+
// ^^^^^^^^^^^^^^^^^^^^ definition scip-java maven . . snapshots/ConstructorsConsumer#
6+
// kind Class
7+
// display_name ConstructorsConsumer
8+
// signature_documentation
9+
// > public class ConstructorsConsumer
10+
// ^^^^^^^^^^^^^^^^^^^^ definition scip-java maven . . snapshots/ConstructorsConsumer#`<init>`().
11+
// kind Constructor
12+
// display_name <init>
13+
// signature_documentation
14+
// > public ConstructorsConsumer()
15+
// ⌄ enclosing_range_start scip-java maven . . snapshots/ConstructorsConsumer#run().
16+
public static void run() {
17+
// ^^^ definition scip-java maven . . snapshots/ConstructorsConsumer#run().
18+
// kind StaticMethod
19+
// display_name run
20+
// signature_documentation
21+
// > public static void run()
22+
new java.io.File("a", "b");
23+
// ^^^^ reference scip-java maven . . java/
24+
// ^^ reference scip-java maven . . java/io/
25+
// ^^^^ reference scip-java maven jdk 17 java/io/File#`<init>`(+3).
26+
new kotlin.text.Regex("a");
27+
// ^^^^^^ reference scip-java maven . . kotlin/
28+
// ^^^^ reference scip-java maven . . kotlin/text/
29+
// ^^^^^ reference scip-java maven . . kotlin/text/Regex#`<init>`(+1).
30+
new StringBuilder("x");
31+
// ^^^^^^^^^^^^^ reference scip-java maven jdk 17 java/lang/StringBuilder#`<init>`(+2).
32+
new java.util.HashMap<String, Integer>();
33+
// ^^^^ reference scip-java maven . . java/
34+
// ^^^^ reference scip-java maven . . java/util/
35+
// ^^^^^^^ reference scip-java maven jdk 17 java/util/HashMap#`<init>`(+2).
36+
// ^^^^^^ reference scip-java maven jdk 17 java/lang/String#
37+
// ^^^^^^^ reference scip-java maven jdk 17 java/lang/Integer#
38+
new Overloaded(1);
39+
// ^^^^^^^^^^ reference scip-java maven . . snapshots/Overloaded#`<init>`(+1).
40+
}
41+
// ⌃ enclosing_range_end scip-java maven . . snapshots/ConstructorsConsumer#run().
42+
}
43+
//⌃ enclosing_range_end scip-java maven . . snapshots/ConstructorsConsumer#
44+
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package snapshots
2+
// ^^^^^^^^^ reference scip-java maven . . snapshots/
3+
4+
//⌄ enclosing_range_start scip-java maven . . snapshots/Overloaded#
5+
// ⌄ enclosing_range_start scip-java maven . . snapshots/Overloaded#`<init>`().
6+
// ⌄ enclosing_range_start scip-java maven . . snapshots/Overloaded#`<init>`().(s)
7+
// ⌄ enclosing_range_start scip-java maven . . snapshots/Overloaded#s.
8+
// ⌄ enclosing_range_start scip-java maven . . snapshots/Overloaded#s.get().
9+
class Overloaded(val s: String) {
10+
// ^^^^^^^^^^ definition scip-java maven . . snapshots/Overloaded#
11+
// kind Class
12+
// display_name Overloaded
13+
// signature_documentation
14+
// > public final class Overloaded : Any
15+
// ^^^^^^^^^^ definition scip-java maven . . snapshots/Overloaded#`<init>`().
16+
// kind Constructor
17+
// display_name Overloaded
18+
// signature_documentation
19+
// > public constructor(s: String): Overloaded
20+
// ^ definition scip-java maven . . snapshots/Overloaded#`<init>`().(s)
21+
// kind Parameter
22+
// display_name s
23+
// signature_documentation
24+
// > s: String
25+
// ^ definition scip-java maven . . snapshots/Overloaded#s.
26+
// kind Property
27+
// display_name s
28+
// signature_documentation
29+
// > public final val s: String
30+
// ^ reference scip-java maven . . snapshots/Overloaded#`<init>`().(s)
31+
// ^ definition scip-java maven . . snapshots/Overloaded#s.get().
32+
// kind Method
33+
// display_name s
34+
// signature_documentation
35+
// > public get(): String
36+
// ^^^^^^ reference scip-java maven . . kotlin/String#
37+
// ⌃ enclosing_range_end scip-java maven . . snapshots/Overloaded#`<init>`().(s)
38+
// ⌃ enclosing_range_end scip-java maven . . snapshots/Overloaded#s.
39+
// ⌃ enclosing_range_end scip-java maven . . snapshots/Overloaded#s.get().
40+
// ⌃ enclosing_range_end scip-java maven . . snapshots/Overloaded#`<init>`().
41+
// ⌄ enclosing_range_start scip-java maven . . snapshots/Overloaded#`<init>`(+1).
42+
// ⌄ enclosing_range_start scip-java maven . . snapshots/Overloaded#`<init>`(+1).(i)
43+
constructor(i: Int) : this(i.toString())
44+
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ definition scip-java maven . . snapshots/Overloaded#`<init>`(+1).
45+
// kind Constructor
46+
// display_name Overloaded
47+
// signature_documentation
48+
// > public constructor(i: Int): Overloaded
49+
// ^ definition scip-java maven . . snapshots/Overloaded#`<init>`(+1).(i)
50+
// kind Parameter
51+
// display_name i
52+
// signature_documentation
53+
// > i: Int
54+
// ^^^ reference scip-java maven . . kotlin/Int#
55+
// ^ reference scip-java maven . . snapshots/Overloaded#`<init>`(+1).(i)
56+
// ^^^^^^^^ reference scip-java maven . . kotlin/Int#toString().
57+
// ⌃ enclosing_range_end scip-java maven . . snapshots/Overloaded#`<init>`(+1).(i)
58+
// ⌃ enclosing_range_end scip-java maven . . snapshots/Overloaded#`<init>`(+1).
59+
}
60+
//⌃ enclosing_range_end scip-java maven . . snapshots/Overloaded#
61+
62+
//⌄ enclosing_range_start scip-java maven . . snapshots/OverloadedAlias#
63+
typealias OverloadedAlias = Overloaded
64+
// ^^^^^^^^^^^^^^^ definition scip-java maven . . snapshots/OverloadedAlias#
65+
// kind TypeAlias
66+
// display_name OverloadedAlias
67+
// signature_documentation
68+
// > public final typealias OverloadedAlias = Overloaded
69+
// >
70+
// ^^^^^^^^^^ reference scip-java maven . . snapshots/Overloaded#
71+
// ⌃ enclosing_range_end scip-java maven . . snapshots/OverloadedAlias#
72+
73+
//⌄ enclosing_range_start scip-java maven . . snapshots/StringIntMap#
74+
typealias StringIntMap = HashMap<String, Int>
75+
// ^^^^^^^^^^^^ definition scip-java maven . . snapshots/StringIntMap#
76+
// kind TypeAlias
77+
// display_name StringIntMap
78+
// signature_documentation
79+
// > public final typealias StringIntMap = HashMap<String, Int>
80+
// >
81+
// ^^^^^^^ reference scip-java maven jdk 17 java/util/HashMap#
82+
// ^^^^^^ reference scip-java maven . . kotlin/String#
83+
// ^^^ reference scip-java maven . . kotlin/Int#
84+
// ⌃ enclosing_range_end scip-java maven . . snapshots/StringIntMap#
85+
86+
//⌄ enclosing_range_start scip-java maven . . snapshots/constructors().
87+
// Each call references the same symbol as its counterpart in ConstructorsConsumer.java.
88+
fun constructors() {
89+
// ^^^^^^^^^^^^ definition scip-java maven . . snapshots/constructors().
90+
// kind Method
91+
// display_name constructors
92+
// signature_documentation
93+
// > public final fun constructors(): Unit
94+
// Library constructors are numbered like javac, private ones included.
95+
java.io.File("a", "b")
96+
// ^^^^ reference scip-java maven . . java/
97+
// ^^ reference scip-java maven . . java/io/
98+
// ^^^^ reference scip-java maven jdk 17 java/io/File#`<init>`(+3).
99+
Regex("a")
100+
// ^^^^^ reference scip-java maven . . kotlin/text/Regex#`<init>`(+1).
101+
// Calls through type aliases reference the aliased class's constructor.
102+
StringBuilder("x")
103+
// ^^^^^^^^^^^^^ reference scip-java maven jdk 17 java/lang/StringBuilder#`<init>`(+2).
104+
StringIntMap()
105+
// ^^^^^^^^^^^^ reference scip-java maven jdk 17 java/util/HashMap#`<init>`(+2).
106+
OverloadedAlias(1)
107+
// ^^^^^^^^^^^^^^^ reference scip-java maven . . snapshots/Overloaded#`<init>`(+1).
108+
}
109+
//⌃ enclosing_range_end scip-java maven . . snapshots/constructors().
110+

‎scip-snapshots/expected/kotlin/common/scip-snapshots/cases/kotlin/common/src/main/kotlin/snapshots/ObjectKt.kt‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
// ^^^^^^^ reference scip-java maven . . kotlin/Nothing#
4343
// ⌃ enclosing_range_end scip-java maven . . snapshots/ObjectKt#fail().(message)
4444
throw RuntimeException(message)
45-
// ^^^^^^^^^^^^^^^^ reference scip-java maven jdk 17 java/lang/RuntimeException#`<init>`().
45+
// ^^^^^^^^^^^^^^^^ reference scip-java maven jdk 17 java/lang/RuntimeException#`<init>`(+1).
4646
// ^^^^^^^ reference scip-java maven . . snapshots/ObjectKt#fail().(message)
4747
}
4848
// ⌃ enclosing_range_end scip-java maven . . snapshots/ObjectKt#fail().

0 commit comments

Comments
 (0)