mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 15:51:01 +00:00
Compare commits
345 Commits
push/pdn_b
...
v1.4.21
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3b14561c4 | ||
|
|
cb93152fed | ||
|
|
4c44045e9d | ||
|
|
40abf82dd4 | ||
|
|
166ce6a2ea | ||
|
|
5e23440a2a | ||
|
|
0b495c1531 | ||
|
|
a48f76d4d9 | ||
|
|
a173e0e631 | ||
|
|
02d925a73b | ||
|
|
be704622cb | ||
|
|
0c5c194c17 | ||
|
|
39ca1b45b5 | ||
|
|
219c200627 | ||
|
|
fd2fd51b3d | ||
|
|
7a55c9dd51 | ||
|
|
3e803a5f18 | ||
|
|
2a25f07c77 | ||
|
|
e9ce4a22c4 | ||
|
|
4bceb0d5a1 | ||
|
|
e30fc4b00c | ||
|
|
45c957becd | ||
|
|
d0c005400b | ||
|
|
49a7e00685 | ||
|
|
0e75999ce1 | ||
|
|
995df014e3 | ||
|
|
90305141cd | ||
|
|
8aea0139b0 | ||
|
|
c37d269225 | ||
|
|
53e74af304 | ||
|
|
5cc229cfb3 | ||
|
|
be71a871ae | ||
|
|
3d0e7d4d77 | ||
|
|
d29d387518 | ||
|
|
5e43889164 | ||
|
|
5ad87a15f0 | ||
|
|
95964be449 | ||
|
|
cb2ca2279d | ||
|
|
5da0af56ee | ||
|
|
6d43560f84 | ||
|
|
af2c46724e | ||
|
|
4245d2ad4e | ||
|
|
e97fe906f1 | ||
|
|
baa11aaf1e | ||
|
|
b2d3570030 | ||
|
|
77500761d0 | ||
|
|
9a7c8f086e | ||
|
|
06a614f3f7 | ||
|
|
a262dba9e3 | ||
|
|
a6d0af82d7 | ||
|
|
e7a07673f8 | ||
|
|
796f1fdf21 | ||
|
|
8c08502e90 | ||
|
|
4cde8c425c | ||
|
|
c17c6a28ee | ||
|
|
bdae207060 | ||
|
|
68a82fdbf6 | ||
|
|
93a1b34c95 | ||
|
|
267aab87c0 | ||
|
|
1dcecec0b7 | ||
|
|
c138aef990 | ||
|
|
0e1b529f62 | ||
|
|
3ae3694991 | ||
|
|
78058f7713 | ||
|
|
7da8ab6e30 | ||
|
|
0b2022aa2b | ||
|
|
433be3bc7d | ||
|
|
489735e51f | ||
|
|
b1950b2511 | ||
|
|
1025e0b1c5 | ||
|
|
fea02daedb | ||
|
|
c3e73a1e86 | ||
|
|
1e3e7e91d2 | ||
|
|
030c2daa4d | ||
|
|
43023f001a | ||
|
|
3f1eb1c105 | ||
|
|
43c8dc174d | ||
|
|
4452b2a0fd | ||
|
|
e2e1615f01 | ||
|
|
d863e174fa | ||
|
|
db880e5a11 | ||
|
|
84b6522b96 | ||
|
|
beeb281c7e | ||
|
|
ea0ce5dbb2 | ||
|
|
1b823f5899 | ||
|
|
270a4f86d3 | ||
|
|
120ae08d93 | ||
|
|
bc3119c290 | ||
|
|
e2d4c511f6 | ||
|
|
ab0ec40e4b | ||
|
|
5171ed36c5 | ||
|
|
0019c30247 | ||
|
|
cbae7004b9 | ||
|
|
d90dbf5f58 | ||
|
|
80f8e8bc38 | ||
|
|
26d98d1adb | ||
|
|
c900714114 | ||
|
|
7729ee1642 | ||
|
|
2eff78ed41 | ||
|
|
da041fa611 | ||
|
|
c53c867106 | ||
|
|
eb98defdba | ||
|
|
0b414dc186 | ||
|
|
85e69f4bbf | ||
|
|
1ba38822ee | ||
|
|
e543e8464a | ||
|
|
a9413b3c4d | ||
|
|
6ba0f08098 | ||
|
|
e9dc79367d | ||
|
|
5cfcddf3e3 | ||
|
|
36c1f2ef40 | ||
|
|
7e1fdfffc2 | ||
|
|
7c4648eab8 | ||
|
|
1b54421feb | ||
|
|
1545c7d1b5 | ||
|
|
11beda80e9 | ||
|
|
e3c22e500c | ||
|
|
8b4ecf5702 | ||
|
|
bd052ee399 | ||
|
|
fd824d3ce7 | ||
|
|
2a38b1c5b8 | ||
|
|
79b4574ef4 | ||
|
|
b6a3ba18e7 | ||
|
|
04da7b5319 | ||
|
|
8ef411a2b3 | ||
|
|
e39cd59a3b | ||
|
|
e81cb1ad73 | ||
|
|
17cd9dc132 | ||
|
|
f4a1ceab57 | ||
|
|
8fa8644aba | ||
|
|
1fb1385de1 | ||
|
|
b75f1b0829 | ||
|
|
dd340e99d2 | ||
|
|
dcfd805e46 | ||
|
|
a9e0002438 | ||
|
|
43ee55be39 | ||
|
|
510e270bd1 | ||
|
|
d9290c605a | ||
|
|
4838b43709 | ||
|
|
45179663ac | ||
|
|
503a4600c9 | ||
|
|
76441af482 | ||
|
|
2d23aeb55d | ||
|
|
eb594f50e0 | ||
|
|
8ef06005ee | ||
|
|
16cb23f321 | ||
|
|
8a88b98cd8 | ||
|
|
aad01b104a | ||
|
|
c2a5779f18 | ||
|
|
f1d3a71e2f | ||
|
|
ec95cc9d02 | ||
|
|
9d9c0d49fb | ||
|
|
22adbc25cf | ||
|
|
ba02083a54 | ||
|
|
83446a6823 | ||
|
|
3c111e1ecf | ||
|
|
f8badc5a5f | ||
|
|
faab992f90 | ||
|
|
83f3f07368 | ||
|
|
6287a10779 | ||
|
|
62001be998 | ||
|
|
e6a3382fa5 | ||
|
|
5c27d7a99a | ||
|
|
2abf731006 | ||
|
|
8931a5295f | ||
|
|
f855ca7eb7 | ||
|
|
3288b220f4 | ||
|
|
614e12eaf3 | ||
|
|
8d0407202e | ||
|
|
c76621e75f | ||
|
|
5172dfea09 | ||
|
|
6783b952fa | ||
|
|
ec7837afe8 | ||
|
|
c2270aa372 | ||
|
|
29fee7de8f | ||
|
|
424d62aa50 | ||
|
|
32ed0739e5 | ||
|
|
2ceb4a3f9a | ||
|
|
0b46f617ac | ||
|
|
c8305b346d | ||
|
|
8e3ce8c46f | ||
|
|
3d3fe203bb | ||
|
|
380fe63da1 | ||
|
|
6588b88cbf | ||
|
|
cf58e0594c | ||
|
|
6746638e7c | ||
|
|
336ef6e038 | ||
|
|
f6979d7b02 | ||
|
|
2f5b895578 | ||
|
|
406e8d5c0c | ||
|
|
e1fd16030f | ||
|
|
d14d7115e9 | ||
|
|
0f53538665 | ||
|
|
827ebe38b0 | ||
|
|
d0aca5b6e7 | ||
|
|
457e999831 | ||
|
|
44dece0da6 | ||
|
|
00622d652e | ||
|
|
4dfe84152b | ||
|
|
a4b90cc0a6 | ||
|
|
fb8139005c | ||
|
|
0bb1d735be | ||
|
|
e75901302b | ||
|
|
cdd7602406 | ||
|
|
8b05372aec | ||
|
|
40c66757e3 | ||
|
|
5ffbe1c674 | ||
|
|
53c13c1ec2 | ||
|
|
d4cb539e7f | ||
|
|
b67bfc1416 | ||
|
|
22342206bc | ||
|
|
5c4d863e64 | ||
|
|
ec3d113be3 | ||
|
|
b97a5892cb | ||
|
|
f06986d557 | ||
|
|
057c0737cd | ||
|
|
9c56160e7a | ||
|
|
1d8881991b | ||
|
|
9839368159 | ||
|
|
1e9ccf9059 | ||
|
|
52c29f1062 | ||
|
|
6d88bfbf09 | ||
|
|
f04290289c | ||
|
|
68211ce62b | ||
|
|
851ea9fb85 | ||
|
|
9b7eba77b8 | ||
|
|
a9cf0df01e | ||
|
|
da190a895e | ||
|
|
a11fe3eac0 | ||
|
|
f7ad2d3fa5 | ||
|
|
f07b8ac612 | ||
|
|
a1ddf68885 | ||
|
|
66225dd449 | ||
|
|
13a2a35299 | ||
|
|
117bad1b6a | ||
|
|
578e52a970 | ||
|
|
596da430ca | ||
|
|
6456d16675 | ||
|
|
251e6cc97f | ||
|
|
ff70f8fbea | ||
|
|
0101c3e208 | ||
|
|
cf4abb4210 | ||
|
|
db2c0856f1 | ||
|
|
f8c74e30ec | ||
|
|
8900e2dde1 | ||
|
|
733f009b5d | ||
|
|
82a3a2ebe6 | ||
|
|
7954517ef7 | ||
|
|
7c5eeebb45 | ||
|
|
62784f1f1a | ||
|
|
5db84fb293 | ||
|
|
301df24d90 | ||
|
|
b4cf209bf5 | ||
|
|
3105b96f39 | ||
|
|
58feedc741 | ||
|
|
2036b31a9b | ||
|
|
ac09c60863 | ||
|
|
93929d0bb5 | ||
|
|
fef425922b | ||
|
|
763657bd06 | ||
|
|
1d66108b30 | ||
|
|
d33391f4f8 | ||
|
|
8a624cbd4e | ||
|
|
699c666459 | ||
|
|
b1a5c827f1 | ||
|
|
baa9c476e3 | ||
|
|
0b46337f40 | ||
|
|
9ca8e24031 | ||
|
|
7725a9000e | ||
|
|
d5df67945f | ||
|
|
4451458014 | ||
|
|
962683caad | ||
|
|
8581298145 | ||
|
|
2166fab0a0 | ||
|
|
5faadc659f | ||
|
|
60c79824a5 | ||
|
|
6daa0a3e93 | ||
|
|
f338f48dc3 | ||
|
|
2adb9c15e7 | ||
|
|
acbf979587 | ||
|
|
f717a410f3 | ||
|
|
6d38c7acaf | ||
|
|
ba0a48ef2c | ||
|
|
18820cacac | ||
|
|
3e920356c7 | ||
|
|
dc36d53ce1 | ||
|
|
36369484a2 | ||
|
|
acf7cb9e4d | ||
|
|
c902e20ff0 | ||
|
|
3d5bbb9ca8 | ||
|
|
21930f040c | ||
|
|
9b39dd1a41 | ||
|
|
5881eef986 | ||
|
|
28f68f8414 | ||
|
|
0ca6d21670 | ||
|
|
ac9cda0be8 | ||
|
|
2142cd244a | ||
|
|
3d313a1ecc | ||
|
|
0a2f22f711 | ||
|
|
62c21fcbb5 | ||
|
|
a21e9d034a | ||
|
|
3362f15257 | ||
|
|
5cdf381c3e | ||
|
|
7d058cd50a | ||
|
|
1fa0dcc897 | ||
|
|
8042c9842c | ||
|
|
96225d92b6 | ||
|
|
f8cd381321 | ||
|
|
a225d0a0fb | ||
|
|
8e213c1fe4 | ||
|
|
45d4eedf10 | ||
|
|
761feab27b | ||
|
|
864cda198c | ||
|
|
e56bf12997 | ||
|
|
623bab16b8 | ||
|
|
ef7c85637d | ||
|
|
e48bf93c67 | ||
|
|
402a2f4d51 | ||
|
|
f2c04e94e3 | ||
|
|
31759df794 | ||
|
|
ed13b7b407 | ||
|
|
2835bf7d76 | ||
|
|
03ea0b16a7 | ||
|
|
c931b57fe1 | ||
|
|
573715fee5 | ||
|
|
f96b53d045 | ||
|
|
abe1485066 | ||
|
|
e4a8aeffe6 | ||
|
|
50461e6150 | ||
|
|
57dcefc80e | ||
|
|
19496981a3 | ||
|
|
8a10ebaa75 | ||
|
|
367d70859a | ||
|
|
96cb169246 | ||
|
|
30a4db4c36 | ||
|
|
c23385b62d | ||
|
|
d0610d7ada | ||
|
|
4cb47dfd07 | ||
|
|
4440675e19 | ||
|
|
f75d650db1 | ||
|
|
a1005d4032 | ||
|
|
07a9f47fd4 | ||
|
|
222db66f60 | ||
|
|
be6a7a501e | ||
|
|
f24dfc654e |
3
.idea/dictionaries/yan.xml
generated
3
.idea/dictionaries/yan.xml
generated
@@ -10,7 +10,10 @@
|
||||
<w>kapt</w>
|
||||
<w>kotlinc</w>
|
||||
<w>mutators</w>
|
||||
<w>parcelable</w>
|
||||
<w>parceler</w>
|
||||
<w>parcelers</w>
|
||||
<w>parcelize</w>
|
||||
<w>repl</w>
|
||||
<w>testdata</w>
|
||||
<w>uast</w>
|
||||
|
||||
12051
ChangeLog.md
12051
ChangeLog.md
File diff suppressed because it is too large
Load Diff
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.resolve.sam.SAM_LOOKUP_NAME
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.util.*
|
||||
import kotlin.collections.HashSet
|
||||
import kotlin.collections.LinkedHashSet
|
||||
@@ -66,7 +67,7 @@ fun makeModuleFile(
|
||||
friendDirs
|
||||
)
|
||||
|
||||
val scriptFile = File.createTempFile("kjps", sanitizeJavaIdentifier(name) + ".script.xml")
|
||||
val scriptFile = Files.createTempFile("kjps", sanitizeJavaIdentifier(name) + ".script.xml").toFile()
|
||||
scriptFile.writeText(builder.asText().toString())
|
||||
return scriptFile
|
||||
}
|
||||
|
||||
@@ -17258,6 +17258,7 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
boolean hasFlags();
|
||||
@@ -17268,6 +17269,7 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
int getFlags();
|
||||
@@ -17463,6 +17465,7 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -17475,6 +17478,7 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -17894,6 +17898,7 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -17906,6 +17911,7 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -17918,6 +17924,7 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public Builder setFlags(int value) {
|
||||
@@ -17933,6 +17940,7 @@ public final class DebugProtoBuf {
|
||||
*hasAnnotations
|
||||
*Visibility
|
||||
*isSecondary
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public Builder clearFlags() {
|
||||
@@ -18307,6 +18315,7 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
boolean hasFlags();
|
||||
@@ -18325,6 +18334,7 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
int getFlags();
|
||||
@@ -18723,6 +18733,7 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -18743,6 +18754,7 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -19639,6 +19651,7 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public boolean hasFlags() {
|
||||
@@ -19659,6 +19672,7 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public int getFlags() {
|
||||
@@ -19679,6 +19693,7 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public Builder setFlags(int value) {
|
||||
@@ -19702,6 +19717,7 @@ public final class DebugProtoBuf {
|
||||
*isExternal
|
||||
*isSuspend
|
||||
*isExpect
|
||||
*hasNonStableParameterNames
|
||||
* </pre>
|
||||
*/
|
||||
public Builder clearFlags() {
|
||||
|
||||
@@ -4656,7 +4656,8 @@ public final class DebugJvmProtoBuf {
|
||||
* <code>extend .org.jetbrains.kotlin.metadata.Class { ... }</code>
|
||||
*
|
||||
* <pre>
|
||||
* isFunctionBodyInInterface: 0 if actual body generated in DefaultImpl, 1 - otherwise (in interface default method)
|
||||
* first bit: isFunctionBodyInInterface: 0 if actual body generated in DefaultImpl, 1 - otherwise (in interface default method)
|
||||
* second bit: is all-compatibility mode or not, 1 - yes, 0 - no
|
||||
* </pre>
|
||||
*/
|
||||
public static final
|
||||
|
||||
@@ -187,7 +187,7 @@ extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
|
||||
extra["versions.ktor-network"] = "1.0.1"
|
||||
|
||||
if (!project.hasProperty("versions.kotlin-native")) {
|
||||
extra["versions.kotlin-native"] = "1.4.20-dev-16314"
|
||||
extra["versions.kotlin-native"] = "1.4.21-release-136"
|
||||
}
|
||||
|
||||
val intellijUltimateEnabled by extra(project.kotlinBuildProperties.intellijUltimateEnabled)
|
||||
@@ -337,7 +337,8 @@ val gradlePluginProjects = listOf(
|
||||
":kotlin-allopen",
|
||||
":kotlin-annotation-processing-gradle",
|
||||
":kotlin-noarg",
|
||||
":kotlin-sam-with-receiver"
|
||||
":kotlin-sam-with-receiver",
|
||||
":kotlin-parcelize-compiler"
|
||||
)
|
||||
|
||||
apply {
|
||||
@@ -702,9 +703,12 @@ tasks {
|
||||
dependsOn("scriptingTest")
|
||||
dependsOn(":kotlin-build-common:test")
|
||||
dependsOn(":compiler:incremental-compilation-impl:test")
|
||||
dependsOn(":compiler:incremental-compilation-impl:testJvmICWithJdk11")
|
||||
dependsOn(":core:descriptors.runtime:test")
|
||||
|
||||
dependsOn("jvmCompilerIntegrationTest")
|
||||
|
||||
dependsOn(":plugins:parcelize:parcelize-compiler:test")
|
||||
}
|
||||
|
||||
register("toolsTest") {
|
||||
@@ -777,7 +781,8 @@ tasks {
|
||||
dependsOn(
|
||||
":plugins:android-extensions-ide:test",
|
||||
":idea:idea-android:test",
|
||||
":kotlin-annotation-processing:test"
|
||||
":kotlin-annotation-processing:test",
|
||||
":plugins:parcelize:parcelize-ide:test"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -866,12 +871,12 @@ tasks {
|
||||
":prepare:ide-plugin-dependencies:incremental-compilation-impl-tests-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-build-common-tests-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-compiler-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-dist-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlin-gradle-statistics-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:kotlinx-serialization-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:noarg-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:sam-with-receiver-compiler-plugin-for-ide:publish",
|
||||
":prepare:ide-plugin-dependencies:compiler-components-for-jps:publish",
|
||||
":prepare:ide-plugin-dependencies:parcelize-compiler-plugin-for-ide:publish",
|
||||
":kotlin-script-runtime:publish",
|
||||
":kotlin-script-util:publish",
|
||||
":kotlin-scripting-common:publish",
|
||||
@@ -886,7 +891,8 @@ tasks {
|
||||
":kotlin-reflect:publish",
|
||||
":kotlin-main-kts:publish",
|
||||
":kotlin-stdlib-js:publish",
|
||||
":kotlin-test:kotlin-test-js:publish"
|
||||
":kotlin-test:kotlin-test-js:publish",
|
||||
":kotlin-coroutines-experimental-compat:publish"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,12 +46,12 @@ if (target_AppCode_Clion) {
|
||||
} else if (target_AndroidStudio) {
|
||||
logger.info("Including modules for AS (mobile plugin) in buildSrc/settings.gradle")
|
||||
|
||||
include ":prepare-deps:cocoa-common-binaries"
|
||||
include ":prepare-deps:appcode-binaries"
|
||||
include ":prepare-deps:lldb-framework"
|
||||
include ":prepare-deps:lldb-frontend"
|
||||
|
||||
project(":prepare-deps:cocoa-common-binaries").projectDir =
|
||||
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/cocoa-common-binaries")
|
||||
project(":prepare-deps:appcode-binaries").projectDir =
|
||||
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/appcode-binaries")
|
||||
project(":prepare-deps:lldb-framework").projectDir =
|
||||
file("${buildProperties.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/lldb-framework")
|
||||
project(":prepare-deps:lldb-frontend").projectDir =
|
||||
|
||||
@@ -54,7 +54,7 @@ enum class Ide(val platform: Platform) : CompatibilityPredicate {
|
||||
AS36(Platform.P192),
|
||||
AS40(Platform.P193),
|
||||
AS41(Platform.P201),
|
||||
AS42(Platform.P201);
|
||||
AS42(Platform.P202);
|
||||
|
||||
val kind = Kind.values().first { it.shortName == name.take(2) }
|
||||
val version = name.dropWhile { !it.isDigit() }.toInt()
|
||||
|
||||
@@ -20,6 +20,10 @@ internal const val PLUGIN_MARKER_SUFFIX = ".gradle.plugin"
|
||||
|
||||
@UseExperimental(ExperimentalStdlibApi::class)
|
||||
fun Project.publishPluginMarkers(withEmptyJars: Boolean = true) {
|
||||
|
||||
fun Project.isSonatypePublish(): Boolean =
|
||||
hasProperty("isSonatypePublish") && property("isSonatypePublish") as Boolean
|
||||
|
||||
val pluginDevelopment = extensions.getByType<PluginBundleExtension>()
|
||||
val publishingExtension = extensions.getByType<PublishingExtension>()
|
||||
val mainPublication = publishingExtension.publications[KotlinBuildPublishingPlugin.PUBLICATION_NAME] as MavenPublication
|
||||
@@ -32,7 +36,12 @@ fun Project.publishPluginMarkers(withEmptyJars: Boolean = true) {
|
||||
|
||||
tasks.named<PublishToMavenRepository>(
|
||||
"publish${markerPublication.name.capitalize(Locale.ROOT)}PublicationTo${KotlinBuildPublishingPlugin.REPOSITORY_NAME}Repository"
|
||||
).configureRepository()
|
||||
).apply {
|
||||
configureRepository()
|
||||
configure {
|
||||
onlyIf { !isSonatypePublish() }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,9 +17,9 @@ import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
|
||||
import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
|
||||
import org.gradle.api.tasks.TaskProvider
|
||||
import org.gradle.kotlin.dsl.*
|
||||
import org.gradle.plugins.signing.Sign
|
||||
import org.gradle.plugins.signing.SigningExtension
|
||||
import org.gradle.plugins.signing.SigningPlugin
|
||||
import java.net.URI
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -108,13 +108,19 @@ class KotlinBuildPublishingPlugin @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
configure<SigningExtension> {
|
||||
setRequired(provider {
|
||||
project.findProperty("signingRequired")?.toString()?.toBoolean()
|
||||
?: project.property("isSonatypeRelease") as Boolean
|
||||
})
|
||||
val signingRequired = provider {
|
||||
project.findProperty("signingRequired")?.toString()?.toBoolean()
|
||||
?: project.property("isSonatypeRelease") as Boolean
|
||||
}
|
||||
|
||||
configure<SigningExtension> {
|
||||
setRequired(signingRequired)
|
||||
sign(extensions.getByType<PublishingExtension>().publications[PUBLICATION_NAME])
|
||||
useGpgCmd()
|
||||
}
|
||||
|
||||
tasks.withType<Sign>().configureEach {
|
||||
setOnlyIf { signingRequired.get() }
|
||||
}
|
||||
|
||||
tasks.register("install") {
|
||||
|
||||
@@ -37,6 +37,7 @@ fun Task.dependsOnKotlinPluginInstall() {
|
||||
":kotlin-noarg:install",
|
||||
":kotlin-sam-with-receiver:install",
|
||||
":kotlin-android-extensions:install",
|
||||
":kotlin-parcelize-compiler:install",
|
||||
":kotlin-build-common:install",
|
||||
":kotlin-compiler-embeddable:install",
|
||||
":native:kotlin-native-utils:install",
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.codegen;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -55,7 +54,6 @@ import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isBoolean;
|
||||
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isPrimitiveClass;
|
||||
@@ -72,12 +70,6 @@ import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class AsmUtil {
|
||||
|
||||
private static final Set<Type> STRING_BUILDER_OBJECT_APPEND_ARG_TYPES = Sets.newHashSet(
|
||||
getType(String.class),
|
||||
getType(StringBuffer.class),
|
||||
getType(CharSequence.class)
|
||||
);
|
||||
|
||||
private static final int NO_FLAG_LOCAL = 0;
|
||||
public static final int NO_FLAG_PACKAGE_PRIVATE = 0;
|
||||
|
||||
@@ -598,20 +590,6 @@ public class AsmUtil {
|
||||
: sort == Type.BYTE || sort == Type.SHORT ? Type.INT_TYPE : type;
|
||||
}
|
||||
|
||||
private static Type stringBuilderAppendType(Type type) {
|
||||
switch (type.getSort()) {
|
||||
case Type.OBJECT:
|
||||
return STRING_BUILDER_OBJECT_APPEND_ARG_TYPES.contains(type) ? type : OBJECT_TYPE;
|
||||
case Type.ARRAY:
|
||||
return OBJECT_TYPE;
|
||||
case Type.BYTE:
|
||||
case Type.SHORT:
|
||||
return Type.INT_TYPE;
|
||||
default:
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
public static void genThrow(@NotNull InstructionAdapter v, @NotNull String exception, @Nullable String message) {
|
||||
v.anew(Type.getObjectType(exception));
|
||||
v.dup();
|
||||
@@ -688,39 +666,28 @@ public class AsmUtil {
|
||||
return index;
|
||||
}
|
||||
|
||||
public static void genStringBuilderConstructor(InstructionAdapter v) {
|
||||
v.visitTypeInsn(NEW, "java/lang/StringBuilder");
|
||||
v.dup();
|
||||
v.invokespecial("java/lang/StringBuilder", "<init>", "()V", false);
|
||||
}
|
||||
|
||||
public static void genInvokeAppendMethod(@NotNull InstructionAdapter v, @NotNull Type type, @Nullable KotlinType kotlinType) {
|
||||
genInvokeAppendMethod(v, type, kotlinType, null);
|
||||
}
|
||||
|
||||
public static void genInvokeAppendMethod(
|
||||
@NotNull InstructionAdapter v,
|
||||
@NotNull StringConcatGenerator generator,
|
||||
@NotNull Type type,
|
||||
@Nullable KotlinType kotlinType,
|
||||
@Nullable KotlinTypeMapper typeMapper
|
||||
@Nullable KotlinTypeMapper typeMapper,
|
||||
@NotNull StackValue stackValue
|
||||
) {
|
||||
Type appendParameterType;
|
||||
|
||||
CallableMethod specializedToString = getSpecializedToStringCallableMethodOrNull(kotlinType, typeMapper);
|
||||
if (specializedToString != null) {
|
||||
specializedToString.genInvokeInstruction(v);
|
||||
appendParameterType = AsmTypes.JAVA_STRING_TYPE;
|
||||
stackValue.put(type, kotlinType, generator.getMv());
|
||||
specializedToString.genInvokeInstruction(generator.getMv());
|
||||
generator.invokeAppend(AsmTypes.JAVA_STRING_TYPE);
|
||||
}
|
||||
else if (kotlinType != null && InlineClassesUtilsKt.isInlineClassType(kotlinType)) {
|
||||
appendParameterType = OBJECT_TYPE;
|
||||
SimpleType nullableAnyType = kotlinType.getConstructor().getBuiltIns().getNullableAnyType();
|
||||
StackValue.coerce(type, kotlinType, appendParameterType, nullableAnyType, v);
|
||||
stackValue.put(type, kotlinType, generator.getMv());
|
||||
StackValue.coerce(type, kotlinType, OBJECT_TYPE, nullableAnyType, generator.getMv());
|
||||
generator.invokeAppend(OBJECT_TYPE);
|
||||
}
|
||||
else {
|
||||
appendParameterType = stringBuilderAppendType(type);
|
||||
generator.putValueOrProcessConstant(stackValue, type, kotlinType);
|
||||
}
|
||||
|
||||
v.invokevirtual("java/lang/StringBuilder", "append", "(" + appendParameterType.getDescriptor() + ")Ljava/lang/StringBuilder;", false);
|
||||
}
|
||||
|
||||
public static StackValue genToString(
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -42,7 +43,7 @@ interface Callable {
|
||||
}
|
||||
}
|
||||
|
||||
fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap) {
|
||||
fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap, state: GenerationState) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtPureClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtPureElement
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface
|
||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
@@ -134,8 +135,9 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
||||
remainingParameters.map { DescriptorToSourceUtils.descriptorToDeclaration(it) as? KtParameter }
|
||||
|
||||
val generateAsFinal =
|
||||
functionDescriptor.modality == Modality.FINAL ||
|
||||
state.languageVersionSettings.supportsFeature(LanguageFeature.GenerateJvmOverloadsAsFinal)
|
||||
(functionDescriptor.modality == Modality.FINAL ||
|
||||
state.languageVersionSettings.supportsFeature(LanguageFeature.GenerateJvmOverloadsAsFinal)) &&
|
||||
!isInterface(functionDescriptor.containingDeclaration)
|
||||
val flags =
|
||||
baseMethodFlags or
|
||||
(if (isStatic) Opcodes.ACC_STATIC else 0) or
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.config.ApiVersion;
|
||||
import org.jetbrains.kotlin.config.JVMAssertionsMode;
|
||||
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor;
|
||||
@@ -370,22 +371,17 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||
if (!functionDescriptor.isSuspend()) return stackValue;
|
||||
|
||||
// When we call suspend operator fun invoke using parens, we cannot box receiver as return type inline class
|
||||
if (resolvedCall instanceof VariableAsFunctionResolvedCall &&
|
||||
functionDescriptor.isOperator() && functionDescriptor.getName().getIdentifier().equals("invoke")
|
||||
) return stackValue;
|
||||
|
||||
KotlinType unboxedInlineClass = CoroutineCodegenUtilKt
|
||||
.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(functionDescriptor, typeMapper);
|
||||
|
||||
StackValue stackValueToWrap = stackValue;
|
||||
KotlinType originalKotlinType;
|
||||
if (unboxedInlineClass != null) {
|
||||
originalKotlinType = unboxedInlineClass;
|
||||
} else {
|
||||
originalKotlinType = stackValueToWrap.kotlinType;
|
||||
}
|
||||
Type originalType;
|
||||
if (unboxedInlineClass != null) {
|
||||
originalType = typeMapper.mapType(unboxedInlineClass);
|
||||
} else {
|
||||
originalType = stackValueToWrap.type;
|
||||
}
|
||||
KotlinType originalKotlinType = unboxedInlineClass != null ? unboxedInlineClass : stackValueToWrap.kotlinType;
|
||||
Type originalType = unboxedInlineClass != null ? typeMapper.mapType(unboxedInlineClass) : stackValueToWrap.type;
|
||||
|
||||
stackValue = new StackValue(originalType, originalKotlinType) {
|
||||
@Override
|
||||
@@ -922,28 +918,27 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
else {
|
||||
return StackValue.operation(type, v -> {
|
||||
genStringBuilderConstructor(v);
|
||||
invokeAppendForEntries(v, entries);
|
||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
||||
StringConcatGenerator generator = StringConcatGenerator.Companion.create(state, v);
|
||||
generator.genStringBuilderConstructorIfNeded();
|
||||
invokeAppendForEntries(generator, entries);
|
||||
generator.genToString();
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void invokeAppendForEntries(InstructionAdapter v, List<StringTemplateEntry> entries) {
|
||||
private void invokeAppendForEntries(StringConcatGenerator generator, List<StringTemplateEntry> entries) {
|
||||
for (StringTemplateEntry entry : entries) {
|
||||
if (entry instanceof StringTemplateEntry.Expression) {
|
||||
invokeAppend(v, ((StringTemplateEntry.Expression) entry).expression);
|
||||
invokeAppend(generator, ((StringTemplateEntry.Expression) entry).expression);
|
||||
}
|
||||
else {
|
||||
String value = ((StringTemplateEntry.Constant) entry).value;
|
||||
if (value.length() == 1) {
|
||||
v.iconst(value.charAt(0));
|
||||
genInvokeAppendMethod(v, Type.CHAR_TYPE, null);
|
||||
generator.putValueOrProcessConstant(StackValue.constant(value.charAt(0), Type.CHAR_TYPE, null));
|
||||
}
|
||||
else {
|
||||
v.aconst(value);
|
||||
genInvokeAppendMethod(v, JAVA_STRING_TYPE, null);
|
||||
generator.addStringConstant(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1703,20 +1698,38 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
Type returnType;
|
||||
KotlinType returnKotlinType;
|
||||
if (isNonLocalReturn) {
|
||||
// This is inline lambda. Find inline-site and check, whether it is suspend functions returning unboxed inline class
|
||||
CodegenContext<?> inlineSiteContext = this.context.getFirstCrossInlineOrNonInlineContext();
|
||||
KotlinType originalInlineClass = null;
|
||||
if (inlineSiteContext instanceof MethodContext) {
|
||||
originalInlineClass = CoroutineCodegenUtilKt
|
||||
.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(
|
||||
((MethodContext) inlineSiteContext).getFunctionDescriptor(), typeMapper);
|
||||
}
|
||||
if (originalInlineClass != null) {
|
||||
returnType = typeMapper.mapType(originalInlineClass);
|
||||
returnKotlinType = originalInlineClass;
|
||||
FunctionDescriptor returnTarget =
|
||||
nonLocalReturn.descriptor instanceof FunctionDescriptor
|
||||
? (FunctionDescriptor) nonLocalReturn.descriptor
|
||||
: null;
|
||||
if (returnTarget == null || !returnTarget.isSuspend()) {
|
||||
JvmKotlinType jvmKotlinType = nonLocalReturn.getJvmKotlinType(typeMapper);
|
||||
returnType = jvmKotlinType.getType();
|
||||
returnKotlinType = jvmKotlinType.getKotlinType();
|
||||
} else if (returnTarget instanceof AnonymousFunctionDescriptor) {
|
||||
// Suspend lambdas always return Any?
|
||||
returnType = OBJECT_TYPE;
|
||||
returnKotlinType = state.getModule().getBuiltIns().getNullableAnyType();
|
||||
} else {
|
||||
returnType = nonLocalReturn.returnType.getType();
|
||||
returnKotlinType = nonLocalReturn.returnType.getKotlinType();
|
||||
// This is inline lambda, but return target is ordinary, yet suspend, function.
|
||||
// Find inline-site and check, whether it is suspend functions returning unboxed inline class
|
||||
CodegenContext<?> inlineSiteContext = this.context.getFirstCrossInlineOrNonInlineContext();
|
||||
KotlinType originalInlineClass = null;
|
||||
if (inlineSiteContext instanceof MethodContext) {
|
||||
FunctionDescriptor view = CoroutineCodegenUtilKt.getOrCreateJvmSuspendFunctionView(returnTarget, state);
|
||||
originalInlineClass =
|
||||
CoroutineCodegenUtilKt.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(view, typeMapper);
|
||||
}
|
||||
if (originalInlineClass != null) {
|
||||
// As an optimization, suspend functions, returning inline classes with reference underlying
|
||||
// type return unboxed inline class. Save the type so the coercer will not box it.
|
||||
returnType = typeMapper.mapType(originalInlineClass);
|
||||
returnKotlinType = originalInlineClass;
|
||||
} else {
|
||||
JvmKotlinType jvmKotlinType = nonLocalReturn.getJvmKotlinType(typeMapper);
|
||||
returnType = jvmKotlinType.getType();
|
||||
returnKotlinType = jvmKotlinType.getKotlinType();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1780,13 +1793,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
FunctionDescriptor containingFunction =
|
||||
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, true).getFirst();
|
||||
//FIRST_FUN_LABEL to prevent clashing with existing labels
|
||||
return new NonLocalReturnInfo(
|
||||
new JvmKotlinType(
|
||||
typeMapper.mapReturnType(containingFunction),
|
||||
containingFunction.getReturnType()
|
||||
),
|
||||
FIRST_FUN_LABEL
|
||||
);
|
||||
return new NonLocalReturnInfo(containingFunction, FIRST_FUN_LABEL);
|
||||
} else {
|
||||
//local
|
||||
return null;
|
||||
@@ -1799,10 +1806,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
assert element != null : "Expression should be not null " + expression.getText();
|
||||
assert elementDescriptor != null : "Descriptor should be not null: " + element.getText();
|
||||
CallableDescriptor function = (CallableDescriptor) elementDescriptor;
|
||||
return new NonLocalReturnInfo(
|
||||
new JvmKotlinType(typeMapper.mapReturnType(function), function.getReturnType()),
|
||||
expression.getLabelName()
|
||||
);
|
||||
return new NonLocalReturnInfo(function, expression.getLabelName());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -2836,7 +2840,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
myFrameMap.leaveTemp(firstReceiverType);
|
||||
}
|
||||
|
||||
callableMethod.afterReceiverGeneration(v, myFrameMap);
|
||||
callableMethod.afterReceiverGeneration(v, myFrameMap, state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4297,7 +4301,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
}
|
||||
|
||||
public void invokeAppend(InstructionAdapter v, KtExpression expr) {
|
||||
public void invokeAppend(StringConcatGenerator generator, KtExpression expr) {
|
||||
expr = KtPsiUtil.safeDeparenthesize(expr);
|
||||
|
||||
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr);
|
||||
@@ -4311,28 +4315,29 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
Type leftType = expressionType(left);
|
||||
|
||||
if (leftType.equals(JAVA_STRING_TYPE)) {
|
||||
invokeAppend(v, left);
|
||||
invokeAppend(v, right);
|
||||
invokeAppend(generator, left);
|
||||
invokeAppend(generator, right);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (expr instanceof KtStringTemplateExpression) {
|
||||
List<StringTemplateEntry> entries = preprocessStringTemplate((KtStringTemplateExpression) expr);
|
||||
invokeAppendForEntries(v, entries);
|
||||
invokeAppendForEntries(generator, entries);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Type exprType = expressionType(expr);
|
||||
KotlinType exprKotlinType = kotlinType(expr);
|
||||
StackValue value;
|
||||
if (compileTimeConstant != null) {
|
||||
StackValue.constant(compileTimeConstant.getValue(), exprType, exprKotlinType).put(exprType, exprKotlinType, v);
|
||||
value = StackValue.constant(compileTimeConstant.getValue(), exprType, exprKotlinType);
|
||||
} else {
|
||||
gen(expr, exprType, exprKotlinType);
|
||||
value = gen(expr);
|
||||
}
|
||||
|
||||
genInvokeAppendMethod(v, exprType, exprKotlinType, typeMapper);
|
||||
genInvokeAppendMethod(generator, exprType, exprKotlinType, typeMapper, value);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -5402,14 +5407,18 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
|
||||
private static class NonLocalReturnInfo {
|
||||
|
||||
private final JvmKotlinType returnType;
|
||||
private final CallableDescriptor descriptor;
|
||||
|
||||
private final String labelName;
|
||||
|
||||
private NonLocalReturnInfo(@NotNull JvmKotlinType type, @NotNull String name) {
|
||||
returnType = type;
|
||||
private NonLocalReturnInfo(@NotNull CallableDescriptor descriptor, @NotNull String name) {
|
||||
this.descriptor = descriptor;
|
||||
labelName = name;
|
||||
}
|
||||
|
||||
private JvmKotlinType getJvmKotlinType(@NotNull KotlinTypeMapper typeMapper) {
|
||||
return new JvmKotlinType(typeMapper.mapReturnType(descriptor), descriptor.getReturnType());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1677,7 +1677,8 @@ public class FunctionCodegen {
|
||||
assert isInterface(containingDeclaration) : "'processInterfaceMethod' method should be called only for interfaces, but: " +
|
||||
containingDeclaration;
|
||||
|
||||
if (JvmAnnotationUtilKt.isCompiledToJvmDefault(memberDescriptor, mode)) {
|
||||
// Fake overrides in interfaces should be expanded to implementation to make proper default check
|
||||
if (JvmAnnotationUtilKt.checkIsImplementationCompiledToJvmDefault(memberDescriptor, mode)) {
|
||||
return (kind != OwnerKind.DEFAULT_IMPLS && !isSynthetic) ||
|
||||
(kind == OwnerKind.DEFAULT_IMPLS &&
|
||||
(isSynthetic || //TODO: move synthetic method generation into interface
|
||||
|
||||
@@ -100,18 +100,19 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
|
||||
mv.visitCode();
|
||||
genStringBuilderConstructor(iv);
|
||||
|
||||
StringConcatGenerator generator = StringConcatGenerator.Companion.create(generationState, iv);
|
||||
generator.genStringBuilderConstructorIfNeded();
|
||||
boolean first = true;
|
||||
|
||||
for (PropertyDescriptor propertyDescriptor : properties) {
|
||||
if (first) {
|
||||
iv.aconst(classDescriptor.getName() + "(" + propertyDescriptor.getName().asString() + "=");
|
||||
generator.addStringConstant(classDescriptor.getName() + "(" + propertyDescriptor.getName().asString() + "=");
|
||||
first = false;
|
||||
}
|
||||
else {
|
||||
iv.aconst(", " + propertyDescriptor.getName().asString() + "=");
|
||||
generator.addStringConstant(", " + propertyDescriptor.getName().asString() + "=");
|
||||
}
|
||||
genInvokeAppendMethod(iv, JAVA_STRING_TYPE, null);
|
||||
|
||||
JvmKotlinType type = genOrLoadOnStack(iv, context, propertyDescriptor, 0);
|
||||
Type asmType = type.getType();
|
||||
@@ -130,13 +131,12 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
||||
kotlinType = DescriptorUtilsKt.getBuiltIns(function).getStringType();
|
||||
}
|
||||
}
|
||||
genInvokeAppendMethod(iv, asmType, kotlinType, typeMapper);
|
||||
genInvokeAppendMethod(generator, asmType, kotlinType, typeMapper, StackValue.onStack(asmType));
|
||||
}
|
||||
|
||||
iv.aconst(")");
|
||||
genInvokeAppendMethod(iv, JAVA_STRING_TYPE, null);
|
||||
generator.addStringConstant(")");
|
||||
|
||||
iv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
|
||||
generator.genToString();
|
||||
iv.areturn(JAVA_STRING_TYPE);
|
||||
|
||||
FunctionCodegen.endVisit(mv, toStringMethodName, getDeclaration());
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import com.google.common.collect.Sets
|
||||
import org.jetbrains.kotlin.codegen.BranchedValue.Companion.FALSE
|
||||
import org.jetbrains.kotlin.codegen.BranchedValue.Companion.TRUE
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.JvmStringConcat
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Handle
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.lang.StringBuilder
|
||||
|
||||
class StringConcatGenerator(val mode: JvmStringConcat, val mv: InstructionAdapter) {
|
||||
|
||||
private val template = StringBuilder("")
|
||||
private val paramTypes = arrayListOf<Type>()
|
||||
private var justFlushed = false
|
||||
|
||||
@JvmOverloads
|
||||
fun genStringBuilderConstructorIfNeded(swap: Boolean = false) {
|
||||
if (mode.isDynamic) return
|
||||
mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder")
|
||||
mv.dup()
|
||||
mv.invokespecial("java/lang/StringBuilder", "<init>", "()V", false)
|
||||
if (swap) {
|
||||
mv.swap()
|
||||
}
|
||||
}
|
||||
|
||||
@JvmOverloads
|
||||
fun putValueOrProcessConstant(stackValue: StackValue, type: Type = stackValue.type, kotlinType: KotlinType? = stackValue.kotlinType) {
|
||||
justFlushed = false
|
||||
if (mode == JvmStringConcat.INDY_WITH_CONSTANTS) {
|
||||
when (stackValue) {
|
||||
is StackValue.Constant -> {
|
||||
template.append(stackValue.value)
|
||||
return
|
||||
}
|
||||
TRUE -> {
|
||||
template.append(true)
|
||||
return
|
||||
}
|
||||
FALSE -> {
|
||||
template.append(false)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
stackValue.put(type, kotlinType, mv)
|
||||
invokeAppend(type)
|
||||
}
|
||||
|
||||
fun addStringConstant(value: String) {
|
||||
putValueOrProcessConstant(StackValue.constant(value, JAVA_STRING_TYPE, null))
|
||||
}
|
||||
|
||||
fun invokeAppend(type: Type) {
|
||||
if (!mode.isDynamic) {
|
||||
mv.invokevirtual(
|
||||
"java/lang/StringBuilder",
|
||||
"append",
|
||||
"(" + stringBuilderAppendType(type) + ")Ljava/lang/StringBuilder;",
|
||||
false
|
||||
)
|
||||
} else {
|
||||
justFlushed = false
|
||||
paramTypes.add(type)
|
||||
template.append("\u0001")
|
||||
if (paramTypes.size == 200) {
|
||||
// Concatenate current arguments into string
|
||||
// because of `StringConcatFactory` limitation add use it as new argument for further processing:
|
||||
// "The number of parameter slots in {@code concatType} is less than or equal to 200"
|
||||
genToString()
|
||||
justFlushed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun genToString() {
|
||||
if (!mode.isDynamic) {
|
||||
mv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
||||
} else {
|
||||
//if state was flushed in `invokeAppend` do nothing
|
||||
if (justFlushed) return
|
||||
if (mode == JvmStringConcat.INDY_WITH_CONSTANTS) {
|
||||
val bootstrap = Handle(
|
||||
Opcodes.H_INVOKESTATIC,
|
||||
"java/lang/invoke/StringConcatFactory",
|
||||
"makeConcatWithConstants",
|
||||
"(Ljava/lang/invoke/MethodHandles\$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;",
|
||||
false
|
||||
)
|
||||
|
||||
mv.invokedynamic(
|
||||
"makeConcatWithConstants",
|
||||
Type.getMethodDescriptor(JAVA_STRING_TYPE, *paramTypes.toTypedArray()),
|
||||
bootstrap,
|
||||
arrayOf(template.toString())
|
||||
)
|
||||
} else {
|
||||
val bootstrap = Handle(
|
||||
Opcodes.H_INVOKESTATIC,
|
||||
"java/lang/invoke/StringConcatFactory",
|
||||
"makeConcat",
|
||||
"(Ljava/lang/invoke/MethodHandles\$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;",
|
||||
false
|
||||
)
|
||||
|
||||
mv.invokedynamic(
|
||||
"makeConcat",
|
||||
Type.getMethodDescriptor(JAVA_STRING_TYPE, *paramTypes.toTypedArray()),
|
||||
bootstrap,
|
||||
arrayOf()
|
||||
)
|
||||
}
|
||||
template.clear()
|
||||
paramTypes.clear()
|
||||
paramTypes.add(JAVA_STRING_TYPE)
|
||||
template.append("\u0001")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val STRING_BUILDER_OBJECT_APPEND_ARG_TYPES: Set<Type> = Sets.newHashSet(
|
||||
AsmTypes.getType(String::class.java),
|
||||
AsmTypes.getType(StringBuffer::class.java),
|
||||
AsmTypes.getType(CharSequence::class.java)
|
||||
)
|
||||
|
||||
private fun stringBuilderAppendType(type: Type): Type {
|
||||
return when (type.sort) {
|
||||
Type.OBJECT -> if (STRING_BUILDER_OBJECT_APPEND_ARG_TYPES.contains(type)) type else AsmTypes.OBJECT_TYPE
|
||||
Type.ARRAY -> AsmTypes.OBJECT_TYPE
|
||||
Type.BYTE, Type.SHORT -> Type.INT_TYPE
|
||||
else -> type
|
||||
}
|
||||
}
|
||||
|
||||
fun create(state: GenerationState, mv: InstructionAdapter) =
|
||||
StringConcatGenerator(state.runtimeStringConcat, mv)
|
||||
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
@@ -294,7 +295,7 @@ class CoroutineCodegenForLambda private constructor(
|
||||
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, funDescriptor,
|
||||
object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||
codegen.v.generateInvokeMethod(signature)
|
||||
codegen.v.generateInvokeMethod(signature, funDescriptor)
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -316,13 +317,13 @@ class CoroutineCodegenForLambda private constructor(
|
||||
)
|
||||
mv.visitCode()
|
||||
with(InstructionAdapter(mv)) {
|
||||
generateInvokeMethod(jvmMethodSignature)
|
||||
generateInvokeMethod(jvmMethodSignature, untypedDescriptor)
|
||||
}
|
||||
|
||||
FunctionCodegen.endVisit(mv, "invoke", element)
|
||||
}
|
||||
|
||||
private fun InstructionAdapter.generateInvokeMethod(signature: JvmMethodSignature) {
|
||||
private fun InstructionAdapter.generateInvokeMethod(signature: JvmMethodSignature, descriptor: FunctionDescriptor) {
|
||||
// this
|
||||
load(0, AsmTypes.OBJECT_TYPE)
|
||||
val parameterTypes = signature.valueParameters.map { it.asmType }
|
||||
@@ -348,16 +349,23 @@ class CoroutineCodegenForLambda private constructor(
|
||||
load(arraySlot, AsmTypes.OBJECT_TYPE)
|
||||
} else {
|
||||
var index = 0
|
||||
val fromKotlinTypes =
|
||||
if (!generateErasedCreate && doNotGenerateInvokeBridge) funDescriptor.allValueParameterTypes()
|
||||
else funDescriptor.allValueParameterTypes().map { funDescriptor.module.builtIns.nullableAnyType }
|
||||
val toKotlinTypes =
|
||||
if (!generateErasedCreate && doNotGenerateInvokeBridge) createCoroutineDescriptor.allValueParameterTypes()
|
||||
else descriptor.allValueParameterTypes()
|
||||
parameterTypes.withVariableIndices().forEach { (varIndex, type) ->
|
||||
load(varIndex + 1, type)
|
||||
StackValue.coerce(type, createArgumentTypes[index++], this)
|
||||
StackValue.coerce(type, fromKotlinTypes[index], createArgumentTypes[index], toKotlinTypes[index], this)
|
||||
index++
|
||||
}
|
||||
}
|
||||
|
||||
// this.create(..)
|
||||
invokevirtual(
|
||||
v.thisName,
|
||||
createCoroutineDescriptor.name.identifier,
|
||||
typeMapper.mapFunctionName(createCoroutineDescriptor, null),
|
||||
Type.getMethodDescriptor(
|
||||
languageVersionSettings.continuationAsmType(),
|
||||
*createArgumentTypes.toTypedArray()
|
||||
@@ -439,12 +447,24 @@ class CoroutineCodegenForLambda private constructor(
|
||||
)
|
||||
} else {
|
||||
if (generateErasedCreate) {
|
||||
load(index, AsmTypes.OBJECT_TYPE)
|
||||
StackValue.coerce(
|
||||
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
||||
this
|
||||
)
|
||||
if (parameter.type.isInlineClassType()) {
|
||||
load(cloneIndex, fieldInfoForCoroutineLambdaParameter.ownerType)
|
||||
load(index, AsmTypes.OBJECT_TYPE)
|
||||
StackValue.unboxInlineClass(AsmTypes.OBJECT_TYPE, parameter.type, this)
|
||||
putfield(
|
||||
fieldInfoForCoroutineLambdaParameter.ownerInternalName,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldName,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldType.descriptor
|
||||
)
|
||||
continue
|
||||
} else {
|
||||
load(index, AsmTypes.OBJECT_TYPE)
|
||||
StackValue.coerce(
|
||||
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
||||
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
||||
this
|
||||
)
|
||||
}
|
||||
} else {
|
||||
load(index, fieldInfoForCoroutineLambdaParameter.fieldType)
|
||||
}
|
||||
@@ -831,3 +851,6 @@ private object FailingFunctionGenerationStrategy : FunctionGenerationStrategy()
|
||||
fun reportSuspensionPointInsideMonitor(element: KtElement, state: GenerationState, stackTraceElement: String) {
|
||||
state.diagnostics.report(ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR.on(element, stackTraceElement))
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.allValueParameterTypes(): List<KotlinType> =
|
||||
(listOfNotNull(extensionReceiverParameter?.type)) + valueParameters.map { it.type }
|
||||
@@ -1239,11 +1239,26 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
||||
val endLabel = insn as? LabelNode ?: insn.findNextOrNull { it is LabelNode } as? LabelNode ?: continue
|
||||
// startLabel can be null in case of parameters
|
||||
@Suppress("NAME_SHADOWING") val startLabel = startLabel ?: lvtRecord.start
|
||||
// No LINENUMBER in range -> no way to put a breakpoint -> do not bother adding a record
|
||||
if (InsnSequence(startLabel, endLabel).none { it is LineNumberNode }) continue
|
||||
method.localVariables.add(
|
||||
LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index)
|
||||
)
|
||||
var recordToExtend: LocalVariableNode? = null
|
||||
for (record in method.localVariables) {
|
||||
if (record.name == lvtRecord.name &&
|
||||
record.desc == lvtRecord.desc &&
|
||||
record.signature == lvtRecord.signature &&
|
||||
record.index == lvtRecord.index
|
||||
) {
|
||||
if (InsnSequence(record.end, startLabel).none { isBeforeSuspendMarker(it) }) {
|
||||
recordToExtend = record
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (recordToExtend != null) {
|
||||
recordToExtend.end = endLabel
|
||||
} else {
|
||||
method.localVariables.add(
|
||||
LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,11 @@ private class UnitSourceInterpreter(private val localVariables: Set<Int>) : Basi
|
||||
|
||||
override fun merge(value1: BasicValue?, value2: BasicValue?): BasicValue? =
|
||||
if (value1 is UnitValue && value2 is UnitValue) {
|
||||
UnitValue(value1.insns.union(value2.insns))
|
||||
val newValue = UnitValue(value1.insns.union(value2.insns))
|
||||
if (newValue.insns.any { it in unspillableUnitValues }) {
|
||||
markUnspillable(newValue)
|
||||
}
|
||||
newValue
|
||||
} else {
|
||||
// Mark unit values as unspillable if we merge them with non-unit values here.
|
||||
// This is conservative since the value could turn out to be unused.
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||
import org.jetbrains.kotlin.resolve.inline.isEffectivelyInlineOnly
|
||||
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
@@ -92,7 +93,9 @@ class SuspendFunctionGenerationStrategy(
|
||||
sourceFile = declaration.containingKtFile.name,
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
|
||||
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
|
||||
internalNameForDispatchReceiver = (originalSuspendDescriptor.containingDeclaration as? ClassDescriptor)?.let {
|
||||
if (it.isInlineClass()) state.typeMapper.mapType(it).internalName else null
|
||||
} ?: containingClassInternalNameOrNull(),
|
||||
languageVersionSettings = languageVersionSettings,
|
||||
disableTailCallOptimizationForFunctionReturningUnit = originalSuspendDescriptor.returnType?.isUnit() == true &&
|
||||
originalSuspendDescriptor.overriddenDescriptors.isNotEmpty() &&
|
||||
|
||||
@@ -475,7 +475,8 @@ fun FunctionDescriptor.originalReturnTypeOfSuspendFunctionReturningUnboxedInline
|
||||
// Force boxing if the function overrides function with different type modulo nullability
|
||||
if (originalDescriptor.overriddenDescriptors.any {
|
||||
(it.original.returnType?.isMarkedNullable == true && it.original.returnType?.isNullableUnderlyingType() == true) ||
|
||||
it.original.returnType?.makeNotNullable() != originalReturnType.makeNotNullable()
|
||||
// We do not care about type parameters, just main class type
|
||||
it.original.returnType?.constructor?.declarationDescriptor != originalReturnType.constructor.declarationDescriptor
|
||||
}) return null
|
||||
// Don't box other inline classes
|
||||
return originalReturnType
|
||||
@@ -542,3 +543,12 @@ val EXPERIMENTAL_CONTINUATION_ASM_TYPE = StandardNames.CONTINUATION_INTERFACE_FQ
|
||||
|
||||
@JvmField
|
||||
val RELEASE_CONTINUATION_ASM_TYPE = StandardNames.CONTINUATION_INTERFACE_FQ_NAME_RELEASE.topLevelClassAsmType()
|
||||
|
||||
fun FunctionDescriptor.isInvokeSuspendOfLambda(): Boolean {
|
||||
if (this !is SimpleFunctionDescriptor) return false
|
||||
if (valueParameters.size != 1 ||
|
||||
valueParameters[0].name.asString() != SUSPEND_CALL_RESULT_NAME ||
|
||||
name.asString() != "invokeSuspend"
|
||||
) return false
|
||||
return containingDeclaration is SyntheticClassDescriptorForLambda
|
||||
}
|
||||
@@ -57,6 +57,7 @@ class AnonymousObjectTransformer(
|
||||
lateinit var superClassName: String
|
||||
var sourceInfo: String? = null
|
||||
var debugInfo: String? = null
|
||||
var debugMetadataAnnotation: AnnotationNode? = null
|
||||
|
||||
createClassReader().accept(object : ClassVisitor(Opcodes.API_VERSION, classBuilder.visitor) {
|
||||
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
|
||||
@@ -77,7 +78,8 @@ class AnonymousObjectTransformer(
|
||||
val innerClassesInfo = FileBasedKotlinClass.InnerClassesInfo()
|
||||
return FileBasedKotlinClass.convertAnnotationVisitor(metadataReader, desc, innerClassesInfo)
|
||||
} else if (desc == DEBUG_METADATA_ANNOTATION_ASM_TYPE.descriptor) {
|
||||
return null
|
||||
debugMetadataAnnotation = AnnotationNode(desc)
|
||||
return debugMetadataAnnotation
|
||||
}
|
||||
return super.visitAnnotation(desc, visible)
|
||||
}
|
||||
@@ -137,12 +139,20 @@ class AnonymousObjectTransformer(
|
||||
methodsToTransform,
|
||||
superClassName
|
||||
)
|
||||
var putDebugMetadata = false
|
||||
loop@ for (next in methodsToTransform) {
|
||||
val deferringVisitor =
|
||||
when {
|
||||
coroutineTransformer.shouldSkip(next) -> continue@loop
|
||||
coroutineTransformer.shouldGenerateStateMachine(next) -> coroutineTransformer.newMethod(next)
|
||||
else -> newMethod(classBuilder, next)
|
||||
else -> {
|
||||
// Debug metadata is not put, but we should keep, since we do not generate state-machine,
|
||||
// if the lambda does not capture crossinline lambdas.
|
||||
if (coroutineTransformer.suspendLambdaWithGeneratedStateMachine(next)) {
|
||||
putDebugMetadata = true
|
||||
}
|
||||
newMethod(classBuilder, next)
|
||||
}
|
||||
}
|
||||
|
||||
if (next.name == "<clinit>") {
|
||||
@@ -190,6 +200,13 @@ class AnonymousObjectTransformer(
|
||||
writeTransformedMetadata(header, classBuilder)
|
||||
}
|
||||
|
||||
// debugMetadataAnnotation can be null in LV < 1.3
|
||||
if (putDebugMetadata && debugMetadataAnnotation != null) {
|
||||
visitor.visitAnnotation(debugMetadataAnnotation!!.desc, true).also {
|
||||
debugMetadataAnnotation!!.accept(it)
|
||||
}
|
||||
}
|
||||
|
||||
writeOuterInfo(visitor)
|
||||
|
||||
if (inliningContext.generateAssertField && fieldNames.none { it.key == ASSERTIONS_DISABLED_FIELD_NAME }) {
|
||||
|
||||
@@ -37,7 +37,7 @@ open class MethodBodyVisitor(mv: MethodVisitor) : MethodVisitor(Opcodes.API_VERS
|
||||
|
||||
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? = null
|
||||
|
||||
override fun visitTypeAnnotation(typeRef: Int, typePath: TypePath, desc: String, visible: Boolean): AnnotationVisitor? = null
|
||||
override fun visitTypeAnnotation(typeRef: Int, typePath: TypePath?, desc: String, visible: Boolean): AnnotationVisitor? = null
|
||||
|
||||
override fun visitParameterAnnotation(parameter: Int, desc: String, visible: Boolean): AnnotationVisitor? = null
|
||||
|
||||
|
||||
@@ -43,11 +43,14 @@ class CoroutineTransformer(
|
||||
fun shouldGenerateStateMachine(node: MethodNode): Boolean {
|
||||
// Continuations are similar to lambdas from bird's view, but we should never generate state machine for them
|
||||
if (isContinuationNotLambda()) return false
|
||||
// there can be suspend lambdas inside inline functions, which do not
|
||||
// capture crossinline lambdas, thus, there is no need to transform them
|
||||
return isSuspendFunctionWithFakeConstructorCall(node) || (isSuspendLambda(node) && !isStateMachine(node))
|
||||
}
|
||||
|
||||
// there can be suspend lambdas inside inline functions, which do not
|
||||
// capture crossinline lambdas, thus, there is no need to transform them
|
||||
fun suspendLambdaWithGeneratedStateMachine(node: MethodNode): Boolean =
|
||||
!isContinuationNotLambda() && isSuspendLambda(node) && isStateMachine(node)
|
||||
|
||||
private fun isContinuationNotLambda(): Boolean = inliningContext.isContinuation &&
|
||||
if (state.languageVersionSettings.isReleaseCoroutines()) superClassName.endsWith("ContinuationImpl")
|
||||
else methods.any { it.name == "getLabel" }
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.intrinsics
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.genInvokeAppendMethod
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.genStringBuilderConstructor
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
@@ -32,68 +32,73 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class Concat : IntrinsicMethod() {
|
||||
fun generateImpl(
|
||||
codegen: ExpressionCodegen,
|
||||
v: InstructionAdapter,
|
||||
returnType: Type,
|
||||
element: PsiElement?,
|
||||
arguments: List<KtExpression>,
|
||||
receiver: StackValue
|
||||
codegen: ExpressionCodegen,
|
||||
v: InstructionAdapter,
|
||||
returnType: Type,
|
||||
element: PsiElement?,
|
||||
arguments: List<KtExpression>,
|
||||
receiver: StackValue
|
||||
): Type {
|
||||
val generator = StringConcatGenerator.create(codegen.state, v)
|
||||
if (element is KtBinaryExpression && element.operationReference.getReferencedNameElementType() == KtTokens.PLUS) {
|
||||
// LHS + RHS
|
||||
genStringBuilderConstructor(v)
|
||||
codegen.invokeAppend(v, element.left)
|
||||
codegen.invokeAppend(v, element.right)
|
||||
}
|
||||
else {
|
||||
// LHS + RHS
|
||||
generator.genStringBuilderConstructorIfNeded()
|
||||
codegen.invokeAppend(generator, element.left)
|
||||
codegen.invokeAppend(generator, element.right)
|
||||
} else {
|
||||
// Explicit plus call LHS?.plus(RHS) or LHS.plus(RHS)
|
||||
receiver.put(AsmTypes.JAVA_STRING_TYPE, v)
|
||||
genStringBuilderConstructor(v)
|
||||
v.swap()
|
||||
genInvokeAppendMethod(v, returnType, null)
|
||||
codegen.invokeAppend(v, arguments[0])
|
||||
generator.genStringBuilderConstructorIfNeded(true)
|
||||
genInvokeAppendMethod(generator, returnType, null, null, StackValue.onStack(JAVA_STRING_TYPE))
|
||||
codegen.invokeAppend(generator, arguments[0])
|
||||
}
|
||||
|
||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
||||
generator.genToString()
|
||||
return JAVA_STRING_TYPE
|
||||
}
|
||||
|
||||
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
object : IntrinsicCallable(method) {
|
||||
override fun invokeMethodWithArguments(
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
receiver: StackValue,
|
||||
codegen: ExpressionCodegen
|
||||
): StackValue {
|
||||
if (resolvedCall.call.callElement.parent is KtCallableReferenceExpression) {
|
||||
// NB we come here only in case of inlined callable reference to String::plus.
|
||||
// This will map arguments properly, invoking callbacks defined in Callable.
|
||||
return super.invokeMethodWithArguments(resolvedCall, receiver, codegen)
|
||||
}
|
||||
return StackValue.operation(returnType) {
|
||||
val arguments = resolvedCall.call.valueArguments.map { it.getArgumentExpression()!! }
|
||||
val actualType = generateImpl(
|
||||
codegen, it, returnType,
|
||||
resolvedCall.call.callElement,
|
||||
arguments,
|
||||
StackValue.receiver(resolvedCall, receiver, codegen, this)
|
||||
)
|
||||
StackValue.coerce(actualType, returnType, it)
|
||||
}
|
||||
object : IntrinsicCallable(method) {
|
||||
lateinit var generator: StringConcatGenerator
|
||||
override fun invokeMethodWithArguments(
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
receiver: StackValue,
|
||||
codegen: ExpressionCodegen
|
||||
): StackValue {
|
||||
if (resolvedCall.call.callElement.parent is KtCallableReferenceExpression) {
|
||||
// NB we come here only in case of inlined callable reference to String::plus.
|
||||
// This will map arguments properly, invoking callbacks defined in Callable.
|
||||
return super.invokeMethodWithArguments(resolvedCall, receiver, codegen)
|
||||
}
|
||||
|
||||
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap) {
|
||||
v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, AsmTypes.JAVA_STRING_TYPE, "java/lang/StringBuilder")
|
||||
v.invokespecial("java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false)
|
||||
}
|
||||
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
// String::plus has type String.(Any?) -> String, thus we have no argument type information
|
||||
// in case of callable reference passed to a generic function, e.g.:
|
||||
// charArrayOf('O', 'K').fold("", String::plus)
|
||||
// TODO Make String::plus generic, and invoke proper StringBuilder#append.
|
||||
AsmUtil.genInvokeAppendMethod(v, AsmTypes.OBJECT_TYPE, null)
|
||||
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false)
|
||||
return StackValue.operation(returnType) {
|
||||
val arguments = resolvedCall.call.valueArguments.map { it.getArgumentExpression()!! }
|
||||
val actualType = generateImpl(
|
||||
codegen, it, returnType,
|
||||
resolvedCall.call.callElement,
|
||||
arguments,
|
||||
StackValue.receiver(resolvedCall, receiver, codegen, this)
|
||||
)
|
||||
StackValue.coerce(actualType, returnType, it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap, state: GenerationState) {
|
||||
generator = StringConcatGenerator.create(state, v)
|
||||
if (!generator.mode.isDynamic) {
|
||||
v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, JAVA_STRING_TYPE, "java/lang/StringBuilder")
|
||||
v.invokespecial("java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V", false)
|
||||
} else {
|
||||
generator.invokeAppend(JAVA_STRING_TYPE)
|
||||
}
|
||||
}
|
||||
|
||||
override fun invokeIntrinsic(v: InstructionAdapter) {
|
||||
// String::plus has type String.(Any?) -> String, thus we have no argument type information
|
||||
// in case of callable reference passed to a generic function, e.g.:
|
||||
// charArrayOf('O', 'K').fold("", String::plus)
|
||||
// TODO Make String::plus generic, and invoke proper StringBuilder#append.
|
||||
generator.invokeAppend(AsmTypes.OBJECT_TYPE)
|
||||
generator.genToString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.codegen.FrameMap
|
||||
import org.jetbrains.kotlin.codegen.generateNewInstanceDupAndPlaceBeforeStackTop
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.Type.*
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
@@ -48,7 +49,7 @@ class RangeTo : IntrinsicMethod() {
|
||||
nullOr(method.dispatchReceiverType, argType),
|
||||
nullOr(method.extensionReceiverType, argType)
|
||||
) {
|
||||
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap) {
|
||||
override fun afterReceiverGeneration(v: InstructionAdapter, frameMap: FrameMap, state: GenerationState) {
|
||||
v.generateNewInstanceDupAndPlaceBeforeStackTop(frameMap, argType, returnType.internalName)
|
||||
}
|
||||
|
||||
|
||||
@@ -16,13 +16,37 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class StringPlus : IntrinsicMethod() {
|
||||
override fun toCallable(method: CallableMethod): Callable =
|
||||
createIntrinsicCallable(method) {
|
||||
it.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "stringPlus",
|
||||
"(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false)
|
||||
object : IntrinsicCallable(method) {
|
||||
private lateinit var generator: StringConcatGenerator
|
||||
|
||||
override fun invokeMethodWithArguments(
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
receiver: StackValue,
|
||||
codegen: ExpressionCodegen
|
||||
): StackValue {
|
||||
generator = StringConcatGenerator.create(codegen.state, codegen.v)
|
||||
return super.invokeMethodWithArguments(resolvedCall, receiver, codegen)
|
||||
}
|
||||
|
||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||
if (!generator.mode.isDynamic) {
|
||||
v.invokestatic(
|
||||
IntrinsicMethods.INTRINSICS_CLASS_NAME, "stringPlus",
|
||||
"(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;", false
|
||||
)
|
||||
} else {
|
||||
generator.invokeAppend(AsmTypes.JAVA_STRING_TYPE)
|
||||
//TODO: process constants properly, do not upcast to object
|
||||
generator.invokeAppend(AsmTypes.OBJECT_TYPE)
|
||||
generator.genToString()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,6 +191,10 @@ class GenerationState private constructor(
|
||||
val languageVersionSettings = configuration.languageVersionSettings
|
||||
|
||||
val target = configuration.get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT
|
||||
val runtimeStringConcat =
|
||||
if (target.bytecodeVersion >= JvmTarget.JVM_9.bytecodeVersion)
|
||||
configuration.get(JVMConfigurationKeys.STRING_CONCAT) ?: JvmStringConcat.INLINE
|
||||
else JvmStringConcat.INLINE
|
||||
|
||||
val moduleName: String = moduleName ?: JvmCodegenUtil.getModuleName(module)
|
||||
val classBuilderMode: ClassBuilderMode = builderFactory.classBuilderMode
|
||||
|
||||
@@ -18,3 +18,8 @@ sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
}
|
||||
|
||||
tasks.getByName<Jar>("jar") {
|
||||
//excludes unused bunch files
|
||||
exclude("META-INF/extensions/*.xml.**")
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<idea-plugin>
|
||||
<id>org.jetbrains.kotlin</id>
|
||||
<version>1.2</version>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="com.intellij.psi.classFileDecompiler"
|
||||
interface="com.intellij.psi.compiled.ClassFileDecompilers$Decompiler"
|
||||
dynamic="true"/>
|
||||
</extensionPoints>
|
||||
</idea-plugin>
|
||||
@@ -352,6 +352,12 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
)
|
||||
var deserializeFakeOverrides: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xinference-compatibility",
|
||||
description = "Enable compatibility changes for generic type inference algorithm"
|
||||
)
|
||||
var inferenceCompatibility: Boolean by FreezableVar(false)
|
||||
|
||||
open fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||
return HashMap<AnalysisFlag<*>, Any>().apply {
|
||||
put(AnalysisFlags.skipMetadataVersionCheck, skipMetadataVersionCheck)
|
||||
@@ -426,6 +432,10 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
put(LanguageFeature.MixedNamedArgumentsInTheirOwnPosition, LanguageFeature.State.ENABLED)
|
||||
}
|
||||
|
||||
if (inferenceCompatibility) {
|
||||
put(LanguageFeature.InferenceCompatibility, LanguageFeature.State.ENABLED)
|
||||
}
|
||||
|
||||
if (progressiveMode) {
|
||||
LanguageFeature.values().filter { it.kind.enabledInProgressiveMode }.forEach {
|
||||
// Don't overwrite other settings: users may want to turn off some particular
|
||||
|
||||
@@ -70,7 +70,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
@Argument(
|
||||
value = "-jvm-target",
|
||||
valueDescription = "<version>",
|
||||
description = "Target version of the generated JVM bytecode (1.6, 1.8, 9, 10, 11, 12, 13 or 14), default is 1.6"
|
||||
description = "Target version of the generated JVM bytecode (1.6, 1.8, 9, 10, 11, 12, 13, 14 or 15), default is 1.6"
|
||||
)
|
||||
var jvmTarget: String? by NullableStringFreezableVar(JvmTarget.DEFAULT.description)
|
||||
|
||||
@@ -333,6 +333,16 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
)
|
||||
var emitJvmTypeAnnotations: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xstring-concat",
|
||||
valueDescription = "{indy-with-constants|indy|inline}",
|
||||
description = """Switch a way in which string concatenation is performed.
|
||||
-Xstring-concat=indy-with-constants Performs string concatenation via `invokedynamic` 'makeConcatWithConstants'. Works only with `-jvm-target 9` or greater
|
||||
-Xstring-concat=indy Performs string concatenation via `invokedynamic` 'makeConcat'. Works only with `-jvm-target 9` or greater
|
||||
-Xstring-concat=inline Performs string concatenation via `StringBuilder`"""
|
||||
)
|
||||
var stringConcat: String? by NullableStringFreezableVar(JvmStringConcat.INLINE.description)
|
||||
|
||||
@Argument(
|
||||
value = "-Xklib",
|
||||
valueDescription = "<path>",
|
||||
|
||||
@@ -141,6 +141,9 @@ class ScriptRunner(private val path: String) : RunnerWithCompiler() {
|
||||
addClasspathArgIfNeeded(classpath)
|
||||
add("-script")
|
||||
add(path)
|
||||
if (arguments.isNotEmpty() && arguments.first() != "--") {
|
||||
add("--")
|
||||
}
|
||||
addAll(arguments)
|
||||
}
|
||||
runCompiler(compilerClasspath, compilerArgs)
|
||||
@@ -153,6 +156,9 @@ class ExpressionRunner(private val code: String) : RunnerWithCompiler() {
|
||||
addClasspathArgIfNeeded(classpath)
|
||||
add("-expression")
|
||||
add(code)
|
||||
if (arguments.isNotEmpty() && arguments.first() != "--") {
|
||||
add("--")
|
||||
}
|
||||
addAll(arguments)
|
||||
}
|
||||
runCompiler(compilerClasspath, compilerArgs)
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler;
|
||||
|
||||
import com.intellij.DynamicBundle;
|
||||
import com.intellij.codeInsight.ContainerProvider;
|
||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
|
||||
import com.intellij.core.JavaCoreApplicationEnvironment;
|
||||
import com.intellij.lang.MetaLanguage;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
||||
import com.intellij.psi.FileContextProvider;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.meta.MetaDataContributor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
||||
|
||||
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
|
||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
||||
registerExtensionPoints();
|
||||
return environment;
|
||||
}
|
||||
|
||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
||||
super(parentDisposable, unitTestMode);
|
||||
}
|
||||
|
||||
private static void registerExtensionPoints() {
|
||||
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
|
||||
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
||||
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
||||
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||
|
||||
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||
|
||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected VirtualFileSystem createJrtFileSystem() {
|
||||
return new CoreJrtFileSystem();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.openapi.project.DumbUtil
|
||||
|
||||
@Suppress("UnstableApiUsage")
|
||||
class KotlinCoreDumbUtil : DumbUtil {
|
||||
override fun <T : Any?> filterByDumbAwarenessHonoringIgnoring(collection: Collection<T>): List<T> =
|
||||
when (collection) {
|
||||
is List<T> -> collection
|
||||
else -> ArrayList(collection)
|
||||
}
|
||||
|
||||
override fun mayUseIndices(): Boolean = false
|
||||
}
|
||||
@@ -488,7 +488,10 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun disposeApplicationEnvironment() {
|
||||
/**
|
||||
* This method is also used in Gradle after configuration phase finished.
|
||||
*/
|
||||
fun disposeApplicationEnvironment() {
|
||||
synchronized(APPLICATION_LOCK) {
|
||||
val environment = ourApplicationEnvironment ?: return
|
||||
ourApplicationEnvironment = null
|
||||
|
||||
@@ -0,0 +1,684 @@
|
||||
/*
|
||||
* Copyright 2010-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 org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.codeInsight.ExternalAnnotationsManager
|
||||
import com.intellij.codeInsight.InferredAnnotationsManager
|
||||
import com.intellij.core.CoreApplicationEnvironment
|
||||
import com.intellij.core.CoreJavaFileManager
|
||||
import com.intellij.core.JavaCoreProjectEnvironment
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.lang.java.JavaParserDefinition
|
||||
import com.intellij.mock.MockProject
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.application.TransactionGuardImpl
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.extensions.ExtensionsArea
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType
|
||||
import com.intellij.openapi.project.DumbUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.*
|
||||
import com.intellij.openapi.vfs.impl.ZipHandler
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.impl.JavaClassSupersImpl
|
||||
import com.intellij.psi.impl.PsiElementFinderImpl
|
||||
import com.intellij.psi.impl.PsiTreeChangePreprocessor
|
||||
import com.intellij.psi.impl.file.impl.JavaFileManager
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.JavaClassSupers
|
||||
import com.intellij.util.io.URLUtil
|
||||
import com.intellij.util.lang.UrlClassLoader
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.FacadeCache
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl
|
||||
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
|
||||
import org.jetbrains.kotlin.cli.common.config.ContentRoot
|
||||
import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
|
||||
import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots
|
||||
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension
|
||||
import org.jetbrains.kotlin.cli.common.extensions.ShellExtension
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
||||
import org.jetbrains.kotlin.cli.jvm.JvmRuntimeVersionsConsistencyChecker
|
||||
import org.jetbrains.kotlin.cli.jvm.config.*
|
||||
import org.jetbrains.kotlin.cli.jvm.index.*
|
||||
import org.jetbrains.kotlin.cli.jvm.javac.JavacWrapperRegistrar
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver
|
||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
|
||||
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
|
||||
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
||||
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||
import org.jetbrains.kotlin.config.APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.extensions.*
|
||||
import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor
|
||||
import org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptor
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.js.translate.extensions.JsSyntheticTranslateExtension
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
|
||||
import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver
|
||||
import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension
|
||||
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
|
||||
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.File
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
class KotlinCoreEnvironment private constructor(
|
||||
val projectEnvironment: JavaCoreProjectEnvironment,
|
||||
initialConfiguration: CompilerConfiguration,
|
||||
configFiles: EnvironmentConfigFiles
|
||||
) {
|
||||
|
||||
class ProjectEnvironment(
|
||||
disposable: Disposable, applicationEnvironment: KotlinCoreApplicationEnvironment
|
||||
) :
|
||||
KotlinCoreProjectEnvironment(disposable, applicationEnvironment) {
|
||||
|
||||
private var extensionRegistered = false
|
||||
|
||||
override fun preregisterServices() {
|
||||
registerProjectExtensionPoints(Extensions.getArea(project))
|
||||
}
|
||||
|
||||
fun registerExtensionsFromPlugins(configuration: CompilerConfiguration) {
|
||||
if (!extensionRegistered) {
|
||||
registerPluginExtensionPoints(project)
|
||||
registerExtensionsFromPlugins(project, configuration)
|
||||
extensionRegistered = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun registerJavaPsiFacade() {
|
||||
with(project) {
|
||||
registerService(
|
||||
CoreJavaFileManager::class.java,
|
||||
ServiceManager.getService(this, JavaFileManager::class.java) as CoreJavaFileManager
|
||||
)
|
||||
|
||||
registerKotlinLightClassSupport(project)
|
||||
|
||||
registerService(ExternalAnnotationsManager::class.java, MockExternalAnnotationsManager())
|
||||
registerService(InferredAnnotationsManager::class.java, MockInferredAnnotationsManager())
|
||||
}
|
||||
|
||||
super.registerJavaPsiFacade()
|
||||
}
|
||||
}
|
||||
|
||||
private val sourceFiles = mutableListOf<KtFile>()
|
||||
private val rootsIndex: JvmDependenciesDynamicCompoundIndex
|
||||
private val packagePartProviders = mutableListOf<JvmPackagePartProvider>()
|
||||
|
||||
private val classpathRootsResolver: ClasspathRootsResolver
|
||||
private val initialRoots = ArrayList<JavaRoot>()
|
||||
|
||||
val configuration: CompilerConfiguration = initialConfiguration.apply { setupJdkClasspathRoots(configFiles) }.copy()
|
||||
|
||||
init {
|
||||
PersistentFSConstants::class.java.getDeclaredField("ourMaxIntellisenseFileSize")
|
||||
.apply { isAccessible = true }
|
||||
.setInt(null, FileUtilRt.LARGE_FOR_CONTENT_LOADING)
|
||||
|
||||
val project = projectEnvironment.project
|
||||
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
|
||||
(projectEnvironment as? ProjectEnvironment)?.registerExtensionsFromPlugins(configuration)
|
||||
// otherwise consider that project environment is properly configured before passing to the environment
|
||||
// TODO: consider some asserts to check important extension points
|
||||
|
||||
project.registerService(DeclarationProviderFactoryService::class.java, CliDeclarationProviderFactoryService(sourceFiles))
|
||||
|
||||
val isJvm = configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
project.registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(isJvm))
|
||||
|
||||
registerProjectServicesForCLI(projectEnvironment)
|
||||
|
||||
registerProjectServices(projectEnvironment.project)
|
||||
|
||||
for (extension in CompilerConfigurationExtension.getInstances(project)) {
|
||||
extension.updateConfiguration(configuration)
|
||||
}
|
||||
|
||||
sourceFiles += createKtFiles(project)
|
||||
|
||||
collectAdditionalSources(project)
|
||||
|
||||
sourceFiles.sortBy { it.virtualFile.path }
|
||||
|
||||
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
|
||||
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
|
||||
val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path ->
|
||||
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
||||
})
|
||||
|
||||
val outputDirectory =
|
||||
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
|
||||
?: configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)?.absolutePath
|
||||
|
||||
classpathRootsResolver = ClasspathRootsResolver(
|
||||
PsiManager.getInstance(project),
|
||||
messageCollector,
|
||||
configuration.getList(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES),
|
||||
this::contentRootToVirtualFile,
|
||||
javaModuleFinder,
|
||||
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
|
||||
outputDirectory?.let(this::findLocalFile)
|
||||
)
|
||||
|
||||
val (initialRoots, javaModules) =
|
||||
classpathRootsResolver.convertClasspathRoots(configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS))
|
||||
this.initialRoots.addAll(initialRoots)
|
||||
|
||||
if (!configuration.getBoolean(JVMConfigurationKeys.SKIP_RUNTIME_VERSION_CHECK) && messageCollector != null) {
|
||||
JvmRuntimeVersionsConsistencyChecker.checkCompilerClasspathConsistency(
|
||||
messageCollector,
|
||||
configuration,
|
||||
initialRoots.mapNotNull { (file, type) -> if (type == JavaRoot.RootType.BINARY) file else null }
|
||||
)
|
||||
}
|
||||
|
||||
val (roots, singleJavaFileRoots) =
|
||||
initialRoots.partition { (file) -> file.isDirectory || file.extension != JavaFileType.DEFAULT_EXTENSION }
|
||||
|
||||
// REPL and kapt2 update classpath dynamically
|
||||
rootsIndex = JvmDependenciesDynamicCompoundIndex().apply {
|
||||
addIndex(JvmDependenciesIndexImpl(roots))
|
||||
updateClasspathFromRootsIndex(this)
|
||||
}
|
||||
|
||||
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize(
|
||||
rootsIndex,
|
||||
packagePartProviders,
|
||||
SingleJavaFileRootsIndex(singleJavaFileRoots),
|
||||
configuration.getBoolean(JVMConfigurationKeys.USE_PSI_CLASS_FILES_READING)
|
||||
)
|
||||
|
||||
project.registerService(
|
||||
JavaModuleResolver::class.java,
|
||||
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList())
|
||||
)
|
||||
|
||||
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
||||
project.registerService(MetadataFinderFactory::class.java, finderFactory)
|
||||
project.registerService(VirtualFileFinderFactory::class.java, finderFactory)
|
||||
|
||||
project.putUserData(APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY, fun(roots: List<File>) {
|
||||
updateClasspath(roots.map { JavaSourceRoot(it, null) })
|
||||
})
|
||||
}
|
||||
|
||||
private fun collectAdditionalSources(project: MockProject) {
|
||||
var unprocessedSources: Collection<KtFile> = sourceFiles
|
||||
val processedSources = HashSet<KtFile>()
|
||||
val processedSourcesByExtension = HashMap<CollectAdditionalSourcesExtension, Collection<KtFile>>()
|
||||
// repeat feeding extensions with sources while new sources a being added
|
||||
var sourceCollectionIterations = 0
|
||||
while (unprocessedSources.isNotEmpty()) {
|
||||
if (sourceCollectionIterations++ > 10) { // TODO: consider using some appropriate global constant
|
||||
throw IllegalStateException("Unable to collect additional sources in reasonable number of iterations")
|
||||
}
|
||||
processedSources.addAll(unprocessedSources)
|
||||
val allNewSources = ArrayList<KtFile>()
|
||||
for (extension in CollectAdditionalSourcesExtension.getInstances(project)) {
|
||||
// do not feed the extension with the sources it returned on the previous iteration
|
||||
val sourcesToProcess = unprocessedSources - (processedSourcesByExtension[extension] ?: emptyList())
|
||||
val newSources = extension.collectAdditionalSourcesAndUpdateConfiguration(sourcesToProcess, configuration, project)
|
||||
if (newSources.isNotEmpty()) {
|
||||
allNewSources.addAll(newSources)
|
||||
processedSourcesByExtension[extension] = newSources
|
||||
}
|
||||
}
|
||||
unprocessedSources = allNewSources.filterNot { processedSources.contains(it) }.distinct()
|
||||
sourceFiles += unprocessedSources
|
||||
}
|
||||
}
|
||||
|
||||
fun addKotlinSourceRoots(rootDirs: List<File>) {
|
||||
val roots = rootDirs.map { KotlinSourceRoot(it.absolutePath, isCommon = false) }
|
||||
sourceFiles += createSourceFilesFromSourceRoots(configuration, project, roots)
|
||||
}
|
||||
|
||||
fun createPackagePartProvider(scope: GlobalSearchScope): JvmPackagePartProvider {
|
||||
return JvmPackagePartProvider(configuration.languageVersionSettings, scope).apply {
|
||||
addRoots(initialRoots, configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY))
|
||||
packagePartProviders += this
|
||||
(ModuleAnnotationsResolver.getInstance(project) as CliModuleAnnotationsResolver).addPackagePartProvider(this)
|
||||
}
|
||||
}
|
||||
|
||||
private val VirtualFile.javaFiles: List<VirtualFile>
|
||||
get() = mutableListOf<VirtualFile>().apply {
|
||||
VfsUtilCore.processFilesRecursively(this@javaFiles) { file ->
|
||||
if (file.fileType == JavaFileType.INSTANCE) {
|
||||
add(file)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private val allJavaFiles: List<File>
|
||||
get() = configuration.javaSourceRoots
|
||||
.mapNotNull(this::findLocalFile)
|
||||
.flatMap { it.javaFiles }
|
||||
.map { File(it.canonicalPath) }
|
||||
|
||||
fun registerJavac(
|
||||
javaFiles: List<File> = allJavaFiles,
|
||||
kotlinFiles: List<KtFile> = sourceFiles,
|
||||
arguments: Array<String>? = null,
|
||||
bootClasspath: List<File>? = null,
|
||||
sourcePath: List<File>? = null
|
||||
): Boolean {
|
||||
return JavacWrapperRegistrar.registerJavac(
|
||||
projectEnvironment.project, configuration, javaFiles, kotlinFiles, arguments, bootClasspath, sourcePath,
|
||||
LightClassGenerationSupport.getInstance(project), packagePartProviders
|
||||
)
|
||||
}
|
||||
|
||||
private val applicationEnvironment: CoreApplicationEnvironment
|
||||
get() = projectEnvironment.environment
|
||||
|
||||
val project: Project
|
||||
get() = projectEnvironment.project
|
||||
|
||||
internal fun countLinesOfCode(sourceFiles: List<KtFile>): Int =
|
||||
sourceFiles.sumBy { sourceFile ->
|
||||
val text = sourceFile.text
|
||||
StringUtil.getLineBreakCount(text) + (if (StringUtil.endsWithLineBreak(text)) 0 else 1)
|
||||
}
|
||||
|
||||
private fun updateClasspathFromRootsIndex(index: JvmDependenciesIndex) {
|
||||
index.indexedRoots.forEach {
|
||||
projectEnvironment.addSourcesToClasspath(it.file)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateClasspath(contentRoots: List<ContentRoot>): List<File>? {
|
||||
// TODO: add new Java modules to CliJavaModuleResolver
|
||||
val newRoots = classpathRootsResolver.convertClasspathRoots(contentRoots).roots
|
||||
|
||||
if (packagePartProviders.isEmpty()) {
|
||||
initialRoots.addAll(newRoots)
|
||||
} else {
|
||||
for (packagePartProvider in packagePartProviders) {
|
||||
packagePartProvider.addRoots(newRoots, configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY))
|
||||
}
|
||||
}
|
||||
|
||||
return rootsIndex.addNewIndexForRoots(newRoots)?.let { newIndex ->
|
||||
updateClasspathFromRootsIndex(newIndex)
|
||||
newIndex.indexedRoots.mapNotNull { (file) ->
|
||||
VfsUtilCore.virtualToIoFile(VfsUtilCore.getVirtualFileForJar(file) ?: file)
|
||||
}.toList()
|
||||
}.orEmpty()
|
||||
}
|
||||
|
||||
private fun contentRootToVirtualFile(root: JvmContentRoot): VirtualFile? =
|
||||
when (root) {
|
||||
is JvmClasspathRoot ->
|
||||
if (root.file.isFile) findJarRoot(root.file) else findExistingRoot(root, "Classpath entry")
|
||||
is JvmModulePathRoot ->
|
||||
if (root.file.isFile) findJarRoot(root.file) else findExistingRoot(root, "Java module root")
|
||||
is JavaSourceRoot ->
|
||||
findExistingRoot(root, "Java source root")
|
||||
else ->
|
||||
throw IllegalStateException("Unexpected root: $root")
|
||||
}
|
||||
|
||||
internal fun findLocalFile(path: String): VirtualFile? =
|
||||
applicationEnvironment.localFileSystem.findFileByPath(path)
|
||||
|
||||
private fun findExistingRoot(root: JvmContentRoot, rootDescription: String): VirtualFile? {
|
||||
return findLocalFile(root.file.absolutePath).also {
|
||||
if (it == null) {
|
||||
report(STRONG_WARNING, "$rootDescription points to a non-existent location: ${root.file}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun findJarRoot(file: File): VirtualFile? =
|
||||
applicationEnvironment.jarFileSystem.findFileByPath("$file${URLUtil.JAR_SEPARATOR}")
|
||||
|
||||
private fun getSourceRootsCheckingForDuplicates(): List<KotlinSourceRoot> {
|
||||
val uniqueSourceRoots = hashSetOf<String>()
|
||||
val result = mutableListOf<KotlinSourceRoot>()
|
||||
|
||||
for (root in configuration.kotlinSourceRoots) {
|
||||
if (!uniqueSourceRoots.add(root.path)) {
|
||||
report(STRONG_WARNING, "Duplicate source root: ${root.path}")
|
||||
}
|
||||
result.add(root)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun getSourceFiles(): List<KtFile> = sourceFiles
|
||||
|
||||
private fun createKtFiles(project: Project): List<KtFile> =
|
||||
createSourceFilesFromSourceRoots(configuration, project, getSourceRootsCheckingForDuplicates())
|
||||
|
||||
internal fun report(severity: CompilerMessageSeverity, message: String) = configuration.report(severity, message)
|
||||
|
||||
companion object {
|
||||
private val LOG = Logger.getInstance(KotlinCoreEnvironment::class.java)
|
||||
|
||||
private val APPLICATION_LOCK = Object()
|
||||
private var ourApplicationEnvironment: KotlinCoreApplicationEnvironment? = null
|
||||
private var ourProjectCount = 0
|
||||
|
||||
@JvmStatic
|
||||
fun createForProduction(
|
||||
parentDisposable: Disposable, configuration: CompilerConfiguration, configFiles: EnvironmentConfigFiles
|
||||
): KotlinCoreEnvironment {
|
||||
setupIdeaStandaloneExecution()
|
||||
val appEnv = getOrCreateApplicationEnvironmentForProduction(parentDisposable, configuration)
|
||||
val projectEnv = ProjectEnvironment(parentDisposable, appEnv)
|
||||
val environment = KotlinCoreEnvironment(projectEnv, configuration, configFiles)
|
||||
|
||||
synchronized(APPLICATION_LOCK) {
|
||||
ourProjectCount++
|
||||
}
|
||||
return environment
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun createForProduction(
|
||||
projectEnvironment: JavaCoreProjectEnvironment, configuration: CompilerConfiguration, configFiles: EnvironmentConfigFiles
|
||||
): KotlinCoreEnvironment {
|
||||
val environment = KotlinCoreEnvironment(projectEnvironment, configuration, configFiles)
|
||||
|
||||
if (projectEnvironment.environment == applicationEnvironment) {
|
||||
// accounting for core environment disposing
|
||||
synchronized(APPLICATION_LOCK) {
|
||||
ourProjectCount++
|
||||
}
|
||||
}
|
||||
return environment
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
@JvmStatic
|
||||
fun createForTests(
|
||||
parentDisposable: Disposable, initialConfiguration: CompilerConfiguration, extensionConfigs: EnvironmentConfigFiles
|
||||
): KotlinCoreEnvironment {
|
||||
val configuration = initialConfiguration.copy()
|
||||
// Tests are supposed to create a single project and dispose it right after use
|
||||
val appEnv = createApplicationEnvironment(parentDisposable, configuration, unitTestMode = true)
|
||||
val projectEnv = ProjectEnvironment(parentDisposable, appEnv)
|
||||
return KotlinCoreEnvironment(projectEnv, configuration, extensionConfigs)
|
||||
}
|
||||
|
||||
// used in the daemon for jar cache cleanup
|
||||
val applicationEnvironment: KotlinCoreApplicationEnvironment? get() = ourApplicationEnvironment
|
||||
|
||||
fun getOrCreateApplicationEnvironmentForProduction(
|
||||
parentDisposable: Disposable, configuration: CompilerConfiguration
|
||||
): KotlinCoreApplicationEnvironment {
|
||||
synchronized(APPLICATION_LOCK) {
|
||||
if (ourApplicationEnvironment == null) {
|
||||
val disposable = Disposer.newDisposable()
|
||||
ourApplicationEnvironment = createApplicationEnvironment(disposable, configuration, unitTestMode = false)
|
||||
ourProjectCount = 0
|
||||
Disposer.register(disposable, Disposable {
|
||||
synchronized(APPLICATION_LOCK) {
|
||||
ourApplicationEnvironment = null
|
||||
}
|
||||
})
|
||||
}
|
||||
// Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally
|
||||
// breaks a lot of tests, therefore it is disabled for production and enabled for tests
|
||||
if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY).toBooleanLenient() != true) {
|
||||
// JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ)
|
||||
// All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well
|
||||
Disposer.register(parentDisposable, Disposable {
|
||||
synchronized(APPLICATION_LOCK) {
|
||||
if (--ourProjectCount <= 0) {
|
||||
disposeApplicationEnvironment()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return ourApplicationEnvironment!!
|
||||
}
|
||||
}
|
||||
|
||||
private fun disposeApplicationEnvironment() {
|
||||
synchronized(APPLICATION_LOCK) {
|
||||
val environment = ourApplicationEnvironment ?: return
|
||||
ourApplicationEnvironment = null
|
||||
Disposer.dispose(environment.parentDisposable)
|
||||
ZipHandler.clearFileAccessorCache()
|
||||
}
|
||||
}
|
||||
|
||||
private fun createApplicationEnvironment(
|
||||
parentDisposable: Disposable, configuration: CompilerConfiguration, unitTestMode: Boolean
|
||||
): KotlinCoreApplicationEnvironment {
|
||||
val applicationEnvironment = KotlinCoreApplicationEnvironment.create(parentDisposable, unitTestMode)
|
||||
|
||||
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/compiler.xml")
|
||||
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/core.xml")
|
||||
|
||||
registerApplicationServicesForCLI(applicationEnvironment)
|
||||
registerApplicationServices(applicationEnvironment)
|
||||
|
||||
return applicationEnvironment
|
||||
}
|
||||
|
||||
private fun registerApplicationExtensionPointsAndExtensionsFrom(configuration: CompilerConfiguration, configFilePath: String) {
|
||||
fun File.hasConfigFile(configFile: String): Boolean =
|
||||
if (isDirectory) File(this, "META-INF" + File.separator + configFile).exists()
|
||||
else try {
|
||||
ZipFile(this).use {
|
||||
it.getEntry("META-INF/$configFile") != null
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
false
|
||||
}
|
||||
|
||||
val pluginRoot: File =
|
||||
configuration.get(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT)?.let(::File)
|
||||
?: PathUtil.getResourcePathForClass(this::class.java).takeIf { it.hasConfigFile(configFilePath) }
|
||||
// hack for load extensions when compiler run directly from project directory (e.g. in tests)
|
||||
?: File("compiler/cli/cli-common/resources").takeIf { it.hasConfigFile(configFilePath) }
|
||||
?: throw IllegalStateException(
|
||||
"Unable to find extension point configuration $configFilePath " +
|
||||
"(cp:\n ${(Thread.currentThread().contextClassLoader as? UrlClassLoader)?.urls?.joinToString("\n ") { it.file }})"
|
||||
)
|
||||
|
||||
registerExtensionPointAndExtensionsEx(pluginRoot, configFilePath, Extensions.getRootArea())
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Suppress("MemberVisibilityCanPrivate") // made public for CLI Android Lint
|
||||
fun registerPluginExtensionPoints(project: MockProject) {
|
||||
ExpressionCodegenExtension.registerExtensionPoint(project)
|
||||
SyntheticResolveExtension.registerExtensionPoint(project)
|
||||
ClassBuilderInterceptorExtension.registerExtensionPoint(project)
|
||||
AnalysisHandlerExtension.registerExtensionPoint(project)
|
||||
PackageFragmentProviderExtension.registerExtensionPoint(project)
|
||||
StorageComponentContainerContributor.registerExtensionPoint(project)
|
||||
DeclarationAttributeAltererExtension.registerExtensionPoint(project)
|
||||
PreprocessedVirtualFileFactoryExtension.registerExtensionPoint(project)
|
||||
JsSyntheticTranslateExtension.registerExtensionPoint(project)
|
||||
CompilerConfigurationExtension.registerExtensionPoint(project)
|
||||
CollectAdditionalSourcesExtension.registerExtensionPoint(project)
|
||||
ExtraImportsProviderExtension.registerExtensionPoint(project)
|
||||
IrGenerationExtension.registerExtensionPoint(project)
|
||||
ScriptEvaluationExtension.registerExtensionPoint(project)
|
||||
ShellExtension.registerExtensionPoint(project)
|
||||
TypeResolutionInterceptor.registerExtensionPoint(project)
|
||||
CandidateInterceptor.registerExtensionPoint(project)
|
||||
}
|
||||
|
||||
internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) {
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
for (registrar in configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) {
|
||||
try {
|
||||
registrar.registerProjectComponents(project, configuration)
|
||||
} catch (e: AbstractMethodError) {
|
||||
val message = "The provided plugin ${registrar.javaClass.name} is not compatible with this version of compiler"
|
||||
// Since the scripting plugin is often discovered in the compiler environment, it is often taken from the incompatible
|
||||
// location, and in many cases this is not a fatal error, therefore strong warning is generated instead of exception
|
||||
if (registrar.javaClass.simpleName == "ScriptingCompilerConfigurationComponentRegistrar") {
|
||||
messageCollector?.report(STRONG_WARNING, "Default scripting plugin is disabled: $message")
|
||||
} else {
|
||||
throw IllegalStateException(message, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun registerApplicationServicesForCLI(applicationEnvironment: KotlinCoreApplicationEnvironment) {
|
||||
// ability to get text from annotations xml files
|
||||
applicationEnvironment.registerFileType(PlainTextFileType.INSTANCE, "xml")
|
||||
applicationEnvironment.registerParserDefinition(JavaParserDefinition())
|
||||
}
|
||||
|
||||
// made public for Upsource
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
@JvmStatic
|
||||
fun registerApplicationServices(applicationEnvironment: KotlinCoreApplicationEnvironment) {
|
||||
with(applicationEnvironment) {
|
||||
registerFileType(KotlinFileType.INSTANCE, "kt")
|
||||
registerFileType(KotlinFileType.INSTANCE, KotlinParserDefinition.STD_SCRIPT_SUFFIX)
|
||||
registerParserDefinition(KotlinParserDefinition())
|
||||
application.registerService(KotlinBinaryClassCache::class.java, KotlinBinaryClassCache())
|
||||
application.registerService(JavaClassSupers::class.java, JavaClassSupersImpl::class.java)
|
||||
application.registerService(TransactionGuard::class.java, TransactionGuardImpl::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun registerProjectExtensionPoints(area: ExtensionsArea) {
|
||||
CoreApplicationEnvironment.registerExtensionPoint(
|
||||
area, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java
|
||||
)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, PsiElementFinder::class.java)
|
||||
|
||||
IdeaExtensionPoints.registerVersionSpecificProjectExtensionPoints(area)
|
||||
}
|
||||
|
||||
// made public for Upsource
|
||||
@JvmStatic
|
||||
@Deprecated("Use registerProjectServices(project) instead.", ReplaceWith("registerProjectServices(projectEnvironment.project)"))
|
||||
fun registerProjectServices(projectEnvironment: JavaCoreProjectEnvironment, messageCollector: MessageCollector?) {
|
||||
registerProjectServices(projectEnvironment.project)
|
||||
}
|
||||
|
||||
// made public for Android Lint
|
||||
@JvmStatic
|
||||
fun registerProjectServices(project: MockProject) {
|
||||
with(project) {
|
||||
registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this))
|
||||
registerService(FacadeCache::class.java, FacadeCache(this))
|
||||
registerService(ModuleAnnotationsResolver::class.java, CliModuleAnnotationsResolver())
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerProjectServicesForCLI(@Suppress("UNUSED_PARAMETER") projectEnvironment: JavaCoreProjectEnvironment) {
|
||||
/**
|
||||
* Note that Kapt may restart code analysis process, and CLI services should be aware of that.
|
||||
* Use PsiManager.getModificationTracker() to ensure that all the data you cached is still valid.
|
||||
*/
|
||||
}
|
||||
|
||||
// made public for Android Lint
|
||||
@JvmStatic
|
||||
fun registerKotlinLightClassSupport(project: MockProject) {
|
||||
with(project) {
|
||||
val traceHolder = CliTraceHolder()
|
||||
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder)
|
||||
val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder)
|
||||
registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
|
||||
registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
|
||||
registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport)
|
||||
registerService(CodeAnalyzerInitializer::class.java, traceHolder)
|
||||
if (getService(DumbUtil::class.java) == null) {
|
||||
@Suppress("UnstableApiUsage")
|
||||
registerService(DumbUtil::class.java, KotlinCoreDumbUtil())
|
||||
}
|
||||
|
||||
val area = Extensions.getArea(this)
|
||||
|
||||
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(JavaElementFinder(this, kotlinAsJavaSupport))
|
||||
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(
|
||||
PsiElementFinderImpl(this, ServiceManager.getService(this, JavaFileManager::class.java))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun CompilerConfiguration.setupJdkClasspathRoots(configFiles: EnvironmentConfigFiles) {
|
||||
if (getBoolean(JVMConfigurationKeys.NO_JDK)) return
|
||||
|
||||
val jvmTarget = configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||
if (!jvmTarget) return
|
||||
|
||||
val jdkHome = get(JVMConfigurationKeys.JDK_HOME)
|
||||
val (javaRoot, classesRoots) = if (jdkHome == null) {
|
||||
val javaHome = File(System.getProperty("java.home"))
|
||||
put(JVMConfigurationKeys.JDK_HOME, javaHome)
|
||||
|
||||
javaHome to PathUtil.getJdkClassesRootsFromCurrentJre()
|
||||
} else {
|
||||
jdkHome to PathUtil.getJdkClassesRoots(jdkHome)
|
||||
}
|
||||
|
||||
if (!CoreJrtFileSystem.isModularJdk(javaRoot)) {
|
||||
if (classesRoots.isEmpty()) {
|
||||
report(ERROR, "No class roots are found in the JDK path: $javaRoot")
|
||||
} else {
|
||||
addJvmSdkRoots(classesRoots)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,24 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu
|
||||
}
|
||||
}
|
||||
|
||||
if (arguments.stringConcat != null) {
|
||||
val runtimeStringConcat = JvmStringConcat.fromString(arguments.stringConcat!!)
|
||||
if (runtimeStringConcat != null) {
|
||||
put(JVMConfigurationKeys.STRING_CONCAT, runtimeStringConcat)
|
||||
if (jvmTarget.bytecodeVersion < JvmTarget.JVM_9.bytecodeVersion && runtimeStringConcat != JvmStringConcat.INLINE) {
|
||||
messageCollector.report(
|
||||
WARNING,
|
||||
"`-Xstring-concat=${arguments.stringConcat}` does nothing with JVM target `${jvmTarget.description}`."
|
||||
)
|
||||
}
|
||||
} else {
|
||||
messageCollector.report(
|
||||
ERROR, "Unknown `string-concat` mode: ${arguments.jvmTarget}\n" +
|
||||
"Supported versions: ${JvmStringConcat.values().joinToString { it.name.toLowerCase() }}"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
addAll(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES, arguments.additionalJavaModules?.asList())
|
||||
}
|
||||
|
||||
|
||||
@@ -111,6 +111,9 @@ public class JVMConfigurationKeys {
|
||||
public static final CompilerConfigurationKey<Boolean> EMIT_JVM_TYPE_ANNOTATIONS =
|
||||
CompilerConfigurationKey.create("Emit JVM type annotations in bytecode");
|
||||
|
||||
public static final CompilerConfigurationKey<JvmStringConcat> STRING_CONCAT =
|
||||
CompilerConfigurationKey.create("Specifies string concatenation scheme");
|
||||
|
||||
public static final CompilerConfigurationKey<List<String>> KLIB_PATHS =
|
||||
CompilerConfigurationKey.create("Paths to .klib libraries");
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.config
|
||||
|
||||
enum class JvmStringConcat(val description: String) {
|
||||
INLINE("inline"),
|
||||
INDY_WITH_CONSTANTS("indy-with-constants"), // makeConcatWithConstants
|
||||
INDY("indy"); // makeConcat
|
||||
|
||||
val isDynamic
|
||||
get() = this != INLINE
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun fromString(string: String) = values().find { it.description == string }
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ enum class JvmTarget(override val description: String) : TargetPlatformVersion {
|
||||
JVM_12("12"),
|
||||
JVM_13("13"),
|
||||
JVM_14("14"),
|
||||
JVM_15("15"),
|
||||
;
|
||||
|
||||
val bytecodeVersion: Int by lazy {
|
||||
@@ -40,6 +41,7 @@ enum class JvmTarget(override val description: String) : TargetPlatformVersion {
|
||||
JVM_12 -> Opcodes.V12
|
||||
JVM_13 -> Opcodes.V12 + 1
|
||||
JVM_14 -> Opcodes.V12 + 2
|
||||
JVM_15 -> Opcodes.V12 + 3
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.io.File
|
||||
import java.io.Serializable
|
||||
import java.net.SocketException
|
||||
import java.nio.channels.ClosedChannelException
|
||||
import java.nio.file.Files
|
||||
import java.rmi.ConnectException
|
||||
import java.rmi.ConnectIOException
|
||||
import java.rmi.UnmarshalException
|
||||
@@ -422,7 +423,7 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
|
||||
report: (DaemonReportCategory, String) -> Unit
|
||||
): Deferred<Pair<CompileServiceAsync?, DaemonJVMOptions>> = GlobalScope.async {
|
||||
registryDir.mkdirs()
|
||||
val timestampMarker = createTempFile("kotlin-daemon-client-tsmarker", directory = registryDir)
|
||||
val timestampMarker = Files.createTempFile(registryDir.toPath(), "kotlin-daemon-client-tsmarker", null).toFile()
|
||||
val aliveWithMetadata = try {
|
||||
walkDaemonsAsync(registryDir, compilerId, timestampMarker, report = report)
|
||||
} finally {
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.io.File
|
||||
import java.io.OutputStream
|
||||
import java.io.PrintStream
|
||||
import java.net.SocketException
|
||||
import java.nio.file.Files
|
||||
import java.rmi.ConnectException
|
||||
import java.rmi.ConnectIOException
|
||||
import java.rmi.UnmarshalException
|
||||
@@ -347,7 +348,7 @@ object KotlinCompilerClient {
|
||||
|
||||
private fun tryFindSuitableDaemonOrNewOpts(registryDir: File, compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, report: (DaemonReportCategory, String) -> Unit): Pair<CompileService?, DaemonJVMOptions> {
|
||||
registryDir.mkdirs()
|
||||
val timestampMarker = createTempFile("kotlin-daemon-client-tsmarker", directory = registryDir)
|
||||
val timestampMarker = Files.createTempFile(registryDir.toPath(), "kotlin-daemon-client-tsmarker", null).toFile()
|
||||
val aliveWithMetadata = try {
|
||||
walkDaemons(registryDir, compilerId, timestampMarker, report = report).toList()
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.daemon.common
|
||||
|
||||
import java.io.File
|
||||
import java.nio.file.Files
|
||||
import java.rmi.registry.LocateRegistry
|
||||
|
||||
|
||||
@@ -106,7 +107,12 @@ private inline fun tryConnectToDaemon(port: Int, report: (DaemonReportCategory,
|
||||
private const val validFlagFileKeywordChars = "abcdefghijklmnopqrstuvwxyz0123456789-_"
|
||||
|
||||
fun makeAutodeletingFlagFile(keyword: String = "compiler-client", baseDir: File? = null): File {
|
||||
val flagFile = File.createTempFile("kotlin-${keyword.filter { validFlagFileKeywordChars.contains(it.toLowerCase()) }}-", "-is-running", baseDir?.takeIf { it.isDirectory && it.exists() })
|
||||
val prefix = "kotlin-${keyword.filter { validFlagFileKeywordChars.contains(it.toLowerCase()) }}-"
|
||||
val flagFile = if (baseDir?.isDirectory == true)
|
||||
Files.createTempFile(baseDir.toPath(), prefix, "-is-running").toFile()
|
||||
else
|
||||
Files.createTempFile(prefix, "-is-running").toFile()
|
||||
|
||||
flagFile.deleteOnExit()
|
||||
return flagFile
|
||||
}
|
||||
|
||||
@@ -920,6 +920,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/deprecatedRepeatable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("dontReportWarningAboutChangingExecutionOrderForVararg.kt")
|
||||
public void testDontReportWarningAboutChangingExecutionOrderForVararg() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/dontReportWarningAboutChangingExecutionOrderForVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("extensionFunctionType.kt")
|
||||
public void testExtensionFunctionType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/extensionFunctionType.kt");
|
||||
@@ -3369,6 +3374,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/checkArguments/booleanExpressions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt17691.kt")
|
||||
public void testKt17691() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/checkArguments/kt17691.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt17691WithEnabledFeature.kt")
|
||||
public void testKt17691WithEnabledFeature() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/checkArguments/kt17691WithEnabledFeature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt1897_diagnostic_part.kt")
|
||||
public void testKt1897_diagnostic_part() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/checkArguments/kt1897_diagnostic_part.kt");
|
||||
@@ -7612,6 +7627,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/enum/SecondaryConstructorCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithoutDelegatingToPrimaryOne.kt")
|
||||
public void testSecondaryConstructorWithoutDelegatingToPrimaryOne() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOne.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt")
|
||||
public void testSecondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/secondaryConstructorWithoutDelegatingToPrimaryOneWithEnabledFeature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("starImportNestedClassAndEntries.kt")
|
||||
public void testStarImportNestedClassAndEntries() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/enum/starImportNestedClassAndEntries.kt");
|
||||
@@ -10684,6 +10709,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/notApproximateWhenCopyDescriptors.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableCaptruredTypeAgainstNullableVariable.kt")
|
||||
public void testNullableCaptruredTypeAgainstNullableVariable() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableCaptruredTypeAgainstNullableVariableWithDisabledComplatibilityFlag.kt")
|
||||
public void testNullableCaptruredTypeAgainstNullableVariableWithDisabledComplatibilityFlag() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/nullableCaptruredTypeAgainstNullableVariableWithDisabledComplatibilityFlag.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overApproximationForInCaptured.kt")
|
||||
public void testOverApproximationForInCaptured() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedTypes/overApproximationForInCaptured.kt");
|
||||
@@ -11055,6 +11090,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/callableReferences.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("fixingVariableDuringAddingConstraintForFirstPosponedArgument.kt")
|
||||
public void testFixingVariableDuringAddingConstraintForFirstPosponedArgument() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/fixingVariableDuringAddingConstraintForFirstPosponedArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lackOfDeepIncorporation.kt")
|
||||
public void testLackOfDeepIncorporation() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/completion/postponedArgumentsAnalysis/lackOfDeepIncorporation.kt");
|
||||
@@ -11965,6 +12005,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41386.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt41394.kt")
|
||||
public void testKt41394() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt41394.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt4420.kt")
|
||||
public void testKt4420() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt4420.kt");
|
||||
@@ -12048,6 +12093,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/inferTypeFromUnresolvedArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42620.kt")
|
||||
public void testKt42620() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/kt42620.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NoAmbiguityForDifferentFunctionTypes.kt")
|
||||
public void testNoAmbiguityForDifferentFunctionTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportingImprovements/NoAmbiguityForDifferentFunctionTypes.kt");
|
||||
@@ -12406,6 +12456,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/inline/recursion.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returnedAnonymousObjects.kt")
|
||||
public void testReturnedAnonymousObjects() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inline/returnedAnonymousObjects.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returns.kt")
|
||||
public void testReturns() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inline/returns.kt");
|
||||
@@ -19167,6 +19222,16 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/typeParameterInDefaultValueInLocalFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreInCatchBlock.kt")
|
||||
public void testUnderscoreInCatchBlock() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/underscoreInCatchBlock.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("underscoreInCatchBlockWithEnabledFeature.kt")
|
||||
public void testUnderscoreInCatchBlockWithEnabledFeature() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/underscoreInCatchBlockWithEnabledFeature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("wrongNumberOfTypeArguments.kt")
|
||||
public void testWrongNumberOfTypeArguments() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/wrongNumberOfTypeArguments.kt");
|
||||
@@ -24205,6 +24270,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/typeParameters/implicitNothingInReturnPosition.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implicitNothingOfJavaCallAgainstNotNothingExpectedType.kt")
|
||||
public void testImplicitNothingOfJavaCallAgainstNotNothingExpectedType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typeParameters/implicitNothingOfJavaCallAgainstNotNothingExpectedType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implicitNothingOnDelegates.kt")
|
||||
public void testImplicitNothingOnDelegates() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typeParameters/implicitNothingOnDelegates.kt");
|
||||
@@ -24860,6 +24930,11 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
runTest("compiler/testData/diagnostics/tests/varargs/AmbiguousVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("assignArrayToVararagInNamedFormWithInference.kt")
|
||||
public void testAssignArrayToVararagInNamedFormWithInference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedFormWithInference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("assignArrayToVararagInNamedForm_1_3.kt")
|
||||
public void testAssignArrayToVararagInNamedForm_1_3() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/varargs/assignArrayToVararagInNamedForm_1_3.kt");
|
||||
@@ -25153,6 +25228,21 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirOldFronte
|
||||
public void testAllFilesPresentInVisibility() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/visibility"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("invisibleSetterOfJavaClass.kt")
|
||||
public void testInvisibleSetterOfJavaClass() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/visibility/invisibleSetterOfJavaClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("invisibleSetterOfJavaClassWithDisabledFeature.kt")
|
||||
public void testInvisibleSetterOfJavaClassWithDisabledFeature() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/visibility/invisibleSetterOfJavaClassWithDisabledFeature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lackOfInvisibleSetterOfJavaClassInSamePackage.kt")
|
||||
public void testLackOfInvisibleSetterOfJavaClassInSamePackage() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/visibility/lackOfInvisibleSetterOfJavaClassInSamePackage.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/when")
|
||||
|
||||
@@ -493,6 +493,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverride.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("javaOverrideAll.kt")
|
||||
public void testJavaOverrideAll() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/javaOverrideAll.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("jvmDefaultInInheritance.kt")
|
||||
public void testJvmDefaultInInheritance() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultInInheritance.kt");
|
||||
@@ -799,6 +804,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/mainInObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("privateCompanionObject.kt")
|
||||
public void testPrivateCompanionObject() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/privateCompanionObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("property.kt")
|
||||
public void testProperty() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmStatic/property.kt");
|
||||
@@ -2998,6 +3008,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt38801.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42620.kt")
|
||||
public void testKt42620() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt42620.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt4975.kt")
|
||||
public void testKt4975() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/kt4975.kt");
|
||||
@@ -3008,6 +3023,29 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/recursiveFlexibleAssertions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class AddEqualityConstraintsWithoutSubtyping extends AbstractFirOldFrontendDiagnosticsTestWithStdlib {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInAddEqualityConstraintsWithoutSubtyping() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("kt41741.kt")
|
||||
public void testKt41741() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping/kt41741.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42195.kt")
|
||||
public void testKt42195() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/addEqualityConstraintsWithoutSubtyping/kt42195.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/annotationsForResolve")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -3219,6 +3257,49 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
||||
public void testSuspendFunctions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/suspendFunctions.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Performance extends AbstractFirOldFrontendDiagnosticsTestWithStdlib {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPerformance() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("reuseBuiltFunctionalTypesForIdLambdas.kt")
|
||||
public void testReuseBuiltFunctionalTypesForIdLambdas() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForIdLambdas.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reuseBuiltFunctionalTypesForLambdas.kt")
|
||||
public void testReuseBuiltFunctionalTypesForLambdas() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForLambdas.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reuseBuiltFunctionalTypesForPairOfLambdas.kt")
|
||||
public void testReuseBuiltFunctionalTypesForPairOfLambdas() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairOfLambdas.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt")
|
||||
public void testReuseBuiltFunctionalTypesForPairsOfDeepLambdas() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepLambdas.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt")
|
||||
public void testReuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfDeepMixedLambdas.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt")
|
||||
public void testReuseBuiltFunctionalTypesForPairsOfIdLambdas() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/completion/postponedArgumentsAnalysis/performance/reuseBuiltFunctionalTypesForPairsOfIdLambdas.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3266,6 +3347,11 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
||||
public void testDontInferToNullableNothingInDelegates() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType/dontInferToNullableNothingInDelegates.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("dontSpreadWarningToNotReturningNothingSubResolvedAtoms.kt")
|
||||
public void testDontSpreadWarningToNotReturningNothingSubResolvedAtoms() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/inference/nothingType/dontSpreadWarningToNotReturningNothingSubResolvedAtoms.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -421,7 +421,7 @@ internal fun IrDeclarationParent.declareThisReceiverParameter(
|
||||
symbolTable.irFactory.createValueParameter(
|
||||
startOffset, endOffset, thisOrigin, symbol,
|
||||
Name.special("<this>"), -1, thisType,
|
||||
varargElementType = null, isCrossinline = false, isNoinline = false
|
||||
varargElementType = null, isCrossinline = false, isNoinline = false, isAssignable = false
|
||||
).apply {
|
||||
this.parent = this@declareThisReceiverParameter
|
||||
receiverDescriptor.bind(this)
|
||||
|
||||
@@ -259,7 +259,7 @@ class Fir2IrDeclarationStorage(
|
||||
startOffset, endOffset, IrDeclarationOrigin.DEFINED, symbol,
|
||||
Name.special("<set-?>"), 0, type,
|
||||
varargElementType = null,
|
||||
isCrossinline = false, isNoinline = false
|
||||
isCrossinline = false, isNoinline = false, isAssignable = false
|
||||
).apply {
|
||||
this.parent = parent
|
||||
descriptor.bind(this)
|
||||
|
||||
@@ -608,7 +608,7 @@ class CallAndReferenceGenerator(
|
||||
putValueArgument(0, assignedValue)
|
||||
}
|
||||
}
|
||||
is IrVariableSymbol -> IrSetVariableImpl(startOffset, endOffset, type, symbol, assignedValue, origin)
|
||||
is IrVariableSymbol -> IrSetValueImpl(startOffset, endOffset, type, symbol, assignedValue, origin)
|
||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
||||
}
|
||||
}.applyTypeArguments(variableAssignment).applyReceivers(variableAssignment, explicitReceiverExpression)
|
||||
|
||||
@@ -270,7 +270,7 @@ class DataClassMembersGenerator(val components: Fir2IrComponents) {
|
||||
) { symbol ->
|
||||
components.irFactory.createValueParameter(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, origin, symbol, name, index, type, null,
|
||||
isCrossinline = false, isNoinline = false
|
||||
isCrossinline = false, isNoinline = false, isAssignable = false
|
||||
)
|
||||
}.apply {
|
||||
parent = irFunction
|
||||
|
||||
@@ -276,6 +276,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt41484.kt")
|
||||
public void testKt41484() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/kt41484.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("methodParameters.kt")
|
||||
public void testMethodParameters() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt");
|
||||
@@ -345,6 +350,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/argumentOrder/extensionInClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt17691.kt")
|
||||
public void testKt17691() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/argumentOrder/kt17691.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt17691WithEnabledFeature.kt")
|
||||
public void testKt17691WithEnabledFeature() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/argumentOrder/kt17691WithEnabledFeature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt9277.kt")
|
||||
public void testKt9277() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/argumentOrder/kt9277.kt");
|
||||
@@ -1732,6 +1747,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testSubstituteStubTypeIntolambdaParameterDescriptor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/builderInference/substituteStubTypeIntolambdaParameterDescriptor.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("substituteTypeVariableIntolambdaParameterDescriptor.kt")
|
||||
public void testSubstituteTypeVariableIntolambdaParameterDescriptor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/builderInference/substituteTypeVariableIntolambdaParameterDescriptor.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/builtinStubMethods")
|
||||
@@ -6443,11 +6463,21 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/builderInferenceAndGenericArrayAcessCall.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("captureInfixFun.kt")
|
||||
public void testCaptureInfixFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/captureInfixFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("captureMutableLocalVariableInsideCoroutineBlock.kt")
|
||||
public void testCaptureMutableLocalVariableInsideCoroutineBlock() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/captureMutableLocalVariableInsideCoroutineBlock.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("captureUnaryOperator.kt")
|
||||
public void testCaptureUnaryOperator() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/captureUnaryOperator.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedVarInSuspendLambda.kt")
|
||||
public void testCapturedVarInSuspendLambda_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/capturedVarInSuspendLambda.kt", "kotlin.coroutines");
|
||||
@@ -6673,6 +6703,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/kt35967.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42028.kt")
|
||||
public void testKt42028() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/kt42028.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lastExpressionIsLoop.kt")
|
||||
public void testLastExpressionIsLoop_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/lastExpressionIsLoop.kt", "kotlin.coroutines");
|
||||
@@ -6748,6 +6783,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/noSuspensionPoints.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("nonLocalReturn.kt")
|
||||
public void testNonLocalReturn() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/nonLocalReturn.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonLocalReturnFromInlineLambdaDeep.kt")
|
||||
public void testNonLocalReturnFromInlineLambdaDeep_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/nonLocalReturnFromInlineLambdaDeep.kt", "kotlin.coroutines");
|
||||
@@ -7432,6 +7472,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/coroutines/inlineClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonLocalReturn.kt")
|
||||
public void testNonLocalReturn() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/nonLocalReturn.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/coroutines/inlineClasses/direct")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -7573,6 +7618,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/direct/covariantOverrideSuspendFun_Int.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("createMangling.kt")
|
||||
public void testCreateMangling() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/direct/createMangling.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("createOverride.kt")
|
||||
public void testCreateOverride() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/direct/createOverride.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericOverrideSuspendFun.kt")
|
||||
public void testGenericOverrideSuspendFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/direct/genericOverrideSuspendFun.kt");
|
||||
@@ -7618,6 +7673,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/inlineClasses/direct/interfaceDelegateWithInlineClass.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("invokeOperator.kt")
|
||||
public void testInvokeOperator() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/direct/invokeOperator.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overrideSuspendFun.kt")
|
||||
public void testOverrideSuspendFun_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/inlineClasses/direct/overrideSuspendFun.kt", "kotlin.coroutines");
|
||||
@@ -7790,6 +7850,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/covariantOverrideSuspendFun_Int.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("createMangling.kt")
|
||||
public void testCreateMangling() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/createMangling.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("createOverride.kt")
|
||||
public void testCreateOverride() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/createOverride.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericOverrideSuspendFun.kt")
|
||||
public void testGenericOverrideSuspendFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/genericOverrideSuspendFun.kt");
|
||||
@@ -7835,6 +7905,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/inlineClasses/resume/interfaceDelegateWithInlineClass.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("invokeOperator.kt")
|
||||
public void testInvokeOperator() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resume/invokeOperator.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overrideSuspendFun.kt")
|
||||
public void testOverrideSuspendFun_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/inlineClasses/resume/overrideSuspendFun.kt", "kotlin.coroutines");
|
||||
@@ -8002,6 +8077,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException/covariantOverrideSuspendFun_Int.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("createMangling.kt")
|
||||
public void testCreateMangling() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException/createMangling.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("createOverride.kt")
|
||||
public void testCreateOverride() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException/createOverride.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericOverrideSuspendFun.kt")
|
||||
public void testGenericOverrideSuspendFun() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException/genericOverrideSuspendFun.kt");
|
||||
@@ -8037,6 +8122,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException/interfaceDelegateWithInlineClass.kt", "kotlin.coroutines");
|
||||
}
|
||||
|
||||
@TestMetadata("invokeOperator.kt")
|
||||
public void testInvokeOperator() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException/invokeOperator.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("overrideSuspendFun.kt")
|
||||
public void testOverrideSuspendFun_1_3() throws Exception {
|
||||
runTestWithPackageReplacement("compiler/testData/codegen/box/coroutines/inlineClasses/resumeWithException/overrideSuspendFun.kt", "kotlin.coroutines");
|
||||
@@ -8729,6 +8819,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/interfaceDelegation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returnInlineClass.kt")
|
||||
public void testReturnInlineClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/returnInlineClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/tailCallOptimizations/simple.kt");
|
||||
@@ -8967,6 +9062,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testRefinedIntTypesAnalysis() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/refinedIntTypesAnalysis.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("safeCallElvis.kt")
|
||||
public void testSafeCallElvis() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/varSpilling/safeCallElvis.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10885,6 +10985,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/enum/constructorWithReordering.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("declaringClassOnEnumObject.kt")
|
||||
public void testDeclaringClassOnEnumObject() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/enum/declaringClassOnEnumObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("deepInnerClassInEnumEntryClass.kt")
|
||||
public void testDeepInnerClassInEnumEntryClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/enum/deepInnerClassInEnumEntryClass.kt");
|
||||
@@ -13867,6 +13972,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/toStringCallingPrivateFun.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("toStringOfUnboxedNullable.kt")
|
||||
public void testToStringOfUnboxedNullable() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/toStringOfUnboxedNullable.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeChecksForInlineClasses.kt")
|
||||
public void testTypeChecksForInlineClasses() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/typeChecksForInlineClasses.kt");
|
||||
@@ -15345,6 +15455,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/ir/kt40083.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt41765.kt")
|
||||
public void testKt41765() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ir/kt41765.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("objectClass.kt")
|
||||
public void testObjectClass() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ir/objectClass.kt");
|
||||
@@ -16072,6 +16187,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/kt40920.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42674.kt")
|
||||
public void testKt42674() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/kt42674.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("oneImplementation.kt")
|
||||
public void testOneImplementation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/oneImplementation.kt");
|
||||
@@ -16234,6 +16354,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/kt14243_2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42674.kt")
|
||||
public void testKt42674() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/kt42674.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("privateFunInInterface.kt")
|
||||
public void testPrivateFunInInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/allCompatibility/privateFunInInterface.kt");
|
||||
@@ -16345,6 +16470,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/interfaceExtension.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42674.kt")
|
||||
public void testKt42674() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/kt42674.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAnnotation.kt")
|
||||
public void testPropertyAnnotation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/propertyAnnotation.kt");
|
||||
@@ -16506,6 +16636,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/kt40920.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42674.kt")
|
||||
public void testKt42674() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/kt42674.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("privateFunInInterface.kt")
|
||||
public void testPrivateFunInInterface() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/privateFunInInterface.kt");
|
||||
@@ -17214,6 +17349,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/kt21246a.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt35716.kt")
|
||||
public void testKt35716() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/kt35716.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt9897_static.kt")
|
||||
public void testKt9897_static() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/jvmStatic/kt9897_static.kt");
|
||||
@@ -21997,6 +22137,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testKt13241_Collection() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/forInIndices/kt13241_Collection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43159_ArrayUpperBound.kt")
|
||||
public void testKt43159_ArrayUpperBound() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/forInIndices/kt43159_ArrayUpperBound.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt43159_GenericArray.kt")
|
||||
public void testKt43159_GenericArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/forInIndices/kt43159_GenericArray.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/ranges/forInProgressionWithIndex")
|
||||
@@ -30018,6 +30168,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/strings/kt3652.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt42457_old.kt")
|
||||
public void testKt42457_old() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/strings/kt42457_old.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt5389_stringBuilderGet.kt")
|
||||
public void testKt5389_stringBuilderGet() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/strings/kt5389_stringBuilderGet.kt");
|
||||
|
||||
@@ -404,7 +404,7 @@ class JavaSymbolProvider(
|
||||
|
||||
private fun hasTopLevelClassOf(classId: ClassId): Boolean {
|
||||
val knownNames = knownClassNamesInPackage.getOrPut(classId.packageFqName) {
|
||||
facade.knownClassNamesInPackage(classId.packageFqName)
|
||||
facade.knownClassNamesInPackage(classId.packageFqName, searchScope)
|
||||
} ?: return true
|
||||
return classId.relativeClassName.topLevelName() in knownNames
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ class JavaOverrideChecker internal constructor(
|
||||
}
|
||||
}
|
||||
return with(context) {
|
||||
isEqualTypeConstructors(
|
||||
areEqualTypeConstructors(
|
||||
substitutor.substituteOrSelf(candidateType).typeConstructor(),
|
||||
substitutor.substituteOrSelf(baseType).typeConstructor()
|
||||
)
|
||||
|
||||
@@ -19,14 +19,14 @@ class JvmMappedScope(
|
||||
) : FirTypeScope() {
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirFunctionSymbol<*>) -> Unit) {
|
||||
val whiteListSignatures = signatures.whiteListSignaturesByName[name]
|
||||
val visibleMethods = signatures.visibleMethodSignaturesByName[name]
|
||||
?: return declaredMemberScope.processFunctionsByName(name, processor)
|
||||
javaMappedClassUseSiteScope.processFunctionsByName(name) { symbol ->
|
||||
val jvmSignature = symbol.fir.computeJvmDescriptor()
|
||||
.replace("kotlin/Any", "java/lang/Object")
|
||||
.replace("kotlin/String", "java/lang/String")
|
||||
.replace("kotlin/Throwable", "java/lang/Throwable")
|
||||
if (jvmSignature in whiteListSignatures) {
|
||||
if (jvmSignature in visibleMethods) {
|
||||
processor(symbol)
|
||||
}
|
||||
}
|
||||
@@ -40,14 +40,14 @@ class JvmMappedScope(
|
||||
) = ProcessorAction.NONE
|
||||
|
||||
override fun processDeclaredConstructors(processor: (FirConstructorSymbol) -> Unit) {
|
||||
val constructorBlackList = signatures.constructorBlackList
|
||||
if (constructorBlackList.isNotEmpty()) {
|
||||
val hiddenConstructors = signatures.hiddenConstructors
|
||||
if (hiddenConstructors.isNotEmpty()) {
|
||||
javaMappedClassUseSiteScope.processDeclaredConstructors { symbol ->
|
||||
val jvmSignature = symbol.fir.computeJvmDescriptor()
|
||||
.replace("kotlin/Any", "java/lang/Object")
|
||||
.replace("kotlin/String", "java/lang/String")
|
||||
.replace("kotlin/Throwable", "java/lang/Throwable")
|
||||
if (jvmSignature !in constructorBlackList) {
|
||||
if (jvmSignature !in hiddenConstructors) {
|
||||
processor(symbol)
|
||||
}
|
||||
}
|
||||
@@ -80,14 +80,14 @@ class JvmMappedScope(
|
||||
}
|
||||
|
||||
companion object {
|
||||
data class Signatures(val whiteListSignaturesByName: Map<Name, Set<String>>, val constructorBlackList: Set<String>) {
|
||||
fun isEmpty() = whiteListSignaturesByName.isEmpty() && constructorBlackList.isEmpty()
|
||||
data class Signatures(val visibleMethodSignaturesByName: Map<Name, Set<String>>, val hiddenConstructors: Set<String>) {
|
||||
fun isEmpty() = visibleMethodSignaturesByName.isEmpty() && hiddenConstructors.isEmpty()
|
||||
fun isNotEmpty() = !isEmpty()
|
||||
}
|
||||
|
||||
// NOTE: No-arg constructors
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private val additionalConstructorBlackList = buildSet<String> {
|
||||
private val additionalHiddenConstructors = buildSet<String> {
|
||||
// kotlin.text.String pseudo-constructors should be used instead of java.lang.String constructors
|
||||
listOf(
|
||||
"",
|
||||
@@ -113,22 +113,22 @@ class JvmMappedScope(
|
||||
fun prepareSignatures(klass: FirRegularClass): Signatures {
|
||||
|
||||
val signaturePrefix = klass.symbol.classId.toString()
|
||||
val whiteListSignaturesByName = mutableMapOf<Name, MutableSet<String>>()
|
||||
JvmBuiltInsSignatures.WHITE_LIST_METHOD_SIGNATURES.filter { signature ->
|
||||
val visibleMethodsByName = mutableMapOf<Name, MutableSet<String>>()
|
||||
JvmBuiltInsSignatures.VISIBLE_METHOD_SIGNATURES.filter { signature ->
|
||||
signature.startsWith(signaturePrefix)
|
||||
}.map { signature ->
|
||||
// +1 to delete dot before function name
|
||||
signature.substring(signaturePrefix.length + 1)
|
||||
}.forEach {
|
||||
whiteListSignaturesByName.getOrPut(Name.identifier(it.substringBefore("("))) { mutableSetOf() }.add(it)
|
||||
visibleMethodsByName.getOrPut(Name.identifier(it.substringBefore("("))) { mutableSetOf() }.add(it)
|
||||
}
|
||||
|
||||
val constructorBlackList =
|
||||
(JvmBuiltInsSignatures.BLACK_LIST_CONSTRUCTOR_SIGNATURES + additionalConstructorBlackList)
|
||||
val hiddenConstructors =
|
||||
(JvmBuiltInsSignatures.HIDDEN_CONSTRUCTOR_SIGNATURES + additionalHiddenConstructors)
|
||||
.filter { it.startsWith(signaturePrefix) }
|
||||
.mapTo(mutableSetOf()) { it.substring(signaturePrefix.length + 1) }
|
||||
|
||||
return Signatures(whiteListSignaturesByName, constructorBlackList)
|
||||
return Signatures(visibleMethodsByName, hiddenConstructors)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRef
|
||||
import org.jetbrains.kotlin.fir.declarations.FirTypeParameterRefsOwner
|
||||
import org.jetbrains.kotlin.fir.renderWithType
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.TypeParameterBasedTypeVariable
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeDeclaredUpperBoundConstraintPosition
|
||||
@@ -68,7 +69,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
|
||||
typeArgument.typeRef.coneType,
|
||||
typeParameter,
|
||||
context.session.inferenceComponents.ctx
|
||||
),
|
||||
).fullyExpandedType(context.session),
|
||||
SimpleConstraintSystemConstraintPosition // TODO
|
||||
)
|
||||
is FirStarProjection -> csBuilder.addEqualityConstraint(
|
||||
|
||||
@@ -50,7 +50,7 @@ class ConstraintSystemCompleter(private val components: BodyResolveComponents) {
|
||||
val postponedAtoms = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms)
|
||||
val variableForFixation =
|
||||
variableFixationFinder.findFirstVariableForFixation(
|
||||
c, allTypeVariables, postponedAtoms, completionMode, candidateReturnType
|
||||
c, allTypeVariables, postponedAtoms, completionMode, candidateReturnType, inferenceCompatibilityMode = true
|
||||
) ?: break
|
||||
|
||||
if (
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||
import org.jetbrains.kotlin.fir.NoMutableState
|
||||
import org.jetbrains.kotlin.fir.types.ConeInferenceContext
|
||||
import org.jetbrains.kotlin.fir.types.ConeTypeCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.InferenceCompatibilityChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintIncorporator
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver
|
||||
@@ -24,7 +25,13 @@ class InferenceComponents(val session: FirSession) : FirSessionComponent {
|
||||
val approximator: AbstractTypeApproximator = object : AbstractTypeApproximator(ctx) {}
|
||||
val trivialConstraintTypeInferenceOracle = TrivialConstraintTypeInferenceOracle.create(ctx)
|
||||
private val incorporator = ConstraintIncorporator(approximator, trivialConstraintTypeInferenceOracle, ConeConstraintSystemUtilContext)
|
||||
private val injector = ConstraintInjector(incorporator, approximator)
|
||||
private val injector = ConstraintInjector(
|
||||
incorporator,
|
||||
approximator,
|
||||
object : InferenceCompatibilityChecker {
|
||||
override val isCompatibilityModeEnabled = true
|
||||
}
|
||||
)
|
||||
val resultTypeResolver = ResultTypeResolver(approximator, trivialConstraintTypeInferenceOracle)
|
||||
|
||||
val constraintSystemFactory = ConstraintSystemFactory()
|
||||
|
||||
@@ -275,7 +275,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
return this
|
||||
}
|
||||
|
||||
override fun isEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean {
|
||||
override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean {
|
||||
if (c1 is ErrorTypeConstructor || c2 is ErrorTypeConstructor) return false
|
||||
|
||||
//assert(c1 is ConeSymbol)
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
|
||||
import org.jetbrains.kotlin.resolve.jvm.TopPackageNamesProvider
|
||||
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
|
||||
import javax.annotation.PostConstruct
|
||||
import javax.inject.Inject
|
||||
@@ -32,10 +33,14 @@ abstract class AbstractJavaClassFinder : JavaClassFinder {
|
||||
protected lateinit var project: Project
|
||||
protected lateinit var javaSearchScope: GlobalSearchScope
|
||||
|
||||
|
||||
@Inject
|
||||
fun setScope(scope: GlobalSearchScope) {
|
||||
javaSearchScope = FilterOutKotlinSourceFilesScope(scope)
|
||||
javaSearchScope =
|
||||
if (scope == GlobalSearchScope.EMPTY_SCOPE) {
|
||||
GlobalSearchScope.EMPTY_SCOPE
|
||||
} else {
|
||||
FilterOutKotlinSourceFilesScope(scope)
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
@@ -48,9 +53,15 @@ abstract class AbstractJavaClassFinder : JavaClassFinder {
|
||||
CodeAnalyzerInitializer.getInstance(project).initialize(trace, codeAnalyzer.moduleDescriptor, codeAnalyzer)
|
||||
}
|
||||
|
||||
inner class FilterOutKotlinSourceFilesScope(baseScope: GlobalSearchScope) : DelegatingGlobalSearchScope(baseScope) {
|
||||
inner class FilterOutKotlinSourceFilesScope(baseScope: GlobalSearchScope) : DelegatingGlobalSearchScope(baseScope),
|
||||
TopPackageNamesProvider {
|
||||
|
||||
override fun contains(file: VirtualFile) = myBaseScope.contains(file) && (file.isDirectory || file.fileType !== KotlinFileType.INSTANCE)
|
||||
override val topPackageNames: Set<String>?
|
||||
get() = (myBaseScope as? TopPackageNamesProvider)?.topPackageNames
|
||||
|
||||
override fun contains(file: VirtualFile) =
|
||||
(file.isDirectory || file.fileType !== KotlinFileType.INSTANCE) &&
|
||||
myBaseScope.contains(file)
|
||||
|
||||
val base: GlobalSearchScope = myBaseScope
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.java
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaPackage
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaPackageImpl
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||
@@ -33,11 +34,16 @@ class JavaClassFinderImpl : AbstractJavaClassFinder() {
|
||||
javaFacade = KotlinJavaPsiFacade.getInstance(project)
|
||||
}
|
||||
|
||||
override fun findClass(request: JavaClassFinder.Request): JavaClass? = javaFacade.findClass(request, javaSearchScope)
|
||||
override fun findClass(request: JavaClassFinder.Request): JavaClass? {
|
||||
return javaFacade.findClass(request, javaSearchScope)
|
||||
}
|
||||
|
||||
override fun findPackage(fqName: FqName) =
|
||||
javaFacade.findPackage(fqName.asString(), javaSearchScope)?.let { JavaPackageImpl(it, javaSearchScope) }
|
||||
override fun findPackage(fqName: FqName): JavaPackage? {
|
||||
return javaFacade.findPackage(fqName.asString(), javaSearchScope)?.let { JavaPackageImpl(it, javaSearchScope) }
|
||||
}
|
||||
|
||||
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String>? = javaFacade.knownClassNamesInPackage(packageFqName)
|
||||
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String>? {
|
||||
return javaFacade.knownClassNamesInPackage(packageFqName, javaSearchScope)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.load.kotlin.incremental
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProviderOptimized
|
||||
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||
@@ -38,29 +38,32 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
|
||||
class IncrementalPackageFragmentProvider(
|
||||
sourceFiles: Collection<KtFile>,
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val storageManager: StorageManager,
|
||||
val deserializationComponents: DeserializationComponents,
|
||||
val incrementalCache: IncrementalCache,
|
||||
val target: TargetId,
|
||||
private val kotlinClassFinder: KotlinClassFinder
|
||||
) : PackageFragmentProvider {
|
||||
sourceFiles: Collection<KtFile>,
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val storageManager: StorageManager,
|
||||
val deserializationComponents: DeserializationComponents,
|
||||
val incrementalCache: IncrementalCache,
|
||||
val target: TargetId,
|
||||
private val kotlinClassFinder: KotlinClassFinder
|
||||
) : PackageFragmentProviderOptimized {
|
||||
private val fqNameToPackageFragment =
|
||||
PackagePartClassUtils.getFilesWithCallables(sourceFiles)
|
||||
.mapTo(hashSetOf()) { it.packageFqName }
|
||||
.keysToMap(this::IncrementalPackageFragment)
|
||||
PackagePartClassUtils.getFilesWithCallables(sourceFiles)
|
||||
.mapTo(hashSetOf()) { it.packageFqName }
|
||||
.keysToMap(this::IncrementalPackageFragment)
|
||||
|
||||
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> = emptySet()
|
||||
|
||||
override fun collectPackageFragments(fqName: FqName, packageFragments: MutableCollection<PackageFragmentDescriptor>) =
|
||||
packageFragments.addIfNotNull(fqNameToPackageFragment[fqName])
|
||||
|
||||
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> {
|
||||
return listOfNotNull(fqNameToPackageFragment[fqName])
|
||||
}
|
||||
|
||||
|
||||
inner class IncrementalPackageFragment(fqName: FqName) : PackageFragmentDescriptorImpl(moduleDescriptor, fqName) {
|
||||
val target: TargetId
|
||||
get() = this@IncrementalPackageFragmentProvider.target
|
||||
@@ -75,34 +78,34 @@ class IncrementalPackageFragmentProvider(
|
||||
}
|
||||
|
||||
inner class IncrementalMultifileClassPackageFragment(
|
||||
val facadeName: JvmClassName,
|
||||
val partsInternalNames: Collection<String>,
|
||||
packageFqName: FqName
|
||||
val facadeName: JvmClassName,
|
||||
val partsInternalNames: Collection<String>,
|
||||
packageFqName: FqName
|
||||
) : PackageFragmentDescriptorImpl(moduleDescriptor, packageFqName) {
|
||||
private val memberScope = storageManager.createLazyValue {
|
||||
ChainedMemberScope.create(
|
||||
"Member scope for incremental compilation: union of multifile class parts data for $facadeName",
|
||||
partsInternalNames.mapNotNull { internalName ->
|
||||
incrementalCache.getPackagePartData(internalName)?.let { (data, strings) ->
|
||||
val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(data, strings)
|
||||
"Member scope for incremental compilation: union of multifile class parts data for $facadeName",
|
||||
partsInternalNames.mapNotNull { internalName ->
|
||||
incrementalCache.getPackagePartData(internalName)?.let { (data, strings) ->
|
||||
val (nameResolver, packageProto) = JvmProtoBufUtil.readPackageDataFrom(data, strings)
|
||||
|
||||
val partName = JvmClassName.byInternalName(internalName)
|
||||
val jvmBinaryClass =
|
||||
kotlinClassFinder.findKotlinClass(ClassId.topLevel(partName.fqNameForTopLevelClassMaybeWithDollars))
|
||||
val partName = JvmClassName.byInternalName(internalName)
|
||||
val jvmBinaryClass =
|
||||
kotlinClassFinder.findKotlinClass(ClassId.topLevel(partName.fqNameForTopLevelClassMaybeWithDollars))
|
||||
|
||||
val metadataVersion =
|
||||
jvmBinaryClass?.classHeader?.metadataVersion
|
||||
val metadataVersion =
|
||||
jvmBinaryClass?.classHeader?.metadataVersion
|
||||
?: JvmMetadataVersion.INSTANCE
|
||||
|
||||
DeserializedPackageMemberScope(
|
||||
this, packageProto, nameResolver, metadataVersion,
|
||||
JvmPackagePartSource(
|
||||
partName, facadeName, packageProto, nameResolver, knownJvmBinaryClass = jvmBinaryClass
|
||||
),
|
||||
deserializationComponents, classNames = { emptyList() }
|
||||
)
|
||||
}
|
||||
DeserializedPackageMemberScope(
|
||||
this, packageProto, nameResolver, metadataVersion,
|
||||
JvmPackagePartSource(
|
||||
partName, facadeName, packageProto, nameResolver, knownJvmBinaryClass = jvmBinaryClass
|
||||
),
|
||||
deserializationComponents, classNames = { emptyList() }
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ fun CallableMemberDescriptor.isCompiledToJvmDefault(jvmDefault: JvmDefaultMode):
|
||||
return JvmProtoBufUtil.isNewPlaceForBodyGeneration(clazz.classProto)
|
||||
}
|
||||
|
||||
fun FunctionDescriptor.checkIsImplementationCompiledToJvmDefault(jvmDefaultMode: JvmDefaultMode): Boolean {
|
||||
fun CallableMemberDescriptor.checkIsImplementationCompiledToJvmDefault(jvmDefaultMode: JvmDefaultMode): Boolean {
|
||||
val actualImplementation =
|
||||
(if (kind.isReal) this else findImplementationFromInterface(this))
|
||||
?: error("Can't find actual implementation for $this")
|
||||
|
||||
@@ -156,7 +156,13 @@ class JavaNullabilityChecker : AdditionalTypeChecker {
|
||||
private fun isNullableTypeAgainstNotNullTypeParameter(
|
||||
subType: KotlinType,
|
||||
superType: KotlinType
|
||||
) = superType is NotNullTypeVariable && subType.isNullable()
|
||||
): Boolean {
|
||||
if (superType !is NotNullTypeVariable) return false
|
||||
return !AbstractNullabilityChecker.isSubtypeOfAny(
|
||||
ClassicTypeCheckerContext(errorTypeEqualsToAnything = true) as AbstractTypeCheckerContext,
|
||||
subType
|
||||
)
|
||||
}
|
||||
|
||||
override fun checkReceiver(
|
||||
receiverParameter: ReceiverParameterDescriptor,
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.config.JvmAnalysisFlags
|
||||
import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
@@ -67,7 +68,7 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget, project: Project) : Declaratio
|
||||
}
|
||||
|
||||
|
||||
if (isInterface(descriptor.containingDeclaration)) {
|
||||
if (!jvmDefaultMode.forAllMethodsWithBody && isInterface(descriptor.containingDeclaration)) {
|
||||
val memberDescriptor = descriptor as? CallableMemberDescriptor ?: return
|
||||
if (descriptor is PropertyAccessorDescriptor) return
|
||||
|
||||
@@ -154,7 +155,7 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget, project: Project) : Declaratio
|
||||
declaration: KtDeclaration,
|
||||
performSpecializationCheck: Boolean
|
||||
): Boolean {
|
||||
if (!performSpecializationCheck) return true
|
||||
if (!performSpecializationCheck || actualImplementation is JavaMethodDescriptor) return true
|
||||
val inheritedSignature = inheritedFun.computeJvmDescriptor(withReturnType = true, withName = false)
|
||||
val originalImplementation = actualImplementation.original
|
||||
val actualSignature = originalImplementation.computeJvmDescriptor(withReturnType = true, withName = false)
|
||||
@@ -200,7 +201,11 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget, project: Project) : Declaratio
|
||||
val classMembers =
|
||||
inheritedFun.overriddenDescriptors.filter { !isInterface(it.containingDeclaration) && !isAnnotationClass(it.containingDeclaration) }
|
||||
val implicitDefaultImplsDelegate =
|
||||
classMembers.firstOrNull { getNonPrivateTraitMembersForDelegation(it, true)?.isCompiledToJvmDefaultWithProperMode(jvmDefaultMode) == false }
|
||||
classMembers.firstOrNull {
|
||||
//TODO: additional processing for platform dependent method is required (https://youtrack.jetbrains.com/issue/KT-42697)
|
||||
it !is JavaCallableMemberDescriptor &&
|
||||
getNonPrivateTraitMembersForDelegation(it, true)?.isCompiledToJvmDefaultWithProperMode(jvmDefaultMode) == false
|
||||
}
|
||||
if (implicitDefaultImplsDelegate != null) return implicitDefaultImplsDelegate
|
||||
return classMembers.firstNotNullResult { findPossibleClashMember(it, jvmDefaultMode) }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.JVM_STATIC_IN_PRIVATE_COMPANION
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class JvmStaticInPrivateCompanionChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
val containingDeclaration = descriptor.containingDeclaration
|
||||
|
||||
if (containingDeclaration !is ClassDescriptor
|
||||
|| !containingDeclaration.isCompanionObject
|
||||
|| !Visibilities.isPrivate(containingDeclaration.visibility.delegate)
|
||||
) return
|
||||
|
||||
val jvmStaticAnnotation = descriptor.annotations.findAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME) ?: return
|
||||
|
||||
val reportTarget = jvmStaticAnnotation.source.safeAs<KotlinSourceElement>()?.psi ?: return
|
||||
context.trace.report(JVM_STATIC_IN_PRIVATE_COMPANION.on(reportTarget))
|
||||
}
|
||||
}
|
||||
@@ -17,28 +17,47 @@
|
||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
|
||||
object ProtectedSyntheticExtensionCallChecker : CallChecker {
|
||||
fun computeSuitableDescriptorAndError(
|
||||
descriptor: SyntheticJavaPropertyDescriptor,
|
||||
reportOn: PsiElement,
|
||||
context: CallCheckerContext
|
||||
): Pair<FunctionDescriptor, DiagnosticFactory3<PsiElement, DeclarationDescriptor, DescriptorVisibility, DeclarationDescriptor>> {
|
||||
val callPosition = context.resolutionContext.callPosition
|
||||
val isLeftSide = callPosition is CallPosition.PropertyAssignment
|
||||
&& (callPosition.leftPart as? KtDotQualifiedExpression)?.selectorExpression == reportOn
|
||||
val getMethod = descriptor.getMethod
|
||||
val setMethod = descriptor.setMethod
|
||||
val isImprovingDiagnosticsEnabled =
|
||||
context.languageVersionSettings.supportsFeature(LanguageFeature.ImproveReportingDiagnosticsOnProtectedMembersOfBaseClass)
|
||||
val needToTakeSetter = isImprovingDiagnosticsEnabled && isLeftSide
|
||||
val suitableDescriptor = if (needToTakeSetter && setMethod != null) setMethod else getMethod
|
||||
|
||||
return suitableDescriptor to if (needToTakeSetter && setMethod != null) Errors.INVISIBLE_SETTER else Errors.INVISIBLE_MEMBER
|
||||
}
|
||||
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
val descriptor = resolvedCall.resultingDescriptor
|
||||
|
||||
val sourceFunction = when (descriptor) {
|
||||
is SyntheticJavaPropertyDescriptor -> descriptor.getMethod
|
||||
// TODO: this branch becomes unnecessary, because common checks are applied to SAM adapters being resolved as common members
|
||||
// But this part may be still useful when we enable backward compatibility mode and SAM adapters become extensions again
|
||||
is SamAdapterExtensionFunctionDescriptor -> descriptor.baseDescriptorForSynthetic
|
||||
else -> return
|
||||
}
|
||||
if (descriptor !is SyntheticJavaPropertyDescriptor) return
|
||||
|
||||
val (sourceFunction, error) = computeSuitableDescriptorAndError(descriptor, reportOn, context)
|
||||
|
||||
val from = context.scope.ownerDescriptor
|
||||
|
||||
@@ -49,12 +68,14 @@ object ProtectedSyntheticExtensionCallChecker : CallChecker {
|
||||
|
||||
val receiverValue = resolvedCall.extensionReceiver as ReceiverValue
|
||||
val receiverTypes = listOf(receiverValue.type) + context.dataFlowInfo.getStableTypes(
|
||||
context.dataFlowValueFactory.createDataFlowValue(receiverValue, context.trace.bindingContext, context.scope.ownerDescriptor),
|
||||
context.languageVersionSettings
|
||||
context.dataFlowValueFactory.createDataFlowValue(
|
||||
receiverValue, context.trace.bindingContext, context.scope.ownerDescriptor
|
||||
),
|
||||
context.languageVersionSettings
|
||||
)
|
||||
|
||||
if (receiverTypes.none { DescriptorVisibilities.isVisible(getReceiverValueWithSmartCast(null, it), sourceFunction, from) }) {
|
||||
context.trace.report(Errors.INVISIBLE_MEMBER.on(reportOn, descriptor, descriptor.visibility, from))
|
||||
context.trace.report(error.on(reportOn, descriptor, descriptor.visibility, from))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
MAP.put(JVM_DEFAULT_IN_DECLARATION, "Usage of ''@{0}'' is only allowed with -Xjvm-default option", STRING);
|
||||
MAP.put(JVM_DEFAULT_THROUGH_INHERITANCE, "Inheritance from an interface with '@JvmDefault' members is only allowed with -Xjvm-default option");
|
||||
MAP.put(USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL, "Super calls of '@JvmDefault' members are only allowed with -Xjvm-default option");
|
||||
MAP.put(NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT, "Non-@JvmDefault interface method cannot override default Java method. Please annotate this method with @JvmDefault");
|
||||
MAP.put(NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT, "Non-@JvmDefault interface method cannot override default Java method. Please annotate this method with @JvmDefault or enable `-Xjvm-default=all|all-compatibility`");
|
||||
MAP.put(EXPLICIT_METADATA_IS_DISALLOWED, "Explicit @Metadata is disallowed");
|
||||
MAP.put(SUSPENSION_POINT_INSIDE_MONITOR, "A suspension point at {0} is inside a critical section", STRING);
|
||||
MAP.put(SUSPENSION_POINT_INSIDE_CRITICAL_SECTION, "The ''{0}'' suspension point is inside a critical section", NAME);
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.storage.NotNullLazyValue
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.storage.getValue
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
class OptionalAnnotationPackageFragmentProvider(
|
||||
module: ModuleDescriptor,
|
||||
@@ -32,7 +33,7 @@ class OptionalAnnotationPackageFragmentProvider(
|
||||
notFoundClasses: NotFoundClasses,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
packagePartProvider: PackagePartProvider,
|
||||
) : PackageFragmentProvider {
|
||||
) : PackageFragmentProviderOptimized {
|
||||
val packages: Map<FqName, PackageFragmentDescriptor> by storageManager.createLazyValue p@{
|
||||
// We call getAllOptionalAnnotationClasses under lazy value only because IncrementalPackagePartProvider requires
|
||||
// deserializationConfiguration to be injected.
|
||||
@@ -79,6 +80,9 @@ class OptionalAnnotationPackageFragmentProvider(
|
||||
}
|
||||
}
|
||||
|
||||
override fun collectPackageFragments(fqName: FqName, packageFragments: MutableCollection<PackageFragmentDescriptor>) =
|
||||
packageFragments.addIfNotNull(packages[fqName])
|
||||
|
||||
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> =
|
||||
packages[fqName]?.let(::listOf).orEmpty()
|
||||
|
||||
|
||||
@@ -95,6 +95,7 @@ object JvmPlatformConfigurator : PlatformConfiguratorBase(
|
||||
) {
|
||||
override fun configureModuleComponents(container: StorageComponentContainer) {
|
||||
container.useImpl<JvmStaticChecker>()
|
||||
container.useImpl<JvmStaticInPrivateCompanionChecker>()
|
||||
container.useImpl<JvmReflectionAPICallChecker>()
|
||||
container.useImpl<JavaSyntheticScopes>()
|
||||
container.useImpl<SamConversionResolverImpl>()
|
||||
|
||||
@@ -162,6 +162,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
return descriptor.valueParameters.isEmpty()
|
||||
&& descriptor.typeParameters.isEmpty()
|
||||
&& descriptor.visibility.isVisibleOutside()
|
||||
&& !(descriptor.isHiddenForResolutionEverywhereBesideSupercalls && descriptor.name.asString() == "isEmpty") // CharSequence.isEmpty() from JDK15
|
||||
}
|
||||
|
||||
private fun isGoodSetMethod(descriptor: FunctionDescriptor, getMethod: FunctionDescriptor): Boolean {
|
||||
@@ -178,6 +179,7 @@ class JavaSyntheticPropertiesScope(storageManager: StorageManager, private val l
|
||||
return parameter.varargElementType == null
|
||||
&& descriptor.typeParameters.isEmpty()
|
||||
&& descriptor.visibility.isVisibleOutside()
|
||||
&& !(descriptor.isHiddenForResolutionEverywhereBesideSupercalls && descriptor.name.asString() == "isEmpty") // CharSequence.isEmpty() from JDK15
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.findOverridden(condition: (FunctionDescriptor) -> Boolean): FunctionDescriptor? {
|
||||
|
||||
@@ -8,9 +8,7 @@ package org.jetbrains.kotlin.analyzer
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.context.ProjectContext
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -238,7 +236,7 @@ private class DelegatingPackageFragmentProvider<M : ModuleInfo>(
|
||||
private val module: ModuleDescriptor,
|
||||
moduleContent: ModuleContent<M>,
|
||||
private val packageOracle: PackageOracle
|
||||
) : PackageFragmentProvider {
|
||||
) : PackageFragmentProviderOptimized {
|
||||
private val syntheticFilePackages = moduleContent.syntheticFiles.map { it.packageFqName }.toSet()
|
||||
|
||||
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> {
|
||||
@@ -247,6 +245,12 @@ private class DelegatingPackageFragmentProvider<M : ModuleInfo>(
|
||||
return resolverForProject.resolverForModuleDescriptor(module).packageFragmentProvider.getPackageFragments(fqName)
|
||||
}
|
||||
|
||||
override fun collectPackageFragments(fqName: FqName, packageFragments: MutableCollection<PackageFragmentDescriptor>) {
|
||||
if (certainlyDoesNotExist(fqName)) return
|
||||
|
||||
resolverForProject.resolverForModuleDescriptor(module).packageFragmentProvider.collectPackageFragmentsOptimizedIfPossible(fqName, packageFragments)
|
||||
}
|
||||
|
||||
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> {
|
||||
if (certainlyDoesNotExist(fqName)) return emptyList()
|
||||
|
||||
|
||||
@@ -129,23 +129,28 @@ class LazyModuleDependencies<M : ModuleInfo>(
|
||||
firstDependency: M? = null,
|
||||
private val resolverForProject: AbstractResolverForProject<M>
|
||||
) : ModuleDependencies {
|
||||
|
||||
private val dependencies = storageManager.createLazyValue {
|
||||
|
||||
val moduleDescriptors = mutableSetOf<ModuleDescriptorImpl>()
|
||||
firstDependency?.let {
|
||||
moduleDescriptors.add(resolverForProject.descriptorForModule(it))
|
||||
}
|
||||
val moduleDescriptor = resolverForProject.descriptorForModule(module)
|
||||
sequence {
|
||||
if (firstDependency != null) {
|
||||
yield(resolverForProject.descriptorForModule(firstDependency))
|
||||
}
|
||||
if (module.dependencyOnBuiltIns() == ModuleInfo.DependencyOnBuiltIns.AFTER_SDK) {
|
||||
yield(moduleDescriptor.builtIns.builtInsModule)
|
||||
}
|
||||
for (dependency in module.dependencies()) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
yield(resolverForProject.descriptorForModule(dependency as M))
|
||||
}
|
||||
if (module.dependencyOnBuiltIns() == ModuleInfo.DependencyOnBuiltIns.LAST) {
|
||||
yield(moduleDescriptor.builtIns.builtInsModule)
|
||||
}
|
||||
}.toList()
|
||||
val dependencyOnBuiltIns = module.dependencyOnBuiltIns()
|
||||
if (dependencyOnBuiltIns == ModuleInfo.DependencyOnBuiltIns.AFTER_SDK) {
|
||||
moduleDescriptors.add(moduleDescriptor.builtIns.builtInsModule)
|
||||
}
|
||||
for (dependency in module.dependencies()) {
|
||||
if (dependency == firstDependency) continue
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
moduleDescriptors.add(resolverForProject.descriptorForModule(dependency as M))
|
||||
}
|
||||
if (dependencyOnBuiltIns == ModuleInfo.DependencyOnBuiltIns.LAST) {
|
||||
moduleDescriptors.add(moduleDescriptor.builtIns.builtInsModule)
|
||||
}
|
||||
moduleDescriptors.toList()
|
||||
}
|
||||
|
||||
override val allDependencies: List<ModuleDescriptorImpl> get() = dependencies()
|
||||
|
||||
@@ -887,7 +887,9 @@ class ControlFlowInformationProvider private constructor(
|
||||
}
|
||||
|
||||
instruction.next?.let { dfs(it) }
|
||||
} else if (instruction.element is KtNameReferenceExpression) {
|
||||
} else if (instruction.element is KtNameReferenceExpression || instruction.element is KtBinaryExpression ||
|
||||
instruction.element is KtUnaryExpression
|
||||
) {
|
||||
val call = instruction.element.getResolvedCall(trace.bindingContext)
|
||||
if (call is VariableAsFunctionResolvedCall) {
|
||||
(call.variableCall.dispatchReceiver as? ExtensionReceiver)?.declarationDescriptor?.apply { markIfNeeded() }
|
||||
|
||||
@@ -285,6 +285,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_UNSIGNED_LITERALS_ERROR = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> JVM_STATIC_IN_PRIVATE_COMPANION = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
// Const
|
||||
DiagnosticFactory0<PsiElement> CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT = DiagnosticFactory0.create(ERROR);
|
||||
@@ -385,14 +386,17 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtDeclaration> CONSTRUCTOR_IN_OBJECT = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
|
||||
DiagnosticFactory0<KtSuperTypeCallEntry> SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<KtConstructorDelegationCall> PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED =
|
||||
DiagnosticFactory0<PsiElement> PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED =
|
||||
DiagnosticFactory0.create(ERROR, PositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL);
|
||||
|
||||
DiagnosticFactory0<PsiElement> PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED_IN_ENUM =
|
||||
DiagnosticFactory0.create(WARNING, PositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL);
|
||||
|
||||
DiagnosticFactory0<KtConstructorDelegationReferenceExpression> DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR =
|
||||
DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<KtConstructorDelegationCall> EXPLICIT_DELEGATION_CALL_REQUIRED =
|
||||
DiagnosticFactory0<PsiElement> EXPLICIT_DELEGATION_CALL_REQUIRED =
|
||||
DiagnosticFactory0.create(ERROR, PositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL);
|
||||
|
||||
DiagnosticFactory1<PsiElement, DeclarationDescriptor> INSTANCE_ACCESS_BEFORE_SUPER_CALL = DiagnosticFactory1.create(ERROR);
|
||||
@@ -625,6 +629,8 @@ public interface Errors {
|
||||
|
||||
DiagnosticFactory1<KtParameter, KotlinType> FORBIDDEN_VARARG_PARAMETER_TYPE = DiagnosticFactory1.create(ERROR, PARAMETER_VARARG_MODIFIER);
|
||||
|
||||
DiagnosticFactory0<PsiElement> CHANGING_ARGUMENTS_EXECUTION_ORDER_FOR_NAMED_VARARGS = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
// Named parameters
|
||||
|
||||
DiagnosticFactory0<KtParameter> DEFAULT_VALUE_NOT_ALLOWED_IN_OVERRIDE = DiagnosticFactory0.create(ERROR, PARAMETER_DEFAULT_VALUE);
|
||||
@@ -886,6 +892,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<PsiElement, String> YIELD_IS_RESERVED = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> UNDERSCORE_IS_RESERVED = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> UNDERSCORE_USAGE_WITHOUT_BACKTICKS = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, String> INVALID_CHARACTERS = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, String> INAPPLICABLE_OPERATOR_MODIFIER = DiagnosticFactory1.create(ERROR);
|
||||
@@ -1029,7 +1036,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtTypeParameterList> LOCAL_VARIABLE_WITH_TYPE_PARAMETERS_WARNING = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory0<KtTypeParameterList> LOCAL_VARIABLE_WITH_TYPE_PARAMETERS = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
DiagnosticFactory3<KtExpression, DeclarationDescriptor, DescriptorVisibility, DeclarationDescriptor> INVISIBLE_SETTER = DiagnosticFactory3.create(ERROR);
|
||||
DiagnosticFactory3<PsiElement, DeclarationDescriptor, DescriptorVisibility, DeclarationDescriptor> INVISIBLE_SETTER = DiagnosticFactory3.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_LOOP_PARAMETER = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, KtKeywordToken> VAL_OR_VAR_ON_FUN_PARAMETER = DiagnosticFactory1.create(ERROR);
|
||||
@@ -1102,7 +1109,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<KtExpression, ClassifierDescriptorWithTypeParameters> NESTED_CLASS_ACCESSED_VIA_INSTANCE_REFERENCE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory2<KtExpression, ClassDescriptor, String> NESTED_CLASS_SHOULD_BE_QUALIFIED = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, ClassDescriptor> INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, ClassDescriptor> INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR, SECONDARY_CONSTRUCTOR_DELEGATION_CALL);
|
||||
DiagnosticFactory1<KtClassOrObject, String> NESTED_CLASS_NOT_ALLOWED = DiagnosticFactory1.create(ERROR, DECLARATION_NAME);
|
||||
DiagnosticFactory1<KtClassOrObject, String> NESTED_CLASS_DEPRECATED = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
|
||||
|
||||
@@ -1126,6 +1133,7 @@ public interface Errors {
|
||||
DiagnosticFactory1<PsiElement, CallableDescriptor> PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory2<KtElement, KtExpression, DeclarationDescriptor> INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory2<KtElement, KtExpression, DeclarationDescriptor> NOT_SUPPORTED_INLINE_PARAMETER_IN_INLINE_PARAMETER_DEFAULT_VALUE = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> PRIVATE_INLINE_FUNCTIONS_RETURNING_ANONYMOUS_OBJECTS = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
DiagnosticFactory0<PsiElement> NON_LOCAL_SUSPENSION_POINT = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, CallableDescriptor> ILLEGAL_SUSPEND_FUNCTION_CALL = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
@@ -46,10 +46,7 @@ object PositioningStrategies {
|
||||
is KtObjectLiteralExpression -> {
|
||||
val objectDeclaration = element.objectDeclaration
|
||||
val objectKeyword = objectDeclaration.getObjectKeyword()!!
|
||||
val delegationSpecifierList = objectDeclaration.getSuperTypeList()
|
||||
if (delegationSpecifierList == null) {
|
||||
return markElement(objectKeyword)
|
||||
}
|
||||
val delegationSpecifierList = objectDeclaration.getSuperTypeList() ?: return markElement(objectKeyword)
|
||||
return markRange(objectKeyword, delegationSpecifierList)
|
||||
}
|
||||
is KtObjectDeclaration -> {
|
||||
@@ -612,15 +609,26 @@ object PositioningStrategies {
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val SECONDARY_CONSTRUCTOR_DELEGATION_CALL: PositioningStrategy<KtConstructorDelegationCall> =
|
||||
object : PositioningStrategy<KtConstructorDelegationCall>() {
|
||||
override fun mark(element: KtConstructorDelegationCall): List<TextRange> {
|
||||
if (element.isImplicit) {
|
||||
val constructor = element.getStrictParentOfType<KtSecondaryConstructor>()!!
|
||||
val valueParameterList = constructor.valueParameterList ?: return markElement(constructor)
|
||||
return markRange(constructor.getConstructorKeyword(), valueParameterList.lastChild)
|
||||
val SECONDARY_CONSTRUCTOR_DELEGATION_CALL: PositioningStrategy<PsiElement> =
|
||||
object : PositioningStrategy<PsiElement>() {
|
||||
override fun mark(element: PsiElement): List<TextRange> {
|
||||
when (element) {
|
||||
is KtSecondaryConstructor -> {
|
||||
val valueParameterList = element.valueParameterList ?: return markElement(element)
|
||||
return markRange(element.getConstructorKeyword(), valueParameterList.lastChild)
|
||||
}
|
||||
is KtConstructorDelegationCall -> {
|
||||
if (element.isImplicit) {
|
||||
// TODO: [VD] FIR collects for some reason implicit KtConstructorDelegationCall
|
||||
// check(!element.isImplicit) { "Implicit KtConstructorDelegationCall should not be collected directly" }
|
||||
val constructor = element.getStrictParentOfType<KtSecondaryConstructor>()!!
|
||||
val valueParameterList = constructor.valueParameterList ?: return markElement(constructor)
|
||||
return markRange(constructor.getConstructorKeyword(), valueParameterList.lastChild)
|
||||
}
|
||||
return markElement(element.calleeExpression ?: element)
|
||||
}
|
||||
else -> error("unexpected element $element")
|
||||
}
|
||||
return markElement(element.calleeExpression ?: element)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -51,25 +51,23 @@ fun ResolutionContext<*>.reportTypeMismatchDueToTypeProjection(
|
||||
): Boolean {
|
||||
if (!TypeUtils.contains(expectedType) { it.isAnyOrNullableAny() || it.isNothing() || it.isNullableNothing() }) return false
|
||||
|
||||
val callPosition = this.callPosition
|
||||
val (resolvedCall, correspondingNotApproximatedTypeByDescriptor: (CallableDescriptor) -> KotlinType?) = when (callPosition) {
|
||||
is CallPosition.ValueArgumentPosition -> Pair(
|
||||
callPosition.resolvedCall, { f: CallableDescriptor ->
|
||||
is CallPosition.ValueArgumentPosition ->
|
||||
callPosition.resolvedCall to { f: CallableDescriptor ->
|
||||
getEffectiveExpectedType(f.valueParameters[callPosition.valueParameter.index], callPosition.valueArgument, this)
|
||||
})
|
||||
is CallPosition.ExtensionReceiverPosition -> Pair<ResolvedCall<*>, (CallableDescriptor) -> KotlinType?>(
|
||||
callPosition.resolvedCall, { f: CallableDescriptor ->
|
||||
f.extensionReceiverParameter?.type
|
||||
})
|
||||
is CallPosition.PropertyAssignment -> Pair<ResolvedCall<out CallableDescriptor>, (CallableDescriptor) -> KotlinType?>(
|
||||
callPosition.leftPart.getResolvedCall(trace.bindingContext) ?: return false, { f: CallableDescriptor ->
|
||||
(f as? PropertyDescriptor)?.setter?.valueParameters?.get(0)?.type
|
||||
})
|
||||
}
|
||||
is CallPosition.ExtensionReceiverPosition ->
|
||||
callPosition.resolvedCall to { f: CallableDescriptor -> f.extensionReceiverParameter?.type }
|
||||
is CallPosition.PropertyAssignment -> {
|
||||
if (callPosition.isLeft) return false
|
||||
val resolvedCall = callPosition.leftPart.getResolvedCall(trace.bindingContext) ?: return false
|
||||
resolvedCall to { f: CallableDescriptor -> (f as? PropertyDescriptor)?.setter?.valueParameters?.get(0)?.type }
|
||||
}
|
||||
is CallPosition.Unknown -> return false
|
||||
}
|
||||
|
||||
val receiverType = resolvedCall.smartCastDispatchReceiverType
|
||||
?: (resolvedCall.dispatchReceiver ?: return false).type
|
||||
?: (resolvedCall.dispatchReceiver ?: return false).type
|
||||
|
||||
val callableDescriptor = resolvedCall.resultingDescriptor.original
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS_ERROR, "{0}", STRING);
|
||||
|
||||
MAP.put(NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES, "Non-parenthesized annotations on function types without receiver aren't yet supported (see KT-31734 for details)");
|
||||
MAP.put(JVM_STATIC_IN_PRIVATE_COMPANION, "@JvmStatic is prohibited in private companion objects. This warning will become an error in the next major version");
|
||||
|
||||
MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING);
|
||||
MAP.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members");
|
||||
@@ -269,6 +270,9 @@ public class DefaultErrorMessages {
|
||||
MAP.put(USELESS_VARARG_ON_PARAMETER, "Vararg on this parameter is useless");
|
||||
MAP.put(MULTIPLE_VARARG_PARAMETERS, "Multiple vararg-parameters are prohibited");
|
||||
MAP.put(FORBIDDEN_VARARG_PARAMETER_TYPE, "Forbidden vararg parameter type: {0}", RENDER_TYPE);
|
||||
MAP.put(CHANGING_ARGUMENTS_EXECUTION_ORDER_FOR_NAMED_VARARGS, "Arguments execution order is going to be changed in a future release." +
|
||||
"The expression for named vararg argument will be executed in the order in which it was listed, not at the end." +
|
||||
"See KT-17691 for more details.");
|
||||
|
||||
MAP.put(EXPECTED_DECLARATION_WITH_BODY, "Expected declaration must not have a body");
|
||||
MAP.put(EXPECTED_CLASS_CONSTRUCTOR_DELEGATION_CALL, "Explicit delegation call for constructor of an expected class is not allowed");
|
||||
@@ -509,6 +513,7 @@ public class DefaultErrorMessages {
|
||||
|
||||
MAP.put(UNDERSCORE_IS_RESERVED, "Names _, __, ___, ..., are reserved in Kotlin");
|
||||
MAP.put(UNDERSCORE_USAGE_WITHOUT_BACKTICKS, "Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)");
|
||||
MAP.put(RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER, "Referencing to an underscore-named parameter is deprecated. It will be an error in a future release.");
|
||||
MAP.put(YIELD_IS_RESERVED, "{0}", STRING);
|
||||
MAP.put(INVALID_CHARACTERS, "Name {0}", STRING);
|
||||
|
||||
@@ -634,6 +639,7 @@ public class DefaultErrorMessages {
|
||||
MAP.put(CONSTRUCTOR_IN_OBJECT, "Constructors are not allowed for objects");
|
||||
MAP.put(SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR, "Supertype initialization is impossible without primary constructor");
|
||||
MAP.put(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED, "Primary constructor call expected");
|
||||
MAP.put(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED_IN_ENUM, "Primary constructor call expected. It's going to be an error in 1.5.");
|
||||
MAP.put(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR, "Call to super is not allowed in enum constructor");
|
||||
MAP.put(PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS, "Primary constructor required for data class");
|
||||
MAP.put(EXPLICIT_DELEGATION_CALL_REQUIRED,
|
||||
@@ -1015,6 +1021,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(PROTECTED_CALL_FROM_PUBLIC_INLINE_ERROR, "Protected function call from public-API inline function is prohibited", NAME);
|
||||
MAP.put(INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE, "Invalid default value for inline parameter: ''{0}''. Only lambdas, anonymous functions, and callable references are supported", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
|
||||
MAP.put(NOT_SUPPORTED_INLINE_PARAMETER_IN_INLINE_PARAMETER_DEFAULT_VALUE, "Usage of inline parameter ''{0}'' in default value for another inline parameter is not supported", ELEMENT_TEXT, SHORT_NAMES_IN_TYPES);
|
||||
MAP.put(PRIVATE_INLINE_FUNCTIONS_RETURNING_ANONYMOUS_OBJECTS, "Return type of the private inline function can't be anonymous. It will be approximated to Any in 1.5." +
|
||||
"See https://youtrack.jetbrains.com/issue/KT-33917 for more details");
|
||||
//Inline non locals
|
||||
MAP.put(NON_LOCAL_RETURN_NOT_ALLOWED, "Can''t inline ''{0}'' here: it may contain non-local returns. Add ''crossinline'' modifier to parameter declaration ''{0}''", ELEMENT_TEXT);
|
||||
MAP.put(INLINE_CALL_CYCLE, "The ''{0}'' invocation is a part of inline cycle", NAME);
|
||||
@@ -1024,8 +1032,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(ILLEGAL_SUSPEND_PROPERTY_ACCESS, "Suspend property ''{0}'' should be accessed only from a coroutine or suspend function", NAME);
|
||||
MAP.put(ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL, "Restricted suspending functions can only invoke member or extension suspending functions on their restricted coroutine scope");
|
||||
MAP.put(NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND, "''suspend'' function can only be called in a form of modifier of a lambda: suspend { ... }");
|
||||
MAP.put(IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION, "Returning type parameter has been inferred to Nothing implicitly. Please, specify type arguments explicitly to hide this warning. Nothing can produce an exception at runtime.");
|
||||
MAP.put(IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE, "Returning type parameter has been inferred to Nothing implicitly because Nothing is more specific than specified expected type. Please specify type arguments explicitly in accordance with expected type to hide this warning. Nothing can produce an exception at runtime.");
|
||||
MAP.put(IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION, "Returning type parameter has been inferred to Nothing implicitly. Please specify type arguments explicitly to hide this warning. Nothing can produce an exception at runtime.");
|
||||
MAP.put(IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE, "Returning type parameter has been inferred to Nothing implicitly because Nothing is more specific than specified expected type. Please specify type arguments explicitly in accordance with expected type to hide this warning. Nothing can produce an exception at runtime. See KT-36776 for more details.");
|
||||
MAP.put(RETURN_FOR_BUILT_IN_SUSPEND, "Using implicit label for this lambda is prohibited");
|
||||
MAP.put(MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND, "Calls having a form of ''suspend {}'' are deprecated because ''suspend'' in the context will have a meaning of a modifier. Add empty argument list to the call: ''suspend() { ... }''");
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.CallResolverUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory;
|
||||
@@ -1371,7 +1372,9 @@ public class DescriptorResolver {
|
||||
}
|
||||
|
||||
if (isStaticNestedClass(classDescriptor)) {
|
||||
trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor));
|
||||
PsiElement onReport = (reportErrorsOn instanceof KtConstructorDelegationCall)
|
||||
? CallResolverUtilKt.reportOnElement((KtConstructorDelegationCall) reportErrorsOn) : reportErrorsOn;
|
||||
trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(onReport, classDescriptor));
|
||||
return false;
|
||||
}
|
||||
classDescriptor = getParentOfType(classDescriptor, ClassDescriptor.class, true);
|
||||
|
||||
@@ -38,9 +38,12 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.classCanHaveAbstractFakeOverride
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getKotlinTypeRefiner
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
import org.jetbrains.kotlin.types.checker.NewKotlinTypeCheckerImpl
|
||||
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
|
||||
import java.util.*
|
||||
@@ -74,7 +77,7 @@ class OverrideResolver(
|
||||
|
||||
val inheritedMemberErrors = CollectErrorInformationForInheritedMembersStrategy(klass, classDescriptor)
|
||||
|
||||
checkInheritedAndDelegatedSignatures(classDescriptor, inheritedMemberErrors, inheritedMemberErrors)
|
||||
checkInheritedAndDelegatedSignatures(classDescriptor, inheritedMemberErrors, inheritedMemberErrors, kotlinTypeRefiner)
|
||||
inheritedMemberErrors.doReportErrors()
|
||||
}
|
||||
|
||||
@@ -200,17 +203,13 @@ class OverrideResolver(
|
||||
overriding: CallableMemberDescriptor,
|
||||
overridden: CallableMemberDescriptor
|
||||
) {
|
||||
reportDelegationProblemIfRequired(
|
||||
RETURN_TYPE_MISMATCH_BY_DELEGATION, RETURN_TYPE_MISMATCH_ON_INHERITANCE, overriding, overridden
|
||||
)
|
||||
}
|
||||
val (diagnosticFactory, relevantDiagnosticFromInheritance) = if (overridden is PropertyDescriptor)
|
||||
PROPERTY_TYPE_MISMATCH_BY_DELEGATION to PROPERTY_TYPE_MISMATCH_ON_INHERITANCE
|
||||
else
|
||||
RETURN_TYPE_MISMATCH_BY_DELEGATION to RETURN_TYPE_MISMATCH_ON_INHERITANCE
|
||||
|
||||
override fun propertyTypeMismatchOnOverride(
|
||||
overriding: PropertyDescriptor,
|
||||
overridden: PropertyDescriptor
|
||||
) {
|
||||
reportDelegationProblemIfRequired(
|
||||
PROPERTY_TYPE_MISMATCH_BY_DELEGATION, PROPERTY_TYPE_MISMATCH_ON_INHERITANCE, overriding, overridden
|
||||
diagnosticFactory, relevantDiagnosticFromInheritance, overriding, overridden
|
||||
)
|
||||
}
|
||||
|
||||
@@ -263,7 +262,6 @@ class OverrideResolver(
|
||||
private interface CheckOverrideReportStrategy {
|
||||
fun overridingFinalMember(overriding: CallableMemberDescriptor, overridden: CallableMemberDescriptor)
|
||||
fun returnTypeMismatchOnOverride(overriding: CallableMemberDescriptor, overridden: CallableMemberDescriptor)
|
||||
fun propertyTypeMismatchOnOverride(overriding: PropertyDescriptor, overridden: PropertyDescriptor)
|
||||
fun varOverriddenByVal(overriding: CallableMemberDescriptor, overridden: CallableMemberDescriptor)
|
||||
}
|
||||
|
||||
@@ -310,19 +308,17 @@ class OverrideResolver(
|
||||
override fun returnTypeMismatchOnOverride(overriding: CallableMemberDescriptor, overridden: CallableMemberDescriptor) {
|
||||
if (!typeMismatchError) {
|
||||
typeMismatchError = true
|
||||
trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(
|
||||
member, declared, DeclarationWithDiagnosticComponents(overridden, platformSpecificDiagnosticComponents)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
override fun propertyTypeMismatchOnOverride(overriding: PropertyDescriptor, overridden: PropertyDescriptor) {
|
||||
if (!typeMismatchError) {
|
||||
typeMismatchError = true
|
||||
if (overridden.isVar) {
|
||||
trace.report(VAR_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden))
|
||||
} else {
|
||||
trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden))
|
||||
when {
|
||||
overridden is PropertyDescriptor && overridden.isVar ->
|
||||
trace.report(VAR_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden))
|
||||
|
||||
overridden is PropertyDescriptor && !overridden.isVar ->
|
||||
trace.report(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE.on(member, declared, overridden))
|
||||
|
||||
else -> trace.report(RETURN_TYPE_MISMATCH_ON_OVERRIDE.on(
|
||||
member, declared, DeclarationWithDiagnosticComponents(overridden, platformSpecificDiagnosticComponents)
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -371,14 +367,10 @@ class OverrideResolver(
|
||||
}
|
||||
}
|
||||
|
||||
override fun propertyTypeMismatchOnOverride(overriding: PropertyDescriptor, overridden: PropertyDescriptor) {
|
||||
throw IllegalStateException("Component functions are not properties")
|
||||
}
|
||||
|
||||
override fun varOverriddenByVal(overriding: CallableMemberDescriptor, overridden: CallableMemberDescriptor) {
|
||||
throw IllegalStateException("Component functions are not properties")
|
||||
}
|
||||
})
|
||||
}, kotlinTypeRefiner)
|
||||
}
|
||||
|
||||
private fun checkOverrideForCopyFunction(copyFunction: CallableMemberDescriptor) {
|
||||
@@ -561,18 +553,25 @@ class OverrideResolver(
|
||||
|
||||
fun getMissingImplementations(classDescriptor: ClassDescriptor): Set<CallableMemberDescriptor> {
|
||||
val collector = CollectMissingImplementationsStrategy()
|
||||
checkInheritedAndDelegatedSignatures(classDescriptor, collector, null)
|
||||
// Note that it is fine to pass default refiner here. Reason:
|
||||
// 1. We bind overrides with proper refiners and [checkInheritedAndDelegatedSignatures] skips all properly-bound overrides,
|
||||
// so we would consider only unbound overrides
|
||||
// 2. Using default refiner instead of proper one can only increase amount of type mismatches, not decrease it
|
||||
// Putting 1 and 2 together means that using default refiner might make already unbound overrides even "more unbound", which
|
||||
// isn't an issue for case of [getMissingImplementations]
|
||||
checkInheritedAndDelegatedSignatures(classDescriptor, collector, null, KotlinTypeRefiner.Default)
|
||||
return collector.shouldImplement
|
||||
}
|
||||
|
||||
private fun checkInheritedAndDelegatedSignatures(
|
||||
classDescriptor: ClassDescriptor,
|
||||
inheritedReportStrategy: CheckInheritedSignaturesReportStrategy,
|
||||
overrideReportStrategyForDelegates: CheckOverrideReportStrategy?
|
||||
overrideReportStrategyForDelegates: CheckOverrideReportStrategy?,
|
||||
kotlinTypeRefiner: KotlinTypeRefiner
|
||||
) {
|
||||
for (member in DescriptorUtils.getAllDescriptors(classDescriptor.defaultType.memberScope)) {
|
||||
if (member is CallableMemberDescriptor) {
|
||||
checkInheritedAndDelegatedSignatures(member, inheritedReportStrategy, overrideReportStrategyForDelegates)
|
||||
checkInheritedAndDelegatedSignatures(member, inheritedReportStrategy, overrideReportStrategyForDelegates, kotlinTypeRefiner)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -580,7 +579,8 @@ class OverrideResolver(
|
||||
private fun checkInheritedAndDelegatedSignatures(
|
||||
descriptor: CallableMemberDescriptor,
|
||||
reportingStrategy: CheckInheritedSignaturesReportStrategy,
|
||||
overrideReportStrategyForDelegates: CheckOverrideReportStrategy?
|
||||
overrideReportStrategyForDelegates: CheckOverrideReportStrategy?,
|
||||
kotlinTypeRefiner: KotlinTypeRefiner
|
||||
) {
|
||||
val kind = descriptor.kind
|
||||
if (kind != FAKE_OVERRIDE && kind != DELEGATION) return
|
||||
@@ -606,10 +606,10 @@ class OverrideResolver(
|
||||
return
|
||||
}
|
||||
|
||||
checkInheritedDescriptorsGroup(descriptor, relevantDirectlyOverridden, reportingStrategy)
|
||||
checkInheritedDescriptorsGroup(descriptor, relevantDirectlyOverridden, reportingStrategy, kotlinTypeRefiner)
|
||||
|
||||
if (kind == DELEGATION && overrideReportStrategyForDelegates != null) {
|
||||
checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates)
|
||||
checkOverridesForMember(descriptor, relevantDirectlyOverridden, overrideReportStrategyForDelegates, kotlinTypeRefiner)
|
||||
}
|
||||
|
||||
if (kind != DELEGATION) {
|
||||
@@ -632,7 +632,7 @@ class OverrideResolver(
|
||||
1 ->
|
||||
if (kind != DELEGATION) {
|
||||
val implementation = concreteOverridden.first()
|
||||
collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementation).forEach {
|
||||
collectAbstractMethodsWithMoreSpecificReturnType(abstractOverridden, implementation, kotlinTypeRefiner).forEach {
|
||||
reportingStrategy.abstractMemberWithMoreSpecificType(it, implementation)
|
||||
}
|
||||
}
|
||||
@@ -703,9 +703,10 @@ class OverrideResolver(
|
||||
|
||||
private fun collectAbstractMethodsWithMoreSpecificReturnType(
|
||||
abstractOverridden: List<CallableMemberDescriptor>,
|
||||
implementation: CallableMemberDescriptor
|
||||
implementation: CallableMemberDescriptor,
|
||||
kotlinTypeRefiner: KotlinTypeRefiner
|
||||
): List<CallableMemberDescriptor> =
|
||||
abstractOverridden.filter { abstractMember -> !isReturnTypeOkForOverride(abstractMember, implementation) }
|
||||
abstractOverridden.filter { abstractMember -> !isReturnTypeOkForOverride(abstractMember, implementation, kotlinTypeRefiner) }
|
||||
|
||||
private fun getRelevantDirectlyOverridden(
|
||||
overriddenByParent: MutableMap<CallableMemberDescriptor, Set<CallableMemberDescriptor>>,
|
||||
@@ -778,23 +779,18 @@ class OverrideResolver(
|
||||
private fun checkInheritedDescriptorsGroup(
|
||||
descriptor: CallableMemberDescriptor,
|
||||
overriddenDescriptors: Collection<CallableMemberDescriptor>,
|
||||
reportingStrategy: CheckInheritedSignaturesReportStrategy
|
||||
reportingStrategy: CheckInheritedSignaturesReportStrategy,
|
||||
kotlinTypeRefiner: KotlinTypeRefiner
|
||||
) {
|
||||
if (overriddenDescriptors.size <= 1) return
|
||||
|
||||
val propertyDescriptor = descriptor as? PropertyDescriptor
|
||||
|
||||
for (overriddenDescriptor in overriddenDescriptors) {
|
||||
if (propertyDescriptor != null) {
|
||||
val overriddenPropertyDescriptor =
|
||||
overriddenDescriptor.assertedCast<PropertyDescriptor> { "$overriddenDescriptor is not a property" }
|
||||
if (!isPropertyTypeOkForOverride(overriddenPropertyDescriptor, propertyDescriptor)) {
|
||||
reportingStrategy.typeMismatchOnInheritance(propertyDescriptor, overriddenPropertyDescriptor)
|
||||
}
|
||||
} else {
|
||||
if (!isReturnTypeOkForOverride(overriddenDescriptor, descriptor)) {
|
||||
reportingStrategy.typeMismatchOnInheritance(descriptor, overriddenDescriptor)
|
||||
}
|
||||
require(descriptor !is PropertyDescriptor || overriddenDescriptor is PropertyDescriptor) {
|
||||
"$overriddenDescriptor is not a property"
|
||||
}
|
||||
|
||||
if (!isReturnTypeOkForOverride(overriddenDescriptor, descriptor, kotlinTypeRefiner)) {
|
||||
reportingStrategy.typeMismatchOnInheritance(descriptor, overriddenDescriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -806,7 +802,7 @@ class OverrideResolver(
|
||||
) {
|
||||
val overriddenDescriptors = declared.overriddenDescriptors
|
||||
|
||||
checkOverridesForMember(declared, overriddenDescriptors, reportError)
|
||||
checkOverridesForMember(declared, overriddenDescriptors, reportError, kotlinTypeRefiner)
|
||||
|
||||
if (overriddenDescriptors.isEmpty()) {
|
||||
val containingDeclaration = declared.containingDeclaration
|
||||
@@ -829,23 +825,18 @@ class OverrideResolver(
|
||||
private fun checkOverridesForMember(
|
||||
memberDescriptor: CallableMemberDescriptor,
|
||||
overriddenDescriptors: Collection<CallableMemberDescriptor>,
|
||||
reportError: CheckOverrideReportStrategy
|
||||
reportError: CheckOverrideReportStrategy,
|
||||
kotlinTypeRefiner: KotlinTypeRefiner
|
||||
) {
|
||||
val propertyMemberDescriptor = if (memberDescriptor is PropertyDescriptor) memberDescriptor else null
|
||||
|
||||
for (overridden in overriddenDescriptors) {
|
||||
if (overridden.modality == Modality.FINAL) {
|
||||
reportError.overridingFinalMember(memberDescriptor, overridden)
|
||||
}
|
||||
|
||||
if (propertyMemberDescriptor != null) {
|
||||
val overriddenProperty = overridden.assertedCast<PropertyDescriptor> {
|
||||
"$overridden is overridden by property $propertyMemberDescriptor"
|
||||
if (!isReturnTypeOkForOverride(overridden, memberDescriptor, kotlinTypeRefiner)) {
|
||||
require(memberDescriptor !is PropertyDescriptor || overridden is PropertyDescriptor) {
|
||||
"$overridden is overridden by property $memberDescriptor"
|
||||
}
|
||||
if (!isPropertyTypeOkForOverride(overriddenProperty, propertyMemberDescriptor)) {
|
||||
reportError.propertyTypeMismatchOnOverride(propertyMemberDescriptor, overriddenProperty)
|
||||
}
|
||||
} else if (!isReturnTypeOkForOverride(overridden, memberDescriptor)) {
|
||||
reportError.returnTypeMismatchOnOverride(memberDescriptor, overridden)
|
||||
}
|
||||
|
||||
@@ -857,7 +848,8 @@ class OverrideResolver(
|
||||
|
||||
private fun isReturnTypeOkForOverride(
|
||||
superDescriptor: CallableDescriptor,
|
||||
subDescriptor: CallableDescriptor
|
||||
subDescriptor: CallableDescriptor,
|
||||
kotlinTypeRefiner: KotlinTypeRefiner,
|
||||
): Boolean {
|
||||
val typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor) ?: return false
|
||||
|
||||
@@ -867,7 +859,11 @@ class OverrideResolver(
|
||||
|
||||
val substitutedSuperReturnType = typeSubstitutor.substitute(superReturnType, Variance.OUT_VARIANCE)!!
|
||||
|
||||
return KotlinTypeChecker.DEFAULT.isSubtypeOf(subReturnType, substitutedSuperReturnType)
|
||||
val typeChecker = NewKotlinTypeCheckerImpl(kotlinTypeRefiner)
|
||||
return if (superDescriptor is PropertyDescriptor && superDescriptor.isVar)
|
||||
typeChecker.equalTypes(subReturnType, substitutedSuperReturnType)
|
||||
else
|
||||
typeChecker.isSubtypeOf(subReturnType, substitutedSuperReturnType)
|
||||
}
|
||||
|
||||
private fun prepareTypeSubstitutor(
|
||||
@@ -886,21 +882,6 @@ class OverrideResolver(
|
||||
return IndexedParametersSubstitution(superTypeParameters, arguments).buildSubstitutor()
|
||||
}
|
||||
|
||||
private fun isPropertyTypeOkForOverride(
|
||||
superDescriptor: PropertyDescriptor,
|
||||
subDescriptor: PropertyDescriptor
|
||||
): Boolean {
|
||||
val typeSubstitutor = prepareTypeSubstitutor(superDescriptor, subDescriptor) ?: return false
|
||||
|
||||
val substitutedSuperReturnType = typeSubstitutor.substitute(superDescriptor.type, Variance.OUT_VARIANCE)!!
|
||||
|
||||
return if (superDescriptor.isVar) {
|
||||
KotlinTypeChecker.DEFAULT.equalTypes(subDescriptor.type, substitutedSuperReturnType)
|
||||
} else {
|
||||
KotlinTypeChecker.DEFAULT.isSubtypeOf(subDescriptor.type, substitutedSuperReturnType)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findDataModifierForDataClass(dataClass: DeclarationDescriptor): PsiElement {
|
||||
val classDeclaration = DescriptorToSourceUtils.getSourceFromDescriptor(dataClass) as KtClassOrObject?
|
||||
if (classDeclaration?.modifierList != null) {
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve
|
||||
import org.jetbrains.kotlin.builtins.PlatformToKotlinClassMapper
|
||||
import org.jetbrains.kotlin.container.*
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.InferenceCompatibilityCheckerImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||
import org.jetbrains.kotlin.resolve.checkers.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.DelegationFilter
|
||||
@@ -38,7 +39,8 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
|
||||
MissingDependencySupertypeChecker.ForDeclarations,
|
||||
FunInterfaceDeclarationChecker(),
|
||||
DeprecatedSinceKotlinAnnotationChecker,
|
||||
ContractDescriptionBlockChecker
|
||||
ContractDescriptionBlockChecker,
|
||||
PrivateInlineFunctionsReturningAnonymousObjectsChecker
|
||||
)
|
||||
|
||||
private val DEFAULT_CALL_CHECKERS = listOf(
|
||||
@@ -52,7 +54,8 @@ private val DEFAULT_CALL_CHECKERS = listOf(
|
||||
UselessElvisCallChecker(), ResultTypeWithNullableOperatorsChecker(), NullableVarargArgumentCallChecker,
|
||||
NamedFunAsExpressionChecker, ContractNotAllowedCallChecker, ReifiedTypeParameterSubstitutionChecker(),
|
||||
MissingDependencySupertypeChecker.ForCalls, AbstractClassInstantiationChecker, SuspendConversionCallChecker,
|
||||
UnitConversionCallChecker, FunInterfaceConstructorReferenceChecker, NullableExtensionOperatorWithSafeCallChecker
|
||||
UnitConversionCallChecker, FunInterfaceConstructorReferenceChecker, NullableExtensionOperatorWithSafeCallChecker,
|
||||
ReferencingToUnderscoreNamedParameterOfCatchBlockChecker, VarargWrongExecutionOrderChecker
|
||||
)
|
||||
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
|
||||
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(
|
||||
@@ -107,6 +110,7 @@ abstract class PlatformConfiguratorBase(
|
||||
|
||||
override fun configureModuleDependentCheckers(container: StorageComponentContainer) {
|
||||
container.useImpl<ExperimentalMarkerDeclarationAnnotationChecker>()
|
||||
container.useImpl<InferenceCompatibilityCheckerImpl>()
|
||||
}
|
||||
|
||||
fun configureExtensionsAndCheckers(container: StorageComponentContainer) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionUtilCore
|
||||
import com.intellij.psi.impl.source.DummyHolder
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
@@ -573,6 +574,9 @@ class QualifiedExpressionResolver(val languageVersionSettings: LanguageVersionSe
|
||||
context: ExpressionTypingContext
|
||||
): Qualifier? {
|
||||
val name = expression.getReferencedNameAsName()
|
||||
if (!expression.isPhysical && !name.isSpecial && name.asString().endsWith(CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED)) {
|
||||
return null
|
||||
}
|
||||
|
||||
val location = KotlinLookupLocation(expression)
|
||||
val qualifierDescriptor = when (receiver) {
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.config.LanguageFeature;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
@@ -334,8 +335,12 @@ public class CallResolver {
|
||||
KtConstructorDelegationCall delegationCall = (KtConstructorDelegationCall) context.call.getCallElement();
|
||||
DeclarationDescriptor container = context.scope.getOwnerDescriptor();
|
||||
assert container instanceof ConstructorDescriptor : "Trying to resolve JetConstructorDelegationCall not in constructor. scope.ownerDescriptor = " + container;
|
||||
return (OverloadResolutionResults) resolveConstructorDelegationCall(context, delegationCall, (KtConstructorDelegationReferenceExpression) calleeExpression,
|
||||
(ClassConstructorDescriptor) container);
|
||||
return (OverloadResolutionResults) resolveConstructorDelegationCall(
|
||||
context,
|
||||
delegationCall,
|
||||
(KtConstructorDelegationReferenceExpression) calleeExpression,
|
||||
(ClassDescriptor) container.getContainingDeclaration()
|
||||
);
|
||||
}
|
||||
else if (calleeExpression == null) {
|
||||
return checkArgumentTypesAndFail(context);
|
||||
@@ -433,18 +438,28 @@ public class CallResolver {
|
||||
dataFlowValueFactory,
|
||||
InferenceSession.Companion.getDefault());
|
||||
|
||||
if (call.getCalleeExpression() == null) return checkArgumentTypesAndFail(context);
|
||||
KtConstructorDelegationReferenceExpression calleeExpression = call.getCalleeExpression();
|
||||
|
||||
if (calleeExpression == null) return checkArgumentTypesAndFail(context);
|
||||
|
||||
ClassDescriptor currentClassDescriptor = constructorDescriptor.getContainingDeclaration();
|
||||
|
||||
if (constructorDescriptor.getConstructedClass().getKind() == ClassKind.ENUM_CLASS && call.isImplicit()) {
|
||||
if (currentClassDescriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||
DiagnosticFactory0<PsiElement> warningOrError;
|
||||
|
||||
if (languageVersionSettings.supportsFeature(LanguageFeature.RequiredPrimaryConstructorDelegationCallInEnums)) {
|
||||
warningOrError = PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED; // error
|
||||
} else {
|
||||
warningOrError = PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED_IN_ENUM; // warning
|
||||
}
|
||||
PsiElement reportOn = calcReportOn(calleeExpression);
|
||||
context.trace.report(warningOrError.on(reportOn));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
return resolveConstructorDelegationCall(
|
||||
context,
|
||||
call,
|
||||
call.getCalleeExpression(),
|
||||
constructorDescriptor
|
||||
);
|
||||
return resolveConstructorDelegationCall(context, call, call.getCalleeExpression(), currentClassDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -452,12 +467,10 @@ public class CallResolver {
|
||||
@NotNull BasicCallResolutionContext context,
|
||||
@NotNull KtConstructorDelegationCall call,
|
||||
@NotNull KtConstructorDelegationReferenceExpression calleeExpression,
|
||||
@NotNull ClassConstructorDescriptor calleeConstructor
|
||||
@NotNull ClassDescriptor currentClassDescriptor
|
||||
) {
|
||||
context.trace.record(BindingContext.LEXICAL_SCOPE, call, context.scope);
|
||||
|
||||
ClassDescriptor currentClassDescriptor = calleeConstructor.getContainingDeclaration();
|
||||
|
||||
boolean isThisCall = calleeExpression.isThis();
|
||||
if (currentClassDescriptor.getKind() == ClassKind.ENUM_CLASS && !isThisCall) {
|
||||
context.trace.report(DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR.on(calleeExpression));
|
||||
@@ -471,9 +484,8 @@ public class CallResolver {
|
||||
if (!isThisCall && currentClassDescriptor.getUnsubstitutedPrimaryConstructor() != null) {
|
||||
if (DescriptorUtils.canHaveDeclaredConstructors(currentClassDescriptor)) {
|
||||
// Diagnostic is meaningless when reporting on interfaces and object
|
||||
context.trace.report(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on(
|
||||
(KtConstructorDelegationCall) calleeExpression.getParent()
|
||||
));
|
||||
PsiElement reportOn = calcReportOn(calleeExpression);
|
||||
context.trace.report(PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED.on(reportOn));
|
||||
}
|
||||
if (call.isImplicit()) return OverloadResolutionResultsImpl.nameNotFound();
|
||||
}
|
||||
@@ -484,9 +496,8 @@ public class CallResolver {
|
||||
}
|
||||
|
||||
|
||||
KotlinType superType = isThisCall ?
|
||||
calleeConstructor.getContainingDeclaration().getDefaultType() :
|
||||
DescriptorUtils.getSuperClassType(currentClassDescriptor);
|
||||
KotlinType superType =
|
||||
isThisCall ? currentClassDescriptor.getDefaultType() : DescriptorUtils.getSuperClassType(currentClassDescriptor);
|
||||
|
||||
Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext> candidatesAndContext =
|
||||
prepareCandidatesAndContextForConstructorCall(superType, context, syntheticScopes);
|
||||
@@ -508,6 +519,13 @@ public class CallResolver {
|
||||
return computeTasksFromCandidatesAndResolvedCall(context, candidates, tracing);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiElement calcReportOn(@NotNull KtConstructorDelegationReferenceExpression calleeExpression) {
|
||||
PsiElement delegationCall = calleeExpression.getParent();
|
||||
return delegationCall instanceof KtConstructorDelegationCall
|
||||
? CallResolverUtilKt.reportOnElement((KtConstructorDelegationCall) delegationCall) : delegationCall;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Pair<Collection<ResolutionCandidate<ConstructorDescriptor>>, BasicCallResolutionContext> prepareCandidatesAndContextForConstructorCall(
|
||||
@NotNull KotlinType superType,
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
|
||||
import org.jetbrains.kotlin.lexer.KtToken
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
||||
@@ -236,9 +237,12 @@ private fun arrayAssignmentToVarargInNamedFormInAnnotation(
|
||||
): Boolean {
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.AssigningArraysToVarargsInNamedFormInAnnotations)) return false
|
||||
|
||||
if (!isParameterOfAnnotation(parameterDescriptor)) return false
|
||||
val isAllowedAssigningSingleElementsToVarargsInNamedForm =
|
||||
!languageVersionSettings.supportsFeature(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm)
|
||||
|
||||
return argument.isNamed() && parameterDescriptor.isVararg && isArrayOrArrayLiteral(argument, trace)
|
||||
if (isAllowedAssigningSingleElementsToVarargsInNamedForm && !isArrayOrArrayLiteral(argument, trace)) return false
|
||||
|
||||
return isParameterOfAnnotation(parameterDescriptor) && argument.isNamed() && parameterDescriptor.isVararg
|
||||
}
|
||||
|
||||
private fun arrayAssignmentToVarargInNamedFormInFunction(
|
||||
@@ -249,7 +253,12 @@ private fun arrayAssignmentToVarargInNamedFormInFunction(
|
||||
): Boolean {
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.AllowAssigningArrayElementsToVarargsInNamedFormForFunctions)) return false
|
||||
|
||||
return argument.isNamed() && parameterDescriptor.isVararg && isArrayOrArrayLiteral(argument, trace)
|
||||
val isAllowedAssigningSingleElementsToVarargsInNamedForm =
|
||||
!languageVersionSettings.supportsFeature(LanguageFeature.ProhibitAssigningSingleElementsToVarargsInNamedForm)
|
||||
|
||||
if (isAllowedAssigningSingleElementsToVarargsInNamedForm && !isArrayOrArrayLiteral(argument, trace)) return false
|
||||
|
||||
return argument.isNamed() && parameterDescriptor.isVararg
|
||||
}
|
||||
|
||||
fun isArrayOrArrayLiteral(argument: ValueArgument, trace: BindingTrace): Boolean {
|
||||
@@ -312,3 +321,7 @@ fun createResolutionCandidatesForConstructors(
|
||||
ResolutionCandidate.create(call, it, dispatchReceiver, receiverKind, knownSubstitutor)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun KtConstructorDelegationCall.reportOnElement() = if (this.isImplicit) {
|
||||
this.getStrictParentOfType<KtSecondaryConstructor>()!!
|
||||
} else this
|
||||
|
||||
@@ -159,7 +159,11 @@ class DiagnosticReporterByTrackingStrategy(
|
||||
|
||||
CallableReferenceCandidatesAmbiguity::class.java -> {
|
||||
val ambiguityDiagnostic = diagnostic as CallableReferenceCandidatesAmbiguity
|
||||
val expression = ambiguityDiagnostic.argument.psiExpression.safeAs<KtCallableReferenceExpression>()
|
||||
val expression = when (val psiExpression = ambiguityDiagnostic.argument.psiExpression) {
|
||||
is KtPsiUtil.KtExpressionWrapper -> psiExpression.baseExpression
|
||||
else -> psiExpression
|
||||
}.safeAs<KtCallableReferenceExpression>()
|
||||
|
||||
val candidates = ambiguityDiagnostic.candidates.map { it.candidate }
|
||||
if (expression != null) {
|
||||
trace.reportDiagnosticOnce(CALLABLE_REFERENCE_RESOLUTION_AMBIGUITY.on(expression.callableReference, candidates))
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.SPECIAL_FUNCTION_NAMES
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.components.stableType
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.psiExpression
|
||||
@@ -96,8 +97,15 @@ object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
|
||||
}
|
||||
|
||||
val resolvedCallAtom = resolvedAtom.getResolvedCallAtom(context.trace.bindingContext) ?: continue
|
||||
val atom = resolvedAtom.atom
|
||||
|
||||
if (atom is SimpleKotlinCallArgument && !atom.receiver.stableType.isNothingOrNullableNothing())
|
||||
continue
|
||||
|
||||
val candidateDescriptor = resolvedCallAtom.candidateDescriptor
|
||||
val isReturnTypeOwnTypeParameter = candidateDescriptor.typeParameters.any { it.defaultType == candidateDescriptor.returnType }
|
||||
val isReturnTypeOwnTypeParameter = candidateDescriptor.typeParameters.any {
|
||||
it.typeConstructor == candidateDescriptor.returnType?.constructor
|
||||
}
|
||||
val isSpecialCall = candidateDescriptor.name in SPECIAL_FUNCTION_NAMES
|
||||
val hasExplicitTypeArguments = resolvedCallAtom.atom.psiKotlinCall.typeArguments.isNotEmpty() // not required
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.builtins.isFunctionOrSuspendFunctionType
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
|
||||
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnceWrtDiagnosticFactoryList
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.SPECIAL_FUNCTION_NAMES
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.psiCallArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.psiExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.psiKotlinCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isUnderscoreNamed
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.kotlin.types.DeferredType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothingOrNullableNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
|
||||
object ReferencingToUnderscoreNamedParameterOfCatchBlockChecker : CallChecker {
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
val descriptor = resolvedCall.resultingDescriptor
|
||||
|
||||
if (descriptor !is LocalVariableDescriptor || !descriptor.isUnderscoreNamed) return
|
||||
|
||||
val sourceElement = descriptor.source as? KotlinSourceElement ?: return
|
||||
val ktParameter = sourceElement.psi as? KtParameter ?: return
|
||||
|
||||
if (ktParameter.isCatchParameter) {
|
||||
context.trace.reportDiagnosticOnce(Errors.RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER.on(reportOn))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isAnnotationConstructor
|
||||
|
||||
object VarargWrongExecutionOrderChecker : CallChecker {
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
val isCorrectExecutionOrderForVarargArgumentsAlreadyUsed =
|
||||
context.languageVersionSettings.getFeatureSupport(LanguageFeature.UseCorrectExecutionOrderForVarargArguments) == LanguageFeature.State.ENABLED
|
||||
|
||||
if (resolvedCall.candidateDescriptor.isAnnotationConstructor()) return
|
||||
|
||||
if (isCorrectExecutionOrderForVarargArgumentsAlreadyUsed) return
|
||||
|
||||
val valueArguments = resolvedCall.call.valueArguments
|
||||
|
||||
val varargIndex = valueArguments.indexOfFirst {
|
||||
resolvedCall.getParameterForArgument(it)?.isVararg == true
|
||||
}.takeIf { it != -1 } ?: return
|
||||
val nonVarargIndex = valueArguments.indexOfLast {
|
||||
resolvedCall.getParameterForArgument(it)?.isVararg != true
|
||||
}.takeIf { it != -1 } ?: return
|
||||
|
||||
if (varargIndex > nonVarargIndex) return
|
||||
|
||||
val varargValueArgument = valueArguments[varargIndex]
|
||||
|
||||
if (!varargValueArgument.isNamed() || varargValueArgument !is PsiElement) return
|
||||
|
||||
// If named form for vararg is used then we can have only one real value argument on a call site
|
||||
context.trace.report(Errors.CHANGING_ARGUMENTS_EXECUTION_ORDER_FOR_NAMED_VARARGS.on(varargValueArgument))
|
||||
}
|
||||
}
|
||||
@@ -33,5 +33,5 @@ sealed class CallPosition {
|
||||
val valueArgument: ValueArgument
|
||||
) : CallPosition()
|
||||
|
||||
class PropertyAssignment(val leftPart: KtExpression?) : CallPosition()
|
||||
class PropertyAssignment(val leftPart: KtExpression?, val isLeft: Boolean) : CallPosition()
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.inference
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.*
|
||||
@@ -81,7 +82,13 @@ class CoroutineInferenceSession(
|
||||
return !storage.notFixedTypeVariables.keys.any {
|
||||
val variable = storage.allTypeVariables[it]
|
||||
val isPostponed = variable != null && variable in storage.postponedTypeVariables
|
||||
!isPostponed && !kotlinConstraintSystemCompleter.variableFixationFinder.isTypeVariableHasProperConstraint(system, it)
|
||||
val useInferenceCompatibilityMode =
|
||||
topLevelCallContext.languageVersionSettings.supportsFeature(LanguageFeature.InferenceCompatibility)
|
||||
!isPostponed && !kotlinConstraintSystemCompleter.variableFixationFinder.isTypeVariableHasProperConstraint(
|
||||
system,
|
||||
it,
|
||||
useInferenceCompatibilityMode
|
||||
)
|
||||
} || candidate.getSubResolvedAtoms().any { it.hasPostponed() }
|
||||
}
|
||||
|
||||
|
||||
@@ -22,12 +22,11 @@ import org.jetbrains.kotlin.diagnostics.Errors.UNRESOLVED_REFERENCE
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.UNRESOLVED_REFERENCE_WRONG_RECEIVER
|
||||
import org.jetbrains.kotlin.psi.Call
|
||||
import org.jetbrains.kotlin.psi.KtConstructorDelegationCall
|
||||
import org.jetbrains.kotlin.psi.KtLambdaArgument
|
||||
import org.jetbrains.kotlin.psi.KtSecondaryConstructor
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.CALL
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.RESOLVED_CALL
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.reportOnElement
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
@@ -83,8 +82,9 @@ class TracingStrategyForImplicitConstructorDelegationCall(
|
||||
}
|
||||
|
||||
private fun reportError(trace: BindingTrace) {
|
||||
if (!trace.bindingContext.diagnostics.forElement(delegationCall).any { it.factory == Errors.EXPLICIT_DELEGATION_CALL_REQUIRED }) {
|
||||
trace.report(Errors.EXPLICIT_DELEGATION_CALL_REQUIRED.on(delegationCall))
|
||||
val reportOn = delegationCall.reportOnElement()
|
||||
if (!trace.bindingContext.diagnostics.forElement(reportOn).any { it.factory == Errors.EXPLICIT_DELEGATION_CALL_REQUIRED }) {
|
||||
trace.report(Errors.EXPLICIT_DELEGATION_CALL_REQUIRED.on(reportOn))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
|
||||
@@ -227,7 +229,13 @@ class KotlinToResolvedCallTransformer(
|
||||
return storedResolvedCall
|
||||
}
|
||||
}
|
||||
return NewResolvedCallImpl(completedSimpleAtom, resultSubstitutor, diagnostics, typeApproximator)
|
||||
return NewResolvedCallImpl(
|
||||
completedSimpleAtom,
|
||||
resultSubstitutor,
|
||||
diagnostics,
|
||||
typeApproximator,
|
||||
expressionTypingServices.languageVersionSettings
|
||||
)
|
||||
}
|
||||
|
||||
fun runCallCheckers(resolvedCall: ResolvedCall<*>, callCheckerContext: CallCheckerContext) {
|
||||
@@ -551,6 +559,7 @@ class TrackingBindingTrace(val trace: BindingTrace) : BindingTrace by trace {
|
||||
sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D> {
|
||||
abstract val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||
abstract val kotlinCall: KotlinCall
|
||||
protected abstract val languageVersionSettings: LanguageVersionSettings
|
||||
|
||||
protected var argumentToParameterMap: Map<ValueArgument, ArgumentMatchImpl>? = null
|
||||
protected var _valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>? = null
|
||||
@@ -620,6 +629,8 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
||||
|
||||
private fun createValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> =
|
||||
LinkedHashMap<ValueParameterDescriptor, ResolvedValueArgument>().also { result ->
|
||||
val needToUseCorrectExecutionOrderForVarargArguments =
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.UseCorrectExecutionOrderForVarargArguments)
|
||||
var varargMappings: MutableList<Pair<ValueParameterDescriptor, VarargValueArgument>>? = null
|
||||
for ((originalParameter, resolvedCallArgument) in argumentMappingByOriginal) {
|
||||
val resultingParameter = resultingDescriptor.valueParameters[originalParameter.index]
|
||||
@@ -630,12 +641,17 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
||||
is ResolvedCallArgument.SimpleArgument -> {
|
||||
val valueArgument = resolvedCallArgument.callArgument.psiCallArgument.valueArgument
|
||||
if (resultingParameter.isVararg) {
|
||||
val vararg = VarargValueArgument().apply { addArgument(valueArgument) }
|
||||
if (varargMappings == null) varargMappings = SmartList()
|
||||
varargMappings.add(resultingParameter to vararg)
|
||||
continue
|
||||
} else
|
||||
if (needToUseCorrectExecutionOrderForVarargArguments) {
|
||||
VarargValueArgument().apply { addArgument(valueArgument) }
|
||||
} else {
|
||||
val vararg = VarargValueArgument().apply { addArgument(valueArgument) }
|
||||
if (varargMappings == null) varargMappings = SmartList()
|
||||
varargMappings.add(resultingParameter to vararg)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
ExpressionValueArgument(valueArgument)
|
||||
}
|
||||
}
|
||||
is ResolvedCallArgument.VarargArgument ->
|
||||
VarargValueArgument().apply {
|
||||
@@ -644,9 +660,11 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
||||
}
|
||||
}
|
||||
|
||||
if (varargMappings != null) {
|
||||
for ((parameter, argument) in varargMappings) {
|
||||
result[parameter] = argument
|
||||
if (varargMappings != null && !needToUseCorrectExecutionOrderForVarargArguments) {
|
||||
if (varargMappings != null) {
|
||||
for ((parameter, argument) in varargMappings) {
|
||||
result[parameter] = argument
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -658,6 +676,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||
substitutor: NewTypeSubstitutor?,
|
||||
private var diagnostics: Collection<KotlinCallDiagnostic>,
|
||||
private val typeApproximator: TypeApproximator,
|
||||
override val languageVersionSettings: LanguageVersionSettings,
|
||||
) : NewAbstractResolvedCall<D>() {
|
||||
var isCompleted = false
|
||||
private set
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.calls.util.CallMaker
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isUnderscoreNamed
|
||||
import org.jetbrains.kotlin.resolve.scopes.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
import org.jetbrains.kotlin.types.*
|
||||
@@ -837,7 +838,11 @@ class PSICallResolver(
|
||||
val catchScope = with(scope) {
|
||||
LexicalWritableScope(this, ownerDescriptor, false, redeclarationChecker, LexicalScopeKind.CATCH)
|
||||
}
|
||||
catchScope.addVariableDescriptor(variableDescriptor)
|
||||
val isReferencingToUnderscoreNamedParameterForbidden =
|
||||
languageVersionSettings.getFeatureSupport(LanguageFeature.ForbidReferencingToUnderscoreNamedParameterOfCatchBlock) == LanguageFeature.State.ENABLED
|
||||
if (!variableDescriptor.isUnderscoreNamed || !isReferencingToUnderscoreNamedParameterForbidden) {
|
||||
catchScope.addVariableDescriptor(variableDescriptor)
|
||||
}
|
||||
return replaceScope(catchScope)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
||||
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.types.typeUtil.shouldBeSubstituted
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class ResolvedAtomCompleter(
|
||||
@@ -212,15 +213,14 @@ class ResolvedAtomCompleter(
|
||||
resultSubstitutor.safeSubstitute(lambda.returnType)
|
||||
}
|
||||
|
||||
val approximatedValueParameterTypes = lambda.parameters.map {
|
||||
// Do substitution and approximation only for stub types, which can appear from builder inference (as postponed variables)
|
||||
if (it is StubType) {
|
||||
val approximatedValueParameterTypes = lambda.parameters.map { parameterType ->
|
||||
if (parameterType.shouldBeSubstituted()) {
|
||||
typeApproximator.approximateDeclarationType(
|
||||
resultSubstitutor.safeSubstitute(it),
|
||||
resultSubstitutor.safeSubstitute(parameterType),
|
||||
local = true,
|
||||
languageVersionSettings = topLevelCallContext.languageVersionSettings
|
||||
)
|
||||
} else it
|
||||
} else parameterType
|
||||
}
|
||||
|
||||
val approximatedReturnType =
|
||||
@@ -277,8 +277,7 @@ class ResolvedAtomCompleter(
|
||||
functionDescriptor.setReturnType(returnType)
|
||||
|
||||
for ((i, valueParameter) in functionDescriptor.valueParameters.withIndex()) {
|
||||
if (valueParameter !is ValueParameterDescriptorImpl || valueParameter.type !is StubType)
|
||||
continue
|
||||
if (valueParameter !is ValueParameterDescriptorImpl || !valueParameter.type.shouldBeSubstituted()) continue
|
||||
valueParameter.setOutType(valueParameters[i])
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.config.AnalysisFlags
|
||||
import org.jetbrains.kotlin.config.ExplicitApiMode
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
|
||||
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPublicApi
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
||||
|
||||
class ExplicitApiDeclarationChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
@@ -22,7 +24,7 @@ class ExplicitApiDeclarationChecker : DeclarationChecker {
|
||||
|
||||
if (descriptor !is DeclarationDescriptorWithVisibility) return
|
||||
if (descriptor is ClassDescriptor && descriptor.kind == ClassKind.ENUM_ENTRY) return // Enum entries does not have visibilities
|
||||
if (!descriptor.isEffectivelyPublicApi) return
|
||||
if (!descriptor.isEffectivelyPublicApi && !descriptor.isPublishedApi()) return
|
||||
|
||||
checkVisibilityModifier(state, declaration, descriptor, context)
|
||||
checkExplicitReturnType(state, declaration, descriptor, context)
|
||||
@@ -105,7 +107,9 @@ class ExplicitApiDeclarationChecker : DeclarationChecker {
|
||||
val callableMemberDescriptor = descriptor as? CallableMemberDescriptor
|
||||
|
||||
val visibility = callableMemberDescriptor?.effectiveVisibility()?.toVisibility()
|
||||
return (checkForPublicApi && visibility?.isPublicAPI == true) || (checkForInternal && visibility == Visibilities.Internal) ||
|
||||
val isPublicApi =
|
||||
visibility?.isPublicAPI == true || (visibility == Visibilities.Internal && callableMemberDescriptor.isPublishedApi())
|
||||
return (checkForPublicApi && isPublicApi) || (checkForInternal && visibility == Visibilities.Internal) ||
|
||||
(checkForPrivate && visibility == Visibilities.Internal)
|
||||
}
|
||||
|
||||
@@ -119,5 +123,20 @@ class ExplicitApiDeclarationChecker : DeclarationChecker {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun publicReturnTypeShouldBePresentInApiMode(
|
||||
element: KtCallableDeclaration,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
descriptor: DeclarationDescriptor?
|
||||
): Boolean {
|
||||
val isInApiMode = languageVersionSettings.getFlag(AnalysisFlags.explicitApiMode) != ExplicitApiMode.DISABLED
|
||||
return isInApiMode && returnTypeRequired(
|
||||
element,
|
||||
descriptor,
|
||||
checkForPublicApi = true,
|
||||
checkForInternal = false,
|
||||
checkForPrivate = false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isPrivate
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
|
||||
|
||||
object PrivateInlineFunctionsReturningAnonymousObjectsChecker : DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.ForbidAnonymousReturnTypesInPrivateInlineFunctions))
|
||||
return
|
||||
|
||||
if (descriptor !is SimpleFunctionDescriptor || !descriptor.isInline || !declaration.isPrivate() || declaration !is KtNamedFunction)
|
||||
return
|
||||
|
||||
val returnTypeConstructor = descriptor.returnType?.constructor ?: return
|
||||
|
||||
if (returnTypeConstructor.supertypes.singleOrNull { it.isAnyOrNullableAny() } == null) return
|
||||
|
||||
val nameIdentifier = declaration.nameIdentifier ?: return
|
||||
val returnTypeDeclarationDescriptor = returnTypeConstructor.declarationDescriptor ?: return
|
||||
|
||||
if (DescriptorUtils.isAnonymousObject(returnTypeDeclarationDescriptor)) {
|
||||
context.trace.report(Errors.PRIVATE_INLINE_FUNCTIONS_RETURNING_ANONYMOUS_OBJECTS.on(nameIdentifier))
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user