mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-05-14 08:31:35 +00:00
Compare commits
212 Commits
rr/abannyk
...
java6-Xint
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d48a7a55c6 | ||
|
|
30639af5a3 | ||
|
|
3add3f091d | ||
|
|
4583e31991 | ||
|
|
f49fe26632 | ||
|
|
73ec5d27a6 | ||
|
|
ac0dc94800 | ||
|
|
789799ac17 | ||
|
|
1f837134bb | ||
|
|
e6e3c9b236 | ||
|
|
5f65b46dfc | ||
|
|
a36135baf1 | ||
|
|
974779e91b | ||
|
|
84334b087c | ||
|
|
62f7e8f71f | ||
|
|
96bd2c54f0 | ||
|
|
931a637bdd | ||
|
|
2165cc8f0d | ||
|
|
e06a60bda5 | ||
|
|
61d5595790 | ||
|
|
dfea915f92 | ||
|
|
81ce1da352 | ||
|
|
bcf47ddc94 | ||
|
|
e790fa8ac9 | ||
|
|
8b3769b88e | ||
|
|
a3ad03d1ad | ||
|
|
b43e5a5e7d | ||
|
|
6a5cf00d7a | ||
|
|
b61277df97 | ||
|
|
229085f3d1 | ||
|
|
f846dd8ea2 | ||
|
|
b1ab597616 | ||
|
|
3293a888ca | ||
|
|
48ef739525 | ||
|
|
825b77cc82 | ||
|
|
b72aa76415 | ||
|
|
a8186d19d6 | ||
|
|
9091ca7b51 | ||
|
|
be097244d4 | ||
|
|
b0d721c9d0 | ||
|
|
290d424111 | ||
|
|
ee45aa6b08 | ||
|
|
886ce055f5 | ||
|
|
5c2753b5d1 | ||
|
|
84c10079e4 | ||
|
|
1ff6dc1275 | ||
|
|
ecbae02f17 | ||
|
|
c6a2d85c87 | ||
|
|
6121d156a1 | ||
|
|
d934c97bf5 | ||
|
|
0b10f255d7 | ||
|
|
c5e6215d27 | ||
|
|
4c943e7cd1 | ||
|
|
8e1c420c9f | ||
|
|
de5dcfcbd8 | ||
|
|
94a94a557d | ||
|
|
89f8c5a651 | ||
|
|
78e20c1098 | ||
|
|
e927764aaf | ||
|
|
15b6a3c88c | ||
|
|
3e892d3184 | ||
|
|
65972fa64c | ||
|
|
1ba6845b59 | ||
|
|
e7275a7cb0 | ||
|
|
e0cc6d44a7 | ||
|
|
67d48d0150 | ||
|
|
96f0b53761 | ||
|
|
af35892007 | ||
|
|
639b7537da | ||
|
|
f5a53c82c5 | ||
|
|
fefc6f9b53 | ||
|
|
d3b1ee42be | ||
|
|
cc571a876a | ||
|
|
242d79ded6 | ||
|
|
b9018e8888 | ||
|
|
5dcaaf47cb | ||
|
|
91e47f1fd7 | ||
|
|
15e978dbd3 | ||
|
|
1dfcec3a93 | ||
|
|
aaffd73feb | ||
|
|
54b9f39b3a | ||
|
|
f4788b479c | ||
|
|
76c15e4444 | ||
|
|
bd7fb56a24 | ||
|
|
4a767c597e | ||
|
|
e942052eb6 | ||
|
|
758eb8f851 | ||
|
|
be22078bd1 | ||
|
|
d8c68aacdd | ||
|
|
fd5169186e | ||
|
|
31ed1ad5d9 | ||
|
|
84bd580f92 | ||
|
|
472ab09511 | ||
|
|
ac222fdb41 | ||
|
|
c0ad1c9b18 | ||
|
|
26cbb020db | ||
|
|
3ff22b67f7 | ||
|
|
d5be258291 | ||
|
|
9fd1cbd2e7 | ||
|
|
d486f7e188 | ||
|
|
0c427555cf | ||
|
|
0f317b01b4 | ||
|
|
0b37b2be6a | ||
|
|
ecde5414dc | ||
|
|
ee927a15a9 | ||
|
|
afbda75581 | ||
|
|
6356b9d501 | ||
|
|
5a11450d77 | ||
|
|
703a353d2e | ||
|
|
c5faf532f5 | ||
|
|
90066d7e50 | ||
|
|
7da47dcde8 | ||
|
|
ac7b459f2a | ||
|
|
5d0461c722 | ||
|
|
26b8e86fe1 | ||
|
|
af12b2fdf0 | ||
|
|
6a7770573c | ||
|
|
8a856e440e | ||
|
|
720edfa6aa | ||
|
|
ebf6ce133b | ||
|
|
3a22761d02 | ||
|
|
b6f35ac44d | ||
|
|
3387615d4a | ||
|
|
cdb04f9cd7 | ||
|
|
af1f57007a | ||
|
|
0b1884c994 | ||
|
|
166f0a597b | ||
|
|
b5f71bacaf | ||
|
|
9d1a6ebb18 | ||
|
|
d12a24418e | ||
|
|
a778cc673e | ||
|
|
157046153f | ||
|
|
01c14a709a | ||
|
|
1abf3a39d4 | ||
|
|
2d015da1ea | ||
|
|
961ee92c15 | ||
|
|
e0c7cda1cf | ||
|
|
f2a067eda0 | ||
|
|
3709616baa | ||
|
|
34878d17eb | ||
|
|
2f60ce21a0 | ||
|
|
535934dc28 | ||
|
|
5f4be07225 | ||
|
|
c2389a94fa | ||
|
|
b541721a79 | ||
|
|
bed42e9ab2 | ||
|
|
14eca72913 | ||
|
|
0749443f7e | ||
|
|
54994a289f | ||
|
|
8481f4a9d2 | ||
|
|
3e2b8a8898 | ||
|
|
b3bb033fe4 | ||
|
|
b63770bc7b | ||
|
|
89e52cb780 | ||
|
|
8eca31e867 | ||
|
|
d37ceb47be | ||
|
|
16dbafced1 | ||
|
|
f431b4b171 | ||
|
|
29584edcdd | ||
|
|
426ac1281d | ||
|
|
2129a762a5 | ||
|
|
a006f35df3 | ||
|
|
61475c48e2 | ||
|
|
3bd6bf1432 | ||
|
|
e31173ca73 | ||
|
|
33ddeffcfd | ||
|
|
117fad2018 | ||
|
|
d023966054 | ||
|
|
14ed660f4f | ||
|
|
5d9915e133 | ||
|
|
e8bd8a938f | ||
|
|
c62a965180 | ||
|
|
b18d4af37b | ||
|
|
2c18406632 | ||
|
|
23605e08be | ||
|
|
af99ad0736 | ||
|
|
71c5c9f6c5 | ||
|
|
b5994fa3a9 | ||
|
|
ae079d9bdd | ||
|
|
64b45e6d1b | ||
|
|
dce8bd4e62 | ||
|
|
7f2eaab02b | ||
|
|
f9eba6e842 | ||
|
|
d530344eda | ||
|
|
5effbce363 | ||
|
|
8b93727f64 | ||
|
|
0395294933 | ||
|
|
f16f9a13fd | ||
|
|
240f86b109 | ||
|
|
741fdee59e | ||
|
|
15a4649675 | ||
|
|
3c3b5aa4ac | ||
|
|
a54a807dc9 | ||
|
|
dac9d7b17a | ||
|
|
ddbdfafa79 | ||
|
|
2ecba6ac39 | ||
|
|
d4586cefb4 | ||
|
|
858e3584a9 | ||
|
|
4f64431f10 | ||
|
|
1b7425f428 | ||
|
|
924678a00d | ||
|
|
26002a040f | ||
|
|
fe1d540c95 | ||
|
|
accd48de8c | ||
|
|
cf531dbbe6 | ||
|
|
ef53f0e0b3 | ||
|
|
6de97e17fe | ||
|
|
7f591bcfd4 | ||
|
|
2320eb8b44 | ||
|
|
0be5602363 | ||
|
|
9ab764e9fd | ||
|
|
1db09d78b3 |
632
ChangeLog.md
632
ChangeLog.md
@@ -1,5 +1,637 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 1.5.10
|
||||
|
||||
### Compiler
|
||||
|
||||
#### Fixes
|
||||
|
||||
- [`KT-41078`](https://youtrack.jetbrains.com/issue/KT-41078) Incorrect type substitution in contracts with type parameters
|
||||
- [`KT-44770`](https://youtrack.jetbrains.com/issue/KT-44770) JVM / IR: "IllegalArgumentException: Unrecognized Type: [null]" Jackson doesn't recognize type
|
||||
- [`KT-45084`](https://youtrack.jetbrains.com/issue/KT-45084) JVM IR: "NoSuchElementException: Sequence contains no element matching the predicate" when inline class is passed to lambda with >22 parameters
|
||||
- [`KT-45779`](https://youtrack.jetbrains.com/issue/KT-45779) JVM / IR: java.lang.NoSuchMethodError: 'int java.lang.Integer.plus(int)' caused by function reference
|
||||
- [`KT-45941`](https://youtrack.jetbrains.com/issue/KT-45941) JVM IR: local functions use generic type parameters of the outer class in the bytecode, which breaks Bytebuddy and MockK
|
||||
- [`KT-46149`](https://youtrack.jetbrains.com/issue/KT-46149) Generate synthetic classes for SAM adapters with erased instead of generic supertype
|
||||
- [`KT-46189`](https://youtrack.jetbrains.com/issue/KT-46189) JVM IR: tailrec function with capturing lambda in default parameter value leads to NoSuchMethodError at runtime
|
||||
- [`KT-46214`](https://youtrack.jetbrains.com/issue/KT-46214) JVM / IR: "IllegalStateException: No mapping for symbol: VALUE_PARAMETER INSTANCE_RECEIVER" on a suspend function in an inner class
|
||||
- [`KT-46238`](https://youtrack.jetbrains.com/issue/KT-46238) JVM IR: BootstrapMethodError in JDK 11+ on intersection type passed in arguments of SAM adapter where SAM interface's type parameter has a non-trivial upper bound
|
||||
- [`KT-46259`](https://youtrack.jetbrains.com/issue/KT-46259) JVM IR: local function for adapted function reference is not declared as ACC_SYNTHETIC
|
||||
- [`KT-46284`](https://youtrack.jetbrains.com/issue/KT-46284) JVM IR: "Unbound private symbol IrClassSymbol" on class reference to script class
|
||||
- [`KT-46402`](https://youtrack.jetbrains.com/issue/KT-46402) IllegalAccessError: "CapturedLambdaInterpreter (in unnamed module @0x71b06418) cannot access class jdk.internal.org.objectweb.asm.Type" caused by inline function with a suspend parameter in Maven project
|
||||
- [`KT-46408`](https://youtrack.jetbrains.com/issue/KT-46408) JVM IR: BootstrapMethodError due to missing bridge for subclass of generic Java interface
|
||||
- [`KT-46426`](https://youtrack.jetbrains.com/issue/KT-46426) JVM IR: Corrupted .class file when passing Array constructor reference as (inline) lambda
|
||||
- [`KT-46455`](https://youtrack.jetbrains.com/issue/KT-46455) OOM on parsing invalid code with string interpolation
|
||||
- [`KT-46503`](https://youtrack.jetbrains.com/issue/KT-46503) JVM IR: "AssertionError: Unexpected variance in super type argument: out @1"
|
||||
- [`KT-46505`](https://youtrack.jetbrains.com/issue/KT-46505) JVM IR: NullPointerException caused by a callable reference with nullable inline value class parameter
|
||||
- [`KT-46512`](https://youtrack.jetbrains.com/issue/KT-46512) JVM / IR: NoSuchMethodError on SAM conversion of a function reference
|
||||
- [`KT-46515`](https://youtrack.jetbrains.com/issue/KT-46515) IndexOutOfBoundsException: "Empty list doesn't contain element at index 0." on bad variable name in 1.5.0
|
||||
- [`KT-46516`](https://youtrack.jetbrains.com/issue/KT-46516) JVM IR: "AnalyzerException: Expected I, but found R" on subclassing AbstractMutableList<Int>
|
||||
- [`KT-46524`](https://youtrack.jetbrains.com/issue/KT-46524) Cannot use unsigned literals with api-version < 1.5 even with opt-in
|
||||
- [`KT-46537`](https://youtrack.jetbrains.com/issue/KT-46537) JVM / IR: "IllegalStateException: No noarg super constructor for CLASS" caused by "No-arg" plugin with annotation on child class
|
||||
- [`KT-46540`](https://youtrack.jetbrains.com/issue/KT-46540) JVM / IR: AnalyzerException: Expected an object reference, but found J caused by java.function.Supplier
|
||||
- [`KT-46554`](https://youtrack.jetbrains.com/issue/KT-46554) JVM IR: "IllegalStateException: No mapping for symbol: VAR IR_TEMPORARY_VARIABLE" with value class constructor delegation call
|
||||
- [`KT-46555`](https://youtrack.jetbrains.com/issue/KT-46555) JVM IR: IllegalAccessError when using Java method reference
|
||||
- [`KT-46562`](https://youtrack.jetbrains.com/issue/KT-46562) Kotlin 1.5.0 generates non-serializable lambdas when they should be serializable
|
||||
- [`KT-46568`](https://youtrack.jetbrains.com/issue/KT-46568) JVM IR: "AssertionError: IrCall expected inside JvmStatic wrapper" on compiling protected static function with return type Nothing inside companion object of abstract class
|
||||
- [`KT-46574`](https://youtrack.jetbrains.com/issue/KT-46574) JVM / IR: ClassCastException caused by runBlocking awaiting call while returning Kotlin.Result type.
|
||||
- [`KT-46579`](https://youtrack.jetbrains.com/issue/KT-46579) JVM IR: "IllegalArgumentException: Sequence contains more than one matching element" for Java enum with overloaded values() static method
|
||||
- [`KT-46584`](https://youtrack.jetbrains.com/issue/KT-46584) JVM IR: Intrinsics.needClassReification (UnsupportedOperationException thrown). Property delegate provider crossinline lambda inlining/reification issue
|
||||
- [`KT-46751`](https://youtrack.jetbrains.com/issue/KT-46751) JVM / IR:"ClassCastException: java.lang.String cannot be cast to java.lang.Void" in extension function in Kotlin 1.5
|
||||
|
||||
### IDE
|
||||
|
||||
- [`KT-45981`](https://youtrack.jetbrains.com/issue/KT-45981) failed to analyze: java.lang.AssertionError: diagnostic callback has been already registered: Code analysis get stuck in AS 2020.3.1.14 & Kotlin v1.5.0-M2
|
||||
- [`KT-46622`](https://youtrack.jetbrains.com/issue/KT-46622) 60+ second freezes with Kotlin plugin 1.5.0: GetModuleInfoKt.findJvmStdlibAcrossDependencies
|
||||
|
||||
### IDE. Gradle Integration
|
||||
|
||||
- [`KT-46417`](https://youtrack.jetbrains.com/issue/KT-46417) [UNRESOLVED_REFERENCE] For project to project dependencies of native platform test source sets
|
||||
|
||||
### Libraries
|
||||
|
||||
- [`KT-46280`](https://youtrack.jetbrains.com/issue/KT-46280) JvmRecord annotation missing constructor in common
|
||||
|
||||
### Middle-end. IR
|
||||
|
||||
- [`KT-44013`](https://youtrack.jetbrains.com/issue/KT-44013) NPE: When calling constructor of a function type while inheriting from it, despite it's an interface
|
||||
|
||||
### Tools. Android Extensions
|
||||
|
||||
- [`KT-46590`](https://youtrack.jetbrains.com/issue/KT-46590) Kotlin Android Extensions 1.5.0 generates bad writeToParcel() method for nullable Array types
|
||||
|
||||
### Tools. Gradle
|
||||
|
||||
- [`KT-41142`](https://youtrack.jetbrains.com/issue/KT-41142) Kotlin version conflict when using Kotlin Gradle plugins in pre-compiled script plugin
|
||||
- [`KT-46353`](https://youtrack.jetbrains.com/issue/KT-46353) Optimizations disabled in Gradle 7 for KAPT when generating sources
|
||||
- [`KT-46368`](https://youtrack.jetbrains.com/issue/KT-46368) Memory leak with 1.5.0-RC when building with Gradle
|
||||
- [`KT-46689`](https://youtrack.jetbrains.com/issue/KT-46689) Track -Xuse-old-backend flag usage
|
||||
|
||||
### Tools. Gradle. JS
|
||||
|
||||
- [`KT-46006`](https://youtrack.jetbrains.com/issue/KT-46006) KJS \ Gradle: Task without declaring an explicit or implicit dependency on `jsGenerateExternalsIntegrated` in Gradle 7
|
||||
- [`KT-46162`](https://youtrack.jetbrains.com/issue/KT-46162) KJS: Exported items unavailable on dev server
|
||||
- [`KT-46331`](https://youtrack.jetbrains.com/issue/KT-46331) KJS: With `kotlin.js.webpack.major.version=4` browserXRun tasks fail
|
||||
|
||||
### Tools. Parcelize
|
||||
|
||||
- [`KT-46567`](https://youtrack.jetbrains.com/issue/KT-46567) Kotlin 1.5.0 parcelize compilation fails in new backend when using TypeParceller with nested generics
|
||||
|
||||
### Tools. kapt
|
||||
|
||||
- [`KT-45532`](https://youtrack.jetbrains.com/issue/KT-45532) Do not create Kapt stubs directory during configuration time
|
||||
|
||||
|
||||
## 1.5.0
|
||||
|
||||
### Backend. Native
|
||||
|
||||
- [`KT-42053`](https://youtrack.jetbrains.com/issue/KT-42053) Support compiler caches for linux_x64
|
||||
- [`KT-43690`](https://youtrack.jetbrains.com/issue/KT-43690) Support compiler caches for ios_arm64
|
||||
|
||||
### Backend. IR
|
||||
|
||||
- [`KT-42684`](https://youtrack.jetbrains.com/issue/KT-42684) StackOverflowError on recursive inline arguments in inline fun
|
||||
|
||||
### Compiler
|
||||
|
||||
#### New Features
|
||||
|
||||
- [`KT-28791`](https://youtrack.jetbrains.com/issue/KT-28791) Kotlin serialization with inline classes
|
||||
- [`KT-30222`](https://youtrack.jetbrains.com/issue/KT-30222) Support JVM target version selection in Kotlin bytecode tool window
|
||||
- [`KT-41884`](https://youtrack.jetbrains.com/issue/KT-41884) Support 'file' target for JvmSynthetic annotation
|
||||
- [`KT-43677`](https://youtrack.jetbrains.com/issue/KT-43677) Support for Java records
|
||||
- [`KT-43920`](https://youtrack.jetbrains.com/issue/KT-43920) Support loading binary Java annotations on fields
|
||||
- [`KT-44278`](https://youtrack.jetbrains.com/issue/KT-44278) Generate SAM-converted lambdas and function references using 'invokedynamic' on JDK 1.8+
|
||||
- [`KT-44650`](https://youtrack.jetbrains.com/issue/KT-44650) Deprecate JVM target version 1.6
|
||||
- [`KT-44787`](https://youtrack.jetbrains.com/issue/KT-44787) Suspend functions in fun interfaces
|
||||
- [`KT-44865`](https://youtrack.jetbrains.com/issue/KT-44865) Allow to declare protected constructors in sealed classes
|
||||
- [`KT-44869`](https://youtrack.jetbrains.com/issue/KT-44869) Compiling sealed interface with version less than 1.5: error message from future could be provided
|
||||
|
||||
|
||||
#### Performance Improvements
|
||||
|
||||
- [`KT-6336`](https://youtrack.jetbrains.com/issue/KT-6336) Optimize generation of local functions
|
||||
- [`KT-7307`](https://youtrack.jetbrains.com/issue/KT-7307) Optimize infix call of String.plus
|
||||
- [`KT-18692`](https://youtrack.jetbrains.com/issue/KT-18692) Optimize '<optimizable_range> step x' for-in loop
|
||||
- [`KT-19978`](https://youtrack.jetbrains.com/issue/KT-19978) Inefficient bytecode generated for function references undergoing Java SAM conversion
|
||||
- [`KT-23565`](https://youtrack.jetbrains.com/issue/KT-23565) OperationsMapGenerated.kt generates unreasonable amount of bytecode
|
||||
- [`KT-23825`](https://youtrack.jetbrains.com/issue/KT-23825) Tail suspend call utilizing elvis operator does not take advantage of suspend tail call optimization
|
||||
- [`KT-23826`](https://youtrack.jetbrains.com/issue/KT-23826) A suspend function on the right side of a returned || condition is not tail call optimized
|
||||
- [`KT-25348`](https://youtrack.jetbrains.com/issue/KT-25348) No compile time unsigned integer conversion when using hex literal
|
||||
- [`KT-26060`](https://youtrack.jetbrains.com/issue/KT-26060) Support a compiler mode to compile lambda expressions using `invokedynamic` instruction
|
||||
- [`KT-26590`](https://youtrack.jetbrains.com/issue/KT-26590) Do not generate create method for suspend lambdas if its arity >= 2
|
||||
- [`KT-27427`](https://youtrack.jetbrains.com/issue/KT-27427) Optimize nullable check introduced with 'as' cast
|
||||
- [`KT-28246`](https://youtrack.jetbrains.com/issue/KT-28246) Redundant boxing/unboxing isn't eliminated by the compiler in case of inline classes and javaClass intrinsic
|
||||
- [`KT-30605`](https://youtrack.jetbrains.com/issue/KT-30605) Constant folding doesn't evaluate inv() function
|
||||
- [`KT-36845`](https://youtrack.jetbrains.com/issue/KT-36845) Generate enum-based TABLESWITCH/LOOKUPSWITCH on a value with smart cast to enum in JVM_IR
|
||||
- [`KT-39585`](https://youtrack.jetbrains.com/issue/KT-39585) JVM BE generates redundant accessor calls when accessing static final field lifted from companion
|
||||
- [`KT-40886`](https://youtrack.jetbrains.com/issue/KT-40886) Old JVM BE unspills ACONST_NULL from continuation
|
||||
- [`KT-42621`](https://youtrack.jetbrains.com/issue/KT-42621) Kotlin binary size considerably larger for code extensively using stream API
|
||||
- [`KT-44153`](https://youtrack.jetbrains.com/issue/KT-44153) NI: Low Memory and IntelliJ hangs when quotes in split() are missed
|
||||
- [`KT-45410`](https://youtrack.jetbrains.com/issue/KT-45410) JVM / IR: Extreme performance regression on arithmetic operations inside a loop
|
||||
|
||||
#### Fixes
|
||||
|
||||
- [`KT-6007`](https://youtrack.jetbrains.com/issue/KT-6007) Support changed return type of inlined generic function when lambda returns anonymous object
|
||||
- [`KT-6055`](https://youtrack.jetbrains.com/issue/KT-6055) Failed invoke plus assign on array element accessed via several args through local get/set convention extensions
|
||||
- [`KT-6879`](https://youtrack.jetbrains.com/issue/KT-6879) CompilationException when local classes hierarchy is placed within other local or inner declaration
|
||||
- [`KT-8120`](https://youtrack.jetbrains.com/issue/KT-8120) NoSuchMethodError on local class constructor call inside a local class
|
||||
- [`KT-8199`](https://youtrack.jetbrains.com/issue/KT-8199) "Cannot pop operand off an empty stack" for local class using a captured variable as default value for constructor parameter
|
||||
- [`KT-10835`](https://youtrack.jetbrains.com/issue/KT-10835) "AssertionError: Non-outer parameter incorrectly mapped to outer" when inlining object literal extending inner class
|
||||
- [`KT-12790`](https://youtrack.jetbrains.com/issue/KT-12790) Don't generate synthetic accessors for private inline function/properties
|
||||
- [`KT-13213`](https://youtrack.jetbrains.com/issue/KT-13213) IllegalArgumentException in ByteVector.putUTF8 on attempt to compile file with moderately long string literal
|
||||
- [`KT-14628`](https://youtrack.jetbrains.com/issue/KT-14628) "UnsupportedOperationException: Don't know how to generate outer expression" for nested class inheriting from inner class with a companion object
|
||||
- [`KT-14833`](https://youtrack.jetbrains.com/issue/KT-14833) JVM internal error: Augment assignment and increment are not supported for local delegated properties and inline properties
|
||||
- [`KT-15403`](https://youtrack.jetbrains.com/issue/KT-15403) Suspend operator get wrong code generated by BE (NoSuchMethodError)
|
||||
- [`KT-15404`](https://youtrack.jetbrains.com/issue/KT-15404) Suspend operator set wrong code generated
|
||||
- [`KT-16084`](https://youtrack.jetbrains.com/issue/KT-16084) Proguard can't find enclosing class of let closure inside apply closure
|
||||
- [`KT-16151`](https://youtrack.jetbrains.com/issue/KT-16151) Internal compiler error when using plusAssign operator with mutable map
|
||||
- [`KT-16221`](https://youtrack.jetbrains.com/issue/KT-16221) Support in/!in suspend operators
|
||||
- [`KT-16282`](https://youtrack.jetbrains.com/issue/KT-16282) "Cannot pop operand off an empty stack" for plusAssign with default parameters in setter operator
|
||||
- [`KT-16445`](https://youtrack.jetbrains.com/issue/KT-16445) `java.lang.VerifyError: Bad type on operand stack` when delegating an interface through a private reified function inside an object
|
||||
- [`KT-16520`](https://youtrack.jetbrains.com/issue/KT-16520) Invalid bytecode semantics for set call by convention with default parameters
|
||||
- [`KT-16567`](https://youtrack.jetbrains.com/issue/KT-16567) Inliner creates redundant objects on source inlining
|
||||
- [`KT-16752`](https://youtrack.jetbrains.com/issue/KT-16752) Delegating function interface to function reference does not work
|
||||
- [`KT-17554`](https://youtrack.jetbrains.com/issue/KT-17554) Incorrect cast to Unit generated on annotated when-expression with a single-branch if inside
|
||||
- [`KT-17738`](https://youtrack.jetbrains.com/issue/KT-17738) Java cannot extend class implementing kotlin.collections.Map
|
||||
- [`KT-17753`](https://youtrack.jetbrains.com/issue/KT-17753) Strange behavior of if and return statements
|
||||
- [`KT-18583`](https://youtrack.jetbrains.com/issue/KT-18583) "ISE: Recursive call in a lazy value" for generic sealed class with nested subclass in a `when(this)` with inferred return type
|
||||
- [`KT-19861`](https://youtrack.jetbrains.com/issue/KT-19861) "IllegalStateException: Label wasn't found during iterating through instructions" for `plusAssign` with safe call
|
||||
- [`KT-20306`](https://youtrack.jetbrains.com/issue/KT-20306) Make 'when' over an 'expect' enum class non-exhaustive
|
||||
- [`KT-20869`](https://youtrack.jetbrains.com/issue/KT-20869) kotlin.jvm.internal.DefaultConstructorMarker should be public
|
||||
- [`KT-20996`](https://youtrack.jetbrains.com/issue/KT-20996) IllegalStateException: Cannot get FQ name of local class: class <no name provided> in metadata serialization for common code
|
||||
- [`KT-21014`](https://youtrack.jetbrains.com/issue/KT-21014) Incorrect bytecode generated for 'PrimitiveArray::size'
|
||||
- [`KT-21092`](https://youtrack.jetbrains.com/issue/KT-21092) Reference `javaClass` for generic property: "couldn't transform method node: get()"
|
||||
- [`KT-21778`](https://youtrack.jetbrains.com/issue/KT-21778) "IllegalStateException: Couldn't build context" for inline function inside an anonymous object
|
||||
- [`KT-21900`](https://youtrack.jetbrains.com/issue/KT-21900) VerifyError on equals on generic primitive type
|
||||
- [`KT-22098`](https://youtrack.jetbrains.com/issue/KT-22098) "UnsupportedOperationException: Don't know how to generate outer expression" on extension function call inside lambda in anonymous object super constructor call
|
||||
- [`KT-22488`](https://youtrack.jetbrains.com/issue/KT-22488) Bad line numbers generated for '&&' expression
|
||||
- [`KT-22972`](https://youtrack.jetbrains.com/issue/KT-22972) A compiler bug(?) in Number class descendants
|
||||
- [`KT-23619`](https://youtrack.jetbrains.com/issue/KT-23619) Transform stateless singleton lambda during inline
|
||||
- [`KT-23881`](https://youtrack.jetbrains.com/issue/KT-23881) Declaration of lambda in inlined apply block holds reference to superfluous references causing leak
|
||||
- [`KT-24135`](https://youtrack.jetbrains.com/issue/KT-24135) Calling invoke on crossinline suspend lambda leads to no state-machine
|
||||
- [`KT-24193`](https://youtrack.jetbrains.com/issue/KT-24193) NoClassDefFoundError: java/lang/Cloneable$DefaultImpls on inheritance from Cloneable through an interface
|
||||
- [`KT-24305`](https://youtrack.jetbrains.com/issue/KT-24305) ClassNotFoundException when using Java reflection on local class in an inlined lambda
|
||||
- [`KT-24564`](https://youtrack.jetbrains.com/issue/KT-24564) Custom operator fun set on ByteArray resolves properly but is miscompiled
|
||||
- [`KT-25400`](https://youtrack.jetbrains.com/issue/KT-25400) "NoClassDefFoundError: kotlin/KotlinPackage" with Turkish system locale on macOS
|
||||
- [`KT-26130`](https://youtrack.jetbrains.com/issue/KT-26130) Incorrect method signature for a generic function with inline class as a type parameter upper bound
|
||||
- [`KT-26360`](https://youtrack.jetbrains.com/issue/KT-26360) "Method from super interface has a different signature" for Interface that extends both interfaces with and without @JvmDefault
|
||||
- [`KT-26473`](https://youtrack.jetbrains.com/issue/KT-26473) Error on compiling inline class with calls of super methods equals(), hashCode(), toString()
|
||||
- [`KT-26474`](https://youtrack.jetbrains.com/issue/KT-26474) VE “Bad type on operand stack” at runtime on calling toString() method of inline class with calls of super methods (toString(), equals(), hashCode()) inside
|
||||
- [`KT-26592`](https://youtrack.jetbrains.com/issue/KT-26592) Do not generate private suspend functions as synthetic package-private
|
||||
- [`KT-27449`](https://youtrack.jetbrains.com/issue/KT-27449) NoSuchMethodError for local suspend function with suspend lambda parameter with default value
|
||||
- [`KT-27469`](https://youtrack.jetbrains.com/issue/KT-27469) "Cannot pop operand off an empty stack" for compound assignment (plusAssign) with a `vararg` operator get
|
||||
- [`KT-27825`](https://youtrack.jetbrains.com/issue/KT-27825) Gradually prohibit non-abstract classes containing abstract members invisible from that classes (internal/package-private)
|
||||
- [`KT-27830`](https://youtrack.jetbrains.com/issue/KT-27830) "Incompatible stack heights" with suspend inline function in do while loop that executes suspend lambda
|
||||
- [`KT-28042`](https://youtrack.jetbrains.com/issue/KT-28042) "Cannot pop operand off an empty stack" for a bound callable reference of lambda inside inline function
|
||||
- [`KT-28166`](https://youtrack.jetbrains.com/issue/KT-28166) "Argument 1: expected I, but found R" for generic method with generic parameter or receiver with inline class upper bound
|
||||
- [`KT-28331`](https://youtrack.jetbrains.com/issue/KT-28331) Consider generating accessors for lateinit properties to avoid assertion on each call
|
||||
- [`KT-28573`](https://youtrack.jetbrains.com/issue/KT-28573) Inliner does not update references to transformed object
|
||||
- [`KT-29331`](https://youtrack.jetbrains.com/issue/KT-29331) "AnalyzerException: Argument 1: expected R, but found I" with local generic extension property called on `Int` receiver
|
||||
- [`KT-29595`](https://youtrack.jetbrains.com/issue/KT-29595) NoClassDefFoundError with inline reified function with lambda argument returning anonymous object
|
||||
- [`KT-29802`](https://youtrack.jetbrains.com/issue/KT-29802) Incorrect reification when the same type parameter name is used for different reified types
|
||||
- [`KT-30041`](https://youtrack.jetbrains.com/issue/KT-30041) "AnalyzerException: Expected an object reference, but found ." on nested suspend function calls outer suspend function
|
||||
- [`KT-30066`](https://youtrack.jetbrains.com/issue/KT-30066) Consider adding annotations to ConeKotlinType
|
||||
- [`KT-30280`](https://youtrack.jetbrains.com/issue/KT-30280) Inline class class literal gets unwrapped in annotation arguments
|
||||
- [`KT-30402`](https://youtrack.jetbrains.com/issue/KT-30402) Constant folding works incorrectly with unsigned arithmetics
|
||||
- [`KT-30548`](https://youtrack.jetbrains.com/issue/KT-30548) "java.lang.IndexOutOfBoundsException: Cannot pop operand off an empty stack" while compiling access to a private lateinit companion field
|
||||
- [`KT-30629`](https://youtrack.jetbrains.com/issue/KT-30629) `java.lang.VerifyError: Bad type on operand stack` when using a function reference to a generic property
|
||||
- [`KT-30933`](https://youtrack.jetbrains.com/issue/KT-30933) Inline function produces IllegalAccessError on property reference from different package
|
||||
- [`KT-31136`](https://youtrack.jetbrains.com/issue/KT-31136) "AnalyzerException: Argument 1: expected R, but found I" on x::javaClass when x is inline class object built around primitive type
|
||||
- [`KT-31227`](https://youtrack.jetbrains.com/issue/KT-31227) Prohibit using array based on non-reified type parameters as reified type arguments on JVM
|
||||
- [`KT-31592`](https://youtrack.jetbrains.com/issue/KT-31592) NoSuchMethodException when inlining public function accessing a protected static Java class member
|
||||
- [`KT-31727`](https://youtrack.jetbrains.com/issue/KT-31727) Object expression captures all variables used in constructor
|
||||
- [`KT-32023`](https://youtrack.jetbrains.com/issue/KT-32023) "AnalyzerException: Expected I, but found R" with inline suspend function used with callable reference
|
||||
- [`KT-32115`](https://youtrack.jetbrains.com/issue/KT-32115) NPE during initialization of enum class with delegated property
|
||||
- [`KT-32153`](https://youtrack.jetbrains.com/issue/KT-32153) "AnalyzerException: Expected an object reference, but found ." with recursive suspend local function
|
||||
- [`KT-32351`](https://youtrack.jetbrains.com/issue/KT-32351) ClassNotFoundException for anonymous object implementing interface inside a lambda with data class and inline methods
|
||||
- [`KT-32384`](https://youtrack.jetbrains.com/issue/KT-32384) Safe cast to generic type argument with inline class upper-bound throws NPE instead of ClassCastException
|
||||
- [`KT-32579`](https://youtrack.jetbrains.com/issue/KT-32579) java.lang.VerifyError: Bad type on operand stack on calling inner class of inherited class in super class when casting to inherited class
|
||||
- [`KT-32749`](https://youtrack.jetbrains.com/issue/KT-32749) "VerifyError: Call to wrong <init> method" with inline function and accessing class field from anonymous object
|
||||
- [`KT-32793`](https://youtrack.jetbrains.com/issue/KT-32793) Generated code crashes by ClassCastException with local suspend function and inline class
|
||||
- [`KT-32812`](https://youtrack.jetbrains.com/issue/KT-32812) "AnalyzerException: Argument 1: expected R, but found I" invoking function with default parameter inherited by inline class
|
||||
- [`KT-32821`](https://youtrack.jetbrains.com/issue/KT-32821) Missing unboxing of inline class for complex hierarchy of suspend calls
|
||||
- [`KT-33155`](https://youtrack.jetbrains.com/issue/KT-33155) ClassNotFoundException for qualified this in anonymous object and as a result of inline function call
|
||||
- [`KT-33173`](https://youtrack.jetbrains.com/issue/KT-33173) Internal error: "AnalyzerException: Expected I, but found R" for supercall inside inline lambda from HashSet.remove implementation
|
||||
- [`KT-33577`](https://youtrack.jetbrains.com/issue/KT-33577) NoSuchFieldError with nested anonymous objects accessing outer instance property
|
||||
- [`KT-33836`](https://youtrack.jetbrains.com/issue/KT-33836) Wrong code generated for a local tailrec suspend function.
|
||||
- [`KT-33873`](https://youtrack.jetbrains.com/issue/KT-33873) ClassCastException invoking UByte setter function via reflection
|
||||
- [`KT-34018`](https://youtrack.jetbrains.com/issue/KT-34018) "Cannot pop operand off an empty stack" with inline lambda with callable reference
|
||||
- [`KT-34186`](https://youtrack.jetbrains.com/issue/KT-34186) JDK11: class file contains malformed variable arity method for vararg sealed class constructor
|
||||
- [`KT-34202`](https://youtrack.jetbrains.com/issue/KT-34202) IllegalAccessError on callable reference of function from multifile facade from standard library
|
||||
- [`KT-34255`](https://youtrack.jetbrains.com/issue/KT-34255) @JvmStatic tailrec function: "Cannot pop operand off an empty stack"
|
||||
- [`KT-34507`](https://youtrack.jetbrains.com/issue/KT-34507) Incorrect generated code for mutable collection stub methods in case of presence of functions with similar signature
|
||||
- [`KT-34665`](https://youtrack.jetbrains.com/issue/KT-34665) Possible index overflow in optimized "for" loop over withIndex()
|
||||
- [`KT-34754`](https://youtrack.jetbrains.com/issue/KT-34754) Flow builder: "AnalyzerException: Expected an object reference, but found ." with recursive suspend local function
|
||||
- [`KT-34816`](https://youtrack.jetbrains.com/issue/KT-34816) "AnalyzerException: Expected an object reference, but found I" on "this" in inline class member extension suspend function
|
||||
- [`KT-34841`](https://youtrack.jetbrains.com/issue/KT-34841) ClassNotFoundException when invoke param function inside anonymous object method
|
||||
- [`KT-35008`](https://youtrack.jetbrains.com/issue/KT-35008) "AnalyzerException: Expected an object reference, but found I" in inline class companion calling private constructor
|
||||
- [`KT-35166`](https://youtrack.jetbrains.com/issue/KT-35166) `NoSuchMethodError` at runtime with local property delegate on anonymous object referencing another anonymous object
|
||||
- [`KT-35224`](https://youtrack.jetbrains.com/issue/KT-35224) It's possible to pass non-spread arrays after arguments with SAM-conversion
|
||||
- [`KT-35301`](https://youtrack.jetbrains.com/issue/KT-35301) MethodInliner fails with "AssertionError: <init> call doesn't correspond to object transformation info" for qualified this in SAM constructor used as parameter of anonymous object inside inline lambda
|
||||
- [`KT-35419`](https://youtrack.jetbrains.com/issue/KT-35419) `Failed to generate expression: KtNamedFunction` for local suspend tailrec function with receiver
|
||||
- [`KT-35511`](https://youtrack.jetbrains.com/issue/KT-35511) VerifyError: "Bad type on operand stack" after reification
|
||||
- [`KT-35553`](https://youtrack.jetbrains.com/issue/KT-35553) Kotlin compiler generates methods that always have line number 1 for Inline Classes
|
||||
- [`KT-35725`](https://youtrack.jetbrains.com/issue/KT-35725) "AssertionError: Couldn't find a context for a super-call" for `super` member call in property initializer of companion object
|
||||
- [`KT-36420`](https://youtrack.jetbrains.com/issue/KT-36420) ClassCastException with inline class Foo extending generic Comparable<Foo>
|
||||
- [`KT-36713`](https://youtrack.jetbrains.com/issue/KT-36713) AnalyzerException: "Incompatible stack heights" with suspend and inline suspend functions
|
||||
- [`KT-36794`](https://youtrack.jetbrains.com/issue/KT-36794) Move $assertionsDisabled field to the top-level class
|
||||
- [`KT-36853`](https://youtrack.jetbrains.com/issue/KT-36853) IR: UninitializedPropertyAccessException on tailrec with object expression in default argument
|
||||
- [`KT-36875`](https://youtrack.jetbrains.com/issue/KT-36875) "RuntimeException: Trying to access skipped parameter" on synthetic local variable access from inline function
|
||||
- [`KT-36916`](https://youtrack.jetbrains.com/issue/KT-36916) AnalyzerException: Argument 1: expected I, but found R when using inline class with rxjava
|
||||
- [`KT-36957`](https://youtrack.jetbrains.com/issue/KT-36957) Exception during codegen: cannot pop operand off an empty stack (Nothing variable in string interpolation)
|
||||
- [`KT-36984`](https://youtrack.jetbrains.com/issue/KT-36984) SAM adapter classes should be generated as anonymous inner classes in JVM_IR
|
||||
- [`KT-37704`](https://youtrack.jetbrains.com/issue/KT-37704) Incorrect SMAP syntax
|
||||
- [`KT-37716`](https://youtrack.jetbrains.com/issue/KT-37716) "AssertionError: <init> call doesn't correspond to object transformation info" with inline reified type parameter, anonymous object and lambda in constructor call
|
||||
- [`KT-37972`](https://youtrack.jetbrains.com/issue/KT-37972) IllegalAccessError on initializing property reference for a property declared in JvmMultifileClass with -Xmultifile-parts-inherit
|
||||
- [`KT-38100`](https://youtrack.jetbrains.com/issue/KT-38100) Support local delegated properties (not inlined) in new JVM default modes
|
||||
- [`KT-38833`](https://youtrack.jetbrains.com/issue/KT-38833) JVM: java.lang.ClassCastException when loop variable is nullable in for loop over unsigned progression
|
||||
- [`KT-38849`](https://youtrack.jetbrains.com/issue/KT-38849) Read-only variable initialized in non-inline lambda using contract callsInPlace EXACTLY_ONCE is not captured correctly in nested lambdas
|
||||
- [`KT-38869`](https://youtrack.jetbrains.com/issue/KT-38869) JVM BE produces invalid bytecode when inheriting from AbstractList and declaring methods that look like MutableList implementors (but they aren't)
|
||||
- [`KT-38965`](https://youtrack.jetbrains.com/issue/KT-38965) "UnsupportedOperationException: Don't know how to generate outer expression: Closure" with reference to local variable in block argument of anonymous object `by` delegation
|
||||
- [`KT-39289`](https://youtrack.jetbrains.com/issue/KT-39289) CCE in if-else inside annotated 'if' statement
|
||||
- [`KT-39425`](https://youtrack.jetbrains.com/issue/KT-39425) AbstractMethodError: "Receiver class does not define or inherit an implementation of the resolved method" using classes with complex Java and Kotlin inheritance hierarchies.
|
||||
- [`KT-39434`](https://youtrack.jetbrains.com/issue/KT-39434) IllegalAccessError with local delegated property in lambda in inlined function
|
||||
- [`KT-39687`](https://youtrack.jetbrains.com/issue/KT-39687) "Couldn't find captured this" when more than 3 inline functions are nested
|
||||
- [`KT-39784`](https://youtrack.jetbrains.com/issue/KT-39784) "IndexOutOfBoundsException: Cannot pop operand off an empty stack" caused by JvmOverloads annotation inside an inline class
|
||||
- [`KT-40165`](https://youtrack.jetbrains.com/issue/KT-40165) ClassCastException caused by SAM conversion used on a functional interface with suspended function
|
||||
- [`KT-40179`](https://youtrack.jetbrains.com/issue/KT-40179) "VerifyError: Bad type on operand stack" with parent class `get` extension function and child class `set` extension function which used inside child class `plusAssign` extension function
|
||||
- [`KT-40277`](https://youtrack.jetbrains.com/issue/KT-40277) Fix generic types in special bridge methods
|
||||
- [`KT-40308`](https://youtrack.jetbrains.com/issue/KT-40308) NoSuchFieldError for multiple delegated extension properties with the same name in a companion object
|
||||
- [`KT-40338`](https://youtrack.jetbrains.com/issue/KT-40338) NoSuchFieldError on property without backing field that is called as function reference
|
||||
- [`KT-40392`](https://youtrack.jetbrains.com/issue/KT-40392) Deprecate JvmDefault annotation and old -Xjvm-default modes
|
||||
- [`KT-40396`](https://youtrack.jetbrains.com/issue/KT-40396) NI: Exceptions when ambiguous type argument and generic invoke
|
||||
- [`KT-40510`](https://youtrack.jetbrains.com/issue/KT-40510) "AssertionError: DELEGATION slice must override something" for ByteBuffer delegation
|
||||
- [`KT-40601`](https://youtrack.jetbrains.com/issue/KT-40601) VerifyError: "interface method reference is in an indirect superinterface" when calling @JvmDefault suspend method
|
||||
- [`KT-40809`](https://youtrack.jetbrains.com/issue/KT-40809) "Couldn't find captured field" compiler error with local function with recursive call through method reference
|
||||
- [`KT-41056`](https://youtrack.jetbrains.com/issue/KT-41056) Increase stub version due to new "contract" keyword
|
||||
- [`KT-41105`](https://youtrack.jetbrains.com/issue/KT-41105) IllegalStateException: 'Couldn't find declaration file <class name>' with inline delegate declared in another file
|
||||
- [`KT-41165`](https://youtrack.jetbrains.com/issue/KT-41165) "IllegalStateException: Concrete fake override public final fun" when an enum class inherits an interface with a variable 'name' or 'ordinal'
|
||||
- [`KT-41222`](https://youtrack.jetbrains.com/issue/KT-41222) "IllegalStateException: Concrete fake override public final fun" when a class property is inherited as merged 'var' from 'val' and 'var' from parent abstract class and interface properties
|
||||
- [`KT-41255`](https://youtrack.jetbrains.com/issue/KT-41255) JDK 11: "VerifyError: Bad type on operand stack" with long function body with annotated `when` expression
|
||||
- [`KT-41427`](https://youtrack.jetbrains.com/issue/KT-41427) NoSuchMethodError caused by implementation by delegation to function reference
|
||||
- [`KT-41508`](https://youtrack.jetbrains.com/issue/KT-41508) ClassNotFoundException caused by object with overridden function inside a lambda with safe cast receiver
|
||||
- [`KT-41750`](https://youtrack.jetbrains.com/issue/KT-41750) Inline classes: ClassCastExceptionError when calling .withIndex() on Iterator over Array
|
||||
- [`KT-41758`](https://youtrack.jetbrains.com/issue/KT-41758) Deprecate kotlin.Metadata.bytecodeVersion and avoid using it in the compiler
|
||||
- [`KT-41770`](https://youtrack.jetbrains.com/issue/KT-41770) AssertionError: "Asm parameter types should be the same length as Kotlin parameter types" cause by fun interface
|
||||
- [`KT-41874`](https://youtrack.jetbrains.com/issue/KT-41874) "IllegalStateException: Couldn't obtain compiled function body" on extension delegated property with inline operator getValue in a different file
|
||||
- [`KT-41917`](https://youtrack.jetbrains.com/issue/KT-41917) [FIR] Incorrect calculating property type for override from intersection scope
|
||||
- [`KT-42012`](https://youtrack.jetbrains.com/issue/KT-42012) IllegalAccess to protected field instead of getter
|
||||
- [`KT-42017`](https://youtrack.jetbrains.com/issue/KT-42017) "AssertionError: Unsigned type expected: UInt?" during codegen when a variable of nullable unsigned type is checking for presence in the range
|
||||
- [`KT-42032`](https://youtrack.jetbrains.com/issue/KT-42032) "AnalyzerException: Expected I, but found R" while using Flow.reduce() with suspend function reference
|
||||
- [`KT-42034`](https://youtrack.jetbrains.com/issue/KT-42034) ArrayIndexOutOfBoundsException in PopBackwardPropagationTransformer on external override of function in inline class
|
||||
- [`KT-42064`](https://youtrack.jetbrains.com/issue/KT-42064) "Parameter specified as non-null is null" with default value of the parameter in operator fun
|
||||
- [`KT-42069`](https://youtrack.jetbrains.com/issue/KT-42069) JVM IR: -Xreport-output-files doesn't report any source files for META-INF/*.kotlin_module files
|
||||
- [`KT-42083`](https://youtrack.jetbrains.com/issue/KT-42083) AbstractMethodError when 'remove' with irrelevant generic parameter but matching JVM signature is present in Kotlin collection class
|
||||
- [`KT-42092`](https://youtrack.jetbrains.com/issue/KT-42092) JVM / IR: "AnalyzerException: Argument 1: expected R, but found J" when trying to add to ArrayList the result of a function applied to int
|
||||
- [`KT-42175`](https://youtrack.jetbrains.com/issue/KT-42175) Psi2ir: "AssertionError: Undefined parameter referenced: <this>" on augmented assignment on this in a BuilderInference lambda
|
||||
- [`KT-42179`](https://youtrack.jetbrains.com/issue/KT-42179) Platform declaration clash when extending abstract Java class implementing 'java.util.Collection' by abstract Kotlin class implementing Kotlin Set or List
|
||||
- [`KT-42321`](https://youtrack.jetbrains.com/issue/KT-42321) JVM IR: do not cast integer value based on the type of a literal receiver of an operator call
|
||||
- [`KT-42337`](https://youtrack.jetbrains.com/issue/KT-42337) NoSuchMethodError in JVM backend with inheritance of private functions in the interface
|
||||
- [`KT-42404`](https://youtrack.jetbrains.com/issue/KT-42404) "Supertypes of the following classes cannot be resolved" in Rider project
|
||||
- [`KT-42472`](https://youtrack.jetbrains.com/issue/KT-42472) No TYPE_INFERENCE_UPPER_BOUND_VIOLATED for Delegated Properties do not check types (in Kotlin 1.4.10)
|
||||
- [`KT-42487`](https://youtrack.jetbrains.com/issue/KT-42487) "IndexOutOfBoundsException: Cannot pop operand off an empty stack" caused by USELESS_IS_CHECK of Double type
|
||||
- [`KT-42533`](https://youtrack.jetbrains.com/issue/KT-42533) `(N until MIN_VALUE).reversed()` should be an empty progression in for loops
|
||||
- [`KT-42588`](https://youtrack.jetbrains.com/issue/KT-42588) "IllegalStateException: Concrete fake override public open fun" caused by `val` override with `var` with delegation.
|
||||
- [`KT-42634`](https://youtrack.jetbrains.com/issue/KT-42634) Different bridges and abstract stubs behavior in abstract class implementing Map<K, String> in JVM and JVM_IR
|
||||
- [`KT-42635`](https://youtrack.jetbrains.com/issue/KT-42635) ClassCastException with inline class in for loop
|
||||
- [`KT-42662`](https://youtrack.jetbrains.com/issue/KT-42662) AbstractMethodError when using partially specialized generic Map class
|
||||
- [`KT-42694`](https://youtrack.jetbrains.com/issue/KT-42694) @get:Synchronized causes the JVM getter method not to be generated
|
||||
- [`KT-42753`](https://youtrack.jetbrains.com/issue/KT-42753) "VerifyError: Bad invokespecial instruction: interface method reference is in an indirect superinterface" with `jvm-default=all`
|
||||
- [`KT-42879`](https://youtrack.jetbrains.com/issue/KT-42879) JVM: Declaration clash in fun interface implementation returning an inline class
|
||||
- [`KT-42900`](https://youtrack.jetbrains.com/issue/KT-42900) "VerifyError: Bad return type" incorrect bytecode when a property and an extension property in inline class have the same names
|
||||
- [`KT-42946`](https://youtrack.jetbrains.com/issue/KT-42946) FIR2IR: Fix super-calls to Java overrides of special built-in
|
||||
- [`KT-42971`](https://youtrack.jetbrains.com/issue/KT-42971) JVM: "AssertionError: Unsigned type expected: T" with UInt loop range
|
||||
- [`KT-42990`](https://youtrack.jetbrains.com/issue/KT-42990) "AssertionError: Next value after NEW should be one generated by DUP" caused by extension properties with accessors annotataed as @JvmStatic
|
||||
- [`KT-43034`](https://youtrack.jetbrains.com/issue/KT-43034) AssertionError: Compiler fails with complicated tailrec + inline case
|
||||
- [`KT-43048`](https://youtrack.jetbrains.com/issue/KT-43048) JVM_IR: Implement coroutines state clearing
|
||||
- [`KT-43050`](https://youtrack.jetbrains.com/issue/KT-43050) JVM IR: incorrect mangling for method with type parameter with inline class bound in the signature
|
||||
- [`KT-43059`](https://youtrack.jetbrains.com/issue/KT-43059) Different bridges behavior in class implementing Map<String, String> in JVM and JVM_IR
|
||||
- [`KT-43063`](https://youtrack.jetbrains.com/issue/KT-43063) Redundant DefaultImpls delegate is generated in old JVM backend on explicit "duplicate" inheritance from interface
|
||||
- [`KT-43069`](https://youtrack.jetbrains.com/issue/KT-43069) JVM: incorrect generic signature for method with implicit return type Nothing overriding a method from Collection
|
||||
- [`KT-43099`](https://youtrack.jetbrains.com/issue/KT-43099) Tailrec call in not tail-call position leads to internal compiler error
|
||||
- [`KT-43106`](https://youtrack.jetbrains.com/issue/KT-43106) JVM: custom `remove` in Iterator subclass results in a synthetic bridge
|
||||
- [`KT-43120`](https://youtrack.jetbrains.com/issue/KT-43120) JVM: "Expected an object reference, but found ." caused by function which is passed as reference to suspend parameter
|
||||
- [`KT-43167`](https://youtrack.jetbrains.com/issue/KT-43167) JVM IR, serialization: "No mapping for symbol: VALUE_PARAMETER INSTANCE_RECEIVER" with data class containing property defined in body
|
||||
- [`KT-43255`](https://youtrack.jetbrains.com/issue/KT-43255) Verify error when inheriting from an abstract class implementing Collection with stub-like method in superclass
|
||||
- [`KT-43303`](https://youtrack.jetbrains.com/issue/KT-43303) NI: False negative TYPE_INFERENCE_UPPER_BOUND_VIOLATED when inferred type argument is not a subtype of type parameter upper bound
|
||||
- [`KT-43333`](https://youtrack.jetbrains.com/issue/KT-43333) AbstractMethodError when calling 'toArray' from Java on a Kotlin Collection with custom internal 'toArray'
|
||||
- [`KT-43334`](https://youtrack.jetbrains.com/issue/KT-43334) AbstractMethodError when calling 'remove' from Java on a Kotlin Collection with custom internal 'remove'
|
||||
- [`KT-43342`](https://youtrack.jetbrains.com/issue/KT-43342) [FIR2IR] No getter or backing field found for delegated member call
|
||||
- [`KT-43347`](https://youtrack.jetbrains.com/issue/KT-43347) [FIR] Synthetic setter with unmatched parameter type isn't found
|
||||
- [`KT-43401`](https://youtrack.jetbrains.com/issue/KT-43401) JVM_IR. Additional `synchronized` flag on JvmOverloads-generated adapter for Synchronized function
|
||||
- [`KT-43405`](https://youtrack.jetbrains.com/issue/KT-43405) Turkish locale, Linux Mint: "NoSuchMethodError: 'int[] kotlin.jvm.internal.Intrinsics$Kotlin.intArrayOf(int[])'" with `intArrayOf` function call
|
||||
- [`KT-43460`](https://youtrack.jetbrains.com/issue/KT-43460) JVM: redundant private setter is generated in case of multifile facade
|
||||
- [`KT-43473`](https://youtrack.jetbrains.com/issue/KT-43473) "VerifyError: Bad type on operand stack" caused by operator `get` with optional argument in superclass when called via square brackets on subclass
|
||||
- [`KT-43518`](https://youtrack.jetbrains.com/issue/KT-43518) JVM_IR. Additional `strictfp` flag on JvmOverloads-generated adapter for Strictfp function
|
||||
- [`KT-43569`](https://youtrack.jetbrains.com/issue/KT-43569) FIR: inapplicable candidate(s): kotlin/collections/set
|
||||
- [`KT-43616`](https://youtrack.jetbrains.com/issue/KT-43616) [FIR] Nullable type parameter-based type after merge in if
|
||||
- [`KT-43669`](https://youtrack.jetbrains.com/issue/KT-43669) FIR: No real overrides for FUN IR_EXTERNAL_DECLARATION_STUB
|
||||
- [`KT-43682`](https://youtrack.jetbrains.com/issue/KT-43682) Inline extension method of a multifile library inline class not found
|
||||
- [`KT-43687`](https://youtrack.jetbrains.com/issue/KT-43687) FIR: UnusedChecker does not take annotation arguments into account
|
||||
- [`KT-43688`](https://youtrack.jetbrains.com/issue/KT-43688) FIR: unused checker doesn't handle invokes properly
|
||||
- [`KT-43749`](https://youtrack.jetbrains.com/issue/KT-43749) "UnsupportedOperationException: Don't know how to generate outer expression: Closure" caused by Flow and collect method with function reference as a parameter
|
||||
- [`KT-43812`](https://youtrack.jetbrains.com/issue/KT-43812) JVM IR: SAM wrapper class with generic supertype mentions missing type parameter in the signature
|
||||
- [`KT-43832`](https://youtrack.jetbrains.com/issue/KT-43832) JVM IR: missing bridges for inheritance of class from interface in a complex generic diamond hierarchy
|
||||
- [`KT-43851`](https://youtrack.jetbrains.com/issue/KT-43851) JVM IR: function call returning object instance is removed during constant propagation
|
||||
- [`KT-43864`](https://youtrack.jetbrains.com/issue/KT-43864) JVM: "Assertion error after mandatory stack transformations: incorrect bytecode" with lateinit property of type T, which has a primitive type upperbound
|
||||
- [`KT-43887`](https://youtrack.jetbrains.com/issue/KT-43887) Problem with FunctionReferenceLowering$FunctionReferenceBuilder in kotlin native
|
||||
- [`KT-43912`](https://youtrack.jetbrains.com/issue/KT-43912) JVM internal error: Augment assignment and increment are not supported for local delegated properties and inline properties
|
||||
- [`KT-43915`](https://youtrack.jetbrains.com/issue/KT-43915) Back-end (JVM) Internal error: wrong bytecode generated for default method
|
||||
- [`KT-43938`](https://youtrack.jetbrains.com/issue/KT-43938) NSME when calling 'kotlin.Number' methods on instance of Java class extending Kolin abstract class extending 'kotlin.Number'
|
||||
- [`KT-43942`](https://youtrack.jetbrains.com/issue/KT-43942) org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Failed to generate function
|
||||
- [`KT-43949`](https://youtrack.jetbrains.com/issue/KT-43949) FIR: unresolved callable reference as lambda return
|
||||
- [`KT-43983`](https://youtrack.jetbrains.com/issue/KT-43983) IllegalStateException: "Couldn't obtain compiled function body for public final suspend inline fun" after moving inline extension function to library
|
||||
- [`KT-43984`](https://youtrack.jetbrains.com/issue/KT-43984) FIR: recursion in overridden symbols
|
||||
- [`KT-43984`](https://youtrack.jetbrains.com/issue/KT-43984) FIR: recursion in overridden symbols
|
||||
- [`KT-44010`](https://youtrack.jetbrains.com/issue/KT-44010) FIR: Inapplicable constructor due to an unresolved reference
|
||||
- [`KT-44030`](https://youtrack.jetbrains.com/issue/KT-44030) FIR2IR: uncached type parameters in delegated property
|
||||
- [`KT-44032`](https://youtrack.jetbrains.com/issue/KT-44032) FIR2IR: uncached type parameters in Java field
|
||||
- [`KT-44050`](https://youtrack.jetbrains.com/issue/KT-44050) FIR: anonymous object as IR parent
|
||||
- [`KT-44054`](https://youtrack.jetbrains.com/issue/KT-44054) FIR2IR: incorrect IR origin for substituted override function
|
||||
- [`KT-44058`](https://youtrack.jetbrains.com/issue/KT-44058) CompilationException: open suspend fun with @JvmStatic in open class companion
|
||||
- [`KT-44069`](https://youtrack.jetbrains.com/issue/KT-44069) please remove deprecated usages
|
||||
- [`KT-44066`](https://youtrack.jetbrains.com/issue/KT-44066) FIR Java: override ambiguity with vararg value type
|
||||
- [`KT-44114`](https://youtrack.jetbrains.com/issue/KT-44114) CompilationException when inlining a extension suspend function declared in interface companion with 'this' reference to extension receiver
|
||||
- [`KT-44131`](https://youtrack.jetbrains.com/issue/KT-44131) "UnsupportedOperationException: Don't know how to generate outer expression: Closure" when using suspend lambda and a function reference
|
||||
- [`KT-44140`](https://youtrack.jetbrains.com/issue/KT-44140) JVM IR: compilation of kotlin.Result crashes with IOOBE while generating toString-impl
|
||||
- [`KT-44141`](https://youtrack.jetbrains.com/issue/KT-44141) JVM IR: "ISE: There should be underlying type for inline class type" on usage of type parameter with Result upper bound inside a lambda
|
||||
- [`KT-44192`](https://youtrack.jetbrains.com/issue/KT-44192) Allow a greater number of constants in an enum class
|
||||
- [`KT-44202`](https://youtrack.jetbrains.com/issue/KT-44202) "ClassCastException" when getting delegated property with inline class and Any/Any? type
|
||||
- [`KT-44210`](https://youtrack.jetbrains.com/issue/KT-44210) KJS / IR: "AssertionError: Undefined parameter referenced: <this> defined" caused by plus assign operators in build blocks
|
||||
- [`KT-44233`](https://youtrack.jetbrains.com/issue/KT-44233) [IR] Collection Stub generation not correctly considering java.util Collection iterators
|
||||
- [`KT-44234`](https://youtrack.jetbrains.com/issue/KT-44234) Private companion property with explicit setter generates invalid bytecode
|
||||
- [`KT-44269`](https://youtrack.jetbrains.com/issue/KT-44269) "[TAILREC_ON_VIRTUAL_MEMBER_ERROR] Tailrec is not allowed on open members" with Spring annotation and private tailrec function
|
||||
- [`KT-44284`](https://youtrack.jetbrains.com/issue/KT-44284) Make Kotlin binaries publicly unavailable (set KotlinCompilerVersion.IS_PRE_RELEASE = true)
|
||||
- [`KT-44316`](https://youtrack.jetbrains.com/issue/KT-44316) ReenteringLazyValueComputationException when analyzing complex lazy delegate
|
||||
- [`KT-44347`](https://youtrack.jetbrains.com/issue/KT-44347) Back-end (JVM) Internal error: Couldn't transform method node for suspend function with wrong local for Continuation
|
||||
- [`KT-44368`](https://youtrack.jetbrains.com/issue/KT-44368) "IllegalStateException: Error type encountered" when inlining 'invoke' operator without enough information on type variable
|
||||
- [`KT-44412`](https://youtrack.jetbrains.com/issue/KT-44412) JVM IR backend fails to compile break in condition of do while
|
||||
- [`KT-44420`](https://youtrack.jetbrains.com/issue/KT-44420) False NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATION with 1.4.30-RC
|
||||
- [`KT-44429`](https://youtrack.jetbrains.com/issue/KT-44429) JVM IR: unnecessary integer unboxing leads to NPE when using mockito-kotlin
|
||||
- [`KT-44439`](https://youtrack.jetbrains.com/issue/KT-44439) Type inference of generic types failing java interop
|
||||
- [`KT-44440`](https://youtrack.jetbrains.com/issue/KT-44440) Too many Nothings in inferred type
|
||||
- [`KT-44471`](https://youtrack.jetbrains.com/issue/KT-44471) Fix failing script tests after switching to 1.5
|
||||
- [`KT-44474`](https://youtrack.jetbrains.com/issue/KT-44474) Compiler expects sealed type inheritors from platform specific source-sets in when expression in common source-set
|
||||
- [`KT-44483`](https://youtrack.jetbrains.com/issue/KT-44483) JVM IR: CCE on calling generic vararg function reference with Array expected type
|
||||
- [`KT-44527`](https://youtrack.jetbrains.com/issue/KT-44527) Suspend function with kotlin.Result: ClassCastException class kotlin.Result cannot be cast to class ...
|
||||
- [`KT-44529`](https://youtrack.jetbrains.com/issue/KT-44529) Inline class calls wrong iterator method in for loop
|
||||
- [`KT-44533`](https://youtrack.jetbrains.com/issue/KT-44533) JVM IR: ClassFormatError on synthetic $suspendImpl method generated in interface for a @JvmDefault function
|
||||
- [`KT-44540`](https://youtrack.jetbrains.com/issue/KT-44540) Regression in 1.4.30 in intellij-community: type mismatch for generic function call with generic Java class
|
||||
- [`KT-44546`](https://youtrack.jetbrains.com/issue/KT-44546) NI: changed variable fixation order (that can lead to changed resolution)
|
||||
- [`KT-44550`](https://youtrack.jetbrains.com/issue/KT-44550) KotlinBinaryClassCache leaks Kotlin plugin classloader on plugin unload
|
||||
- [`KT-44563`](https://youtrack.jetbrains.com/issue/KT-44563) Type Inference loosing type annotations in lambda type expectation for function calls with block parameters
|
||||
- [`KT-44583`](https://youtrack.jetbrains.com/issue/KT-44583) "Supertypes of the following classes cannot be resolved" error message gives no context
|
||||
- [`KT-44627`](https://youtrack.jetbrains.com/issue/KT-44627) JVM IR: ACCIDENTAL_OVERRIDE when overriding a generic field where the type parameter has a primitive bound
|
||||
- [`KT-44631`](https://youtrack.jetbrains.com/issue/KT-44631) "IndexOutOfBoundsException: Cannot pop operand off an empty stack" caused by a default param in inner class constructor which uses method or field from receiver
|
||||
- [`KT-44647`](https://youtrack.jetbrains.com/issue/KT-44647) "IllegalAccessError: class TestKt tried to access private method" with String Builder `get` and `inc` operator
|
||||
- [`KT-44651`](https://youtrack.jetbrains.com/issue/KT-44651) JVM / IR: "IllegalStateException: Illegal type substitutor" with if-else inside class constructor argument inside another if-else
|
||||
- [`KT-44660`](https://youtrack.jetbrains.com/issue/KT-44660) Internal inline functions in companion object with inline class return type fails compilation
|
||||
- [`KT-44671`](https://youtrack.jetbrains.com/issue/KT-44671) JVM_IR: ClassCastException: Result$Failure cannot be cast to Result with multithreaded coroutines
|
||||
- [`KT-44703`](https://youtrack.jetbrains.com/issue/KT-44703) JVM / IR: "IllegalStateException: Unhandled special name in mangledNameFor" caused by a reference to inline class inside interface's companion with lazy initialization
|
||||
- [`KT-44712`](https://youtrack.jetbrains.com/issue/KT-44712) JVM / IR: Behavior change after enabling with Mockito
|
||||
- [`KT-44714`](https://youtrack.jetbrains.com/issue/KT-44714) Debugger / Coroutines: Local variables are trimmed out too aggressively
|
||||
- [`KT-44722`](https://youtrack.jetbrains.com/issue/KT-44722) JVM IR: ClassCastException with inline class, let and bound function reference
|
||||
- [`KT-44726`](https://youtrack.jetbrains.com/issue/KT-44726) JVM IR: Incorrect KType nullability for platform type reified as non-null
|
||||
- [`KT-44781`](https://youtrack.jetbrains.com/issue/KT-44781) JVM IR: java.lang.NoSuchFieldError: $noName_0 when calling a crossinline lambda within a suspending lambda
|
||||
- [`KT-44798`](https://youtrack.jetbrains.com/issue/KT-44798) JVM IR: Inherited platform declarations clash for class implementing both List and Set
|
||||
- [`KT-44801`](https://youtrack.jetbrains.com/issue/KT-44801) 1.4.30 JVM IR: Unbound symbols not allowed with anonymous object
|
||||
- [`KT-44803`](https://youtrack.jetbrains.com/issue/KT-44803) FIR bootstrap: incorrect nullability is set for type alias-based type
|
||||
- [`KT-44827`](https://youtrack.jetbrains.com/issue/KT-44827) Non-existing outer class is written in anonymous class for SAM wrapper in inline lambda with capture
|
||||
- [`KT-44837`](https://youtrack.jetbrains.com/issue/KT-44837) JVM / IR: ClassCastException with Result object when it is used by a generic method in a suspend call
|
||||
- [`KT-44875`](https://youtrack.jetbrains.com/issue/KT-44875) JVM_IR. `hashCode` call is generated on interface target in fun interface equality
|
||||
- [`KT-44878`](https://youtrack.jetbrains.com/issue/KT-44878) JVM_IR: "IllegalStateException: Unexpected types" when checking non-nullable variable is `in` range between nullable ones with smart-cast
|
||||
- [`KT-44926`](https://youtrack.jetbrains.com/issue/KT-44926) MPP: Actual typealias to compiled inline class incompatible with expect inline class
|
||||
- [`KT-44947`](https://youtrack.jetbrains.com/issue/KT-44947) Sealed interfaces: Sealed fun interface leads to "NoWhenBranchMatchedException"
|
||||
- [`KT-44993`](https://youtrack.jetbrains.com/issue/KT-44993) JVM IR: VerifyError on getfield with Kotlin generic field and elvis operator
|
||||
- [`KT-45008`](https://youtrack.jetbrains.com/issue/KT-45008) JVM IR: hashCode is generated as invokeinterface if smart cast to interface is present
|
||||
- [`KT-45011`](https://youtrack.jetbrains.com/issue/KT-45011) JVM / IR: "AssertionError: Unbound symbols not allowed"
|
||||
- [`KT-45022`](https://youtrack.jetbrains.com/issue/KT-45022) IR: "AssertionError: Undefined variable referenced" from psi2ir caused by plusAssign operator of object
|
||||
- [`KT-45064`](https://youtrack.jetbrains.com/issue/KT-45064) JVM IR: "java.lang.AssertionError: SyntheticAccessorLowering should not attempt to modify other files!" with member reference to property in another file with private setter
|
||||
- [`KT-45067`](https://youtrack.jetbrains.com/issue/KT-45067) "IllegalArgumentException: Wildcard mast have a bound for annotation of WILDCARD_BOUND position" with BEAM SDK 2.27
|
||||
- [`KT-45069`](https://youtrack.jetbrains.com/issue/KT-45069) JVM / IR: New SAM conversions mode fails when converting from Unit to Any
|
||||
- [`KT-45131`](https://youtrack.jetbrains.com/issue/KT-45131) JVM / IR: "RuntimeException: Lambda, SAM or anonymous object should have only one constructor" caused by inline class that type cast to reified type parameter inside lambda in inline function
|
||||
- [`KT-45139`](https://youtrack.jetbrains.com/issue/KT-45139) Inline class: AssertionError: Expected top level inline class
|
||||
- [`KT-45166`](https://youtrack.jetbrains.com/issue/KT-45166) JVM / IR: "AbstractMethodError: Receiver class does not define or inherit an implementation of the resolved method of interface" caused by interface with suspend function
|
||||
- [`KT-45187`](https://youtrack.jetbrains.com/issue/KT-45187) JVM / IR: ClassCastException caused by substituting generic type of vararg parameter with java.lang.Void
|
||||
- [`KT-45195`](https://youtrack.jetbrains.com/issue/KT-45195) JVM IR: annotation methods are generated as default interface methods if `allopen` is used
|
||||
- [`KT-45243`](https://youtrack.jetbrains.com/issue/KT-45243) "IllegalStateException: Lambdas shouldn't be visited by ESExpressionVisitor" caused by lambda inside `kotlin.test.assertNotNull`
|
||||
- [`KT-45259`](https://youtrack.jetbrains.com/issue/KT-45259) JVM: ClassCastException caused by Result as lambda parameter type
|
||||
- [`KT-45292`](https://youtrack.jetbrains.com/issue/KT-45292) AssertionError with recursive inline extension property
|
||||
- [`KT-45300`](https://youtrack.jetbrains.com/issue/KT-45300) Deprecate super calls in public-api inline functions
|
||||
- [`KT-45409`](https://youtrack.jetbrains.com/issue/KT-45409) Rename jspecify annotations’ package and default not null annotation
|
||||
- [`KT-45446`](https://youtrack.jetbrains.com/issue/KT-45446) JVM / IR: NullPointerException caused by unreachable code and comparison
|
||||
- [`KT-45721`](https://youtrack.jetbrains.com/issue/KT-45721) JVM / IR: "Unbound symbols not allowed" caused by class reference in sequence lambda
|
||||
- [`KT-45853`](https://youtrack.jetbrains.com/issue/KT-45853) JVM / IR: "Accidental override" caused by inheriting Throwable.getCause from Java interface
|
||||
- [`KT-45861`](https://youtrack.jetbrains.com/issue/KT-45861) Turning warnings into errors for calls with type parameters annotated by @OnlyInputTypes
|
||||
- [`KT-45865`](https://youtrack.jetbrains.com/issue/KT-45865) JVM IR: "VerifyError: Bad type on operand stack" with `enumValueOf` on a value from a list of strings
|
||||
- [`KT-45868`](https://youtrack.jetbrains.com/issue/KT-45868) JVM IR: ClassCastException with SAM function in init block when SAM is generated via invokedynamic
|
||||
- [`KT-45920`](https://youtrack.jetbrains.com/issue/KT-45920) JVM IR: "Accidental override" on redefining `get()` in custom Map class
|
||||
- [`KT-45934`](https://youtrack.jetbrains.com/issue/KT-45934) JVM IR: "java.lang.IllegalStateException: Function has no body" for class implementing interface by delegation
|
||||
- [`KT-45945`](https://youtrack.jetbrains.com/issue/KT-45945) JVM / IR: "AssertionError: Unexpected variance in super type argument" with contravariance and intersection types
|
||||
- [`KT-45963`](https://youtrack.jetbrains.com/issue/KT-45963) JVM / IR: "AbstractMethodError: Receiver class does not define or inherit an implementation of the resolved method" in Dokka tests
|
||||
- [`KT-45967`](https://youtrack.jetbrains.com/issue/KT-45967) JVM IR: "IllegalAccessError" with invokedynamic to Java SAM over callable reference to private function
|
||||
- [`KT-45982`](https://youtrack.jetbrains.com/issue/KT-45982) Wrong subtyping result on captured types with postponed type variables
|
||||
- [`KT-46007`](https://youtrack.jetbrains.com/issue/KT-46007) JVM / IR: "ClassCastException: kotlin.Unit cannot be cast to java.lang.String" caused by default suspend function in interface
|
||||
- [`KT-46060`](https://youtrack.jetbrains.com/issue/KT-46060) JVM IR: NullPointerException from RangeContainsLowering when `contains` is a @JvmStatic function in object
|
||||
- [`KT-46069`](https://youtrack.jetbrains.com/issue/KT-46069) JVM IR: unbound type parameter on generic bound adapted function reference
|
||||
- [`KT-46092`](https://youtrack.jetbrains.com/issue/KT-46092) JVM IR: AssertionError "Array type expected: @[FlexibleNullability] kotlin.CharArray?" on super call to Java constructor with primitive vararg
|
||||
- [`KT-46104`](https://youtrack.jetbrains.com/issue/KT-46104) The message on inline -> value class migration should not say that inline classes are deprecated
|
||||
- [`KT-46131`](https://youtrack.jetbrains.com/issue/KT-46131) Kotlin 1.5.0-RC errors when reading class file
|
||||
- [`KT-46160`](https://youtrack.jetbrains.com/issue/KT-46160) JVM IR: IllegalAccessException at runtime for member reference to JvmMultifileClass member from stdlib
|
||||
- [`KT-46186`](https://youtrack.jetbrains.com/issue/KT-46186) Type inference regression in Kotlin 1.5 with constrained generic return types
|
||||
|
||||
### Docs & Examples
|
||||
|
||||
- [`KT-45884`](https://youtrack.jetbrains.com/issue/KT-45884) Incorrect description for JVM `toUpperCase` method
|
||||
|
||||
### IDE
|
||||
|
||||
- [`KT-33233`](https://youtrack.jetbrains.com/issue/KT-33233) Use dependency of library to build built-ins in IDE, instead of loading them from the current classloader
|
||||
- [`KT-34023`](https://youtrack.jetbrains.com/issue/KT-34023) kotlin.KotlinNullPointerException at org.jetbrains.kotlin.backend.common.FunctionsFromAnyGenerator.getPrimaryConstructorProperties(FunctionsFromAnyGenerator.kt:66)
|
||||
- [`KT-35947`](https://youtrack.jetbrains.com/issue/KT-35947) KFunctionN.call is unresolved in IDE in Kotlin/JVM project
|
||||
- [`KT-37702`](https://youtrack.jetbrains.com/issue/KT-37702) Code analysis speed: on-the-fly analysis diagnostics reporting
|
||||
- [`KT-41048`](https://youtrack.jetbrains.com/issue/KT-41048) [FIR-IDE] Properly implement methods in KtFirPackageScope
|
||||
- [`KT-41671`](https://youtrack.jetbrains.com/issue/KT-41671) Missing nullability information in properties using type inference from get()
|
||||
- [`KT-43824`](https://youtrack.jetbrains.com/issue/KT-43824) KtLightClassForSourceDeclaration#isInheritor works in a different way than java implementation
|
||||
- [`KT-44128`](https://youtrack.jetbrains.com/issue/KT-44128) IDE: Kotlin JVM record has incorrect property accessors as seen from Java
|
||||
- [`KT-44487`](https://youtrack.jetbrains.com/issue/KT-44487) MPP, IDE: No error in IDE when sealed class inheritor from common source-set is not used in exhaustive when expression in platform source-set
|
||||
- [`KT-45254`](https://youtrack.jetbrains.com/issue/KT-45254) Highlighting for files with certain errors appears only on second opening
|
||||
- [`KT-46097`](https://youtrack.jetbrains.com/issue/KT-46097) Light classes: Incomplete nullability information for a getter method of a kotlin property defined in private constructor
|
||||
|
||||
### IDE. Decompiler, Indexing, Stubs
|
||||
|
||||
- [`KT-43699`](https://youtrack.jetbrains.com/issue/KT-43699) IDE: Unresolved extension method from Java code for simple class with typealias and generics (IllegalStateException: Unknown type parameter)
|
||||
- [`KT-44756`](https://youtrack.jetbrains.com/issue/KT-44756) Infinite "UpToDateStubIndexMismatch: PSI and index do not match." with IDEA 2021.1 EAP upon attempt to open "org.gradle.configurationcache" even they seem to be the same
|
||||
|
||||
### IDE. Gradle Integration
|
||||
|
||||
- [`KT-37127`](https://youtrack.jetbrains.com/issue/KT-37127) Implement precise importing of platforms of root source sets (commonMain/commonTest) when hierarchical multiplatform support is enabled
|
||||
- [`KT-42048`](https://youtrack.jetbrains.com/issue/KT-42048) KJS / Gradle integration: Could not determine the dependencies of task ':webApp:testPackageJson' in Android Studio 4.2 Canary 11
|
||||
|
||||
### IDE. Gradle. Script
|
||||
|
||||
- [`KT-46215`](https://youtrack.jetbrains.com/issue/KT-46215) Dead lock on closing project during the import in IJ211 through ScriptDefinitionsManager
|
||||
|
||||
### IDE. Inspections and Intentions
|
||||
|
||||
- [`KT-23824`](https://youtrack.jetbrains.com/issue/KT-23824) Return lifted out of if condition causes suspend tail call optimization to no longer apply
|
||||
- [`KT-38155`](https://youtrack.jetbrains.com/issue/KT-38155) Lift assignment out of 'if' produces type mismatch without manually adding a semicolon
|
||||
- [`KT-44821`](https://youtrack.jetbrains.com/issue/KT-44821) IDE: False positive NO_ELSE_IN_WHEN caused by sealed class and when in another module
|
||||
- [`KT-46088`](https://youtrack.jetbrains.com/issue/KT-46088) [IDEA] Incorrect behavior of replace inline class with value class intention
|
||||
|
||||
### IDE. Misc
|
||||
|
||||
- [`KT-44675`](https://youtrack.jetbrains.com/issue/KT-44675) Incorrect reference to resource into 202 plugin
|
||||
|
||||
### IDE. Refactorings
|
||||
|
||||
- [`KT-44079`](https://youtrack.jetbrains.com/issue/KT-44079) Sealed Interfaces: Move refactoring should warn about violation of hierarchy restrictions
|
||||
- [`KT-44839`](https://youtrack.jetbrains.com/issue/KT-44839) Sealed interfaces: move refactoring warnings works with "more freedom for sealed classes" rules for language level < 1.5
|
||||
|
||||
### IDE. Script
|
||||
|
||||
- [`KT-43288`](https://youtrack.jetbrains.com/issue/KT-43288) Allow push notifications about script configuration /dependencies changes via the `ScriptDefinitionsProvider` EP
|
||||
|
||||
### JavaScript
|
||||
|
||||
- [`KT-39272`](https://youtrack.jetbrains.com/issue/KT-39272) KJS / IR: Can't use javascript keywords as JsName
|
||||
- [`KT-41650`](https://youtrack.jetbrains.com/issue/KT-41650) JS IR BE: `default` should be a reserved identifier
|
||||
- [`KT-42176`](https://youtrack.jetbrains.com/issue/KT-42176) KJS / IR: Interface default method in sub-interface not resolved correctly from extension on super-interface
|
||||
- [`KT-44103`](https://youtrack.jetbrains.com/issue/KT-44103) [JSIR] TypeError when bumping from 1.4.20 to 1.4.30-M1
|
||||
- [`KT-44180`](https://youtrack.jetbrains.com/issue/KT-44180) KJS / IR: NPE in ConstTransformer of compileDevelopmentExecutableKotlinJs/compileProductionExecutableKotlinJs tasks
|
||||
- [`KT-44415`](https://youtrack.jetbrains.com/issue/KT-44415) Kotlin/JS with IR and kotlin-react: "too much recursion" error in runtime in browser
|
||||
- [`KT-44433`](https://youtrack.jetbrains.com/issue/KT-44433) KJS IR: support function interfaces with suspend member
|
||||
- [`KT-44469`](https://youtrack.jetbrains.com/issue/KT-44469) KJS / IR: Incorrect export functions with bridges
|
||||
- [`KT-44718`](https://youtrack.jetbrains.com/issue/KT-44718) MPP/ KJS: "IllegalStateException: Unsupported operation" with serialization plugin and incremental compilation
|
||||
- [`KT-44796`](https://youtrack.jetbrains.com/issue/KT-44796) KJS / IR: default parameter of function with @JsName leads to "RangeError: Maximum call stack size exceeded"
|
||||
- [`KT-45059`](https://youtrack.jetbrains.com/issue/KT-45059) KJS / IR: Add possibility for runtime diagnostics of DCE result
|
||||
|
||||
### Libraries
|
||||
|
||||
- [`KT-12109`](https://youtrack.jetbrains.com/issue/KT-12109) Add stdlib method that combines mapNotNull() and first/firstOrNull()
|
||||
- [`KT-25571`](https://youtrack.jetbrains.com/issue/KT-25571) Make random implementations serializable
|
||||
- [`KT-26234`](https://youtrack.jetbrains.com/issue/KT-26234) Floored division and remainder function for numeric types
|
||||
- [`KT-32996`](https://youtrack.jetbrains.com/issue/KT-32996) kotlin.test: add assertContentEquals for comparing content of arrays, iterables, sequences
|
||||
- [`KT-39177`](https://youtrack.jetbrains.com/issue/KT-39177) Make CharCategory available in common multiplatform code
|
||||
- [`KT-40225`](https://youtrack.jetbrains.com/issue/KT-40225) Support adding kotlin-test as a single dependency, as it should be with a multiplatform library
|
||||
- [`KT-42071`](https://youtrack.jetbrains.com/issue/KT-42071) Strict version of String.toBoolean()
|
||||
- [`KT-42720`](https://youtrack.jetbrains.com/issue/KT-42720) Kotlin ArrayDeque on JVM: provide optimized toArray method
|
||||
- [`KT-42840`](https://youtrack.jetbrains.com/issue/KT-42840) Commonize and generalize String.contentEquals that is currently JVM-only
|
||||
- [`KT-43772`](https://youtrack.jetbrains.com/issue/KT-43772) Kotlin/Native unfinished workers detected.
|
||||
- [`KT-44168`](https://youtrack.jetbrains.com/issue/KT-44168) Prevent storing NaN and negative zero in kotlin.time.Duration
|
||||
- [`KT-44369`](https://youtrack.jetbrains.com/issue/KT-44369) Commonize Char.titlecaseChar() and Char.titlecase() that are currently JVM-only
|
||||
- [`KT-44783`](https://youtrack.jetbrains.com/issue/KT-44783) Add IS_VALUE flag for value classes to kotlinx-metadata-jvm
|
||||
- [`KT-44815`](https://youtrack.jetbrains.com/issue/KT-44815) Remove kotlin-annotations-android and JVM compiler support for @ParameterName/@DefaultValue/@DefaultNull
|
||||
- [`KT-45213`](https://youtrack.jetbrains.com/issue/KT-45213) Update Unicode version used in K/N for Char and String case conversion functions
|
||||
|
||||
### Middle-end. IR
|
||||
|
||||
- [`KT-43831`](https://youtrack.jetbrains.com/issue/KT-43831) Compilation failed, IrSimpleFunctionPublicSymbolImpl is already bound
|
||||
- [`KT-44100`](https://youtrack.jetbrains.com/issue/KT-44100) KJS / IR: Top level declarations added in IR plugin are not referenceable from other modules
|
||||
- [`KT-45170`](https://youtrack.jetbrains.com/issue/KT-45170) IR: "AssertionError: Single expression value for GET_OBJECT" caused by inc operator of field inside scope function inside object
|
||||
|
||||
### Native
|
||||
|
||||
- [`KT-42446`](https://youtrack.jetbrains.com/issue/KT-42446) Native: SIGSEGV in Kotlin_Array_get on linuxArm64
|
||||
- [`KT-43502`](https://youtrack.jetbrains.com/issue/KT-43502) [K/N] relocation R_X86_64_PC32 cannot be used against symbol __environ; recompile with -fPIC
|
||||
- [`KT-44295`](https://youtrack.jetbrains.com/issue/KT-44295) 1.4.21 Kotlin native ndk compiler crash
|
||||
- [`KT-44774`](https://youtrack.jetbrains.com/issue/KT-44774) ld fails with CALL16 reloc at 0x48f00 not against global symbol (Linux MIPS)
|
||||
- [`KT-44746`](https://youtrack.jetbrains.com/issue/KT-44746) Different hashCode() results for Kotlin/Native stdlib
|
||||
|
||||
### Native. C and ObjC Import
|
||||
|
||||
- [`KT-44824`](https://youtrack.jetbrains.com/issue/KT-44824) cinterop tool no longer appends .klib to produced klibs
|
||||
|
||||
### Native. C Export
|
||||
|
||||
- [`KT-36639`](https://youtrack.jetbrains.com/issue/KT-36639) MPP: Build ios "staticLib" or "sharedLib" binary failed if interface contains member extension function
|
||||
- [`KT-41725`](https://youtrack.jetbrains.com/issue/KT-41725) Dynamic library doesn't load on raspberrypi
|
||||
|
||||
### Native. ObjC Export
|
||||
|
||||
- [`KT-44549`](https://youtrack.jetbrains.com/issue/KT-44549) In the Xcode debug session, call stack is missing a frame when the iOS app fails
|
||||
|
||||
### Native. Platforms
|
||||
|
||||
- [`KT-45094`](https://youtrack.jetbrains.com/issue/KT-45094) Fail to compile Kotlin Native sources under Oracle Linux 7
|
||||
|
||||
### Reflection
|
||||
|
||||
- [`KT-44594`](https://youtrack.jetbrains.com/issue/KT-44594) Avoid using unnecessary array types reflection in kotlin-reflect
|
||||
- [`KT-44782`](https://youtrack.jetbrains.com/issue/KT-44782) Add KClass.isValue to kotlin-reflect
|
||||
|
||||
### Tools. Ant
|
||||
|
||||
- [`KT-16227`](https://youtrack.jetbrains.com/issue/KT-16227) Ant task: do not include runtime by default if destination is a jar
|
||||
- [`KT-44293`](https://youtrack.jetbrains.com/issue/KT-44293) Support fork mode in kotlinc Ant task
|
||||
|
||||
### Tools. CLI
|
||||
|
||||
- [`KT-17344`](https://youtrack.jetbrains.com/issue/KT-17344) Include kotlin-reflect to resulting jar if "-include-runtime" is specified
|
||||
- [`KT-43220`](https://youtrack.jetbrains.com/issue/KT-43220) -include-runtime should add .kotlin_builtins to the output
|
||||
- [`KT-43704`](https://youtrack.jetbrains.com/issue/KT-43704) Illegal reflective access by com.intellij.util.ReflectionUtil to method java.util.ResourceBundle.setParent(java.util.ResourceBundle)
|
||||
- [`KT-44078`](https://youtrack.jetbrains.com/issue/KT-44078) Do not include module-info.class of kotlin-stdlib.jar to the resulting jar with -include-runtime
|
||||
- [`KT-44232`](https://youtrack.jetbrains.com/issue/KT-44232) CLI: do not pass -noverify to java process starting from JDK 13
|
||||
- [`KT-45566`](https://youtrack.jetbrains.com/issue/KT-45566) JDK 16 - e: java.lang.NoClassDefFoundError: Could not initialize class org.jetbrains.kotlin.com.intellij.pom.java.LanguageLevel
|
||||
|
||||
### Tools. CLI. Native
|
||||
|
||||
- [`KT-43874`](https://youtrack.jetbrains.com/issue/KT-43874) Native / CLI: provide a way to show difference between Jvm and Native compilers
|
||||
|
||||
### Tools. Compiler Plugins
|
||||
|
||||
- [`KT-45783`](https://youtrack.jetbrains.com/issue/KT-45783) Serialization: "AnalyzerException: Expected an object reference, but found I" caused by `JvmInline` and `Serializable` annotations
|
||||
|
||||
### Tools. Gradle
|
||||
|
||||
- [`KT-31027`](https://youtrack.jetbrains.com/issue/KT-31027) java.lang.NoSuchMethodError: No static method hashCode(Z)I in class Ljava/lang/Boolean; or its super classes (declaration of 'java.lang.Boolean' appears in /system/framework/core-libart.jar)
|
||||
- [`KT-43605`](https://youtrack.jetbrains.com/issue/KT-43605) Kotlin Gradle Plugin 1.4.20 undeclared system property reads cause problems with Gradle configuration cache enabled
|
||||
- [`KT-44204`](https://youtrack.jetbrains.com/issue/KT-44204) Kotlin Gradle Plugin 1.4.21 makes impossible to use ANTLR in other plugins
|
||||
- [`KT-44361`](https://youtrack.jetbrains.com/issue/KT-44361) Gradle: deprecate options includeRuntime, noStdlib, noReflect
|
||||
- [`KT-44462`](https://youtrack.jetbrains.com/issue/KT-44462) Kotlin Gradle plugin creates `compile` configuration with Gradle 7.0
|
||||
- [`KT-44834`](https://youtrack.jetbrains.com/issue/KT-44834) Gradle Kotlin DSL: Add `languageSettings` configuration lambda without `apply` call
|
||||
- [`KT-44949`](https://youtrack.jetbrains.com/issue/KT-44949) Compatibility with Gradle 7.0
|
||||
- [`KT-44957`](https://youtrack.jetbrains.com/issue/KT-44957) gradle - target.compilations seems to be deprecated
|
||||
- [`KT-45340`](https://youtrack.jetbrains.com/issue/KT-45340) Update minimal supported version of Kotlin Gradle Plugin to 6.1
|
||||
|
||||
### Tools. Gradle. JS
|
||||
|
||||
- [`KT-43237`](https://youtrack.jetbrains.com/issue/KT-43237) KJS: `-jsLegacy` Naming Convention is incompatible with NPM
|
||||
- [`KT-43869`](https://youtrack.jetbrains.com/issue/KT-43869) Error in webpack configuration not displayed
|
||||
- [`KT-44614`](https://youtrack.jetbrains.com/issue/KT-44614) Update Node.JS and Yarn versions
|
||||
- [`KT-44616`](https://youtrack.jetbrains.com/issue/KT-44616) Kotlin/JS: IR backend with React: "Uncaught TypeError: _this__0 is undefined" runtime error in browser
|
||||
- [`KT-45574`](https://youtrack.jetbrains.com/issue/KT-45574) Sync Kotlin/JS compile tasks into one folder (build/js/packages/<package>/kotlin)
|
||||
|
||||
### Tools. Gradle. Multiplatform
|
||||
|
||||
- [`KT-42098`](https://youtrack.jetbrains.com/issue/KT-42098) Commonizer is re-launched for every included Gradle build
|
||||
- [`KT-43116`](https://youtrack.jetbrains.com/issue/KT-43116) Merge together MultiplatformHighlightingTest and MultiplatformAnalysisTest
|
||||
- [`KT-44322`](https://youtrack.jetbrains.com/issue/KT-44322) KotlinTargetComponent maintenance for -sources.jar
|
||||
- [`KT-44900`](https://youtrack.jetbrains.com/issue/KT-44900) Support gradle configuration cache with kotlin.multiplatform plugin
|
||||
|
||||
### Tools. Gradle. Native
|
||||
|
||||
- [`KT-46122`](https://youtrack.jetbrains.com/issue/KT-46122) kotlinx-serialization and kotlinx-datetime can't be built with 1.5.0-RC
|
||||
|
||||
### Tools. JPS
|
||||
|
||||
- [`KT-13631`](https://youtrack.jetbrains.com/issue/KT-13631) Compilation fails on Turkish locale because of locale-sensitive uppercasing
|
||||
- [`KT-44644`](https://youtrack.jetbrains.com/issue/KT-44644) Mark all `@JvmMultifileClass` parts compiled in the previous round as dirty in the JPS plugin, similarly to how it’s done in the Gradle plugin
|
||||
|
||||
### Tools. Scripts
|
||||
|
||||
- [`KT-45194`](https://youtrack.jetbrains.com/issue/KT-45194) KT: Generate Kotlin Entities script: it doesn't work
|
||||
- [`KT-44580`](https://youtrack.jetbrains.com/issue/KT-44580) Scripts: Unable to set new file annotation hooks after first snippet compilation
|
||||
|
||||
### Tools. kapt
|
||||
|
||||
- [`KT-43686`](https://youtrack.jetbrains.com/issue/KT-43686) KaptWithoutKotlincTask should use `@CompileClasspath` for `kotlinStdlibClasspath` for cache relocateability.
|
||||
- [`KT-44130`](https://youtrack.jetbrains.com/issue/KT-44130) KAPT changes field order in 1.4.30-M1
|
||||
- [`KT-44909`](https://youtrack.jetbrains.com/issue/KT-44909) Kapt: ReenteringLazyValueComputationException without stacktrace caused by `when` expression with sealed class function without explicit return type
|
||||
- [`KT-45168`](https://youtrack.jetbrains.com/issue/KT-45168) KAPT: Java stubs generated for Kotlin files generated by annotation processors
|
||||
|
||||
|
||||
## 1.4.32
|
||||
|
||||
### IDE
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
[](https://www.apache.org/licenses/LICENSE-2.0)
|
||||
[](https://ge.jetbrains.com/scans?search.rootProjectNames=Kotlin)
|
||||
|
||||
[Join Kotlin 1.5 Online Event on May 25, 2021!](https://pages.jetbrains.com/kotlin-online-event-2021/github-readme)
|
||||
|
||||
# Kotlin Programming Language
|
||||
|
||||
Welcome to [Kotlin](https://kotlinlang.org/)!
|
||||
|
||||
@@ -39,4 +39,4 @@ class GeneratedJvmClass(
|
||||
}
|
||||
}
|
||||
|
||||
fun File.isModuleMappingFile() = extension == ModuleMapping.MAPPING_FILE_EXT && parentFile.name == "META-INF"
|
||||
fun File.isModuleMappingFile() = extension == ModuleMapping.MAPPING_FILE_EXT && parentFile.name == "META-INF"
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.incremental
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import org.jetbrains.kotlin.build.GeneratedFile
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
|
||||
import org.jetbrains.kotlin.incremental.js.IrTranslationResultValue
|
||||
import org.jetbrains.kotlin.incremental.js.TranslationResultValue
|
||||
@@ -48,6 +49,7 @@ open class IncrementalJsCache(
|
||||
private const val INLINE_FUNCTIONS = "inline-functions"
|
||||
private const val HEADER_FILE_NAME = "header.meta"
|
||||
private const val PACKAGE_META_FILE = "packages-meta"
|
||||
private const val SOURCE_TO_JS_OUTPUT = "source-to-js-output"
|
||||
|
||||
fun hasHeaderFile(cachesDir: File) = File(cachesDir, HEADER_FILE_NAME).exists()
|
||||
}
|
||||
@@ -60,6 +62,7 @@ open class IncrementalJsCache(
|
||||
private val irTranslationResults = registerMap(IrTranslationResultMap(IR_TRANSLATION_RESULT_MAP.storageFile, pathConverter))
|
||||
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile, pathConverter))
|
||||
private val packageMetadata = registerMap(PackageMetadataMap(PACKAGE_META_FILE.storageFile))
|
||||
private val sourceToJsOutputsMap = registerMap(SourceToJsOutputMap(SOURCE_TO_JS_OUTPUT.storageFile, pathConverter))
|
||||
|
||||
private val dirtySources = hashSetOf<File>()
|
||||
|
||||
@@ -75,6 +78,7 @@ open class IncrementalJsCache(
|
||||
|
||||
override fun markDirty(removedAndCompiledSources: Collection<File>) {
|
||||
removedAndCompiledSources.forEach { sourceFile ->
|
||||
sourceToJsOutputsMap.remove(sourceFile)
|
||||
// The common prefix of all FQN parents has to be the file package
|
||||
sourceToClassesMap[sourceFile].map { it.parentOrNull()?.asString() ?: "" }.minByOrNull { it.length }?.let {
|
||||
packageMetadata.remove(it)
|
||||
@@ -95,6 +99,10 @@ open class IncrementalJsCache(
|
||||
}
|
||||
}
|
||||
|
||||
fun getOutputsBySource(sourceFile: File): Collection<File> {
|
||||
return sourceToJsOutputsMap.get(sourceFile)
|
||||
}
|
||||
|
||||
fun compareAndUpdate(incrementalResults: IncrementalResultsConsumerImpl, changesCollector: ChangesCollector) {
|
||||
val translatedFiles = incrementalResults.packageParts
|
||||
|
||||
@@ -175,6 +183,17 @@ open class IncrementalJsCache(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateSourceToOutputMap(
|
||||
generatedFiles: Iterable<GeneratedFile>,
|
||||
) {
|
||||
for (generatedFile in generatedFiles) {
|
||||
for (source in generatedFile.sourceFiles) {
|
||||
if (dirtySources.contains(source))
|
||||
sourceToJsOutputsMap.add(source, generatedFile.outputFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object TranslationResultValueExternalizer : DataExternalizer<TranslationResultValue> {
|
||||
@@ -215,17 +234,20 @@ private class TranslationResultMap(
|
||||
override fun dumpValue(value: TranslationResultValue): String =
|
||||
"Metadata: ${value.metadata.md5()}, Binary AST: ${value.binaryAst.md5()}, InlineData: ${value.inlineData.md5()}"
|
||||
|
||||
@Synchronized
|
||||
fun put(sourceFile: File, newMetadata: ByteArray, newBinaryAst: ByteArray, newInlineData: ByteArray) {
|
||||
storage[pathConverter.toPath(sourceFile)] =
|
||||
TranslationResultValue(metadata = newMetadata, binaryAst = newBinaryAst, inlineData = newInlineData)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
operator fun get(sourceFile: File): TranslationResultValue? =
|
||||
storage[pathConverter.toPath(sourceFile)]
|
||||
|
||||
fun keys(): Collection<File> =
|
||||
storage.keys.map { pathConverter.toFile(it) }
|
||||
|
||||
@Synchronized
|
||||
fun remove(sourceFile: File, changesCollector: ChangesCollector) {
|
||||
val path = pathConverter.toPath(sourceFile)
|
||||
val protoBytes = storage[path]!!.metadata
|
||||
@@ -359,6 +381,7 @@ private class InlineFunctionsMap(
|
||||
storageFile: File,
|
||||
private val pathConverter: FileToPathConverter
|
||||
) : BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
|
||||
@Synchronized
|
||||
fun process(srcFile: File, newMap: Map<String, Long>, changesCollector: ChangesCollector) {
|
||||
val key = pathConverter.toPath(srcFile)
|
||||
val oldMap = storage[key] ?: emptyMap()
|
||||
@@ -376,6 +399,7 @@ private class InlineFunctionsMap(
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun remove(sourceFile: File) {
|
||||
storage.remove(pathConverter.toPath(sourceFile))
|
||||
}
|
||||
|
||||
@@ -47,10 +47,16 @@ abstract class BasicMap<K : Comparable<K>, V>(
|
||||
storage.flush(memoryCachesOnly)
|
||||
}
|
||||
|
||||
// avoid unsynchronized close
|
||||
fun close() {
|
||||
storage.close()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun closeForTest() {
|
||||
close()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun dump(): String {
|
||||
return with(StringBuilder()) {
|
||||
|
||||
@@ -34,7 +34,6 @@ class CachingLazyStorage<K, V>(
|
||||
) : LazyStorage<K, V> {
|
||||
private var storage: PersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
@@ -46,32 +45,36 @@ class CachingLazyStorage<K, V>(
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
}
|
||||
|
||||
return storage!!
|
||||
}
|
||||
|
||||
override val keys: Collection<K>
|
||||
@Synchronized
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
@Synchronized
|
||||
override operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
@Synchronized
|
||||
override operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
@Synchronized
|
||||
override operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendData(key, { valueExternalizer.save(it, value) })
|
||||
}
|
||||
@@ -103,7 +106,11 @@ class CachingLazyStorage<K, V>(
|
||||
|
||||
@Synchronized
|
||||
override fun close() {
|
||||
storage?.close()
|
||||
try {
|
||||
storage?.close()
|
||||
} finally {
|
||||
storage = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> = PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
|
||||
@@ -28,6 +28,7 @@ internal open class ClassOneToManyMap(storageFile: File) : BasicStringMap<Collec
|
||||
storage.append(key.asString(), listOf(value.asString()))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
operator fun get(key: FqName): Collection<FqName> =
|
||||
storage[key.asString()]?.map(::FqName) ?: setOf()
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ class NonCachingLazyStorage<K, V>(
|
||||
) : LazyStorage<K, V> {
|
||||
private var storage: PersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
@@ -43,7 +42,6 @@ class NonCachingLazyStorage<K, V>(
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
@@ -53,22 +51,28 @@ class NonCachingLazyStorage<K, V>(
|
||||
}
|
||||
|
||||
override val keys: Collection<K>
|
||||
@Synchronized
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
@Synchronized
|
||||
override operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
@Synchronized
|
||||
override operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
@Synchronized
|
||||
override operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
|
||||
}
|
||||
@@ -100,7 +104,11 @@ class NonCachingLazyStorage<K, V>(
|
||||
|
||||
@Synchronized
|
||||
override fun close() {
|
||||
storage?.close()
|
||||
try {
|
||||
storage?.close()
|
||||
} finally {
|
||||
storage = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> =
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import java.io.File
|
||||
|
||||
class SourceToJsOutputMap(storageFile: File, private val pathConverter: FileToPathConverter) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
|
||||
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
|
||||
|
||||
@Synchronized
|
||||
fun add(key: File, value: File) {
|
||||
storage.append(pathConverter.toPath(key), listOf(pathConverter.toPath(value)))
|
||||
}
|
||||
|
||||
operator fun get(sourceFile: File): Collection<File> =
|
||||
storage[pathConverter.toPath(sourceFile)]?.map { pathConverter.toFile(it) } ?: setOf()
|
||||
|
||||
|
||||
@Synchronized
|
||||
operator fun set(key: File, values: Collection<File>) {
|
||||
if (values.isEmpty()) {
|
||||
remove(key)
|
||||
return
|
||||
}
|
||||
|
||||
storage[pathConverter.toPath(key)] = values.map { pathConverter.toPath(it) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun remove(key: File) {
|
||||
storage.remove(pathConverter.toPath(key))
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun removeValues(key: File, removed: Set<File>) {
|
||||
val notRemoved = this[key].filter { it !in removed }
|
||||
this[key] = notRemoved
|
||||
}
|
||||
}
|
||||
@@ -182,7 +182,7 @@ extra["versions.jflex"] = "1.7.0"
|
||||
extra["versions.markdown"] = "0.1.25"
|
||||
extra["versions.trove4j"] = "1.0.20181211"
|
||||
extra["versions.completion-ranking-kotlin"] = "0.1.3"
|
||||
extra["versions.r8"] = "2.1.96"
|
||||
extra["versions.r8"] = "2.2.64"
|
||||
val immutablesVersion = "0.3.1"
|
||||
extra["versions.kotlinx-collections-immutable"] = immutablesVersion
|
||||
extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
|
||||
@@ -1135,7 +1135,7 @@ fun Project.configureJvmProject(javaHome: String, javaVersion: String) {
|
||||
}
|
||||
|
||||
tasks.withType<KotlinCompile> {
|
||||
kotlinOptions.jdkHome = javaHome
|
||||
kotlinOptions.jdkHome = javaHome.takeUnless { kotlinBuildProperties.suppressJdkHomeWarning }
|
||||
kotlinOptions.jvmTarget = javaVersion
|
||||
kotlinOptions.freeCompilerArgs += "-Xjvm-default=compatibility"
|
||||
}
|
||||
|
||||
@@ -20,3 +20,5 @@ val KotlinBuildProperties.jarCompression: Boolean get() = getBoolean("kotlin.bui
|
||||
val KotlinBuildProperties.ignoreTestFailures: Boolean get() = getBoolean("ignoreTestFailures", isTeamcityBuild)
|
||||
|
||||
val KotlinBuildProperties.disableWerror: Boolean get() = getBoolean("kotlin.build.disable.werror", false)
|
||||
|
||||
val KotlinBuildProperties.suppressJdkHomeWarning: Boolean get() = getBoolean("kotlin.suppress.jdkHome.warning", false)
|
||||
|
||||
@@ -34,10 +34,10 @@ import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
||||
import org.jetbrains.kotlin.resolve.constants.*;
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil;
|
||||
import org.jetbrains.kotlin.types.FlexibleType;
|
||||
import org.jetbrains.kotlin.types.FlexibleTypesKt;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
@@ -376,7 +376,7 @@ public abstract class AnnotationCodegen {
|
||||
// We do not generate annotations whose classes are optional (annotated with `@OptionalExpectation`) because if an annotation entry
|
||||
// is resolved to the expected declaration, this means that annotation has no actual class, and thus should not be generated.
|
||||
// (Otherwise we would've resolved the entry to the actual annotation class.)
|
||||
if (ExpectedActualDeclarationChecker.isOptionalAnnotationClass(classDescriptor)) {
|
||||
if (OptionalAnnotationUtil.isOptionalAnnotationClass(classDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@ import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStat
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker;
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||
import org.jetbrains.kotlin.resolve.lazy.descriptors.PackageDescriptorUtilKt;
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil;
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments;
|
||||
import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
@@ -91,8 +91,8 @@ public class PackageCodegenImpl implements PackageCodegen {
|
||||
if (declaration instanceof KtClassOrObject) {
|
||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, declaration);
|
||||
if (PsiUtilsKt.hasExpectModifier(declaration)) {
|
||||
if (descriptor != null && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(descriptor)) {
|
||||
assert ExpectedActualDeclarationChecker.isOptionalAnnotationClass(descriptor) :
|
||||
if (descriptor != null && OptionalAnnotationUtil.shouldGenerateExpectClass(descriptor)) {
|
||||
assert OptionalAnnotationUtil.isOptionalAnnotationClass(descriptor) :
|
||||
"Expect class should be generated only if it's an optional annotation: " + descriptor;
|
||||
state.getFactory().getPackagePartRegistry().getOptionalAnnotations().add(descriptor);
|
||||
}
|
||||
|
||||
@@ -7,9 +7,7 @@ package org.jetbrains.kotlin.codegen.coroutines
|
||||
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE
|
||||
@@ -601,21 +599,6 @@ class CoroutineCodegenForLambda private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun isCapturedSuspendLambda(closure: CalculatedClosure, name: String, bindingContext: BindingContext): Boolean {
|
||||
for ((param, value) in closure.captureVariables) {
|
||||
if (param !is ValueParameterDescriptor) continue
|
||||
if (value.fieldName != name) continue
|
||||
return param.type.isSuspendFunctionTypeOrSubtype
|
||||
}
|
||||
val classDescriptor = closure.capturedOuterClassDescriptor ?: return false
|
||||
return isCapturedSuspendLambda(classDescriptor, name, bindingContext)
|
||||
}
|
||||
|
||||
fun isCapturedSuspendLambda(classDescriptor: ClassDescriptor, name: String, bindingContext: BindingContext): Boolean {
|
||||
val closure = bindingContext[CLOSURE, classDescriptor] ?: return false
|
||||
return isCapturedSuspendLambda(closure, name, bindingContext)
|
||||
}
|
||||
|
||||
private class AddEndLabelMethodVisitor(
|
||||
delegate: MethodVisitor,
|
||||
access: Int,
|
||||
|
||||
@@ -1276,16 +1276,13 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
||||
fun isAlive(insnIndex: Int, variableIndex: Int): Boolean =
|
||||
liveness[insnIndex].isAlive(variableIndex)
|
||||
|
||||
fun nextSuspensionPointEndLabel(insn: AbstractInsnNode): LabelNode {
|
||||
val suspensionPoint =
|
||||
InsnSequence(insn, method.instructions.last).firstOrNull { isAfterSuspendMarker(it) } ?: method.instructions.last
|
||||
return suspensionPoint as? LabelNode ?: suspensionPoint.findNextOrNull { it is LabelNode } as LabelNode
|
||||
}
|
||||
|
||||
fun nextSuspensionPointStartLabel(insn: AbstractInsnNode): LabelNode {
|
||||
val suspensionPoint =
|
||||
InsnSequence(insn, method.instructions.last).firstOrNull { isBeforeSuspendMarker(it) } ?: method.instructions.last
|
||||
return suspensionPoint as? LabelNode ?: suspensionPoint.findPreviousOrNull { it is LabelNode } as LabelNode
|
||||
fun nextLabel(node: AbstractInsnNode?): LabelNode? {
|
||||
var current = node
|
||||
while (current != null) {
|
||||
if (current is LabelNode) return current
|
||||
current = current.next
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun min(a: LabelNode, b: LabelNode): LabelNode =
|
||||
@@ -1294,9 +1291,6 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
||||
fun max(a: LabelNode, b: LabelNode): LabelNode =
|
||||
if (method.instructions.indexOf(a) < method.instructions.indexOf(b)) b else a
|
||||
|
||||
fun containsSuspensionPoint(a: LabelNode, b: LabelNode): Boolean =
|
||||
InsnSequence(min(a, b), max(a, b)).none { isBeforeSuspendMarker(it) }
|
||||
|
||||
val oldLvt = arrayListOf<LocalVariableNode>()
|
||||
for (record in method.localVariables) {
|
||||
oldLvt += record
|
||||
@@ -1317,35 +1311,40 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
||||
// No variable in LVT -> do not add one
|
||||
val lvtRecord = oldLvt.findRecord(insnIndex, variableIndex) ?: continue
|
||||
if (lvtRecord.name == CONTINUATION_VARIABLE_NAME) continue
|
||||
// Extend lvt record to the next suspension point
|
||||
val endLabel = min(lvtRecord.end, nextSuspensionPointEndLabel(insn))
|
||||
// End the local when it is no longer live. Since it is not live, we will not spill and unspill it across
|
||||
// suspension points. It is tempting to keep it alive until the next suspension point to leave it visible in
|
||||
// the debugger for as long as possible. However, in the case of loops, the resumption after suspension can
|
||||
// have a backwards edge targeting instruction between the point of death and the next suspension point.
|
||||
//
|
||||
// For example, code such as the following:
|
||||
//
|
||||
// listOf<String>.forEach {
|
||||
// yield(it)
|
||||
// }
|
||||
//
|
||||
// Generates code of this form with a back edge after resumption that will lead to invalid locals tables
|
||||
// if the local range is extended to the next suspension point.
|
||||
//
|
||||
// iterator = iterable.iterator()
|
||||
// L1: (iterable dies here)
|
||||
// load iterator.next if there
|
||||
// yield suspension point
|
||||
//
|
||||
// L2: (resumption point)
|
||||
// restore live variables (not including iterable)
|
||||
// goto L1 (iterator not restored here, so we cannot not have iterator live at L1)
|
||||
val endLabel = nextLabel(insn.next)?.let { min(lvtRecord.end, it) } ?: lvtRecord.end
|
||||
// startLabel can be null in case of parameters
|
||||
@Suppress("NAME_SHADOWING") val startLabel = startLabel ?: lvtRecord.start
|
||||
// Attempt to extend existing local variable node corresponding to the record in
|
||||
// the original local variable table.
|
||||
val recordToExtend: LocalVariableNode? = oldLvtNodeToLatestNewLvtNode[lvtRecord]
|
||||
if (recordToExtend != null && containsSuspensionPoint(recordToExtend.end, startLabel)) {
|
||||
recordToExtend.end = endLabel
|
||||
} else {
|
||||
val node = LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index)
|
||||
if (lvtRecord !in oldLvtNodeToLatestNewLvtNode) {
|
||||
method.localVariables.add(node)
|
||||
}
|
||||
oldLvtNodeToLatestNewLvtNode[lvtRecord] = node
|
||||
val node = LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index)
|
||||
if (lvtRecord !in oldLvtNodeToLatestNewLvtNode) {
|
||||
method.localVariables.add(node)
|
||||
}
|
||||
oldLvtNodeToLatestNewLvtNode[lvtRecord] = node
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val deadVariables = arrayListOf<Int>()
|
||||
outer@for (variableIndex in start until method.maxLocals) {
|
||||
if (oldLvt.none { it.index == variableIndex }) continue
|
||||
for (insnIndex in 0 until (method.instructions.size() - 1)) {
|
||||
if (isAlive(insnIndex, variableIndex)) continue@outer
|
||||
}
|
||||
deadVariables += variableIndex
|
||||
}
|
||||
|
||||
for (variable in oldLvt) {
|
||||
// $continuation and $result are dead, but they are used by debugger, as well as fake inliner variables
|
||||
// For example, $continuation is used to create async stack trace
|
||||
@@ -1361,19 +1360,5 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
||||
method.localVariables.add(variable)
|
||||
continue
|
||||
}
|
||||
|
||||
// Shrink LVT records of dead variables to the next suspension point
|
||||
if (variable.index in deadVariables) {
|
||||
method.localVariables.add(
|
||||
LocalVariableNode(
|
||||
variable.name,
|
||||
variable.desc,
|
||||
variable.signature,
|
||||
variable.start,
|
||||
min(variable.end, nextSuspensionPointStartLabel(variable.start)),
|
||||
variable.index
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
|
||||
Pair(it, typeArguments[candidateDescriptor.typeParameters[it.index]]!!.asTypeProjection())
|
||||
}.toMap()
|
||||
|
||||
newCall.setResultingSubstitutor(
|
||||
newCall.setSubstitutor(
|
||||
TypeConstructorSubstitution.createByParametersMap(newTypeArguments).buildSubstitutor()
|
||||
)
|
||||
|
||||
|
||||
@@ -547,7 +547,7 @@ class AnonymousObjectTransformer(
|
||||
capturedParamBuilder.addCapturedParam(desc, desc.fieldName, !capturedOuterThisTypes.add(desc.type.className))
|
||||
else
|
||||
capturedParamBuilder.addCapturedParam(desc, addUniqueField(desc.fieldName + INLINE_TRANSFORMATION_SUFFIX), false)
|
||||
if (info is ExpressionLambda && info.isCapturedSuspend(desc)) {
|
||||
if (desc.isSuspend) {
|
||||
recapturedParamInfo.functionalArgument = NonInlineableArgumentForInlineableParameterCalledInSuspend
|
||||
}
|
||||
val composed = StackValue.field(
|
||||
|
||||
@@ -18,8 +18,6 @@ package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
|
||||
class CapturedParamDesc(private val containingLambdaType: Type, val fieldName: String, val type: Type) {
|
||||
|
||||
val containingLambdaName: String
|
||||
get() = containingLambdaType.internalName
|
||||
class CapturedParamDesc(containingLambdaType: Type, val fieldName: String, val type: Type, val isSuspend: Boolean = false) {
|
||||
val containingLambdaName: String = containingLambdaType.internalName
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.codegen.inline
|
||||
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -53,7 +52,7 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
||||
val field = remapper.findField(FieldInsnNode(0, info.containingLambdaName, info.fieldName, ""))
|
||||
?: error("Captured field not found: " + info.containingLambdaName + "." + info.fieldName)
|
||||
val recapturedParamInfo = builder.addCapturedParam(field, info.fieldName)
|
||||
if (this is ExpressionLambda && isCapturedSuspend(info)) {
|
||||
if (info.isSuspend) {
|
||||
recapturedParamInfo.functionalArgument = NonInlineableArgumentForInlineableParameterCalledInSuspend
|
||||
}
|
||||
}
|
||||
@@ -61,14 +60,9 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
|
||||
return builder.buildParameters()
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
fun LambdaInfo.getCapturedParamInfo(descriptor: EnclosedValueDescriptor): CapturedParamDesc {
|
||||
return capturedParamDesc(descriptor.fieldName, descriptor.type)
|
||||
}
|
||||
|
||||
fun LambdaInfo.capturedParamDesc(fieldName: String, fieldType: Type): CapturedParamDesc {
|
||||
return CapturedParamDesc(lambdaClassType, fieldName, fieldType)
|
||||
fun LambdaInfo.capturedParamDesc(fieldName: String, fieldType: Type, isSuspend: Boolean): CapturedParamDesc {
|
||||
return CapturedParamDesc(lambdaClassType, fieldName, fieldType, isSuspend)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -81,8 +75,6 @@ abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInli
|
||||
node = sourceCompiler.generateLambdaBody(this, reifiedTypeParametersUsages)
|
||||
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
|
||||
}
|
||||
|
||||
abstract fun isCapturedSuspend(desc: CapturedParamDesc): Boolean
|
||||
}
|
||||
|
||||
abstract class DefaultLambda(
|
||||
@@ -123,11 +115,11 @@ abstract class DefaultLambda(
|
||||
if (isFunctionReference || isPropertyReference)
|
||||
constructor?.desc?.let { Type.getArgumentTypes(it) }?.singleOrNull()?.let {
|
||||
originalBoundReceiverType = it
|
||||
listOf(capturedParamDesc(AsmUtil.RECEIVER_PARAMETER_NAME, AsmUtil.boxType(it)))
|
||||
listOf(capturedParamDesc(AsmUtil.RECEIVER_PARAMETER_NAME, AsmUtil.boxType(it), isSuspend = false))
|
||||
} ?: emptyList()
|
||||
else
|
||||
constructor?.findCapturedFieldAssignmentInstructions()?.map { fieldNode ->
|
||||
capturedParamDesc(fieldNode.name, Type.getType(fieldNode.desc))
|
||||
capturedParamDesc(fieldNode.name, Type.getType(fieldNode.desc), isSuspend = false)
|
||||
}?.toList() ?: emptyList()
|
||||
isBoundCallableReference = (isFunctionReference || isPropertyReference) && capturedVars.isNotEmpty()
|
||||
|
||||
|
||||
@@ -11,9 +11,7 @@ import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getMethodAsmFlags
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor
|
||||
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isCapturedSuspendLambda
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
@@ -299,42 +297,27 @@ class PsiExpressionLambda(
|
||||
arrayListOf<CapturedParamDesc>().apply {
|
||||
val captureThis = closure.capturedOuterClassDescriptor
|
||||
if (captureThis != null) {
|
||||
val kotlinType = captureThis.defaultType
|
||||
val type = typeMapper.mapType(kotlinType)
|
||||
val descriptor = EnclosedValueDescriptor(
|
||||
AsmUtil.CAPTURED_THIS_FIELD, null,
|
||||
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_THIS_FIELD, false, StackValue.LOCAL_0),
|
||||
type, kotlinType
|
||||
)
|
||||
add(getCapturedParamInfo(descriptor))
|
||||
add(capturedParamDesc(AsmUtil.CAPTURED_THIS_FIELD, typeMapper.mapType(captureThis.defaultType), isSuspend = false))
|
||||
}
|
||||
|
||||
val capturedReceiver = closure.capturedReceiverFromOuterContext
|
||||
if (capturedReceiver != null) {
|
||||
val fieldName = closure.getCapturedReceiverFieldName(typeMapper.bindingContext, languageVersionSettings)
|
||||
val type = typeMapper.mapType(capturedReceiver).let {
|
||||
if (isBoundCallableReference) AsmUtil.boxType(it) else it
|
||||
}
|
||||
|
||||
val fieldName = closure.getCapturedReceiverFieldName(typeMapper.bindingContext, languageVersionSettings)
|
||||
val descriptor = EnclosedValueDescriptor(
|
||||
fieldName, null,
|
||||
StackValue.field(type, capturedReceiver, lambdaClassType, fieldName, false, StackValue.LOCAL_0),
|
||||
type, capturedReceiver
|
||||
)
|
||||
add(getCapturedParamInfo(descriptor))
|
||||
add(capturedParamDesc(fieldName, type, isSuspend = false))
|
||||
}
|
||||
|
||||
closure.captureVariables.values.forEach { descriptor ->
|
||||
add(getCapturedParamInfo(descriptor))
|
||||
closure.captureVariables.forEach { (parameter, value) ->
|
||||
val isSuspend = parameter is ValueParameterDescriptor && parameter.type.isSuspendFunctionTypeOrSubtype
|
||||
add(capturedParamDesc(value.fieldName, value.type, isSuspend))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val isPropertyReference: Boolean
|
||||
get() = propertyReferenceInfo != null
|
||||
|
||||
override fun isCapturedSuspend(desc: CapturedParamDesc): Boolean =
|
||||
isCapturedSuspendLambda(closure, desc.fieldName, typeMapper.bindingContext)
|
||||
}
|
||||
|
||||
class PsiDefaultLambda(
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
package org.jetbrains.kotlin.codegen.inline.coroutines
|
||||
|
||||
import com.intellij.util.ArrayUtil
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilder
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||
import org.jetbrains.kotlin.codegen.coroutines.*
|
||||
import org.jetbrains.kotlin.codegen.inline.*
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
@@ -15,6 +17,7 @@ import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
@@ -250,7 +253,18 @@ fun FieldInsnNode.isSuspendLambdaCapturedByOuterObjectOrLambda(inliningContext:
|
||||
while (container !is ClassDescriptor) {
|
||||
container = container.containingDeclaration ?: return false
|
||||
}
|
||||
return isCapturedSuspendLambda(container, name, inliningContext.state.bindingContext)
|
||||
val bindingContext = inliningContext.state.bindingContext
|
||||
var classDescriptor: ClassDescriptor? = container
|
||||
while (classDescriptor != null) {
|
||||
val closure = bindingContext[CodegenBinding.CLOSURE, classDescriptor] ?: return false
|
||||
for ((param, value) in closure.captureVariables) {
|
||||
if (param is ValueParameterDescriptor && value.fieldName == name) {
|
||||
return param.type.isSuspendFunctionTypeOrSubtype
|
||||
}
|
||||
}
|
||||
classDescriptor = closure.capturedOuterClassDescriptor
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Interpreter, that keeps track of captured functional arguments
|
||||
|
||||
@@ -17,12 +17,9 @@
|
||||
package org.jetbrains.kotlin.codegen.optimization.boxing
|
||||
|
||||
import org.jetbrains.kotlin.codegen.optimization.OptimizationMethodVisitor
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.debugText
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.isLoadOperation
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.peekWords
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
|
||||
import org.jetbrains.kotlin.codegen.optimization.removeNodeGetNext
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
@@ -32,91 +29,66 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
|
||||
import java.util.*
|
||||
|
||||
private typealias Transformation = (AbstractInsnNode) -> Unit
|
||||
|
||||
class PopBackwardPropagationTransformer : MethodTransformer() {
|
||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
if (!OptimizationMethodVisitor.canBeOptimizedUsingSourceInterpreter(methodNode)) return
|
||||
Transformer(methodNode).transform()
|
||||
if (methodNode.instructions.any { it.isPop() || it.isPurePush() }) {
|
||||
Transformer(methodNode).transform()
|
||||
}
|
||||
}
|
||||
|
||||
private class Transformer(val methodNode: MethodNode) {
|
||||
private interface Transformation {
|
||||
fun apply(insn: AbstractInsnNode)
|
||||
}
|
||||
|
||||
private inline fun Transformation(crossinline body: (AbstractInsnNode) -> Unit): Transformation =
|
||||
object : Transformation {
|
||||
override fun apply(insn: AbstractInsnNode) {
|
||||
body(insn)
|
||||
}
|
||||
}
|
||||
|
||||
private val REPLACE_WITH_NOP = Transformation { insnList.set(it, createRemovableNopInsn()) }
|
||||
private val REPLACE_WITH_POP1 = Transformation { insnList.set(it, InsnNode(Opcodes.POP)) }
|
||||
private val REPLACE_WITH_POP2 = Transformation { insnList.set(it, InsnNode(Opcodes.POP2)) }
|
||||
private val INSERT_POP1_AFTER = Transformation { insnList.insert(it, InsnNode(Opcodes.POP)) }
|
||||
private val INSERT_POP2_AFTER = Transformation { insnList.insert(it, InsnNode(Opcodes.POP2)) }
|
||||
private val REPLACE_WITH_NOP: Transformation = { insnList.set(it, InsnNode(Opcodes.NOP)) }
|
||||
private val REPLACE_WITH_POP1: Transformation = { insnList.set(it, InsnNode(Opcodes.POP)) }
|
||||
private val REPLACE_WITH_POP2: Transformation = { insnList.set(it, InsnNode(Opcodes.POP2)) }
|
||||
private val INSERT_POP1_AFTER: Transformation = { insnList.insert(it, InsnNode(Opcodes.POP)) }
|
||||
private val INSERT_POP2_AFTER: Transformation = { insnList.insert(it, InsnNode(Opcodes.POP2)) }
|
||||
|
||||
private val insnList = methodNode.instructions
|
||||
|
||||
private val insns = insnList.toArray()
|
||||
|
||||
private val dontTouchInsnIndices = BitSet(insns.size)
|
||||
private val transformations = hashMapOf<AbstractInsnNode, Transformation>()
|
||||
private val removableNops = hashSetOf<InsnNode>()
|
||||
|
||||
private val frames by lazy { analyzeMethodBody() }
|
||||
|
||||
fun transform() {
|
||||
if (insns.none { it.isPop() || it.isPurePush() }) return
|
||||
|
||||
computeTransformations()
|
||||
for ((insn, transformation) in transformations.entries) {
|
||||
transformation.apply(insn)
|
||||
}
|
||||
postprocessNops()
|
||||
}
|
||||
|
||||
private fun analyzeMethodBody(): Array<out Frame<SourceValue>?> {
|
||||
val frames = Analyzer<SourceValue>(HazardsTrackingInterpreter()).analyze("fake", methodNode)
|
||||
|
||||
postprocessStackHazards(frames)
|
||||
|
||||
return frames
|
||||
}
|
||||
|
||||
private fun postprocessStackHazards(frames: Array<out Frame<SourceValue>?>) {
|
||||
val insns = methodNode.instructions.toArray()
|
||||
for (i in frames.indices) {
|
||||
val frames = Analyzer(HazardsTrackingInterpreter()).analyze("fake", methodNode)
|
||||
for ((i, insn) in insns.withIndex()) {
|
||||
val frame = frames[i] ?: continue
|
||||
val insn = insns[i]
|
||||
|
||||
when (insn.opcode) {
|
||||
Opcodes.POP2 -> {
|
||||
val top2 = frame.peekWords(2) ?: throwIncorrectBytecode(insn, frame)
|
||||
top2.forEach { it.insns.markAsDontTouch() }
|
||||
}
|
||||
Opcodes.DUP_X1 -> {
|
||||
val top2 = frame.peekWords(1, 1) ?: throwIncorrectBytecode(insn, frame)
|
||||
top2.forEach { it.insns.markAsDontTouch() }
|
||||
}
|
||||
Opcodes.DUP2_X1 -> {
|
||||
val top3 = frame.peekWords(2, 1) ?: throwIncorrectBytecode(insn, frame)
|
||||
top3.forEach { it.insns.markAsDontTouch() }
|
||||
}
|
||||
Opcodes.DUP_X2 -> {
|
||||
val top3 = frame.peekWords(1, 2) ?: throwIncorrectBytecode(insn, frame)
|
||||
top3.forEach { it.insns.markAsDontTouch() }
|
||||
}
|
||||
Opcodes.DUP2_X2 -> {
|
||||
val top4 = frame.peekWords(2, 2) ?: throwIncorrectBytecode(insn, frame)
|
||||
top4.forEach { it.insns.markAsDontTouch() }
|
||||
Opcodes.POP ->
|
||||
frame.top()?.let { input ->
|
||||
// If this POP won't be removed, other POPs that touch the same values have to stay as well.
|
||||
if (input.insns.any { it.shouldKeep() } || input.longerWhenFusedWithPop()) {
|
||||
input.insns.markAsDontTouch()
|
||||
}
|
||||
}
|
||||
Opcodes.POP2 -> frame.peekWords(2)?.forEach { it.insns.markAsDontTouch() }
|
||||
Opcodes.DUP_X1 -> frame.peekWords(1, 1)?.forEach { it.insns.markAsDontTouch() }
|
||||
Opcodes.DUP2_X1 -> frame.peekWords(2, 1)?.forEach { it.insns.markAsDontTouch() }
|
||||
Opcodes.DUP_X2 -> frame.peekWords(1, 2)?.forEach { it.insns.markAsDontTouch() }
|
||||
Opcodes.DUP2_X2 -> frame.peekWords(2, 2)?.forEach { it.insns.markAsDontTouch() }
|
||||
}
|
||||
}
|
||||
|
||||
val transformations = hashMapOf<AbstractInsnNode, Transformation>()
|
||||
for ((i, insn) in insns.withIndex()) {
|
||||
val frame = frames[i] ?: continue
|
||||
if (insn.opcode == Opcodes.POP) {
|
||||
val input = frame.top() ?: continue
|
||||
if (input.insns.none { it.shouldKeep() }) {
|
||||
transformations[insn] = REPLACE_WITH_NOP
|
||||
input.insns.forEach {
|
||||
if (it !in transformations) {
|
||||
transformations[it] = it.combineWithPop(frames, input.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun throwIncorrectBytecode(insn: AbstractInsnNode?, frame: Frame<SourceValue>): Nothing {
|
||||
throw AssertionError("Incorrect bytecode at ${methodNode.instructions.indexOf(insn)}: ${insn.debugText} $frame")
|
||||
for ((insn, transformation) in transformations.entries) {
|
||||
transformation(insn)
|
||||
}
|
||||
}
|
||||
|
||||
private inner class HazardsTrackingInterpreter : SourceInterpreter(Opcodes.API_VERSION) {
|
||||
@@ -133,9 +105,7 @@ class PopBackwardPropagationTransformer : MethodTransformer() {
|
||||
}
|
||||
|
||||
override fun unaryOperation(insn: AbstractInsnNode, value: SourceValue): SourceValue {
|
||||
if (insn.opcode != Opcodes.CHECKCAST && !insn.isPrimitiveTypeConversion()) {
|
||||
value.insns.markAsDontTouch()
|
||||
}
|
||||
value.insns.markAsDontTouch()
|
||||
return super.unaryOperation(insn, value)
|
||||
}
|
||||
|
||||
@@ -164,153 +134,48 @@ class PopBackwardPropagationTransformer : MethodTransformer() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun computeTransformations() {
|
||||
transformations.clear()
|
||||
|
||||
for (i in insns.indices) {
|
||||
if (frames[i] == null) continue
|
||||
val insn = insns[i]
|
||||
|
||||
if (insn.opcode == Opcodes.POP) {
|
||||
propagatePopBackwards(insn, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun propagatePopBackwards(insn: AbstractInsnNode, poppedValueSize: Int) {
|
||||
if (transformations.containsKey(insn)) return
|
||||
|
||||
private fun SourceValue.longerWhenFusedWithPop() = insns.fold(0) { x, insn ->
|
||||
when {
|
||||
insn.opcode == Opcodes.POP -> {
|
||||
val inputTop = getInputTop(insn)
|
||||
val sources = inputTop.insns
|
||||
if (sources.all { !isDontTouch(it) } && sources.any { isTransformablePopOperand(it) }) {
|
||||
transformations[insn] = replaceWithNopTransformation()
|
||||
sources.forEach { propagatePopBackwards(it, inputTop.size) }
|
||||
insn.isPurePush() -> x - 1
|
||||
insn.isPrimitiveBoxing() || insn.isPrimitiveTypeConversion() -> x
|
||||
else -> x + 1
|
||||
}
|
||||
} > 0
|
||||
|
||||
private fun AbstractInsnNode.combineWithPop(frames: Array<out Frame<SourceValue>?>, resultSize: Int): Transformation =
|
||||
when {
|
||||
isPurePush() -> REPLACE_WITH_NOP
|
||||
isPrimitiveBoxing() || isPrimitiveTypeConversion() -> {
|
||||
val index = insnList.indexOf(this)
|
||||
val frame = frames[index] ?: throw AssertionError("dead instruction #$index used by non-dead instruction")
|
||||
val input = frame.top() ?: throw AssertionError("coercion instruction at #$index has no input")
|
||||
when (input.size) {
|
||||
1 -> REPLACE_WITH_POP1
|
||||
2 -> REPLACE_WITH_POP2
|
||||
else -> throw AssertionError("Unexpected pop value size: ${input.size}")
|
||||
}
|
||||
}
|
||||
|
||||
insn.opcode == Opcodes.CHECKCAST -> {
|
||||
val inputTop = getInputTop(insn)
|
||||
val sources = inputTop.insns
|
||||
val resultType = (insn as TypeInsnNode).desc
|
||||
if (sources.all { !isDontTouch(it) } && sources.any { isTransformableCheckcastOperand(it, resultType) }) {
|
||||
transformations[insn] = replaceWithNopTransformation()
|
||||
sources.forEach { propagatePopBackwards(it, inputTop.size) }
|
||||
} else {
|
||||
transformations[insn] = insertPopAfterTransformation(poppedValueSize)
|
||||
else ->
|
||||
when (resultSize) {
|
||||
1 -> INSERT_POP1_AFTER
|
||||
2 -> INSERT_POP2_AFTER
|
||||
else -> throw AssertionError("Unexpected pop value size: $resultSize")
|
||||
}
|
||||
}
|
||||
|
||||
insn.isPrimitiveBoxing() -> {
|
||||
val boxedValueSize = getInputTop(insn).size
|
||||
transformations[insn] = replaceWithPopTransformation(boxedValueSize)
|
||||
}
|
||||
|
||||
insn.isPurePush() -> {
|
||||
transformations[insn] = replaceWithNopTransformation()
|
||||
}
|
||||
|
||||
insn.isPrimitiveTypeConversion() -> {
|
||||
val inputTop = getInputTop(insn)
|
||||
val sources = inputTop.insns
|
||||
if (sources.all { !isDontTouch(it) }) {
|
||||
transformations[insn] = replaceWithNopTransformation()
|
||||
sources.forEach { propagatePopBackwards(it, inputTop.size) }
|
||||
} else {
|
||||
transformations[insn] = replaceWithPopTransformation(poppedValueSize)
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
transformations[insn] = insertPopAfterTransformation(poppedValueSize)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun postprocessNops() {
|
||||
var node: AbstractInsnNode? = insnList.first
|
||||
var hasRemovableNops = false
|
||||
while (node != null) {
|
||||
node = node.next
|
||||
val begin = node ?: break
|
||||
while (node != null && node !is LabelNode) {
|
||||
if (node in removableNops) {
|
||||
hasRemovableNops = true
|
||||
}
|
||||
node = node.next
|
||||
}
|
||||
val end = node
|
||||
if (hasRemovableNops) {
|
||||
removeUnneededNopsInRange(begin, end)
|
||||
}
|
||||
hasRemovableNops = false
|
||||
}
|
||||
}
|
||||
|
||||
private fun removeUnneededNopsInRange(begin: AbstractInsnNode, end: AbstractInsnNode?) {
|
||||
var node: AbstractInsnNode? = begin
|
||||
var keepNop = true
|
||||
while (node != null && node != end) {
|
||||
if (node in removableNops && !keepNop) {
|
||||
node = insnList.removeNodeGetNext(node)
|
||||
} else {
|
||||
if (node.isMeaningful) keepNop = false
|
||||
node = node.next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun replaceWithPopTransformation(size: Int): Transformation =
|
||||
when (size) {
|
||||
1 -> REPLACE_WITH_POP1
|
||||
2 -> REPLACE_WITH_POP2
|
||||
else -> throw AssertionError("Unexpected pop value size: $size")
|
||||
}
|
||||
|
||||
private fun insertPopAfterTransformation(size: Int): Transformation =
|
||||
when (size) {
|
||||
1 -> INSERT_POP1_AFTER
|
||||
2 -> INSERT_POP2_AFTER
|
||||
else -> throw AssertionError("Unexpected pop value size: $size")
|
||||
}
|
||||
|
||||
private fun replaceWithNopTransformation(): Transformation =
|
||||
REPLACE_WITH_NOP
|
||||
|
||||
private fun createRemovableNopInsn() =
|
||||
InsnNode(Opcodes.NOP).apply { removableNops.add(this) }
|
||||
|
||||
private fun getInputTop(insn: AbstractInsnNode): SourceValue {
|
||||
val i = insnList.indexOf(insn)
|
||||
val frame = frames[i] ?: throw AssertionError("Unexpected dead instruction #$i")
|
||||
return frame.top() ?: throw AssertionError("Instruction #$i has empty stack on input")
|
||||
}
|
||||
|
||||
private fun isTransformableCheckcastOperand(it: AbstractInsnNode, resultType: String) =
|
||||
it.isPrimitiveBoxing() && (it as MethodInsnNode).owner == resultType
|
||||
|
||||
private fun isTransformablePopOperand(insn: AbstractInsnNode) =
|
||||
insn.opcode == Opcodes.CHECKCAST || insn.isPrimitiveBoxing() || insn.isPurePush()
|
||||
|
||||
private fun isDontTouch(insn: AbstractInsnNode) =
|
||||
dontTouchInsnIndices[insnList.indexOf(insn)]
|
||||
private fun AbstractInsnNode.shouldKeep() =
|
||||
dontTouchInsnIndices[insnList.indexOf(this)]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun AbstractInsnNode.isPurePush() =
|
||||
isLoadOperation() ||
|
||||
opcode in Opcodes.ACONST_NULL..Opcodes.LDC + 2 ||
|
||||
isUnitInstance()
|
||||
isLoadOperation() || opcode in Opcodes.ACONST_NULL..Opcodes.LDC + 2 || isUnitInstance()
|
||||
|
||||
fun AbstractInsnNode.isPop() =
|
||||
opcode == Opcodes.POP || opcode == Opcodes.POP2
|
||||
|
||||
fun AbstractInsnNode.isUnitInstance() =
|
||||
opcode == Opcodes.GETSTATIC &&
|
||||
this is FieldInsnNode && owner == "kotlin/Unit" && name == "INSTANCE"
|
||||
opcode == Opcodes.GETSTATIC && this is FieldInsnNode && owner == "kotlin/Unit" && name == "INSTANCE"
|
||||
|
||||
fun AbstractInsnNode.isPrimitiveTypeConversion() =
|
||||
opcode in Opcodes.I2L..Opcodes.I2S
|
||||
|
||||
@@ -19,14 +19,12 @@ package org.jetbrains.kotlin.codegen.optimization.boxing
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.findPreviousOrNull
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.InsnList
|
||||
import org.jetbrains.org.objectweb.asm.tree.InsnNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
|
||||
class StackPeepholeOptimizationsTransformer : MethodTransformer() {
|
||||
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||
while (transformOnce(methodNode)) {
|
||||
while (true) {
|
||||
if (!transformOnce(methodNode)) break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,20 +113,26 @@ class StackPeepholeOptimizationsTransformer : MethodTransformer() {
|
||||
opcode == Opcodes.DUP
|
||||
|
||||
private fun AbstractInsnNode.isPurePushOfSize1(): Boolean =
|
||||
opcode in Opcodes.ACONST_NULL..Opcodes.FCONST_2 ||
|
||||
opcode in Opcodes.BIPUSH..Opcodes.ILOAD ||
|
||||
opcode == Opcodes.FLOAD ||
|
||||
opcode == Opcodes.ALOAD ||
|
||||
isUnitInstance()
|
||||
!isLdcOfSize2() && (
|
||||
opcode in Opcodes.ACONST_NULL..Opcodes.FCONST_2 ||
|
||||
opcode in Opcodes.BIPUSH..Opcodes.ILOAD ||
|
||||
opcode == Opcodes.FLOAD ||
|
||||
opcode == Opcodes.ALOAD ||
|
||||
isUnitInstance()
|
||||
)
|
||||
|
||||
private fun AbstractInsnNode.isEliminatedByPop2() =
|
||||
isPurePushOfSize2() ||
|
||||
opcode == Opcodes.DUP2
|
||||
|
||||
private fun AbstractInsnNode.isPurePushOfSize2(): Boolean =
|
||||
opcode == Opcodes.LCONST_0 || opcode == Opcodes.LCONST_1 ||
|
||||
isLdcOfSize2() ||
|
||||
opcode == Opcodes.LCONST_0 || opcode == Opcodes.LCONST_1 ||
|
||||
opcode == Opcodes.DCONST_0 || opcode == Opcodes.DCONST_1 ||
|
||||
opcode == Opcodes.LLOAD ||
|
||||
opcode == Opcodes.DLOAD
|
||||
|
||||
private fun AbstractInsnNode.isLdcOfSize2(): Boolean =
|
||||
opcode == Opcodes.LDC && this is LdcInsnNode && (this.cst is Double || this.cst is Long)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,4 +29,7 @@ class JvmCodegenStringTable @JvmOverloads constructor(
|
||||
ClassId(fqName.parent(), FqName.topLevel(fqName.shortName()), true)
|
||||
}
|
||||
}
|
||||
|
||||
override val isLocalClassIdReplacementKeptGeneric: Boolean
|
||||
get() = true
|
||||
}
|
||||
|
||||
@@ -21,7 +21,10 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JvmModulePathRoot
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||
import org.jetbrains.kotlin.codegen.CodegenFactory
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
@@ -130,6 +133,7 @@ object FirKotlinToJvmBytecodeCompiler {
|
||||
getPackagePartProvider = { environment.createPackagePartProvider(it) },
|
||||
dependenciesConfigurator = {
|
||||
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
|
||||
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
|
||||
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
|
||||
},
|
||||
sessionConfigurator = {
|
||||
|
||||
@@ -13,7 +13,6 @@ plugins {
|
||||
dependencies {
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core", "guava", rootProject = rootProject) }
|
||||
|
||||
testApi(intellijDep())
|
||||
testApi(projectTests(":compiler:test-infrastructure"))
|
||||
testApi(projectTests(":compiler:test-infrastructure-utils"))
|
||||
testApi(projectTests(":compiler:tests-compiler-utils"))
|
||||
|
||||
@@ -81,7 +81,7 @@ public final class CharRange : R|kotlin/ranges/CharProgression|, R|kotlin/ranges
|
||||
|
||||
}
|
||||
|
||||
public abstract interface ClosedRange<T> : R|kotlin/Any| {
|
||||
public abstract interface ClosedRange<T : R|kotlin/Comparable<T>|> : R|kotlin/Any| {
|
||||
public open operator fun contains(value: R|T|): R|kotlin/Boolean|
|
||||
|
||||
public open fun isEmpty(): R|kotlin/Boolean|
|
||||
|
||||
@@ -12,9 +12,9 @@ public final fun doubleArrayOf(vararg elements: R|kotlin/DoubleArray|): R|kotlin
|
||||
|
||||
public final inline fun <reified T> emptyArray(): R|kotlin/Array<T>|
|
||||
|
||||
@R|kotlin/SinceKotlin|(version = String(1.1)) public final inline fun <reified T> enumValueOf(name: R|kotlin/String|): R|T|
|
||||
@R|kotlin/SinceKotlin|(version = String(1.1)) public final inline fun <reified T : R|kotlin/Enum<T>|> enumValueOf(name: R|kotlin/String|): R|T|
|
||||
|
||||
@R|kotlin/SinceKotlin|(version = String(1.1)) public final inline fun <reified T> enumValues(): R|kotlin/Array<T>|
|
||||
@R|kotlin/SinceKotlin|(version = String(1.1)) public final inline fun <reified T : R|kotlin/Enum<T>|> enumValues(): R|kotlin/Array<T>|
|
||||
|
||||
public final fun floatArrayOf(vararg elements: R|kotlin/FloatArray|): R|kotlin/FloatArray|
|
||||
|
||||
@@ -529,7 +529,7 @@ public final class DoubleArray : R|kotlin/Any|, R|kotlin/Cloneable|, R|java/io/S
|
||||
|
||||
}
|
||||
|
||||
public abstract class Enum<E> : R|kotlin/Comparable<E>|, R|java/io/Serializable| {
|
||||
public abstract class Enum<E : R|kotlin/Enum<E>|> : R|kotlin/Comparable<E>|, R|java/io/Serializable| {
|
||||
public final companion object Companion : R|kotlin/Any| {
|
||||
private constructor(): R|kotlin/Enum.Companion|
|
||||
|
||||
@@ -551,7 +551,7 @@ public abstract class Enum<E> : R|kotlin/Comparable<E>|, R|java/io/Serializable|
|
||||
public final val ordinal: R|kotlin/Int|
|
||||
public get(): R|kotlin/Int|
|
||||
|
||||
public constructor<E>(name: R|kotlin/String| = STUB, ordinal: R|kotlin/Int| = STUB): R|kotlin/Enum<E>|
|
||||
public constructor<E : R|kotlin/Enum<E>|>(name: R|kotlin/String| = STUB, ordinal: R|kotlin/Int| = STUB): R|kotlin/Enum<E>|
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
fun test(
|
||||
val f: String.() -> Int = { length }
|
||||
f: String.() -> Int = { length }
|
||||
): Int {
|
||||
return "".f()
|
||||
}
|
||||
|
||||
@@ -3,5 +3,5 @@ interface <!CONSTRUCTOR_IN_INTERFACE!>A(val s: String)<!>
|
||||
interface <!CONSTRUCTOR_IN_INTERFACE!>B constructor(val s: String)<!>
|
||||
|
||||
interface C {
|
||||
<!CONSTRUCTOR_IN_INTERFACE!>constructor(val s: String)<!> {}
|
||||
<!CONSTRUCTOR_IN_INTERFACE!>constructor(s: String)<!> {}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
interface List<out T : Any> {
|
||||
operator fun get(index: Int): T
|
||||
|
||||
infix fun concat(other: List<T>): List<T>
|
||||
infix fun concat(other: List<<!TYPE_VARIANCE_CONFLICT!>T<!>>): List<T>
|
||||
}
|
||||
|
||||
typealias StringList = List<out String>
|
||||
|
||||
@@ -5,7 +5,7 @@ FILE: kt40131.kt
|
||||
}
|
||||
public final val <T : R|kotlin/reflect/KClass<*>|> R|T|.myJava1: R|java/lang/Class<*>|
|
||||
public get(): R|java/lang/Class<*>| {
|
||||
^ this@R|/myJava1|.R|/javaImpl|<R|kotlin/Any?|>
|
||||
^ this@R|/myJava1|.R|/javaImpl|<R|kotlin/Any|>
|
||||
}
|
||||
public final val <E : R|kotlin/Any|, T : R|kotlin/reflect/KClass<E>|> R|T|.myJava2: R|java/lang/Class<E>|
|
||||
public get(): R|java/lang/Class<E>| {
|
||||
|
||||
@@ -6,7 +6,7 @@ val <U> KClass<U>.javaImpl: Class<U>
|
||||
get() = null!!
|
||||
|
||||
val <T : KClass<*>> T.myJava1: Class<*>
|
||||
get() = <!DEBUG_INFO_EXPRESSION_TYPE("java.lang.Class<out kotlin.Any?>")!>javaImpl<!>
|
||||
get() = <!DEBUG_INFO_EXPRESSION_TYPE("java.lang.Class<out kotlin.Any>")!>javaImpl<!>
|
||||
|
||||
val <E : Any, T : KClass<E>> T.myJava2: Class<E>
|
||||
get() = <!DEBUG_INFO_EXPRESSION_TYPE("java.lang.Class<E>")!>javaImpl<!>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// !WITH_NEW_INFERENCE
|
||||
|
||||
fun <R> myRun(b: () -> R): R = b()
|
||||
|
||||
|
||||
@@ -492,11 +492,11 @@ digraph nullability_kt {
|
||||
176 [label="Access variable R|/Q.data|"];
|
||||
177 [label="Access variable R|<local>/q|"];
|
||||
178 [label="Access variable R|/Q.data|"];
|
||||
179 [label="Access variable <Inapplicable(UNSAFE_CALL): /MyData.s>#"];
|
||||
179 [label="Access variable <Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#"];
|
||||
180 [label="Access variable R|<local>/q|"];
|
||||
181 [label="Access variable R|/Q.data|"];
|
||||
182 [label="Access variable <Inapplicable(UNSAFE_CALL): /MyData.s>#"];
|
||||
183 [label="Function call: R|<local>/q|.R|/Q.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#.R|kotlin/Int.inc|()"];
|
||||
182 [label="Access variable <Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#"];
|
||||
183 [label="Function call: R|<local>/q|.R|/Q.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#.R|kotlin/Int.inc|()"];
|
||||
184 [label="Exit block"];
|
||||
}
|
||||
185 [label="Exit when branch result"];
|
||||
@@ -566,11 +566,11 @@ digraph nullability_kt {
|
||||
208 [label="Access variable R|/Q.data|"];
|
||||
209 [label="Access variable R|<local>/q|"];
|
||||
210 [label="Access variable R|/Q.data|"];
|
||||
211 [label="Access variable <Inapplicable(UNSAFE_CALL): /MyData.s>#"];
|
||||
211 [label="Access variable <Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#"];
|
||||
212 [label="Access variable R|<local>/q|"];
|
||||
213 [label="Access variable R|/Q.data|"];
|
||||
214 [label="Access variable <Inapplicable(UNSAFE_CALL): /MyData.s>#"];
|
||||
215 [label="Function call: R|<local>/q|.R|/Q.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#.R|kotlin/Int.inc|()"];
|
||||
214 [label="Access variable <Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#"];
|
||||
215 [label="Function call: R|<local>/q|.R|/Q.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#.R|kotlin/Int.inc|()"];
|
||||
216 [label="Exit block"];
|
||||
}
|
||||
217 [label="Exit function test_6" style="filled" fillcolor=red];
|
||||
@@ -1280,11 +1280,11 @@ digraph nullability_kt {
|
||||
490 [label="Access variable R|/QImplWithCustomGetter.data|"];
|
||||
491 [label="Access variable R|<local>/q|"];
|
||||
492 [label="Access variable R|/QImplWithCustomGetter.data|"];
|
||||
493 [label="Access variable <Inapplicable(UNSAFE_CALL): /MyData.s>#"];
|
||||
493 [label="Access variable <Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#"];
|
||||
494 [label="Access variable R|<local>/q|"];
|
||||
495 [label="Access variable R|/QImplWithCustomGetter.data|"];
|
||||
496 [label="Access variable <Inapplicable(UNSAFE_CALL): /MyData.s>#"];
|
||||
497 [label="Function call: R|<local>/q|.R|/QImplWithCustomGetter.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#.R|kotlin/Int.inc|()"];
|
||||
496 [label="Access variable <Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#"];
|
||||
497 [label="Function call: R|<local>/q|.R|/QImplWithCustomGetter.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#.R|kotlin/Int.inc|()"];
|
||||
498 [label="Exit block"];
|
||||
}
|
||||
499 [label="Exit when branch result"];
|
||||
@@ -1363,11 +1363,11 @@ digraph nullability_kt {
|
||||
524 [label="Access variable R|/QImplMutable.data|"];
|
||||
525 [label="Access variable R|<local>/q|"];
|
||||
526 [label="Access variable R|/QImplMutable.data|"];
|
||||
527 [label="Access variable <Inapplicable(UNSAFE_CALL): /MyData.s>#"];
|
||||
527 [label="Access variable <Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#"];
|
||||
528 [label="Access variable R|<local>/q|"];
|
||||
529 [label="Access variable R|/QImplMutable.data|"];
|
||||
530 [label="Access variable <Inapplicable(UNSAFE_CALL): /MyData.s>#"];
|
||||
531 [label="Function call: R|<local>/q|.R|/QImplMutable.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#.R|kotlin/Int.inc|()"];
|
||||
530 [label="Access variable <Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#"];
|
||||
531 [label="Function call: R|<local>/q|.R|/QImplMutable.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#.R|kotlin/Int.inc|()"];
|
||||
532 [label="Exit block"];
|
||||
}
|
||||
533 [label="Exit when branch result"];
|
||||
|
||||
@@ -102,8 +102,8 @@ FILE: nullability.kt
|
||||
when () {
|
||||
!=(R|<local>/q|?.{ $subj$.R|/Q.data| }?.{ $subj$.R|/MyData.s| }?.{ $subj$.R|kotlin/Int.inc|() }, Null(null)) -> {
|
||||
R|<local>/q|.R|/Q.data|
|
||||
R|<local>/q|.R|/Q.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#
|
||||
R|<local>/q|.R|/Q.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#.R|kotlin/Int.inc|()
|
||||
R|<local>/q|.R|/Q.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#
|
||||
R|<local>/q|.R|/Q.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#.R|kotlin/Int.inc|()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,8 +111,8 @@ FILE: nullability.kt
|
||||
public final fun test_6(q: R|Q?|): R|kotlin/Unit| {
|
||||
R|<local>/q|?.{ $subj$.R|/Q.data| }?.{ $subj$.R|/MyData.s| }?.{ $subj$.R|kotlin/Int.inc|() } ?: ^test_6 Unit
|
||||
R|<local>/q|.R|/Q.data|
|
||||
R|<local>/q|.R|/Q.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#
|
||||
R|<local>/q|.R|/Q.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#.R|kotlin/Int.inc|()
|
||||
R|<local>/q|.R|/Q.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#
|
||||
R|<local>/q|.R|/Q.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#.R|kotlin/Int.inc|()
|
||||
}
|
||||
public final fun test_7(q: R|Q?|): R|kotlin/Unit| {
|
||||
when () {
|
||||
@@ -216,8 +216,8 @@ FILE: nullability.kt
|
||||
when () {
|
||||
!=(R|<local>/q|?.{ $subj$.R|/QImplWithCustomGetter.data| }?.{ $subj$.R|/MyData.s| }?.{ $subj$.R|kotlin/Int.inc|() }, Null(null)) -> {
|
||||
R|<local>/q|.R|/QImplWithCustomGetter.data|
|
||||
R|<local>/q|.R|/QImplWithCustomGetter.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#
|
||||
R|<local>/q|.R|/QImplWithCustomGetter.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#.R|kotlin/Int.inc|()
|
||||
R|<local>/q|.R|/QImplWithCustomGetter.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#
|
||||
R|<local>/q|.R|/QImplWithCustomGetter.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#.R|kotlin/Int.inc|()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,8 +226,8 @@ FILE: nullability.kt
|
||||
when () {
|
||||
!=(R|<local>/q|?.{ $subj$.R|/QImplMutable.data| }?.{ $subj$.R|/MyData.s| }?.{ $subj$.R|kotlin/Int.inc|() }, Null(null)) -> {
|
||||
R|<local>/q|.R|/QImplMutable.data|
|
||||
R|<local>/q|.R|/QImplMutable.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#
|
||||
R|<local>/q|.R|/QImplMutable.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#.R|kotlin/Int.inc|()
|
||||
R|<local>/q|.R|/QImplMutable.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#
|
||||
R|<local>/q|.R|/QImplMutable.data|.<Inapplicable(UNSTABLE_SMARTCAST): /MyData.s>#.R|kotlin/Int.inc|()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,8 +67,8 @@ fun test_5(q: Q?) {
|
||||
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
|
||||
if (q?.data?.s?.inc() != null) {
|
||||
q.data // good
|
||||
q.data<!UNSAFE_CALL!>.<!>s // should be bad
|
||||
q.data<!UNSAFE_CALL!>.<!>s.inc() // should be bad
|
||||
<!SMARTCAST_IMPOSSIBLE!>q.data<!>.s // should be bad
|
||||
<!SMARTCAST_IMPOSSIBLE!>q.data<!>.s.inc() // should be bad
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,8 +76,8 @@ fun test_6(q: Q?) {
|
||||
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
|
||||
q?.data?.s?.inc() ?: return
|
||||
q.data // good
|
||||
q.data<!UNSAFE_CALL!>.<!>s // should be bad
|
||||
q.data<!UNSAFE_CALL!>.<!>s.inc() // should be bad
|
||||
<!SMARTCAST_IMPOSSIBLE!>q.data<!>.s // should be bad
|
||||
<!SMARTCAST_IMPOSSIBLE!>q.data<!>.s.inc() // should be bad
|
||||
}
|
||||
|
||||
fun test_7(q: Q?) {
|
||||
@@ -162,8 +162,8 @@ fun test_12(q: QImplWithCustomGetter?) {
|
||||
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
|
||||
if (q?.data?.s?.inc() != null) {
|
||||
q.data // good
|
||||
q.data<!UNSAFE_CALL!>.<!>s // should be bad
|
||||
q.data<!UNSAFE_CALL!>.<!>s.inc() // should be bad
|
||||
<!SMARTCAST_IMPOSSIBLE!>q.data<!>.s // should be bad
|
||||
<!SMARTCAST_IMPOSSIBLE!>q.data<!>.s.inc() // should be bad
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ fun test_13(q: QImplMutable?) {
|
||||
// `q.data` is a property that is mutable, so we can NOT smartcast it to non-nullable MyData.
|
||||
if (q?.data?.s?.inc() != null) {
|
||||
q.data // good
|
||||
q.data<!UNSAFE_CALL!>.<!>s // should be bad
|
||||
q.data<!UNSAFE_CALL!>.<!>s.inc() // should be bad
|
||||
<!SMARTCAST_IMPOSSIBLE!>q.data<!>.s // should be bad
|
||||
<!SMARTCAST_IMPOSSIBLE!>q.data<!>.s.inc() // should be bad
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ FILE: KtFirCompositeScope.kt
|
||||
public final fun getAllNames(): R|kotlin/collections/Set<kotlin/String>| {
|
||||
^getAllNames R|/withValidityAssertion|<R|kotlin/collections/Set<kotlin/String>|>(<L> = withValidityAssertion@fun <anonymous>(): R|kotlin/collections/Set<kotlin/String>| <inline=Inline, kind=UNKNOWN> {
|
||||
^ R|/buildSet|<R|kotlin/String|>(<L> = buildSet@fun R|kotlin/collections/MutableSet<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
|
||||
this@R|/KtFirCompositeScope|.R|/KtFirCompositeScope.subScopes|.R|kotlin/collections/flatMapTo|<R|KtScope|, R|kotlin/String|, R|kotlin/collections/MutableCollection<in kotlin/String>|>(this@R|special/anonymous|, <L> = flatMapTo@fun <anonymous>(it: R|KtScope|): R|kotlin/collections/Iterable<kotlin/String>| <inline=Inline, kind=UNKNOWN> {
|
||||
this@R|/KtFirCompositeScope|.R|/KtFirCompositeScope.subScopes|.R|kotlin/collections/flatMapTo|<R|KtScope|, R|kotlin/String|, R|kotlin/collections/MutableSet<kotlin/String>|>(this@R|special/anonymous|, <L> = flatMapTo@fun <anonymous>(it: R|KtScope|): R|kotlin/collections/Iterable<kotlin/String>| <inline=Inline, kind=UNKNOWN> {
|
||||
^ R|<local>/it|.R|/KtScope.getAllNames|()
|
||||
}
|
||||
)
|
||||
|
||||
@@ -990,9 +990,21 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationForClassTypeParameter.kt")
|
||||
public void testAnnotationForClassTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationForClassTypeParameter.kt");
|
||||
@TestMetadata("AnnotationForClassTypeParameter_15.kt")
|
||||
public void testAnnotationForClassTypeParameter_15() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationForClassTypeParameter_15.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationForClassTypeParameter_16.kt")
|
||||
public void testAnnotationForClassTypeParameter_16() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationForClassTypeParameter_16.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationForClassTypeParameter_typeUseFlag.kt")
|
||||
public void testAnnotationForClassTypeParameter_typeUseFlag() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationForClassTypeParameter_typeUseFlag.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1343,6 +1355,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/RecursivelyIncorrectlyAnnotatedParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("requireKotlin.kt")
|
||||
public void testRequireKotlin() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/requireKotlin.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("RetentionsOfAnnotationWithExpressionTarget_after.kt")
|
||||
public void testRetentionsOfAnnotationWithExpressionTarget_after() throws Exception {
|
||||
@@ -12632,6 +12650,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("labaledCall.kt")
|
||||
public void testLabaledCall() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/labaledCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleLambdaInCallWithAnotherLambdaWithBuilderInference.kt")
|
||||
public void testSimpleLambdaInCallWithAnotherLambdaWithBuilderInference() throws Exception {
|
||||
@@ -12668,17 +12692,115 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferencesErrorTypeUnrestricted.kt")
|
||||
public void testSpecialCallsWithCallableReferencesErrorTypeUnrestricted() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorTypeUnrestricted.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferencesNonStrictOnlyInputTypes.kt")
|
||||
public void testSpecialCallsWithCallableReferencesNonStrictOnlyInputTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesNonStrictOnlyInputTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferencesUnrestricted.kt")
|
||||
public void testSpecialCallsWithCallableReferencesUnrestricted() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesUnrestricted.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithLambdas.kt")
|
||||
public void testSpecialCallsWithLambdas() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithLambdas.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/constraints")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Constraints {
|
||||
@Test
|
||||
public void testAllFilesPresentInConstraints() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/constraints"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("violating.kt")
|
||||
public void testViolating() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class StubTypes {
|
||||
@Test
|
||||
public void testAllFilesPresentInStubTypes() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("capturedTypes.kt")
|
||||
public void testCapturedTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperType.kt")
|
||||
public void testCommonSuperType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeContravariant.kt")
|
||||
public void testCommonSuperTypeContravariant() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeCovariant.kt")
|
||||
public void testCommonSuperTypeCovariant() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeInvariant.kt")
|
||||
public void testCommonSuperTypeInvariant() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeNullable.kt")
|
||||
public void testCommonSuperTypeNullable() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("intersect.kt")
|
||||
public void testIntersect() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("memberScope.kt")
|
||||
public void testMemberScope() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullability.kt")
|
||||
public void testNullability() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/nullability.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("renderingStubTypes.kt")
|
||||
public void testRenderingStubTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@@ -32230,6 +32352,48 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
public void testCompleteIrrelevantCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/completeIrrelevantCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incorrectCalls.kt")
|
||||
public void testIncorrectCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/incorrectCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incorrectCallsWithRestrictions.kt")
|
||||
public void testIncorrectCallsWithRestrictions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/incorrectCallsWithRestrictions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inferCoroutineTypeInOldVersion.kt")
|
||||
public void testInferCoroutineTypeInOldVersion() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/inferCoroutineTypeInOldVersion.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveUsualCallWithBuilderInference.kt")
|
||||
public void testResolveUsualCallWithBuilderInference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveUsualCallWithBuilderInferenceWithRestrictions.kt")
|
||||
public void testResolveUsualCallWithBuilderInferenceWithRestrictions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtension.kt")
|
||||
public void testUseInferenceInformationFromExtension() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/useInferenceInformationFromExtension.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtensionWithRestrictions.kt")
|
||||
public void testUseInferenceInformationFromExtensionWithRestrictions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/useInferenceInformationFromExtensionWithRestrictions.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@@ -33420,18 +33584,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraints_1_2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incorrectCalls.kt")
|
||||
public void testIncorrectCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/incorrectCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inferCoroutineTypeInOldVersion.kt")
|
||||
public void testInferCoroutineTypeInOldVersion() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/inferCoroutineTypeInOldVersion.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inferenceFromMethodInsideLocalVariable.kt")
|
||||
public void testInferenceFromMethodInsideLocalVariable() throws Exception {
|
||||
@@ -33576,12 +33728,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveUsualCallWithBuilderInference.kt")
|
||||
public void testResolveUsualCallWithBuilderInference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/resolveUsualCallWithBuilderInference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("returnTypeInference.kt")
|
||||
public void testReturnTypeInference() throws Exception {
|
||||
@@ -33630,12 +33776,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtension.kt")
|
||||
public void testUseInferenceInformationFromExtension() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/useInferenceInformationFromExtension.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("variableCallInsideBuilderFunction.kt")
|
||||
public void testVariableCallInsideBuilderFunction() throws Exception {
|
||||
|
||||
@@ -990,9 +990,21 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationForClassTypeParameter.kt")
|
||||
public void testAnnotationForClassTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationForClassTypeParameter.kt");
|
||||
@TestMetadata("AnnotationForClassTypeParameter_15.kt")
|
||||
public void testAnnotationForClassTypeParameter_15() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationForClassTypeParameter_15.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationForClassTypeParameter_16.kt")
|
||||
public void testAnnotationForClassTypeParameter_16() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationForClassTypeParameter_16.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("AnnotationForClassTypeParameter_typeUseFlag.kt")
|
||||
public void testAnnotationForClassTypeParameter_typeUseFlag() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/AnnotationForClassTypeParameter_typeUseFlag.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1343,6 +1355,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/RecursivelyIncorrectlyAnnotatedParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("requireKotlin.kt")
|
||||
public void testRequireKotlin() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/requireKotlin.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("RetentionsOfAnnotationWithExpressionTarget_after.kt")
|
||||
public void testRetentionsOfAnnotationWithExpressionTarget_after() throws Exception {
|
||||
@@ -12632,6 +12650,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("labaledCall.kt")
|
||||
public void testLabaledCall() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/labaledCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleLambdaInCallWithAnotherLambdaWithBuilderInference.kt")
|
||||
public void testSimpleLambdaInCallWithAnotherLambdaWithBuilderInference() throws Exception {
|
||||
@@ -12668,17 +12692,115 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferencesErrorTypeUnrestricted.kt")
|
||||
public void testSpecialCallsWithCallableReferencesErrorTypeUnrestricted() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesErrorTypeUnrestricted.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferencesNonStrictOnlyInputTypes.kt")
|
||||
public void testSpecialCallsWithCallableReferencesNonStrictOnlyInputTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesNonStrictOnlyInputTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferencesUnrestricted.kt")
|
||||
public void testSpecialCallsWithCallableReferencesUnrestricted() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithCallableReferencesUnrestricted.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithLambdas.kt")
|
||||
public void testSpecialCallsWithLambdas() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/specialCallsWithLambdas.kt");
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/constraints")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class Constraints {
|
||||
@Test
|
||||
public void testAllFilesPresentInConstraints() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/constraints"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("violating.kt")
|
||||
public void testViolating() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/constraints/violating.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class StubTypes {
|
||||
@Test
|
||||
public void testAllFilesPresentInStubTypes() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("capturedTypes.kt")
|
||||
public void testCapturedTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/capturedTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperType.kt")
|
||||
public void testCommonSuperType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeContravariant.kt")
|
||||
public void testCommonSuperTypeContravariant() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeContravariant.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeCovariant.kt")
|
||||
public void testCommonSuperTypeCovariant() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeCovariant.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeInvariant.kt")
|
||||
public void testCommonSuperTypeInvariant() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeInvariant.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeNullable.kt")
|
||||
public void testCommonSuperTypeNullable() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/commonSuperTypeNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("intersect.kt")
|
||||
public void testIntersect() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/intersect.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("memberScope.kt")
|
||||
public void testMemberScope() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/memberScope.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullability.kt")
|
||||
public void testNullability() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/nullability.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("renderingStubTypes.kt")
|
||||
public void testRenderingStubTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/builderInference/stubTypes/renderingStubTypes.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@@ -32230,6 +32352,48 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
public void testCompleteIrrelevantCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/completeIrrelevantCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incorrectCalls.kt")
|
||||
public void testIncorrectCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/incorrectCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incorrectCallsWithRestrictions.kt")
|
||||
public void testIncorrectCallsWithRestrictions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/incorrectCallsWithRestrictions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inferCoroutineTypeInOldVersion.kt")
|
||||
public void testInferCoroutineTypeInOldVersion() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/inferCoroutineTypeInOldVersion.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveUsualCallWithBuilderInference.kt")
|
||||
public void testResolveUsualCallWithBuilderInference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveUsualCallWithBuilderInferenceWithRestrictions.kt")
|
||||
public void testResolveUsualCallWithBuilderInferenceWithRestrictions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/resolveUsualCallWithBuilderInferenceWithRestrictions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtension.kt")
|
||||
public void testUseInferenceInformationFromExtension() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/useInferenceInformationFromExtension.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtensionWithRestrictions.kt")
|
||||
public void testUseInferenceInformationFromExtensionWithRestrictions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/useInferenceInformationFromExtensionWithRestrictions.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@@ -33420,18 +33584,6 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/extensionsWithNonValuableConstraints_1_2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("incorrectCalls.kt")
|
||||
public void testIncorrectCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/incorrectCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inferCoroutineTypeInOldVersion.kt")
|
||||
public void testInferCoroutineTypeInOldVersion() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/inferCoroutineTypeInOldVersion.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inferenceFromMethodInsideLocalVariable.kt")
|
||||
public void testInferenceFromMethodInsideLocalVariable() throws Exception {
|
||||
@@ -33576,12 +33728,6 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/recursiveGenerators2.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("resolveUsualCallWithBuilderInference.kt")
|
||||
public void testResolveUsualCallWithBuilderInference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/resolveUsualCallWithBuilderInference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("returnTypeInference.kt")
|
||||
public void testReturnTypeInference() throws Exception {
|
||||
@@ -33630,12 +33776,6 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("useInferenceInformationFromExtension.kt")
|
||||
public void testUseInferenceInformationFromExtension() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/useInferenceInformationFromExtension.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("variableCallInsideBuilderFunction.kt")
|
||||
public void testVariableCallInsideBuilderFunction() throws Exception {
|
||||
|
||||
@@ -21,10 +21,12 @@ import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import kotlin.properties.PropertyDelegateProvider
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
|
||||
@@ -68,6 +70,18 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val FLOAT_LITERAL_OUT_OF_RANGE by error<PsiElement>()
|
||||
val WRONG_LONG_SUFFIX by error<KtElement>(PositioningStrategy.LONG_LITERAL_SUFFIX)
|
||||
val DIVISION_BY_ZERO by warning<KtExpression>()
|
||||
val VAL_OR_VAR_ON_LOOP_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
||||
parameter<KtKeywordToken>("valOrVar")
|
||||
}
|
||||
val VAL_OR_VAR_ON_FUN_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
||||
parameter<KtKeywordToken>("valOrVar")
|
||||
}
|
||||
val VAL_OR_VAR_ON_CATCH_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
||||
parameter<KtKeywordToken>("valOrVar")
|
||||
}
|
||||
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
|
||||
parameter<KtKeywordToken>("valOrVar")
|
||||
}
|
||||
}
|
||||
|
||||
val UNRESOLVED by object : DiagnosticGroup("Unresolved") {
|
||||
@@ -417,6 +431,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val RETURN_TYPE_MISMATCH by error<KtExpression>(PositioningStrategy.WHOLE_ELEMENT) {
|
||||
parameter<ConeKotlinType>("expectedType")
|
||||
parameter<ConeKotlinType>("actualType")
|
||||
parameter<FirSimpleFunction>("targetFunction")
|
||||
}
|
||||
|
||||
val CYCLIC_GENERIC_UPPER_BOUND by error<PsiElement>()
|
||||
@@ -436,6 +451,26 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
parameter<ConeKotlinType>("typeA")
|
||||
parameter<ConeKotlinType>("typeB")
|
||||
}
|
||||
|
||||
val TYPE_VARIANCE_CONFLICT by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||
parameter<FirTypeParameterSymbol>("typeParameter")
|
||||
parameter<Variance>("typeParameterVariance")
|
||||
parameter<Variance>("variance")
|
||||
parameter<ConeKotlinType>("containingType")
|
||||
}
|
||||
|
||||
val TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
|
||||
parameter<FirTypeParameterSymbol>("typeParameter")
|
||||
parameter<Variance>("typeParameterVariance")
|
||||
parameter<Variance>("variance")
|
||||
parameter<ConeKotlinType>("containingType")
|
||||
}
|
||||
|
||||
val SMARTCAST_IMPOSSIBLE by error<KtExpression> {
|
||||
parameter<ConeKotlinType>("desiredType")
|
||||
parameter<FirExpression>("subject")
|
||||
parameter<String>("description")
|
||||
}
|
||||
}
|
||||
|
||||
val REFLECTION by object : DiagnosticGroup("Reflection") {
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
|
||||
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
@@ -30,6 +31,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtAnnotation
|
||||
@@ -64,6 +66,7 @@ import org.jetbrains.kotlin.psi.KtValueArgument
|
||||
import org.jetbrains.kotlin.psi.KtWhenEntry
|
||||
import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
/*
|
||||
* This file was generated automatically
|
||||
@@ -98,6 +101,10 @@ object FirErrors {
|
||||
val FLOAT_LITERAL_OUT_OF_RANGE by error0<PsiElement>()
|
||||
val WRONG_LONG_SUFFIX by error0<KtElement>(SourceElementPositioningStrategies.LONG_LITERAL_SUFFIX)
|
||||
val DIVISION_BY_ZERO by warning0<KtExpression>()
|
||||
val VAL_OR_VAR_ON_LOOP_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
val VAL_OR_VAR_ON_FUN_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
val VAL_OR_VAR_ON_CATCH_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
|
||||
|
||||
// Unresolved
|
||||
val INVISIBLE_REFERENCE by error1<PsiElement, AbstractFirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
@@ -287,13 +294,16 @@ object FirErrors {
|
||||
val REIFIED_TYPE_PARAMETER_NO_INLINE by error0<KtTypeParameter>(SourceElementPositioningStrategies.REIFIED_MODIFIER)
|
||||
val TYPE_PARAMETERS_NOT_ALLOWED by error0<KtDeclaration>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
|
||||
val TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER by error0<KtTypeParameter>()
|
||||
val RETURN_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>(SourceElementPositioningStrategies.WHOLE_ELEMENT)
|
||||
val RETURN_TYPE_MISMATCH by error3<KtExpression, ConeKotlinType, ConeKotlinType, FirSimpleFunction>(SourceElementPositioningStrategies.WHOLE_ELEMENT)
|
||||
val CYCLIC_GENERIC_UPPER_BOUND by error0<PsiElement>()
|
||||
val DEPRECATED_TYPE_PARAMETER_SYNTAX by error0<KtDeclaration>(SourceElementPositioningStrategies.TYPE_PARAMETERS_LIST)
|
||||
val MISPLACED_TYPE_PARAMETER_CONSTRAINTS by warning0<KtTypeParameter>()
|
||||
val DYNAMIC_UPPER_BOUND by error0<KtTypeReference>()
|
||||
val INCOMPATIBLE_TYPES by error2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||
val INCOMPATIBLE_TYPES_WARNING by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
|
||||
val TYPE_VARIANCE_CONFLICT by error4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE by error4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
|
||||
val SMARTCAST_IMPOSSIBLE by error3<KtExpression, ConeKotlinType, FirExpression, String>()
|
||||
|
||||
// Reflection
|
||||
val EXTENSION_IN_CLASS_REFERENCE_NOT_ALLOWED by error1<KtExpression, FirCallableDeclaration<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
|
||||
|
||||
@@ -156,30 +156,34 @@ object FirReturnsImpliesAnalyzer : FirControlFlowChecker() {
|
||||
variableStorage: VariableStorage,
|
||||
flow: Flow,
|
||||
context: CheckerContext
|
||||
): MutableTypeStatements? = when (this) {
|
||||
is ConeBinaryLogicExpression -> {
|
||||
val left = left.buildTypeStatements(function, logicSystem, variableStorage, flow, context)
|
||||
val right = right.buildTypeStatements(function, logicSystem, variableStorage, flow, context)
|
||||
if (left != null && right != null) {
|
||||
if (kind == LogicOperationKind.AND) {
|
||||
left.apply { mergeTypeStatements(right) }
|
||||
} else logicSystem.orForTypeStatements(left, right)
|
||||
} else (left ?: right)
|
||||
}
|
||||
is ConeIsInstancePredicate -> {
|
||||
): MutableTypeStatements? {
|
||||
fun buildTypeStatements(arg: ConeValueParameterReference, exactType: Boolean, type: ConeKotlinType): MutableTypeStatements? {
|
||||
val fir = function.getParameterSymbol(arg.parameterIndex, context).fir
|
||||
val realVar = variableStorage.getOrCreateRealVariable(flow, fir.symbol, fir)
|
||||
realVar?.to(simpleTypeStatement(realVar, !isNegated, type))?.let { mutableMapOf(it) }
|
||||
?.takeIf {
|
||||
it.stability == PropertyStability.STABLE_VALUE ||
|
||||
// TODO: consider removing the part below
|
||||
it.stability == PropertyStability.LOCAL_VAR
|
||||
}
|
||||
return realVar?.to(simpleTypeStatement(realVar, exactType, type))?.let { mutableMapOf(it) }
|
||||
}
|
||||
is ConeIsNullPredicate -> {
|
||||
val fir = function.getParameterSymbol(arg.parameterIndex, context).fir
|
||||
val realVar = variableStorage.getOrCreateRealVariable(flow, fir.symbol, fir)
|
||||
realVar?.to(simpleTypeStatement(realVar, isNegated, context.session.builtinTypes.anyType.type))?.let { mutableMapOf(it) }
|
||||
}
|
||||
is ConeLogicalNot -> arg.buildTypeStatements(function, logicSystem, variableStorage, flow, context)
|
||||
?.mapValuesTo(mutableMapOf()) { (_, value) -> value.invert() }
|
||||
return when (this) {
|
||||
is ConeBinaryLogicExpression -> {
|
||||
val left = left.buildTypeStatements(function, logicSystem, variableStorage, flow, context)
|
||||
val right = right.buildTypeStatements(function, logicSystem, variableStorage, flow, context)
|
||||
if (left != null && right != null) {
|
||||
if (kind == LogicOperationKind.AND) {
|
||||
left.apply { mergeTypeStatements(right) }
|
||||
} else logicSystem.orForTypeStatements(left, right)
|
||||
} else (left ?: right)
|
||||
}
|
||||
is ConeIsInstancePredicate -> buildTypeStatements(arg, !isNegated, type)
|
||||
is ConeIsNullPredicate -> buildTypeStatements(arg, isNegated, context.session.builtinTypes.anyType.type)
|
||||
is ConeLogicalNot -> arg.buildTypeStatements(function, logicSystem, variableStorage, flow, context)
|
||||
?.mapValuesTo(mutableMapOf()) { (_, value) -> value.invert() }
|
||||
|
||||
else -> null
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.isInapplicableWith(operation: Operation, session: FirSession): Boolean {
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirDelegationInInterfac
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirFunctionTypeParametersSyntaxChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirTypeParameterSyntaxChecker
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirReservedUnderscoreDeclarationChecker
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
|
||||
object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
override val basicDeclarationCheckers: Set<FirBasicDeclarationChecker>
|
||||
@@ -65,6 +66,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirNotImplementedOverrideChecker,
|
||||
FirThrowableSubclassChecker,
|
||||
FirOpenMemberChecker,
|
||||
FirClassVarianceChecker
|
||||
)
|
||||
|
||||
override val regularClassCheckers: Set<FirRegularClassChecker>
|
||||
|
||||
@@ -89,6 +89,15 @@ internal fun checkConstantArguments(
|
||||
)
|
||||
return ConstantArgumentKind.NOT_CONST
|
||||
}
|
||||
expressionSymbol is FirConstructor -> {
|
||||
if (expression.typeRef.coneType.isUnsignedType) {
|
||||
(expression as FirFunctionCall).arguments.forEach { argumentExpression ->
|
||||
checkConstantArguments(argumentExpression, session)?.let { return it }
|
||||
}
|
||||
} else {
|
||||
return ConstantArgumentKind.NOT_CONST
|
||||
}
|
||||
}
|
||||
expression is FirFunctionCall -> {
|
||||
val calleeReference = expression.calleeReference
|
||||
if (calleeReference is FirErrorNamedReference) {
|
||||
@@ -103,6 +112,7 @@ internal fun checkConstantArguments(
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
when (calleeReference.name) {
|
||||
in OperatorNameConventions.BINARY_OPERATION_NAMES, in OperatorNameConventions.UNARY_OPERATION_NAMES,
|
||||
OperatorNameConventions.SHL, OperatorNameConventions.SHR, OperatorNameConventions.USHR,
|
||||
|
||||
@@ -11,10 +11,13 @@ import com.intellij.psi.tree.TokenSet
|
||||
import com.intellij.util.diff.FlyweightCapableTreeStructure
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.valOrVarKeyword
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtModifierList
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.psi.KtValVarKeywordOwner
|
||||
|
||||
// DO
|
||||
// - use this to retrieve modifiers on the source and confirm a certain modifier indeed appears
|
||||
@@ -96,3 +99,10 @@ operator fun FirModifierList?.contains(token: KtModifierKeywordToken): Boolean =
|
||||
fun FirElement.getModifier(token: KtModifierKeywordToken): FirModifier<*>? = source.getModifierList()?.get(token)
|
||||
|
||||
fun FirElement.hasModifier(token: KtModifierKeywordToken): Boolean = token in source.getModifierList()
|
||||
|
||||
internal val FirSourceElement?.valOrVarKeyword: KtKeywordToken?
|
||||
get() = when (this) {
|
||||
null -> null
|
||||
is FirPsiSourceElement<*> -> (psi as? KtValVarKeywordOwner)?.valOrVarKeyword?.let { it.node?.elementType as? KtKeywordToken }
|
||||
is FirLightSourceElement -> treeStructure.valOrVarKeyword(lighterASTNode)?.tokenType as? KtKeywordToken
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.name.StandardClassIds.primitiveArrayTypeByElementType
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.StandardClassIds.unsignedArrayTypeByElementType
|
||||
|
||||
object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() {
|
||||
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
@@ -84,6 +85,9 @@ object FirAnnotationClassDeclarationChecker : FirRegularClassChecker() {
|
||||
classId in primitiveArrayTypeByElementType.values -> {
|
||||
// DO NOTHING: primitive arrays are allowed
|
||||
}
|
||||
classId in unsignedArrayTypeByElementType.values -> {
|
||||
// DO NOTHING: arrays of unsigned types are allowed
|
||||
}
|
||||
classId == StandardClassIds.Array -> {
|
||||
if (!isAllowedArray(typeRef, context.session))
|
||||
reporter.reportOn(typeRef.source, FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER, context)
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.checker.TypeCheckingProcedure
|
||||
|
||||
object FirClassVarianceChecker : FirClassChecker() {
|
||||
override fun check(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
checkTypeParameters(declaration.typeParameters, Variance.OUT_VARIANCE, context, reporter)
|
||||
|
||||
for (superTypeRef in declaration.superTypeRefs) {
|
||||
checkVarianceConflict(superTypeRef, Variance.OUT_VARIANCE, context, reporter)
|
||||
}
|
||||
|
||||
for (member in declaration.declarations) {
|
||||
if (member is FirMemberDeclaration) {
|
||||
if (Visibilities.isPrivate(member.status.visibility)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if (member is FirTypeParameterRefsOwner) {
|
||||
checkTypeParameters(member.typeParameters, Variance.IN_VARIANCE, context, reporter)
|
||||
}
|
||||
|
||||
if (member is FirCallableDeclaration<*>) {
|
||||
checkCallableDeclaration(member, context, reporter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkCallableDeclaration(
|
||||
member: FirCallableDeclaration<*>,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
val memberSource = member.source
|
||||
if (member is FirSimpleFunction) {
|
||||
if (memberSource != null && memberSource.kind !is FirFakeSourceElementKind) {
|
||||
for (param in member.valueParameters) {
|
||||
checkVarianceConflict(param.returnTypeRef, Variance.IN_VARIANCE, context, reporter)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val returnTypeVariance =
|
||||
if (member is FirProperty && member.isVar) Variance.INVARIANT else Variance.OUT_VARIANCE
|
||||
|
||||
var returnSource = member.returnTypeRef.source
|
||||
if (returnSource != null && memberSource != null) {
|
||||
if (returnSource.kind is FirFakeSourceElementKind && memberSource.kind !is FirFakeSourceElementKind) {
|
||||
returnSource = memberSource
|
||||
}
|
||||
}
|
||||
|
||||
checkVarianceConflict(member.returnTypeRef, returnTypeVariance, context, reporter, returnSource)
|
||||
|
||||
val receiverTypeRef = member.receiverTypeRef
|
||||
if (receiverTypeRef != null) {
|
||||
checkVarianceConflict(receiverTypeRef, Variance.IN_VARIANCE, context, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkTypeParameters(
|
||||
typeParameters: List<FirTypeParameterRef>, variance: Variance,
|
||||
context: CheckerContext, reporter: DiagnosticReporter
|
||||
) {
|
||||
for (typeParameter in typeParameters) {
|
||||
if (typeParameter is FirTypeParameter) {
|
||||
for (bound in typeParameter.bounds) {
|
||||
checkVarianceConflict(bound, variance, context, reporter)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkVarianceConflict(
|
||||
type: FirTypeRef, variance: Variance,
|
||||
context: CheckerContext, reporter: DiagnosticReporter,
|
||||
source: FirSourceElement? = null
|
||||
) {
|
||||
checkVarianceConflict(type.coneType, variance, type, type.coneType, context, reporter, source)
|
||||
}
|
||||
|
||||
private fun checkVarianceConflict(
|
||||
type: ConeKotlinType,
|
||||
variance: Variance,
|
||||
typeRef: FirTypeRef?,
|
||||
containingType: ConeKotlinType,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter,
|
||||
source: FirSourceElement? = null,
|
||||
isInAbbreviation: Boolean = false
|
||||
) {
|
||||
if (type is ConeTypeParameterType) {
|
||||
val fullyExpandedType = type.fullyExpandedType(context.session)
|
||||
val typeParameter = type.lookupTag.typeParameterSymbol.fir
|
||||
val resultSource = source ?: typeRef?.source
|
||||
if (resultSource != null &&
|
||||
!typeParameter.variance.allowsPosition(variance) &&
|
||||
!fullyExpandedType.attributes.contains(CompilerConeAttributes.UnsafeVariance)
|
||||
) {
|
||||
val factory =
|
||||
if (isInAbbreviation) FirErrors.TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE else FirErrors.TYPE_VARIANCE_CONFLICT
|
||||
reporter.report(
|
||||
factory.on(
|
||||
resultSource,
|
||||
typeParameter.symbol,
|
||||
typeParameter.variance,
|
||||
variance,
|
||||
containingType
|
||||
),
|
||||
context
|
||||
)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if (type is ConeClassLikeType) {
|
||||
val fullyExpandedType = type.fullyExpandedType(context.session)
|
||||
val declFir = fullyExpandedType.lookupTag.toSymbol(context.session)?.fir
|
||||
if (declFir is FirClass<*>) {
|
||||
for ((index, typeArgument) in fullyExpandedType.typeArguments.withIndex()) {
|
||||
val paramVariance = (declFir.typeParameters.getOrNull(index) as? FirTypeParameter)?.variance ?: continue
|
||||
|
||||
val argVariance = when (typeArgument.kind) {
|
||||
ProjectionKind.IN -> Variance.IN_VARIANCE
|
||||
ProjectionKind.OUT -> Variance.OUT_VARIANCE
|
||||
ProjectionKind.INVARIANT -> Variance.INVARIANT
|
||||
else -> continue
|
||||
}
|
||||
|
||||
val typeArgumentType = typeArgument.type ?: continue
|
||||
|
||||
val projectionKind = TypeCheckingProcedure.getEffectiveProjectionKind(paramVariance, argVariance)!!
|
||||
val newVariance = when (projectionKind) {
|
||||
TypeCheckingProcedure.EnrichedProjectionKind.OUT -> variance
|
||||
TypeCheckingProcedure.EnrichedProjectionKind.IN -> variance.opposite()
|
||||
TypeCheckingProcedure.EnrichedProjectionKind.INV -> Variance.INVARIANT
|
||||
TypeCheckingProcedure.EnrichedProjectionKind.STAR -> null // CONFLICTING_PROJECTION error was reported
|
||||
}
|
||||
|
||||
if (newVariance != null) {
|
||||
val subTypeRef = extractChildFirTypeRef(typeRef, index)
|
||||
|
||||
checkVarianceConflict(
|
||||
typeArgumentType, newVariance, subTypeRef, containingType,
|
||||
context, reporter,subTypeRef?.source ?: source,
|
||||
fullyExpandedType != type
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractChildFirTypeRef(typeRef: FirTypeRef?, index: Int): FirTypeRef? {
|
||||
if (typeRef is FirResolvedTypeRef) {
|
||||
val delegatedTypeRef = typeRef.delegatedTypeRef
|
||||
if (delegatedTypeRef is FirUserTypeRef) {
|
||||
val typeArgument = delegatedTypeRef.qualifier[0].typeArgumentList.typeArguments.elementAtOrNull(index)
|
||||
if (typeArgument is FirTypeProjectionWithVariance) {
|
||||
return typeArgument.typeRef
|
||||
}
|
||||
} else if (delegatedTypeRef is FirFunctionTypeRef) {
|
||||
if (index < delegatedTypeRef.valueParameters.size) {
|
||||
return delegatedTypeRef.valueParameters.elementAt(index).returnTypeRef
|
||||
}
|
||||
if (index == delegatedTypeRef.valueParameters.size) {
|
||||
return delegatedTypeRef.returnTypeRef
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,13 @@
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirRealSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isInline
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOnWithSuppression
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.valOrVarKeyword
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
@@ -31,10 +32,11 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
|
||||
checkVarargParameters(declaration, context, reporter)
|
||||
checkParameterTypes(declaration, context, reporter)
|
||||
checkUninitializedParameter(declaration, context, reporter)
|
||||
checkValOrVarParameter(declaration, context, reporter)
|
||||
}
|
||||
|
||||
private fun checkParameterTypes(declaration: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (valueParameter in declaration.valueParameters) {
|
||||
private fun checkParameterTypes(function: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (valueParameter in function.valueParameters) {
|
||||
val returnTypeRef = valueParameter.returnTypeRef
|
||||
if (returnTypeRef !is FirErrorTypeRef) continue
|
||||
// type problems on real source are already reported by ConeDiagnostic.toFirDiagnostics
|
||||
@@ -105,4 +107,23 @@ object FirFunctionParameterChecker : FirFunctionChecker() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkValOrVarParameter(function: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (function is FirConstructor && function.isPrimary) {
|
||||
// `val/var` is valid for primary constructors, but not for secondary constructors
|
||||
return
|
||||
}
|
||||
|
||||
for (valueParameter in function.valueParameters) {
|
||||
val source = valueParameter.source
|
||||
if (source?.kind is FirFakeSourceElementKind) continue
|
||||
source.valOrVarKeyword?.let {
|
||||
if (function is FirConstructor) {
|
||||
reporter.reportOn(source, FirErrors.VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER, it, context)
|
||||
} else {
|
||||
reporter.reportOn(source, FirErrors.VAL_OR_VAR_ON_FUN_PARAMETER, it, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.ConstantArgumentKind
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.checkConstantArguments
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.findSingleArgumentByName
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
@@ -20,17 +21,18 @@ import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.resolve.fqName
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.RequireKotlinConstants
|
||||
|
||||
object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
||||
private val versionArgumentName = Name.identifier("version")
|
||||
private val deprecatedSinceKotlinFqName = FqName("kotlin.DeprecatedSinceKotlin")
|
||||
private val sinceKotlinFqName = FqName("kotlin.SinceKotlin")
|
||||
|
||||
private val annotationFqNamesWithVersion = setOf(
|
||||
FqName("kotlin.internal.RequireKotlin"),
|
||||
RequireKotlinConstants.FQ_NAME,
|
||||
sinceKotlinFqName,
|
||||
deprecatedSinceKotlinFqName
|
||||
)
|
||||
|
||||
override fun check(expression: FirAnnotationCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
@@ -38,10 +40,11 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
||||
val fqName = expression.fqName(context.session)
|
||||
for ((arg, _) in argumentMapping) {
|
||||
val argExpression = (arg as? FirNamedArgumentExpression)?.expression ?: arg
|
||||
checkAnnotationArgumentWithSubElements(argExpression, fqName, context.session, reporter, context)
|
||||
checkAnnotationArgumentWithSubElements(argExpression, context.session, reporter, context)
|
||||
?.let { reporter.reportOn(argExpression.source, it, context) }
|
||||
}
|
||||
|
||||
checkAnnotationsWithVersion(fqName, expression, context, reporter)
|
||||
checkDeprecatedSinceKotlin(expression.source, fqName, argumentMapping, context, reporter)
|
||||
|
||||
val args = expression.argumentList.arguments
|
||||
@@ -54,7 +57,6 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
||||
|
||||
private fun checkAnnotationArgumentWithSubElements(
|
||||
expression: FirExpression,
|
||||
fqName: FqName?,
|
||||
session: FirSession,
|
||||
reporter: DiagnosticReporter,
|
||||
context: CheckerContext
|
||||
@@ -66,7 +68,7 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
||||
for (arg in args.arguments) {
|
||||
val sourceForReport = arg.source
|
||||
|
||||
when (val err = checkAnnotationArgumentWithSubElements(arg, fqName, session, reporter, context)) {
|
||||
when (val err = checkAnnotationArgumentWithSubElements(arg, session, reporter, context)) {
|
||||
null -> {
|
||||
//DO NOTHING
|
||||
}
|
||||
@@ -86,12 +88,12 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
||||
is FirVarargArgumentsExpression -> {
|
||||
for (arg in expression.arguments) {
|
||||
val unwrappedArg = if (arg is FirSpreadArgumentExpression) arg.expression else arg
|
||||
checkAnnotationArgumentWithSubElements(unwrappedArg, fqName, session, reporter, context)
|
||||
checkAnnotationArgumentWithSubElements(unwrappedArg, session, reporter, context)
|
||||
?.let { reporter.reportOn(unwrappedArg.source, it, context) }
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
val error = when (checkConstantArguments(expression, session)) {
|
||||
return when (checkConstantArguments(expression, session)) {
|
||||
ConstantArgumentKind.NOT_CONST -> FirErrors.ANNOTATION_ARGUMENT_MUST_BE_CONST
|
||||
ConstantArgumentKind.ENUM_NOT_CONST -> FirErrors.ANNOTATION_ARGUMENT_MUST_BE_ENUM_CONST
|
||||
ConstantArgumentKind.NOT_KCLASS_LITERAL -> FirErrors.ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL
|
||||
@@ -103,33 +105,47 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
||||
if (expression is FirFunctionCall) checkArgumentList(expression.argumentList)
|
||||
else null
|
||||
}
|
||||
if (error != null) {
|
||||
return error
|
||||
} else if (annotationFqNamesWithVersion.contains(fqName)) {
|
||||
val argSource = expression.source
|
||||
if (argSource != null) {
|
||||
val stringValue = (expression as? FirConstExpression<*>)?.value as? String
|
||||
if (stringValue != null) {
|
||||
if (!stringValue.matches(RequireKotlinConstants.VERSION_REGEX)) {
|
||||
reporter.reportOn(argSource, FirErrors.ILLEGAL_KOTLIN_VERSION_STRING_VALUE, context)
|
||||
} else if (fqName == sinceKotlinFqName) {
|
||||
val version = ApiVersion.parse(stringValue)
|
||||
val specified = context.session.languageVersionSettings.apiVersion
|
||||
if (version != null && version > specified) {
|
||||
reporter.report(
|
||||
FirErrors.NEWER_VERSION_IN_SINCE_KOTLIN.on(argSource, specified.versionString),
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun parseVersionExpressionOrReport(
|
||||
expression: FirExpression,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
): ApiVersion? {
|
||||
val constantExpression = (expression as? FirConstExpression<*>)
|
||||
?: ((expression as? FirNamedArgumentExpression)?.expression as? FirConstExpression<*>) ?: return null
|
||||
val stringValue = constantExpression.value as? String ?: return null
|
||||
if (!stringValue.matches(RequireKotlinConstants.VERSION_REGEX)) {
|
||||
reporter.reportOn(expression.source, FirErrors.ILLEGAL_KOTLIN_VERSION_STRING_VALUE, context)
|
||||
return null
|
||||
}
|
||||
val version = ApiVersion.parse(stringValue)
|
||||
if (version == null) {
|
||||
reporter.reportOn(expression.source, FirErrors.ILLEGAL_KOTLIN_VERSION_STRING_VALUE, context)
|
||||
}
|
||||
return version
|
||||
}
|
||||
|
||||
private fun checkAnnotationsWithVersion(
|
||||
fqName: FqName?,
|
||||
annotationCall: FirAnnotationCall,
|
||||
context: CheckerContext,
|
||||
reporter: DiagnosticReporter
|
||||
) {
|
||||
if (!annotationFqNamesWithVersion.contains(fqName)) return
|
||||
val versionExpression = annotationCall.findSingleArgumentByName(versionArgumentName) ?: return
|
||||
val version = parseVersionExpressionOrReport(versionExpression, context, reporter) ?: return
|
||||
if (fqName == sinceKotlinFqName) {
|
||||
val specified = context.session.languageVersionSettings.apiVersion
|
||||
if (version > specified) {
|
||||
reporter.reportOn(versionExpression.source, FirErrors.NEWER_VERSION_IN_SINCE_KOTLIN, specified.versionString, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkDeprecatedSinceKotlin(
|
||||
source: FirSourceElement?,
|
||||
fqName: FqName?,
|
||||
@@ -150,12 +166,8 @@ object FirAnnotationArgumentChecker : FirAnnotationCallChecker() {
|
||||
for (argument in argumentMapping) {
|
||||
val identifier = argument.value.name.identifier
|
||||
if (identifier == "warningSince" || identifier == "errorSince" || identifier == "hiddenSince") {
|
||||
val argKey = argument.key
|
||||
val constExpression = (argKey as? FirConstExpression<*>)
|
||||
?: ((argKey as? FirNamedArgumentExpression)?.expression as? FirConstExpression<*>)
|
||||
val stringValue = constExpression?.value as? String
|
||||
if (stringValue != null) {
|
||||
val version = ApiVersion.parse(stringValue)
|
||||
val version = parseVersionExpressionOrReport(argument.key, context, reporter)
|
||||
if (version != null) {
|
||||
when (identifier) {
|
||||
"warningSince" -> warningSince = version
|
||||
"errorSince" -> errorSince = version
|
||||
|
||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.isSubtypeOfThrowable
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.valOrVarKeyword
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
@@ -18,9 +19,14 @@ object FirCatchParameterChecker : FirTryExpressionChecker() {
|
||||
override fun check(expression: FirTryExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
for (catchEntry in expression.catches) {
|
||||
val catchParameter = catchEntry.parameter
|
||||
val source = catchParameter.source ?: continue
|
||||
|
||||
if (catchParameter.defaultValue != null) {
|
||||
reporter.reportOn(catchParameter.source, FirErrors.CATCH_PARAMETER_WITH_DEFAULT_VALUE, context)
|
||||
reporter.reportOn(source, FirErrors.CATCH_PARAMETER_WITH_DEFAULT_VALUE, context)
|
||||
}
|
||||
|
||||
source.valOrVarKeyword?.let {
|
||||
reporter.reportOn(source, FirErrors.VAL_OR_VAR_ON_CATCH_PARAMETER, it, context)
|
||||
}
|
||||
|
||||
val coneType = catchParameter.returnTypeRef.coneType
|
||||
@@ -28,15 +34,15 @@ object FirCatchParameterChecker : FirTryExpressionChecker() {
|
||||
val isReified = coneType.lookupTag.typeParameterSymbol.fir.isReified
|
||||
|
||||
if (isReified) {
|
||||
reporter.reportOn(catchParameter.source, FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE, context)
|
||||
reporter.reportOn(source, FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE, context)
|
||||
} else {
|
||||
reporter.reportOn(catchParameter.source, FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE, context)
|
||||
reporter.reportOn(source, FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE, context)
|
||||
}
|
||||
}
|
||||
|
||||
val session = context.session
|
||||
if (!coneType.isSubtypeOfThrowable(session)) {
|
||||
reporter.reportOn(catchParameter.source, FirErrors.THROWABLE_TYPE_MISMATCH, coneType, context)
|
||||
reporter.reportOn(source, FirErrors.THROWABLE_TYPE_MISMATCH, coneType, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.valOrVarKeyword
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HAS_NEXT_FUNCTION_AMBIGUITY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HAS_NEXT_FUNCTION_NONE_APPLICABLE
|
||||
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
object FirForLoopChecker : FirBlockChecker() {
|
||||
override fun check(expression: FirBlock, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
if (expression.source?.kind != FirFakeSourceElementKind.DesugaredForLoop) return
|
||||
|
||||
val statements = expression.statements
|
||||
val iteratorDeclaration = statements[0] as? FirProperty ?: return
|
||||
val whileLoop = statements[1] as? FirWhileLoop ?: return
|
||||
@@ -57,6 +59,7 @@ object FirForLoopChecker : FirBlockChecker() {
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
val hasNextCall = whileLoop.condition as FirFunctionCall
|
||||
checkSpecialFunctionCall(
|
||||
hasNextCall,
|
||||
@@ -67,9 +70,10 @@ object FirForLoopChecker : FirBlockChecker() {
|
||||
HAS_NEXT_MISSING,
|
||||
noneApplicableFactory = HAS_NEXT_FUNCTION_NONE_APPLICABLE
|
||||
)
|
||||
val elementDeclaration = whileLoop.block.statements.firstOrNull() as? FirProperty ?: return
|
||||
if (elementDeclaration.initializer?.source?.kind != FirFakeSourceElementKind.DesugaredForLoop) return
|
||||
val nextCall = elementDeclaration.initializer as FirFunctionCall
|
||||
|
||||
val loopParameter = whileLoop.block.statements.firstOrNull() as? FirProperty ?: return
|
||||
if (loopParameter.initializer?.source?.kind != FirFakeSourceElementKind.DesugaredForLoop) return
|
||||
val nextCall = loopParameter.initializer as FirFunctionCall
|
||||
checkSpecialFunctionCall(
|
||||
nextCall,
|
||||
reporter,
|
||||
@@ -79,6 +83,11 @@ object FirForLoopChecker : FirBlockChecker() {
|
||||
NEXT_MISSING,
|
||||
noneApplicableFactory = NEXT_NONE_APPLICABLE
|
||||
)
|
||||
|
||||
val loopParameterSource = loopParameter.source
|
||||
loopParameterSource.valOrVarKeyword?.let {
|
||||
reporter.reportOn(loopParameterSource, FirErrors.VAL_OR_VAR_ON_LOOP_PARAMETER, it, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkSpecialFunctionCall(
|
||||
|
||||
@@ -10,13 +10,16 @@ import org.jetbrains.kotlin.fir.analysis.checkers.isSubtypeForTypeMismatch
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULL_FOR_NONNULL_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_TYPE_MISMATCH
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SMARTCAST_IMPOSSIBLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
||||
import org.jetbrains.kotlin.fir.expressions.FirReturnExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.isExhaustive
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
|
||||
object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
|
||||
override fun check(expression: FirReturnExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
@@ -36,7 +39,23 @@ object FirFunctionReturnTypeMismatchChecker : FirReturnExpressionChecker() {
|
||||
if (resultExpression.isNullLiteral && functionReturnType.nullability == ConeNullability.NOT_NULL) {
|
||||
reporter.reportOn(resultExpression.source, NULL_FOR_NONNULL_TYPE, context)
|
||||
} else {
|
||||
reporter.report(RETURN_TYPE_MISMATCH.on(returnExpressionSource, functionReturnType, returnExpressionType), context)
|
||||
if (resultExpression is FirExpressionWithSmartcast && resultExpression.smartcastStability != SmartcastStability.STABLE_VALUE &&
|
||||
isSubtypeForTypeMismatch(typeContext, subtype = resultExpression.smartcastType.coneType, supertype = functionReturnType)
|
||||
) {
|
||||
reporter.reportOn(
|
||||
returnExpressionSource,
|
||||
SMARTCAST_IMPOSSIBLE,
|
||||
functionReturnType,
|
||||
resultExpression,
|
||||
resultExpression.smartcastStability.description,
|
||||
context
|
||||
)
|
||||
} else {
|
||||
reporter.report(
|
||||
RETURN_TYPE_MISMATCH.on(returnExpressionSource, functionReturnType, returnExpressionType, targetElement),
|
||||
context
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,18 @@ fun <P : PsiElement, A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
|
||||
source?.let { report(factory.on(it, a, b, c), context) }
|
||||
}
|
||||
|
||||
fun <P : PsiElement, A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
|
||||
source: FirSourceElement?,
|
||||
factory: FirDiagnosticFactory4<P, A, B, C, D>,
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
d: D,
|
||||
context: CheckerContext
|
||||
) {
|
||||
source?.let { report(factory.on(it, a, b, c, d), context) }
|
||||
}
|
||||
|
||||
inline fun withSuppressedDiagnostics(
|
||||
element: FirElement,
|
||||
context: CheckerContext,
|
||||
@@ -120,3 +132,17 @@ fun <P : PsiElement, A : Any, B : Any, C : Any> DiagnosticReporter.reportOnWithS
|
||||
}
|
||||
}
|
||||
|
||||
fun <P : PsiElement, A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOnWithSuppression(
|
||||
element: FirElement,
|
||||
factory: FirDiagnosticFactory4<P, A, B, C, D>,
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
d: D,
|
||||
context: CheckerContext
|
||||
) {
|
||||
withSuppressedDiagnostics(element, context) {
|
||||
reportOn(element.source, factory, a, b, c, d, it)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,9 +5,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.diagnostics
|
||||
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.LanguageFeatureMessageRenderer
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.*
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.Renderers.RENDER_POSITION_VARIANCE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBIGUOUS_CALLS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR
|
||||
@@ -274,6 +273,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SEALED_SUPERTYPE_
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SETTER_VISIBILITY_INCONSISTENT_WITH_PROPERTY_VISIBILITY
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SINGLETON_IN_SUPERTYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SMARTCAST_IMPOSSIBLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPES_FOR_ANNOTATION_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_APPEARS_TWICE
|
||||
@@ -300,6 +300,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_IN
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_ON_LHS_OF_DOT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_VARIANCE_CONFLICT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNEXPECTED_SAFE_CALL
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_ENUM_COMPANION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_ENUM_ENTRY
|
||||
@@ -327,6 +329,10 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_IS_CHECK
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_CLASS_CANNOT_BE_CLONEABLE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_CATCH_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_FUN_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_LOOP_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR
|
||||
@@ -347,6 +353,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_MODIFIER_TA
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_PARAMETER_TYPE
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.WRONG_SETTER_RETURN_TYPE
|
||||
import org.jetbrains.kotlin.resolve.VarianceConflictDiagnosticData
|
||||
|
||||
@Suppress("unused")
|
||||
class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
@@ -382,6 +389,10 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
map.put(VARIABLE_EXPECTED, "Variable expected")
|
||||
map.put(DELEGATION_IN_INTERFACE, "Interfaces cannot use delegation")
|
||||
map.put(NESTED_CLASS_NOT_ALLOWED, "{0} is not allowed here", TO_STRING)
|
||||
map.put(VAL_OR_VAR_ON_LOOP_PARAMETER, "''{0}'' on loop parameter is not allowed", TO_STRING);
|
||||
map.put(VAL_OR_VAR_ON_FUN_PARAMETER, "''{0}'' on function parameter is not allowed", TO_STRING);
|
||||
map.put(VAL_OR_VAR_ON_CATCH_PARAMETER, "''{0}'' on catch parameter is not allowed", TO_STRING);
|
||||
map.put(VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER, "''{0}'' on secondary constructor parameter is not allowed", TO_STRING);
|
||||
|
||||
// Unresolved
|
||||
map.put(INVISIBLE_REFERENCE, "Symbol {0} is invisible", SYMBOL)
|
||||
@@ -624,6 +635,24 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
map.put(UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE, "Extension function type can not be used as an upper bound")
|
||||
map.put(INCOMPATIBLE_TYPES, "Incompatible types: {0} and {1}", RENDER_TYPE, RENDER_TYPE)
|
||||
map.put(INCOMPATIBLE_TYPES_WARNING, "Potentially incompatible types: {0} and {1}", RENDER_TYPE, RENDER_TYPE)
|
||||
map.put(
|
||||
SMARTCAST_IMPOSSIBLE,
|
||||
"Smart cast to ''{0}'' is impossible, because ''{1}'' is a {2}",
|
||||
RENDER_TYPE,
|
||||
FIR,
|
||||
TO_STRING
|
||||
)
|
||||
|
||||
map.put(
|
||||
TYPE_VARIANCE_CONFLICT,
|
||||
"Type parameter {0} is declared as ''{1}'' but occurs in ''{2}'' position in type {3}",
|
||||
SYMBOL, RENDER_POSITION_VARIANCE, RENDER_POSITION_VARIANCE, RENDER_TYPE
|
||||
)
|
||||
map.put(
|
||||
TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE,
|
||||
"Type parameter {0} is declared as ''{1}'' but occurs in ''{2}'' position in abbreviated type {3}",
|
||||
SYMBOL, RENDER_POSITION_VARIANCE, RENDER_POSITION_VARIANCE, RENDER_TYPE
|
||||
)
|
||||
|
||||
map.put(
|
||||
BOUNDS_NOT_ALLOWED_IF_BOUNDED_BY_TYPE_PARAMETER,
|
||||
@@ -654,7 +683,7 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
||||
|
||||
map.put(TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER, "Type parameter of a property must be used in its receiver type")
|
||||
|
||||
map.put(RETURN_TYPE_MISMATCH, "Return type mismatch: expected {0}, actual {1}", RENDER_TYPE, RENDER_TYPE)
|
||||
map.put(RETURN_TYPE_MISMATCH, "Return type mismatch: expected {0}, actual {1}", RENDER_TYPE, RENDER_TYPE, NOT_RENDERED)
|
||||
|
||||
map.put(CYCLIC_GENERIC_UPPER_BOUND, "Type parameter has cyclic upper bounds")
|
||||
|
||||
|
||||
@@ -144,6 +144,7 @@ class FirDiagnosticFactory4<P : PsiElement, A, B, C, D>(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun incorrectElement(element: FirSourceElement): Nothing {
|
||||
throw IllegalArgumentException("Unknown element type: ${element::class}")
|
||||
}
|
||||
@@ -174,3 +175,13 @@ fun <P : PsiElement, A, B, C> FirDiagnosticFactory3<P, A, B, C>.on(
|
||||
): FirDiagnosticWithParameters3<*, A, B, C>? {
|
||||
return element?.let { on(it, a, b, c) }
|
||||
}
|
||||
|
||||
fun <P : PsiElement, A, B, C, D> FirDiagnosticFactory4<P, A, B, C, D>.on(
|
||||
element: FirSourceElement?,
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
d: D
|
||||
): FirDiagnosticWithParameters4<*, A, B, C, D>? {
|
||||
return element?.let { on(it, a, b, c, d) }
|
||||
}
|
||||
@@ -9,12 +9,18 @@ import org.jetbrains.kotlin.diagnostics.rendering.*
|
||||
|
||||
interface FirDiagnosticRenderer<D : FirDiagnostic<*>> : DiagnosticRenderer<D> {
|
||||
override fun render(diagnostic: D): String
|
||||
|
||||
override fun renderParameters(diagnostic: D): Array<out Any?>
|
||||
}
|
||||
|
||||
class SimpleFirDiagnosticRenderer(private val message: String) : FirDiagnosticRenderer<FirSimpleDiagnostic<*>> {
|
||||
override fun render(diagnostic: FirSimpleDiagnostic<*>): String {
|
||||
return message
|
||||
}
|
||||
|
||||
override fun renderParameters(diagnostic: FirSimpleDiagnostic<*>): Array<out Any?> {
|
||||
return arrayOf()
|
||||
}
|
||||
}
|
||||
|
||||
sealed class AbstractFirDiagnosticWithParametersRenderer<D : FirDiagnostic<*>>(
|
||||
|
||||
@@ -409,12 +409,15 @@ object LightTreePositioningStrategies {
|
||||
endOffset: Int,
|
||||
tree: FlyweightCapableTreeStructure<LighterASTNode>
|
||||
): List<TextRange> {
|
||||
//PSI counterpart simply search for first RPAR descendant, but this one is more correct
|
||||
return tree.findDescendantByType(node, KtNodeTypes.VALUE_ARGUMENT_LIST)?.let { valueArgumentList ->
|
||||
val nodeToStart = when (node.tokenType) {
|
||||
in KtTokens.QUALIFIED_ACCESS -> tree.findLastChildByType(node, KtNodeTypes.CALL_EXPRESSION) ?: node
|
||||
else -> node
|
||||
}
|
||||
return tree.findDescendantByType(nodeToStart, KtNodeTypes.VALUE_ARGUMENT_LIST)?.let { valueArgumentList ->
|
||||
tree.findLastChildByType(valueArgumentList, KtTokens.RPAR)?.let { rpar ->
|
||||
markElement(rpar, startOffset, endOffset, tree, node)
|
||||
}
|
||||
} ?: markElement(node, startOffset, endOffset, tree, node)
|
||||
} ?: markElement(nodeToStart, startOffset, endOffset, tree, node)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,7 +457,7 @@ object LightTreePositioningStrategies {
|
||||
return markElement(it, startOffset, endOffset, tree, node)
|
||||
}
|
||||
}
|
||||
if (node.tokenType != KtNodeTypes.DOT_QUALIFIED_EXPRESSION && node.tokenType != KtNodeTypes.SAFE_ACCESS_EXPRESSION) {
|
||||
if (node.tokenType !in KtTokens.QUALIFIED_ACCESS) {
|
||||
return super.mark(node, startOffset, endOffset, tree)
|
||||
}
|
||||
val selector = tree.selector(node)
|
||||
@@ -865,7 +868,7 @@ private fun FlyweightCapableTreeStructure<LighterASTNode>.rightParenthesis(node:
|
||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.objectKeyword(node: LighterASTNode): LighterASTNode? =
|
||||
findChildByType(node, KtTokens.OBJECT_KEYWORD)
|
||||
|
||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.valOrVarKeyword(node: LighterASTNode): LighterASTNode? =
|
||||
internal fun FlyweightCapableTreeStructure<LighterASTNode>.valOrVarKeyword(node: LighterASTNode): LighterASTNode? =
|
||||
findChildByType(node, VAL_VAR_TOKEN_SET)
|
||||
|
||||
internal fun FlyweightCapableTreeStructure<LighterASTNode>.visibilityModifier(declaration: LighterASTNode): LighterASTNode? =
|
||||
@@ -1021,7 +1024,7 @@ fun FlyweightCapableTreeStructure<LighterASTNode>.collectDescendantsOfType(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun FlyweightCapableTreeStructure<LighterASTNode>.findChildByType(node: LighterASTNode, type: TokenSet): LighterASTNode? {
|
||||
fun FlyweightCapableTreeStructure<LighterASTNode>.findChildByType(node: LighterASTNode, type: TokenSet): LighterASTNode? {
|
||||
val childrenRef = Ref<Array<LighterASTNode?>>()
|
||||
getChildren(node, childrenRef)
|
||||
return childrenRef.get()?.firstOrNull { it?.tokenType in type }
|
||||
|
||||
@@ -46,6 +46,15 @@ private fun ConeDiagnostic.toFirDiagnostic(
|
||||
val candidate = candidates.first { it.currentApplicability == CandidateApplicability.UNSAFE_CALL }
|
||||
val unsafeCall = candidate.diagnostics.firstIsInstance<UnsafeCall>()
|
||||
mapUnsafeCallError(candidate, unsafeCall, source, qualifiedAccessSource)
|
||||
} else if (this.applicability == CandidateApplicability.UNSTABLE_SMARTCAST) {
|
||||
val unstableSmartcast =
|
||||
this.candidates.first { it.currentApplicability == CandidateApplicability.UNSTABLE_SMARTCAST }.diagnostics.firstIsInstance<UnstableSmartCast>()
|
||||
FirErrors.SMARTCAST_IMPOSSIBLE.on(
|
||||
unstableSmartcast.argument.source,
|
||||
unstableSmartcast.targetType,
|
||||
unstableSmartcast.argument,
|
||||
unstableSmartcast.argument.smartcastStability.description
|
||||
)
|
||||
} else {
|
||||
FirErrors.NONE_APPLICABLE.on(source, this.candidates.map { it.symbol })
|
||||
}
|
||||
@@ -134,8 +143,8 @@ private fun mapInapplicableCandidateError(
|
||||
source: FirSourceElement,
|
||||
qualifiedAccessSource: FirSourceElement?,
|
||||
): List<FirDiagnostic<FirSourceElement>> {
|
||||
// TODO: Need to distinguish SMARTCAST_IMPOSSIBLE
|
||||
return diagnostic.candidate.diagnostics.filter { it.applicability == diagnostic.applicability }.mapNotNull { rootCause ->
|
||||
val genericDiagnostic = FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)
|
||||
val diagnostics = diagnostic.candidate.diagnostics.filter { it.applicability == diagnostic.applicability }.mapNotNull { rootCause ->
|
||||
when (rootCause) {
|
||||
is VarargArgumentOutsideParentheses -> FirErrors.VARARG_OUTSIDE_PARENTHESES.on(
|
||||
rootCause.argument.source ?: qualifiedAccessSource
|
||||
@@ -166,9 +175,21 @@ private fun mapInapplicableCandidateError(
|
||||
is InfixCallOfNonInfixFunction -> FirErrors.INFIX_MODIFIER_REQUIRED.on(source, rootCause.function)
|
||||
is OperatorCallOfNonOperatorFunction ->
|
||||
FirErrors.OPERATOR_MODIFIER_REQUIRED.on(source, rootCause.function, rootCause.function.fir.name.asString())
|
||||
else -> null
|
||||
is UnstableSmartCast -> FirErrors.SMARTCAST_IMPOSSIBLE.on(
|
||||
rootCause.argument.source,
|
||||
rootCause.targetType,
|
||||
rootCause.argument,
|
||||
rootCause.argument.smartcastStability.description
|
||||
)
|
||||
else -> genericDiagnostic
|
||||
}
|
||||
}.ifEmpty { listOf(FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol)) }
|
||||
}.distinct()
|
||||
return if (diagnostics.size > 1) {
|
||||
// If there are more specific diagnostics, filter out the generic diagnostic.
|
||||
diagnostics.filter { it != genericDiagnostic }
|
||||
} else {
|
||||
diagnostics
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
|
||||
@@ -80,7 +80,7 @@ class FirTypeDeserializer(
|
||||
for ((index, proto) in typeParameterProtos.withIndex()) {
|
||||
val builder = builders[index]
|
||||
builder.apply {
|
||||
proto.upperBoundList.mapTo(bounds) {
|
||||
proto.upperBounds(typeTable).mapTo(bounds) {
|
||||
buildResolvedTypeRef { type = type(it) }
|
||||
}
|
||||
addDefaultBoundIfNecessary()
|
||||
|
||||
@@ -17,10 +17,6 @@ dependencies {
|
||||
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
|
||||
testCompileOnly(intellijDep())
|
||||
|
||||
testRuntimeOnly(intellijDep())
|
||||
|
||||
testCompileOnly(project(":kotlin-test:kotlin-test-jvm"))
|
||||
testCompileOnly(project(":kotlin-test:kotlin-test-junit"))
|
||||
testApi(projectTests(":compiler:test-infrastructure"))
|
||||
@@ -39,6 +35,33 @@ dependencies {
|
||||
|
||||
testCompileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
testRuntimeOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
|
||||
testRuntimeOnly(intellijDep()) {
|
||||
includeJars(
|
||||
"jps-model",
|
||||
"extensions",
|
||||
"util",
|
||||
"platform-api",
|
||||
"platform-impl",
|
||||
"idea",
|
||||
"guava",
|
||||
"trove4j",
|
||||
"asm-all",
|
||||
"log4j",
|
||||
"jdom",
|
||||
"streamex",
|
||||
"bootstrap",
|
||||
"jna",
|
||||
rootProject = rootProject
|
||||
)
|
||||
}
|
||||
|
||||
Platform[202] {
|
||||
testRuntimeOnly(intellijDep()) { includeJars("intellij-deps-fastutil-8.3.1-1") }
|
||||
}
|
||||
Platform[203].orHigher {
|
||||
testRuntimeOnly(intellijDep()) { includeJars("intellij-deps-fastutil-8.3.1-3") }
|
||||
}
|
||||
}
|
||||
|
||||
val generationRoot = projectDir.resolve("tests-gen")
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
@@ -214,6 +215,10 @@ open class FirJvmMangleComputer(
|
||||
}
|
||||
is FirClassSymbol -> symbol.fir.accept(copy(MangleMode.FQNAME), false)
|
||||
is FirTypeParameterSymbol -> tBuilder.mangleTypeParameterReference(symbol.fir)
|
||||
// This is performed for a case with invisible class-like symbol in fake override
|
||||
null -> (type.lookupTag as? ConeClassLikeLookupTag)?.let {
|
||||
tBuilder.append(it.classId)
|
||||
}
|
||||
}
|
||||
|
||||
type.typeArguments.asList().ifNotEmpty {
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.ir.util.classId
|
||||
import org.jetbrains.kotlin.ir.util.coerceToUnitIfNeeded
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
|
||||
class Fir2IrImplicitCastInserter(
|
||||
private val components: Fir2IrComponents,
|
||||
@@ -274,7 +275,11 @@ class Fir2IrImplicitCastInserter(
|
||||
}
|
||||
|
||||
override fun visitExpressionWithSmartcast(expressionWithSmartcast: FirExpressionWithSmartcast, data: IrElement): IrExpression {
|
||||
return implicitCastOrExpression(data as IrExpression, expressionWithSmartcast.typeRef)
|
||||
return if (expressionWithSmartcast.smartcastStability == SmartcastStability.STABLE_VALUE) {
|
||||
implicitCastOrExpression(data as IrExpression, expressionWithSmartcast.typeRef)
|
||||
} else {
|
||||
data as IrExpression
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitExpressionWithSmartcastToNull(
|
||||
|
||||
@@ -52,6 +52,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/annotations/annotatedObjectLiteral.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationOnWhen.kt")
|
||||
public void testAnnotationOnWhen() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/annotationOnWhen.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationProperty.kt")
|
||||
public void testAnnotationProperty() throws Exception {
|
||||
@@ -1638,6 +1644,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/boxingOptimization/kt19767_chain.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46859.kt")
|
||||
public void testKt46859() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/boxingOptimization/kt46859.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt5493.kt")
|
||||
public void testKt5493() throws Exception {
|
||||
@@ -2434,6 +2446,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayConstructor.kt")
|
||||
public void testArrayConstructor() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/arrayConstructor.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("arrayConstructorArgument.kt")
|
||||
public void testArrayConstructorArgument() throws Exception {
|
||||
@@ -2536,6 +2554,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/callableReference/kt44483.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46902.kt")
|
||||
public void testKt46902() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/kt46902.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nested.kt")
|
||||
public void testNested() throws Exception {
|
||||
@@ -15264,6 +15288,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/extensionProperties/inClassWithSetter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46952.kt")
|
||||
public void testKt46952() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/extensionProperties/kt46952.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt9897.kt")
|
||||
public void testKt9897() throws Exception {
|
||||
@@ -15662,6 +15692,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/fir/noSymbolForIntRangeIterator.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SamWithReceiverMavenProjectImportHandler.kt")
|
||||
public void testSamWithReceiverMavenProjectImportHandler() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/fir/SamWithReceiverMavenProjectImportHandler.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("SuspendExtension.kt")
|
||||
public void testSuspendExtension() throws Exception {
|
||||
@@ -17563,18 +17599,78 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/callableReferencesProperCompletion.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("capturedTypes.kt")
|
||||
public void testCapturedTypes() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/capturedTypes.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperType.kt")
|
||||
public void testCommonSuperType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/commonSuperType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeContravariant.kt")
|
||||
public void testCommonSuperTypeContravariant() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/commonSuperTypeContravariant.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeCovariant.kt")
|
||||
public void testCommonSuperTypeCovariant() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/commonSuperTypeCovariant.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeInvariant.kt")
|
||||
public void testCommonSuperTypeInvariant() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/commonSuperTypeInvariant.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("commonSuperTypeNullable.kt")
|
||||
public void testCommonSuperTypeNullable() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/commonSuperTypeNullable.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("intersect.kt")
|
||||
public void testIntersect() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/intersect.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt41164.kt")
|
||||
public void testKt41164() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/kt41164.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("labaledCall.kt")
|
||||
public void testLabaledCall() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/labaledCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("lackOfNullCheckOnNullableInsideBuild.kt")
|
||||
public void testLackOfNullCheckOnNullableInsideBuild() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/lackOfNullCheckOnNullableInsideBuild.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("memberScope.kt")
|
||||
public void testMemberScope() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/memberScope.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullability.kt")
|
||||
public void testNullability() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/nullability.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("propagateInferenceSessionIntoDeclarationAnalyzers.kt")
|
||||
public void testPropagateInferenceSessionIntoDeclarationAnalyzers() throws Exception {
|
||||
@@ -17593,6 +17689,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesDontCareTypeInBlockExpression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferencesDontCareTypeInBlockExression.kt")
|
||||
public void testSpecialCallsWithCallableReferencesDontCareTypeInBlockExression() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesDontCareTypeInBlockExression.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferencesDontRewriteAtSlice.kt")
|
||||
public void testSpecialCallsWithCallableReferencesDontRewriteAtSlice() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/specialCallsWithCallableReferencesDontRewriteAtSlice.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("specialCallsWithCallableReferencesErrorType.kt")
|
||||
public void testSpecialCallsWithCallableReferencesErrorType() throws Exception {
|
||||
@@ -17658,6 +17766,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testTopDownCompletionWithTwoBuilderInferenceCalls() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/topDownCompletionWithTwoBuilderInferenceCalls.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("withExpectedType.kt")
|
||||
public void testWithExpectedType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inference/builderInference/withExpectedType.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21109,6 +21223,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/genericLambdaSignature.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inlineOnly.kt")
|
||||
public void testInlineOnly() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/invokedynamic/sam/inlineOnly.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("insideInitBlock.kt")
|
||||
public void testInsideInitBlock() throws Exception {
|
||||
@@ -27247,6 +27367,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testKt20844() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/optimizations/kt20844.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46921.kt")
|
||||
public void testKt46921() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/optimizations/kt46921.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@@ -27878,6 +28004,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/primitiveTypes/kt446.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46864_double.kt")
|
||||
public void testKt46864_double() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/primitiveTypes/kt46864_double.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46864_long.kt")
|
||||
public void testKt46864_long() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/primitiveTypes/kt46864_long.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt518.kt")
|
||||
public void testKt518() throws Exception {
|
||||
@@ -40522,6 +40660,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
public void testKt46578_propertyRef() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/syntheticAccessors/protectedJavaFieldAccessor/kt46578_propertyRef.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("kt46900_jkk_inheritance.kt")
|
||||
public void testKt46900_jkk_inheritance() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/syntheticAccessors/protectedJavaFieldAccessor/kt46900_jkk_inheritance.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
@@ -4981,12 +4981,24 @@ public class FirBlackBoxInlineCodegenTestGenerated extends AbstractFirBlackBoxIn
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/suspend/inlineClass"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("returnBoxedFromLambda.kt")
|
||||
public void testReturnBoxedFromLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/inlineClass/returnBoxedFromLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("returnUnboxedDirect.kt")
|
||||
public void testReturnUnboxedDirect() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/inlineClass/returnUnboxedDirect.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("returnUnboxedFromLambda.kt")
|
||||
public void testReturnUnboxedFromLambda() throws Exception {
|
||||
runTest("compiler/testData/codegen/boxInline/suspend/inlineClass/returnUnboxedFromLambda.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("returnUnboxedResume.kt")
|
||||
public void testReturnUnboxedResume() throws Exception {
|
||||
|
||||
@@ -131,7 +131,7 @@ class JvmMappedScope(
|
||||
|
||||
// NOTE: No-arg constructors
|
||||
@OptIn(ExperimentalStdlibApi::class)
|
||||
private val additionalHiddenConstructors = buildSet {
|
||||
private val additionalHiddenConstructors = buildSet<String> {
|
||||
// kotlin.text.String pseudo-constructors should be used instead of java.lang.String constructors
|
||||
listOf(
|
||||
"",
|
||||
|
||||
@@ -40,8 +40,6 @@ private val expressionSet = listOf(
|
||||
FUN
|
||||
)
|
||||
|
||||
val qualifiedAccessTokens = TokenSet.create(DOT_QUALIFIED_EXPRESSION, SAFE_ACCESS_EXPRESSION)
|
||||
|
||||
fun String?.nameAsSafeName(defaultName: String = ""): Name {
|
||||
return when {
|
||||
this != null -> Name.identifier(this.replace("`", ""))
|
||||
|
||||
@@ -86,7 +86,7 @@ class ExpressionsConverter(
|
||||
ANNOTATED_EXPRESSION -> convertAnnotatedExpression(expression)
|
||||
CLASS_LITERAL_EXPRESSION -> convertClassLiteralExpression(expression)
|
||||
CALLABLE_REFERENCE_EXPRESSION -> convertCallableReferenceExpression(expression)
|
||||
in qualifiedAccessTokens -> convertQualifiedExpression(expression)
|
||||
in QUALIFIED_ACCESS -> convertQualifiedExpression(expression)
|
||||
CALL_EXPRESSION -> convertCallExpression(expression)
|
||||
WHEN -> convertWhenExpression(expression)
|
||||
ARRAY_ACCESS_EXPRESSION -> convertArrayAccessExpression(expression)
|
||||
|
||||
@@ -10,7 +10,10 @@ import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.fir.*
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.*
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeStubDiagnostic
|
||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||
@@ -23,12 +26,12 @@ import org.jetbrains.kotlin.fir.resolve.calls.ImplicitDispatchReceiverValue
|
||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.*
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.getSymbolByTypeRef
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectData
|
||||
import org.jetbrains.kotlin.fir.symbols.*
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
@@ -36,6 +39,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.name.*
|
||||
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
|
||||
fun List<FirQualifierPart>.toTypeProjections(): Array<ConeTypeProjection> =
|
||||
asReversed().flatMap { it.typeArgumentList.typeArguments.map { typeArgument -> typeArgument.toConeTypeProjection() } }.toTypedArray()
|
||||
@@ -246,7 +250,8 @@ private fun BodyResolveComponents.typeFromSymbol(symbol: AbstractFirBasedSymbol<
|
||||
fun BodyResolveComponents.transformQualifiedAccessUsingSmartcastInfo(
|
||||
qualifiedAccessExpression: FirQualifiedAccessExpression
|
||||
): FirQualifiedAccessExpression {
|
||||
val typesFromSmartCast = dataFlowAnalyzer.getTypeUsingSmartcastInfo(qualifiedAccessExpression) ?: return qualifiedAccessExpression
|
||||
val (stability, typesFromSmartCast) = dataFlowAnalyzer.getTypeUsingSmartcastInfo(qualifiedAccessExpression)
|
||||
?: return qualifiedAccessExpression
|
||||
val originalType = qualifiedAccessExpression.resultType.coneType
|
||||
// For example, if (x == null) { ... },
|
||||
// we don't want to smartcast to Nothing?, but we want to record the nullability to its own kind of node.
|
||||
@@ -267,9 +272,11 @@ fun BodyResolveComponents.transformQualifiedAccessUsingSmartcastInfo(
|
||||
return buildExpressionWithSmartcastToNull {
|
||||
originalExpression = qualifiedAccessExpression
|
||||
// TODO: Use Nothing? during resolution?
|
||||
typeRef = intersectedTypeRefWithoutNullableNothing
|
||||
smartcastType = intersectedTypeRefWithoutNullableNothing
|
||||
// NB: Nothing? in types from smartcast in DFA is recorded here (and the expression kind itself).
|
||||
this.typesFromSmartCast = typesFromSmartCast
|
||||
// TODO: differentiate capture local variable
|
||||
this.smartcastStability = stability.impliedSmartcastStability ?: SmartcastStability.STABLE_VALUE
|
||||
}
|
||||
}
|
||||
val allTypes = typesFromSmartCast.also {
|
||||
@@ -285,8 +292,10 @@ fun BodyResolveComponents.transformQualifiedAccessUsingSmartcastInfo(
|
||||
}
|
||||
return buildExpressionWithSmartcast {
|
||||
originalExpression = qualifiedAccessExpression
|
||||
typeRef = intersectedTypeRef
|
||||
smartcastType = intersectedTypeRef
|
||||
this.typesFromSmartCast = typesFromSmartCast
|
||||
// TODO: differentiate capture local variable
|
||||
this.smartcastStability = stability.impliedSmartcastStability ?: SmartcastStability.STABLE_VALUE
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,9 +10,11 @@ import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolved
|
||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.FirUnstableSmartcastTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirScopeWithFakeOverrideTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.impl.FirStandardOverrideChecker
|
||||
@@ -25,6 +27,25 @@ import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
|
||||
fun FirExpressionWithSmartcast.smartcastScope(
|
||||
useSiteSession: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
): FirTypeScope? {
|
||||
val smartcastType = smartcastType.coneType
|
||||
val smartcastScope = smartcastType.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
if (smartcastStability == SmartcastStability.STABLE_VALUE) {
|
||||
return smartcastScope
|
||||
}
|
||||
val originalScope = originalType.coneType.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
?: return smartcastScope
|
||||
|
||||
if (smartcastScope == null) {
|
||||
return originalScope
|
||||
}
|
||||
return FirUnstableSmartcastTypeScope(smartcastType, smartcastScope, originalScope)
|
||||
}
|
||||
|
||||
fun ConeKotlinType.scope(
|
||||
useSiteSession: FirSession,
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.utils.WeakPair
|
||||
import org.jetbrains.kotlin.fir.utils.component1
|
||||
import org.jetbrains.kotlin.fir.utils.component2
|
||||
@@ -93,8 +94,18 @@ private fun mapTypeAliasArguments(
|
||||
val type = (projection as? ConeKotlinTypeProjection)?.type ?: return null
|
||||
val symbol = (type as? ConeTypeParameterType)?.lookupTag?.symbol ?: return super.substituteArgument(projection)
|
||||
val mappedProjection = typeAliasMap[symbol] ?: return super.substituteArgument(projection)
|
||||
val mappedType = (mappedProjection as? ConeKotlinTypeProjection)?.type.updateNullabilityIfNeeded(type)
|
||||
?: return mappedProjection
|
||||
var mappedType = (mappedProjection as? ConeKotlinTypeProjection)?.type.updateNullabilityIfNeeded(type)
|
||||
mappedType = when (mappedType) {
|
||||
is ConeClassErrorType,
|
||||
is ConeClassLikeTypeImpl,
|
||||
is ConeDefinitelyNotNullType,
|
||||
is ConeTypeParameterTypeImpl,
|
||||
is ConeFlexibleType -> {
|
||||
mappedType.withAttributes(type.attributes, useSiteSession.typeContext)
|
||||
}
|
||||
null -> return mappedProjection
|
||||
else -> mappedType
|
||||
}
|
||||
|
||||
return when (mappedProjection.kind + projection.kind) {
|
||||
ProjectionKind.STAR -> ConeStarProjection
|
||||
|
||||
@@ -30,9 +30,9 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubtypeConstraintIfCompatible
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystemConstraintPosition
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
import org.jetbrains.kotlin.types.model.CaptureStatus
|
||||
import org.jetbrains.kotlin.types.model.TypeSystemCommonSuperTypesContext
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.runIf
|
||||
@@ -358,17 +358,7 @@ private fun checkApplicabilityForArgumentType(
|
||||
) {
|
||||
if (expectedType == null) return
|
||||
|
||||
fun unstableSmartCastOrSubtypeError(
|
||||
unstableType: ConeKotlinType?,
|
||||
actualExpectedType: ConeKotlinType,
|
||||
position: ConstraintPosition
|
||||
): ResolutionDiagnostic {
|
||||
if (unstableType != null) {
|
||||
if (csBuilder.addSubtypeConstraintIfCompatible(unstableType, actualExpectedType, position)) {
|
||||
return UnstableSmartCast.ResolutionError(argument, unstableType)
|
||||
}
|
||||
}
|
||||
|
||||
fun subtypeError(actualExpectedType: ConeKotlinType): ResolutionDiagnostic {
|
||||
if (argument.isNullLiteral && actualExpectedType.nullability == ConeNullability.NOT_NULL) {
|
||||
return NullForNotNullType(argument)
|
||||
}
|
||||
@@ -406,14 +396,17 @@ private fun checkApplicabilityForArgumentType(
|
||||
}
|
||||
|
||||
if (!csBuilder.addSubtypeConstraintIfCompatible(argumentType, expectedType, position)) {
|
||||
val smartcastExpression = argument as? FirExpressionWithSmartcast
|
||||
if (smartcastExpression != null && smartcastExpression.smartcastStability != SmartcastStability.STABLE_VALUE) {
|
||||
val unstableType = smartcastExpression.smartcastType.coneType
|
||||
if (csBuilder.addSubtypeConstraintIfCompatible(unstableType, expectedType, position)) {
|
||||
sink.reportDiagnostic(UnstableSmartCast(smartcastExpression, expectedType))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (!isReceiver) {
|
||||
sink.reportDiagnosticIfNotNull(
|
||||
unstableSmartCastOrSubtypeError(
|
||||
unstableType = null, // TODO: handle unstable smartcasts
|
||||
expectedType,
|
||||
position
|
||||
)
|
||||
)
|
||||
sink.reportDiagnosticIfNotNull(subtypeError(expectedType))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
||||
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildExpressionWithSmartcast
|
||||
import org.jetbrains.kotlin.fir.expressions.builder.buildThisReceiverExpression
|
||||
@@ -16,6 +17,7 @@ import org.jetbrains.kotlin.fir.renderWithType
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||
import org.jetbrains.kotlin.fir.resolve.scope
|
||||
import org.jetbrains.kotlin.fir.resolve.smartcastScope
|
||||
import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype
|
||||
import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator
|
||||
import org.jetbrains.kotlin.fir.scopes.FirTypeScope
|
||||
@@ -27,6 +29,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.coneType
|
||||
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
|
||||
interface Receiver
|
||||
|
||||
@@ -56,7 +59,11 @@ abstract class AbstractExplicitReceiverValue<E : FirExpression> : AbstractExplic
|
||||
|
||||
class ExpressionReceiverValue(
|
||||
override val explicitReceiver: FirExpression
|
||||
) : AbstractExplicitReceiverValue<FirExpression>(), ReceiverValue
|
||||
) : AbstractExplicitReceiverValue<FirExpression>(), ReceiverValue {
|
||||
override fun scope(useSiteSession: FirSession, scopeSession: ScopeSession): FirTypeScope? =
|
||||
(receiverExpression as? FirExpressionWithSmartcast)?.smartcastScope(useSiteSession, scopeSession)
|
||||
?: type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
}
|
||||
|
||||
sealed class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
|
||||
val boundSymbol: S,
|
||||
@@ -89,8 +96,9 @@ sealed class ImplicitReceiverValue<S : AbstractFirBasedSymbol<*>>(
|
||||
} else {
|
||||
buildExpressionWithSmartcast {
|
||||
originalExpression = originalReceiverExpression
|
||||
typeRef = originalReceiverExpression.typeRef.resolvedTypeFromPrototype(type)
|
||||
smartcastType = originalReceiverExpression.typeRef.resolvedTypeFromPrototype(type)
|
||||
typesFromSmartCast = listOf(type)
|
||||
smartcastStability = SmartcastStability.STABLE_VALUE
|
||||
}
|
||||
}
|
||||
implicitScope = type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
||||
import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
@@ -74,21 +75,7 @@ object LowerPriorityToPreserveCompatibilityDiagnostic : ResolutionDiagnostic(RES
|
||||
|
||||
object CandidateChosenUsingOverloadResolutionByLambdaAnnotation : ResolutionDiagnostic(RESOLVED)
|
||||
|
||||
sealed class UnstableSmartCast(
|
||||
val argument: FirExpression,
|
||||
val targetType: ConeKotlinType,
|
||||
applicability: CandidateApplicability
|
||||
) : ResolutionDiagnostic(applicability) {
|
||||
class ResolutionError(
|
||||
argument: FirExpression,
|
||||
targetType: ConeKotlinType,
|
||||
) : UnstableSmartCast(argument, targetType, MAY_THROW_RUNTIME_ERROR)
|
||||
|
||||
class DiagnosticError(
|
||||
argument: FirExpression,
|
||||
targetType: ConeKotlinType,
|
||||
) : UnstableSmartCast(argument, targetType, RESOLVED_WITH_ERROR)
|
||||
}
|
||||
class UnstableSmartCast(val argument: FirExpressionWithSmartcast, val targetType: ConeKotlinType) : ResolutionDiagnostic(UNSTABLE_SMARTCAST)
|
||||
|
||||
class ArgumentTypeMismatch(
|
||||
val expectedType: ConeKotlinType,
|
||||
|
||||
@@ -26,6 +26,8 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
|
||||
import org.jetbrains.kotlin.types.AbstractNullabilityChecker
|
||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
|
||||
abstract class ResolutionStage {
|
||||
abstract suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext)
|
||||
@@ -105,6 +107,19 @@ object CheckDispatchReceiver : ResolutionStage() {
|
||||
}
|
||||
}
|
||||
|
||||
if (explicitReceiverExpression is FirExpressionWithSmartcast && explicitReceiverExpression.smartcastStability != SmartcastStability.STABLE_VALUE) {
|
||||
val expectedDispatchReceiverType = (candidate.symbol.fir as? FirCallableMemberDeclaration)?.dispatchReceiverType
|
||||
if (expectedDispatchReceiverType != null &&
|
||||
!AbstractTypeChecker.isSubtypeOf(
|
||||
context.session.typeContext,
|
||||
explicitReceiverExpression.originalType.coneType,
|
||||
expectedDispatchReceiverType
|
||||
)
|
||||
) {
|
||||
sink.yieldDiagnostic(UnstableSmartCast(explicitReceiverExpression, expectedDispatchReceiverType))
|
||||
}
|
||||
}
|
||||
|
||||
val dispatchReceiverValueType = candidate.dispatchReceiverValue?.type ?: return
|
||||
|
||||
if (!AbstractNullabilityChecker.isSubtypeOfAny(context.session.typeContext, dispatchReceiverValueType)) {
|
||||
|
||||
@@ -16,24 +16,27 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.*
|
||||
import org.jetbrains.kotlin.fir.resolve.PersistentImplicitReceiverStack
|
||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.contracts.buildContractFir
|
||||
import org.jetbrains.kotlin.fir.resolve.dfa.contracts.createArgumentsMapping
|
||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformer
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType
|
||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.name.CallableId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.StandardClassIds
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
|
||||
@@ -159,7 +162,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
|
||||
// ----------------------------------- Requests -----------------------------------
|
||||
|
||||
fun getTypeUsingSmartcastInfo(qualifiedAccessExpression: FirQualifiedAccessExpression): MutableList<ConeKotlinType>? {
|
||||
fun getTypeUsingSmartcastInfo(qualifiedAccessExpression: FirQualifiedAccessExpression): Pair<PropertyStability, MutableList<ConeKotlinType>>? {
|
||||
/*
|
||||
* DataFlowAnalyzer holds variables only for declarations that have some smartcast (or can have)
|
||||
* If there is no useful information there is no data flow variable also
|
||||
@@ -167,13 +170,14 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
val symbol: AbstractFirBasedSymbol<*> = qualifiedAccessExpression.symbol ?: return null
|
||||
val flow = graphBuilder.lastNode.flow
|
||||
var variable = variableStorage.getRealVariableWithoutUnwrappingAlias(symbol, qualifiedAccessExpression, flow) ?: return null
|
||||
val stability = variable.stability
|
||||
val result = mutableListOf<ConeKotlinType>()
|
||||
flow.directAliasMap[variable]?.let {
|
||||
result.addIfNotNull(it.originalType)
|
||||
variable = it.variable
|
||||
}
|
||||
flow.getTypeStatement(variable)?.exactType?.let { result += it }
|
||||
return result.takeIf { it.isNotEmpty() }
|
||||
return result.takeIf { it.isNotEmpty() }?.let { stability to it }
|
||||
}
|
||||
|
||||
fun returnExpressionsOfAnonymousFunction(function: FirAnonymousFunction): Collection<FirStatement> {
|
||||
@@ -441,7 +445,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
val operandVariable = variableStorage.getOrCreateVariable(node.previousFlow, operand)
|
||||
// expression == const -> expression != null
|
||||
flow.addImplication((expressionVariable eq isEq) implies (operandVariable notEq null))
|
||||
if (operandVariable is RealVariable) {
|
||||
if (operandVariable.isReal()) {
|
||||
flow.addImplication((expressionVariable eq isEq) implies (operandVariable typeEq any))
|
||||
}
|
||||
|
||||
@@ -820,7 +824,7 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
?: return@let
|
||||
|
||||
val variable = variableStorage.getOrCreateVariable(flow, receiver)
|
||||
if (variable is RealVariable) {
|
||||
if (variable.isReal()) {
|
||||
if (shouldFork) {
|
||||
flow = logicSystem.forkFlow(flow)
|
||||
}
|
||||
@@ -1006,7 +1010,12 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
assignment: FirVariableAssignment?
|
||||
) {
|
||||
val flow = node.flow
|
||||
val propertyVariable = variableStorage.getOrCreateRealVariableWithoutUnwrappingAlias(flow, property.symbol, assignment ?: property)
|
||||
val propertyVariable = variableStorage.getOrCreateRealVariableWithoutUnwrappingAlias(
|
||||
flow,
|
||||
property.symbol,
|
||||
assignment ?: property,
|
||||
if (property.isVal) PropertyStability.STABLE_VALUE else PropertyStability.LOCAL_VAR
|
||||
)
|
||||
val isAssignment = assignment != null
|
||||
if (isAssignment) {
|
||||
logicSystem.removeLocalVariableAlias(flow, propertyVariable)
|
||||
@@ -1014,13 +1023,21 @@ abstract class FirDataFlowAnalyzer<FLOW : Flow>(
|
||||
logicSystem.recordNewAssignment(flow, propertyVariable, context.newAssignmentIndex())
|
||||
}
|
||||
|
||||
variableStorage.getOrCreateRealVariable(flow, initializer.symbol, initializer)?.let { initializerVariable ->
|
||||
logicSystem.addLocalVariableAlias(
|
||||
flow, propertyVariable,
|
||||
RealVariableAndType(initializerVariable, initializer.coneType)
|
||||
)
|
||||
// node.flow.addImplication((propertyVariable notEq null) implies (initializerVariable notEq null))
|
||||
}
|
||||
variableStorage.getOrCreateRealVariable(flow, initializer.symbol, initializer)
|
||||
?.let { initializerVariable ->
|
||||
// TODO: handle capture variable
|
||||
if ((initializerVariable.stability == PropertyStability.STABLE_VALUE || initializerVariable.stability == PropertyStability.LOCAL_VAR) &&
|
||||
(propertyVariable.stability == PropertyStability.STABLE_VALUE || propertyVariable.stability == PropertyStability.LOCAL_VAR)
|
||||
) {
|
||||
logicSystem.addLocalVariableAlias(
|
||||
flow, propertyVariable,
|
||||
RealVariableAndType(initializerVariable, initializer.coneType)
|
||||
)
|
||||
// node.flow.addImplication((propertyVariable notEq null) implies (initializerVariable notEq null))
|
||||
} else {
|
||||
logicSystem.replaceVariableFromConditionInStatements(flow, initializerVariable, propertyVariable)
|
||||
}
|
||||
}
|
||||
|
||||
variableStorage.getSyntheticVariable(initializer)?.let { initializerVariable ->
|
||||
/*
|
||||
|
||||
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.fir.resolve.dfa
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.modality
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
@@ -34,14 +36,24 @@ class VariableStorage(private val session: FirSession) {
|
||||
|
||||
fun clear(): VariableStorage = VariableStorage(session)
|
||||
|
||||
fun getOrCreateRealVariableWithoutUnwrappingAlias(flow: Flow, symbol: AbstractFirBasedSymbol<*>, fir: FirElement): RealVariable {
|
||||
fun getOrCreateRealVariableWithoutUnwrappingAlias(
|
||||
flow: Flow,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
fir: FirElement,
|
||||
stability: PropertyStability
|
||||
): RealVariable {
|
||||
val realFir = fir.unwrapElement()
|
||||
val identifier = getIdentifierBySymbol(flow, symbol, realFir)
|
||||
return _realVariables.getOrPut(identifier) { createRealVariableInternal(flow, identifier, realFir) }
|
||||
return _realVariables.getOrPut(identifier) { createRealVariableInternal(flow, identifier, realFir, stability) }
|
||||
}
|
||||
|
||||
private fun getOrCreateRealVariable(flow: Flow, symbol: AbstractFirBasedSymbol<*>, fir: FirElement): RealVariable {
|
||||
val variable = getOrCreateRealVariableWithoutUnwrappingAlias(flow, symbol, fir)
|
||||
private fun getOrCreateRealVariable(
|
||||
flow: Flow,
|
||||
symbol: AbstractFirBasedSymbol<*>,
|
||||
fir: FirElement,
|
||||
stability: PropertyStability
|
||||
): RealVariable {
|
||||
val variable = getOrCreateRealVariableWithoutUnwrappingAlias(flow, symbol, fir, stability)
|
||||
return flow.directAliasMap[variable]?.variable ?: variable
|
||||
}
|
||||
|
||||
@@ -69,7 +81,12 @@ class VariableStorage(private val session: FirSession) {
|
||||
/**
|
||||
* [originalFir] used for extracting expression under <when_subject> and extracting receiver
|
||||
*/
|
||||
private fun createRealVariableInternal(flow: Flow, identifier: Identifier, originalFir: FirElement): RealVariable {
|
||||
private fun createRealVariableInternal(
|
||||
flow: Flow,
|
||||
identifier: Identifier,
|
||||
originalFir: FirElement,
|
||||
stability: PropertyStability
|
||||
): RealVariable {
|
||||
val receiver: FirExpression?
|
||||
val isThisReference: Boolean
|
||||
val expression: FirQualifiedAccess? = when (originalFir) {
|
||||
@@ -88,12 +105,12 @@ class VariableStorage(private val session: FirSession) {
|
||||
}
|
||||
|
||||
val receiverVariable = receiver?.let { getOrCreateVariable(flow, it) }
|
||||
return RealVariable(identifier, isThisReference, receiverVariable, counter++)
|
||||
return RealVariable(identifier, isThisReference, receiverVariable, counter++, stability)
|
||||
}
|
||||
|
||||
@JvmName("getOrCreateRealVariableOrNull")
|
||||
fun getOrCreateRealVariable(flow: Flow, symbol: AbstractFirBasedSymbol<*>?, fir: FirElement): RealVariable? =
|
||||
symbol.takeIf { it.isStable(fir) }?.let { getOrCreateRealVariable(flow, it, fir) }
|
||||
symbol.getStability(fir)?.let { getOrCreateRealVariable(flow, symbol!!, fir, it) }
|
||||
|
||||
fun createSyntheticVariable(fir: FirElement): SyntheticVariable =
|
||||
SyntheticVariable(fir, counter++).also { syntheticVariables[fir] = it }
|
||||
@@ -101,8 +118,9 @@ class VariableStorage(private val session: FirSession) {
|
||||
fun getOrCreateVariable(flow: Flow, fir: FirElement): DataFlowVariable {
|
||||
val realFir = fir.unwrapElement()
|
||||
val symbol = realFir.symbol
|
||||
return if (symbol.isStable(realFir)) {
|
||||
getOrCreateRealVariable(flow, symbol!!, realFir)
|
||||
val stability = symbol.getStability(realFir)
|
||||
return if (stability != null) {
|
||||
getOrCreateRealVariable(flow, symbol!!, realFir, stability)
|
||||
} else {
|
||||
syntheticVariables[realFir] ?: createSyntheticVariable(realFir)
|
||||
}
|
||||
@@ -110,7 +128,7 @@ class VariableStorage(private val session: FirSession) {
|
||||
|
||||
fun getRealVariableWithoutUnwrappingAlias(symbol: AbstractFirBasedSymbol<*>?, fir: FirElement, flow: Flow): RealVariable? {
|
||||
val realFir = fir.unwrapElement()
|
||||
return symbol.takeIf { it.isStable(realFir) }?.let {
|
||||
return symbol.takeIf { it.getStability(realFir) != null }?.let {
|
||||
_realVariables[getIdentifierBySymbol(flow, it, realFir.unwrapElement())]
|
||||
}
|
||||
}
|
||||
@@ -126,7 +144,8 @@ class VariableStorage(private val session: FirSession) {
|
||||
fun getVariable(fir: FirElement, flow: Flow): DataFlowVariable? {
|
||||
val realFir = fir.unwrapElement()
|
||||
val symbol = realFir.symbol
|
||||
return if (symbol.isStable(fir)) {
|
||||
val stability = symbol.getStability(fir)
|
||||
return if (stability != null) {
|
||||
getRealVariable(symbol, realFir, flow)
|
||||
} else {
|
||||
getSyntheticVariable(fir)
|
||||
@@ -138,44 +157,45 @@ class VariableStorage(private val session: FirSession) {
|
||||
}
|
||||
|
||||
fun removeSyntheticVariable(variable: DataFlowVariable) {
|
||||
if (variable !is SyntheticVariable) return
|
||||
if (!variable.isSynthetic()) return
|
||||
syntheticVariables.remove(variable.fir)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalContracts::class)
|
||||
fun AbstractFirBasedSymbol<*>?.isStable(originalFir: FirElement): Boolean {
|
||||
fun AbstractFirBasedSymbol<*>?.getStability(originalFir: FirElement): PropertyStability? {
|
||||
contract {
|
||||
returns(true) implies(this@isStable != null)
|
||||
returnsNotNull() implies (this@getStability != null)
|
||||
}
|
||||
when (this) {
|
||||
is FirAnonymousObjectSymbol -> return false
|
||||
is FirAnonymousObjectSymbol -> return null
|
||||
is FirFunctionSymbol<*>,
|
||||
is FirClassSymbol<*>,
|
||||
is FirBackingFieldSymbol -> return true
|
||||
null -> return false
|
||||
is FirBackingFieldSymbol -> return PropertyStability.STABLE_VALUE
|
||||
null -> return null
|
||||
}
|
||||
if (originalFir is FirThisReceiverExpression) return true
|
||||
if (this !is FirVariableSymbol<*>) return false
|
||||
if (originalFir is FirThisReceiverExpression) return PropertyStability.STABLE_VALUE
|
||||
if (this !is FirVariableSymbol<*>) return null
|
||||
|
||||
val property = this.fir as? FirProperty ?: return true
|
||||
val property = this.fir as? FirProperty ?: return PropertyStability.STABLE_VALUE
|
||||
|
||||
return when {
|
||||
property.isLocal -> true
|
||||
property.isVar -> false
|
||||
property.receiverTypeRef != null -> false
|
||||
property.getter.let { it != null && it !is FirDefaultPropertyAccessor } -> false
|
||||
property.delegate != null -> PropertyStability.DELEGATED_PROPERTY
|
||||
property.isLocal -> if (property.isVal) PropertyStability.STABLE_VALUE else PropertyStability.LOCAL_VAR
|
||||
property.isVar -> PropertyStability.MUTABLE_PROPERTY
|
||||
property.receiverTypeRef != null -> PropertyStability.PROPERTY_WITH_GETTER
|
||||
property.getter.let { it != null && it !is FirDefaultPropertyAccessor } -> PropertyStability.PROPERTY_WITH_GETTER
|
||||
property.moduleData.session != session -> PropertyStability.ALIEN_PUBLIC_PROPERTY
|
||||
property.modality != Modality.FINAL -> {
|
||||
val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccess)?.dispatchReceiver ?: return false
|
||||
val receiverType = dispatchReceiver.typeRef.coneTypeSafe<ConeClassLikeType>()?.fullyExpandedType(session) ?: return false
|
||||
val receiverSymbol = receiverType.lookupTag.toSymbol(session) ?: return false
|
||||
val dispatchReceiver = (originalFir.unwrapElement() as? FirQualifiedAccess)?.dispatchReceiver ?: return null
|
||||
val receiverType = dispatchReceiver.typeRef.coneTypeSafe<ConeClassLikeType>()?.fullyExpandedType(session) ?: return null
|
||||
val receiverSymbol = receiverType.lookupTag.toSymbol(session) ?: return null
|
||||
when (val receiverFir = receiverSymbol.fir) {
|
||||
is org.jetbrains.kotlin.fir.declarations.FirAnonymousObject -> true
|
||||
is org.jetbrains.kotlin.fir.declarations.FirRegularClass -> receiverFir.modality == Modality.FINAL
|
||||
is FirAnonymousObject -> PropertyStability.STABLE_VALUE
|
||||
is FirRegularClass -> if (receiverFir.modality == Modality.FINAL) PropertyStability.STABLE_VALUE else PropertyStability.PROPERTY_WITH_GETTER
|
||||
else -> throw IllegalStateException("Should not be here: $receiverFir")
|
||||
}
|
||||
|
||||
}
|
||||
else -> true
|
||||
else -> PropertyStability.STABLE_VALUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.types.ConeClassErrorType
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
@@ -33,11 +34,37 @@ sealed class DataFlowVariable(private val variableIndexForDebug: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
enum class PropertyStability(val impliedSmartcastStability: SmartcastStability?) {
|
||||
// Immutable and no custom getter or local.
|
||||
// Smartcast is definitely safe regardless of usage.
|
||||
STABLE_VALUE(SmartcastStability.STABLE_VALUE),
|
||||
|
||||
// Open or custom getter.
|
||||
// Smartcast is always unsafe regardless of usage.
|
||||
PROPERTY_WITH_GETTER(SmartcastStability.PROPERTY_WITH_GETTER),
|
||||
|
||||
// Protected / public member value from another module.
|
||||
// Smartcast is always unsafe regardless of usage.
|
||||
ALIEN_PUBLIC_PROPERTY(SmartcastStability.ALIEN_PUBLIC_PROPERTY),
|
||||
|
||||
// Smartcast may or may not be safe, depending on whether there are concurrent writes to this local variable.
|
||||
LOCAL_VAR(null),
|
||||
|
||||
// Mutable member property of a class or object.
|
||||
// Smartcast is always unsafe regardless of usage.
|
||||
MUTABLE_PROPERTY(SmartcastStability.MUTABLE_PROPERTY),
|
||||
|
||||
// Delegated property of a class or object.
|
||||
// Smartcast is always unsafe regardless of usage.
|
||||
DELEGATED_PROPERTY(SmartcastStability.DELEGATED_PROPERTY),
|
||||
}
|
||||
|
||||
class RealVariable(
|
||||
val identifier: Identifier,
|
||||
val isThisReference: Boolean,
|
||||
val explicitReceiverVariable: DataFlowVariable?,
|
||||
variableIndexForDebug: Int
|
||||
variableIndexForDebug: Int,
|
||||
val stability: PropertyStability,
|
||||
) : DataFlowVariable(variableIndexForDebug) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
return this === other
|
||||
|
||||
@@ -63,7 +63,7 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
|
||||
|
||||
val checkers = buildList {
|
||||
exhaustivenessCheckers.filterTo(this) { it.isApplicable(cleanSubjectType, session) }
|
||||
if (isNotEmpty() && cleanSubjectType.isMarkedNullable) {
|
||||
if (isNotEmpty<WhenExhaustivenessChecker>() && cleanSubjectType.isMarkedNullable) {
|
||||
add(WhenOnNullableExhaustivenessChecker)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,6 +639,7 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform
|
||||
}
|
||||
|
||||
checkNotNullCall.argumentList.transformArguments(transformer, ResolutionMode.ContextDependent)
|
||||
checkNotNullCall.transformAnnotations(transformer, ResolutionMode.ContextIndependent)
|
||||
|
||||
var callCompleted = false
|
||||
val result = components.syntheticCallGenerator.generateCalleeForCheckNotNullCall(checkNotNullCall, resolutionContext)?.let {
|
||||
|
||||
@@ -251,11 +251,15 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
)
|
||||
}
|
||||
|
||||
override fun createStubType(typeVariable: TypeVariableMarker): StubTypeMarker {
|
||||
override fun createStubTypeForBuilderInference(typeVariable: TypeVariableMarker): StubTypeMarker {
|
||||
require(typeVariable is ConeTypeVariable) { "$typeVariable should subtype of ${ConeTypeVariable::class.qualifiedName}" }
|
||||
return ConeStubType(typeVariable, ConeNullability.create(typeVariable.defaultType().isMarkedNullable()))
|
||||
}
|
||||
|
||||
// TODO
|
||||
override fun createStubTypeForTypeVariablesInSubtyping(typeVariable: TypeVariableMarker) =
|
||||
createStubTypeForBuilderInference(typeVariable)
|
||||
|
||||
override fun KotlinTypeMarker.removeAnnotations(): KotlinTypeMarker {
|
||||
require(this is ConeKotlinType)
|
||||
return withAttributes(ConeAttributes.Empty, this@ConeInferenceContext)
|
||||
|
||||
@@ -380,7 +380,15 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.isStubType(): Boolean {
|
||||
return this is StubTypeMarker
|
||||
return this is ConeStubType // TODO: distinguish stub types for builder inference and for subtyping
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.isStubTypeForVariableInSubtyping(): Boolean {
|
||||
return this is ConeStubType // TODO: distinguish stub types for builder inference and for subtyping
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.isStubTypeForBuilderInference(): Boolean {
|
||||
return this is ConeStubType // TODO: distinguish stub types for builder inference and for subtyping
|
||||
}
|
||||
|
||||
override fun intersectTypes(types: List<SimpleTypeMarker>): SimpleTypeMarker {
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
||||
|
||||
@@ -31,6 +32,8 @@ abstract class FirExpressionWithSmartcast : FirQualifiedAccessExpression() {
|
||||
abstract val originalExpression: FirQualifiedAccessExpression
|
||||
abstract val typesFromSmartCast: Collection<ConeKotlinType>
|
||||
abstract val originalType: FirTypeRef
|
||||
abstract val smartcastType: FirTypeRef
|
||||
abstract val smartcastStability: SmartcastStability
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitExpressionWithSmartcast(this, data)
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.references.FirReference
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeProjection
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
import org.jetbrains.kotlin.fir.visitors.*
|
||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
||||
|
||||
@@ -31,6 +32,8 @@ abstract class FirExpressionWithSmartcastToNull : FirExpressionWithSmartcast() {
|
||||
abstract override val originalExpression: FirQualifiedAccessExpression
|
||||
abstract override val typesFromSmartCast: Collection<ConeKotlinType>
|
||||
abstract override val originalType: FirTypeRef
|
||||
abstract override val smartcastType: FirTypeRef
|
||||
abstract override val smartcastStability: SmartcastStability
|
||||
|
||||
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitExpressionWithSmartcastToNull(this, data)
|
||||
|
||||
|
||||
@@ -10,14 +10,16 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionWithSmartcastImpl
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
|
||||
class FirExpressionWithSmartcastBuilder {
|
||||
lateinit var originalExpression: FirQualifiedAccessExpression
|
||||
lateinit var typeRef: FirTypeRef
|
||||
lateinit var smartcastType: FirTypeRef
|
||||
lateinit var typesFromSmartCast: Collection<ConeKotlinType>
|
||||
lateinit var smartcastStability: SmartcastStability
|
||||
|
||||
fun build(): FirExpressionWithSmartcast {
|
||||
return FirExpressionWithSmartcastImpl(originalExpression, typeRef, typesFromSmartCast)
|
||||
return FirExpressionWithSmartcastImpl(originalExpression, smartcastType, typesFromSmartCast, smartcastStability)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,14 +10,16 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirExpressionWithSmartcastToNullImpl
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
|
||||
class FirExpressionWithSmartcastToNullBuilder {
|
||||
lateinit var originalExpression: FirQualifiedAccessExpression
|
||||
lateinit var typeRef: FirTypeRef
|
||||
lateinit var smartcastType: FirTypeRef
|
||||
lateinit var typesFromSmartCast: Collection<ConeKotlinType>
|
||||
lateinit var smartcastStability: SmartcastStability
|
||||
|
||||
fun build(): FirExpressionWithSmartcastToNull {
|
||||
return FirExpressionWithSmartcastToNullImpl(originalExpression, typeRef, typesFromSmartCast)
|
||||
return FirExpressionWithSmartcastToNullImpl(originalExpression, smartcastType, typesFromSmartCast, smartcastStability)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,11 +19,13 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
|
||||
internal class FirExpressionWithSmartcastImpl(
|
||||
override var originalExpression: FirQualifiedAccessExpression,
|
||||
override val typeRef: FirTypeRef,
|
||||
override val typesFromSmartCast: Collection<ConeKotlinType>
|
||||
override val smartcastType: FirTypeRef,
|
||||
override val typesFromSmartCast: Collection<ConeKotlinType>,
|
||||
override val smartcastStability: SmartcastStability
|
||||
) : FirExpressionWithSmartcast() {
|
||||
init {
|
||||
assert(originalExpression.typeRef is FirResolvedTypeRef)
|
||||
@@ -37,6 +39,10 @@ internal class FirExpressionWithSmartcastImpl(
|
||||
override val extensionReceiver: FirExpression get() = originalExpression.extensionReceiver
|
||||
override val calleeReference: FirReference get() = originalExpression.calleeReference
|
||||
override val originalType: FirTypeRef get() = originalExpression.typeRef
|
||||
// A FirExpressionWithSmartcast is only an effective smartcast if `smartcastStability == SmartcastStability.STABLE_VALUE`. Otherwise,
|
||||
// it's the same as the `originalExpression` under the hood. The reason we still create such a smartcast expression is for diagnostics
|
||||
// purpose only.
|
||||
override val typeRef: FirTypeRef get() = if (smartcastStability == SmartcastStability.STABLE_VALUE) smartcastType else originalType
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirExpressionWithSmartcast {
|
||||
originalExpression = originalExpression.transformSingle(transformer, data)
|
||||
|
||||
@@ -16,11 +16,13 @@ import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.FirVisitor
|
||||
import org.jetbrains.kotlin.fir.visitors.transformSingle
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
|
||||
class FirExpressionWithSmartcastToNullImpl(
|
||||
override var originalExpression: FirQualifiedAccessExpression,
|
||||
override val typeRef: FirTypeRef,
|
||||
override val typesFromSmartCast: Collection<ConeKotlinType>
|
||||
override val smartcastType: FirTypeRef,
|
||||
override val typesFromSmartCast: Collection<ConeKotlinType>,
|
||||
override val smartcastStability: SmartcastStability
|
||||
) : FirExpressionWithSmartcastToNull() {
|
||||
init {
|
||||
assert(originalExpression.typeRef is FirResolvedTypeRef)
|
||||
@@ -34,6 +36,10 @@ class FirExpressionWithSmartcastToNullImpl(
|
||||
override val extensionReceiver: FirExpression get() = originalExpression.extensionReceiver
|
||||
override val calleeReference: FirReference get() = originalExpression.calleeReference
|
||||
override val originalType: FirTypeRef get() = originalExpression.typeRef
|
||||
// A FirExpressionWithSmartcast is only an effective smartcast if `smartcastStability == SmartcastStability.STABLE_VALUE`. Otherwise,
|
||||
// it's the same as the `originalExpression` under the hood. The reason we still create such a smartcast expression is for diagnostics
|
||||
// purpose only.
|
||||
override val typeRef: FirTypeRef get() = if (smartcastStability == SmartcastStability.STABLE_VALUE) smartcastType else originalType
|
||||
|
||||
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirExpressionWithSmartcastToNull {
|
||||
originalExpression = originalExpression.transformSingle(transformer, data)
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
/**
|
||||
* Special type scope for unstable smartcast. The purpose of this scope is only to report "SMARTCAST_IMPOSSIBLE" diagnostics.
|
||||
*
|
||||
* This scope will serve all candidates available in the original scope. In addition, it also serve all additional members that are
|
||||
* available from the smartcast type. This way, these additional members can be resolved. Later in
|
||||
* [org.jetbrains.kotlin.fir.resolve.calls.CheckDispatchReceiver], these additional members are rejected with "UnstableSmartcast"
|
||||
* diagnostic, which surfaces as "SMARTCAST_IMPOSSIBLE" diagnostic.
|
||||
*/
|
||||
class FirUnstableSmartcastTypeScope(
|
||||
private val smartcastType: ConeKotlinType,
|
||||
private val smartcastScope: FirTypeScope,
|
||||
private val originalScope: FirTypeScope
|
||||
) : FirTypeScope(), FirContainingNamesAwareScope {
|
||||
private val scopes = listOf(smartcastScope, originalScope)
|
||||
override fun processClassifiersByNameWithSubstitution(
|
||||
name: Name,
|
||||
processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit
|
||||
) {
|
||||
for (scope in scopes) {
|
||||
scope.processClassifiersByNameWithSubstitution(name, processor)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <T> processComposite(
|
||||
process: FirTypeScope.(Name, (T) -> Unit) -> Unit,
|
||||
name: Name,
|
||||
noinline processor: (T) -> Unit
|
||||
) {
|
||||
val unique = mutableSetOf<T>()
|
||||
for (scope in scopes) {
|
||||
scope.process(name) {
|
||||
if (unique.add(it)) {
|
||||
processor(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun processFunctionsByName(name: Name, processor: (FirNamedFunctionSymbol) -> Unit) {
|
||||
return processComposite(FirScope::processFunctionsByName, name, processor)
|
||||
}
|
||||
|
||||
override fun processPropertiesByName(name: Name, processor: (FirVariableSymbol<*>) -> Unit) {
|
||||
return processComposite(FirScope::processPropertiesByName, name, processor)
|
||||
}
|
||||
|
||||
private inline fun <N, T : FirCallableSymbol<*>> processTypedComposite(
|
||||
process: FirTypeScope.(N, (T, FirTypeScope) -> ProcessorAction) -> ProcessorAction,
|
||||
name: N,
|
||||
noinline processor: (T, FirTypeScope) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
originalScope.process(name) { symbol, firTypeScope ->
|
||||
processor(symbol, firTypeScope)
|
||||
}.let { if (it == ProcessorAction.STOP) return ProcessorAction.STOP }
|
||||
|
||||
smartcastScope.process(name) { symbol, firTypeScope ->
|
||||
// Only process the symbol if the dispatcher type is exactly the smartcast type. This way, we don't add any additional
|
||||
// symbols that already exists in the original scope.
|
||||
if ((symbol.fir as? FirCallableMemberDeclaration)?.dispatchReceiverType == smartcastType) {
|
||||
processor(symbol, firTypeScope)
|
||||
} else {
|
||||
ProcessorAction.NEXT
|
||||
}
|
||||
}.let { if (it == ProcessorAction.STOP) return ProcessorAction.STOP }
|
||||
return ProcessorAction.NEXT
|
||||
}
|
||||
|
||||
override fun processDirectOverriddenFunctionsWithBaseScope(
|
||||
functionSymbol: FirNamedFunctionSymbol,
|
||||
processor: (FirNamedFunctionSymbol, FirTypeScope) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
return processTypedComposite(FirTypeScope::processDirectOverriddenFunctionsWithBaseScope, functionSymbol, processor)
|
||||
}
|
||||
|
||||
override fun processDirectOverriddenPropertiesWithBaseScope(
|
||||
propertySymbol: FirPropertySymbol,
|
||||
processor: (FirPropertySymbol, FirTypeScope) -> ProcessorAction
|
||||
): ProcessorAction {
|
||||
return processTypedComposite(FirTypeScope::processDirectOverriddenPropertiesWithBaseScope, propertySymbol, processor)
|
||||
}
|
||||
|
||||
override fun getCallableNames(): Set<Name> {
|
||||
return scopes.flatMapTo(hashSetOf()) { it.getContainingCallableNamesIfPresent() }
|
||||
}
|
||||
|
||||
override fun getClassifierNames(): Set<Name> {
|
||||
return scopes.flatMapTo(hashSetOf()) { it.getContainingClassifierNamesIfPresent() }
|
||||
}
|
||||
|
||||
override val scopeOwnerLookupNames: List<String> by lazy(LazyThreadSafetyMode.PUBLICATION) {
|
||||
scopes.flatMap { it.scopeOwnerLookupNames }
|
||||
}
|
||||
}
|
||||
@@ -83,4 +83,6 @@ object FieldSets {
|
||||
val modality = field(modalityType, nullable = true)
|
||||
|
||||
val scopeProvider = field("scopeProvider", firScopeProviderType)
|
||||
|
||||
val smartcastStability = field(smartcastStabilityType)
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.tree.generator.FieldSets.name
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.receivers
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.returnTypeRef
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.scopeProvider
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.smartcastStability
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.status
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.superTypeRefs
|
||||
import org.jetbrains.kotlin.fir.tree.generator.FieldSets.symbol
|
||||
@@ -458,12 +459,16 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
|
||||
+field("originalExpression", qualifiedAccessExpression)
|
||||
+field("typesFromSmartCast", "Collection<ConeKotlinType>", null, customType = coneKotlinTypeType)
|
||||
+field("originalType", typeRef)
|
||||
+field("smartcastType", typeRef)
|
||||
+smartcastStability
|
||||
}
|
||||
|
||||
expressionWithSmartcastToNull.configure {
|
||||
+field("originalExpression", qualifiedAccessExpression)
|
||||
+field("typesFromSmartCast", "Collection<ConeKotlinType>", null, customType = coneKotlinTypeType)
|
||||
+field("originalType", typeRef)
|
||||
+field("smartcastType", typeRef)
|
||||
+smartcastStability
|
||||
}
|
||||
|
||||
safeCallExpression.configure {
|
||||
|
||||
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.SmartcastStability
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
|
||||
val sourceElementType = type("fir", "FirSourceElement")
|
||||
@@ -31,6 +32,7 @@ val nameType = type(Name::class)
|
||||
val visibilityType = type(Visibility::class)
|
||||
val effectiveVisibilityType = type("descriptors", "EffectiveVisibility")
|
||||
val modalityType = type(Modality::class)
|
||||
val smartcastStabilityType = type(SmartcastStability::class)
|
||||
val fqNameType = type(FqName::class)
|
||||
val classIdType = type(ClassId::class)
|
||||
val annotationUseSiteTargetType = type(AnnotationUseSiteTarget::class)
|
||||
|
||||
@@ -9,4 +9,6 @@ import org.jetbrains.kotlin.diagnostics.UnboundDiagnostic
|
||||
|
||||
interface DiagnosticRenderer<in D : UnboundDiagnostic> {
|
||||
fun render(diagnostic: D): String
|
||||
|
||||
fun renderParameters(diagnostic: D): Array<out Any?>
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ object RuntimeAssertionsTypeChecker : AdditionalTypeChecker {
|
||||
expressionTypeWithSmartCast: KotlinType,
|
||||
c: ResolutionContext<*>
|
||||
) {
|
||||
if (TypeUtils.noExpectedType(c.expectedType) || c.expectedType is StubType) return
|
||||
if (TypeUtils.noExpectedType(c.expectedType) || c.expectedType is StubTypeForBuilderInference) return
|
||||
|
||||
val assertionInfo = RuntimeAssertionInfo.create(
|
||||
c.expectedType,
|
||||
|
||||
@@ -15,7 +15,6 @@ dependencies {
|
||||
compile(project(":compiler:frontend.common"))
|
||||
compile(project(":kotlin-script-runtime"))
|
||||
compile(commonDep("io.javaslang","javaslang"))
|
||||
api(project(":core:compiler.common.jvm"))
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeJars("trove4j", "guava", rootProject = rootProject) }
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.diagnostics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DiagnosticFactory4<E extends PsiElement, A, B, C, D> extends DiagnosticFactoryWithPsiElement<E, DiagnosticWithParameters4<E, A, B, C, D>> {
|
||||
|
||||
protected DiagnosticFactory4(Severity severity, PositioningStrategy<? super E> positioningStrategy) {
|
||||
super(severity, positioningStrategy);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T extends PsiElement, A, B, C, D> DiagnosticFactory4<T, A, B, C, D> create(Severity severity) {
|
||||
return create(severity, PositioningStrategies.DEFAULT);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T extends PsiElement, A, B, C, D> DiagnosticFactory4<T, A, B, C, D> create(Severity severity, PositioningStrategy<? super T> positioningStrategy) {
|
||||
return new DiagnosticFactory4<>(severity, positioningStrategy);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ParametrizedDiagnostic<E> on(@NotNull E element, @NotNull A a, @NotNull B b, @NotNull C c, @NotNull D d) {
|
||||
return new DiagnosticWithParameters4<>(element, a, b, c, d,this, getSeverity());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2010-2015 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.diagnostics;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class DiagnosticWithParameters4<E extends PsiElement, A, B, C, D> extends AbstractDiagnostic<E> {
|
||||
private final A a;
|
||||
private final B b;
|
||||
private final C c;
|
||||
private final D d;
|
||||
|
||||
public DiagnosticWithParameters4(
|
||||
@NotNull E psiElement,
|
||||
@NotNull A a,
|
||||
@NotNull B b,
|
||||
@NotNull C c,
|
||||
@NotNull D d,
|
||||
@NotNull DiagnosticFactory4<E, A, B, C, D> factory,
|
||||
@NotNull Severity severity
|
||||
) {
|
||||
super(psiElement, factory, severity);
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
this.d = d;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public DiagnosticFactory4<E, A, B, C, D> getFactory() {
|
||||
return (DiagnosticFactory4<E, A, B, C, D>) super.getFactory();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public A getA() {
|
||||
return a;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public B getB() {
|
||||
return b;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public C getC() {
|
||||
return c;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public D getD() {
|
||||
return d;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getFactory() + "(a = " + a + ", b = " + b + ", c = " + c + ", d = " + d + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
DiagnosticWithParameters4<?, ?, ?, ?, ?> that = (DiagnosticWithParameters4<?, ?, ?, ?, ?>) o;
|
||||
return Objects.equals(a, that.a) &&
|
||||
Objects.equals(b, that.b) &&
|
||||
Objects.equals(c, that.c) &&
|
||||
Objects.equals(d, that.d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), a, b, c, d);
|
||||
}
|
||||
}
|
||||
@@ -614,7 +614,11 @@ object PositioningStrategies {
|
||||
@JvmField
|
||||
val VALUE_ARGUMENTS: PositioningStrategy<KtElement> = object : PositioningStrategy<KtElement>() {
|
||||
override fun mark(element: KtElement): List<TextRange> {
|
||||
return markElement(element.findDescendantOfType<KtValueArgumentList>()?.rightParenthesis ?: element)
|
||||
val qualifiedAccess = when (element) {
|
||||
is KtQualifiedExpression -> element.selectorExpression ?: element
|
||||
else -> element
|
||||
}
|
||||
return markElement(qualifiedAccess.findDescendantOfType<KtValueArgumentList>()?.rightParenthesis ?: qualifiedAccess)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ fun ResolutionContext<*>.reportTypeMismatchDueToTypeProjection(
|
||||
}
|
||||
|
||||
fun BindingTrace.reportDiagnosticOnce(diagnostic: Diagnostic) {
|
||||
if (bindingContext.diagnostics.forElement(diagnostic.psiElement).any { it.factory == diagnostic.factory }) return
|
||||
if (bindingContext.diagnostics.noSuppression().forElement(diagnostic.psiElement).any { it.factory == diagnostic.factory }) return
|
||||
|
||||
report(diagnostic)
|
||||
}
|
||||
@@ -119,8 +119,10 @@ fun BindingTrace.reportDiagnosticOnceWrtDiagnosticFactoryList(
|
||||
diagnosticToReport: Diagnostic,
|
||||
vararg diagnosticFactories: DiagnosticFactory<*>,
|
||||
) {
|
||||
val hasAlreadyReportedDiagnosticFromListOrSameType = bindingContext.diagnostics.forElement(diagnosticToReport.psiElement)
|
||||
.any { diagnostic -> diagnostic.factory == diagnosticToReport.factory || diagnosticFactories.any { it == diagnostic.factory } }
|
||||
val hasAlreadyReportedDiagnosticFromListOrSameType =
|
||||
bindingContext.diagnostics.noSuppression()
|
||||
.forElement(diagnosticToReport.psiElement)
|
||||
.any { diagnostic -> diagnostic.factory == diagnosticToReport.factory || diagnosticFactories.any { it == diagnostic.factory } }
|
||||
|
||||
if (hasAlreadyReportedDiagnosticFromListOrSameType) return
|
||||
|
||||
|
||||
@@ -79,6 +79,16 @@ public final class DiagnosticFactoryToRendererMap {
|
||||
map.put(factory, new DiagnosticWithParameters3Renderer<A, B, C>(message, rendererA, rendererB, rendererC));
|
||||
}
|
||||
|
||||
public <E extends PsiElement, A, B, C, D> void put(@NotNull DiagnosticFactory4<E, A, B, C, D> factory,
|
||||
@NotNull String message,
|
||||
@Nullable DiagnosticParameterRenderer<? super A> rendererA,
|
||||
@Nullable DiagnosticParameterRenderer<? super B> rendererB,
|
||||
@Nullable DiagnosticParameterRenderer<? super C> rendererC,
|
||||
@Nullable DiagnosticParameterRenderer<? super D> rendererD) {
|
||||
checkMutability();
|
||||
map.put(factory, new DiagnosticWithParameters4Renderer<A, B, C, D>(message, rendererA, rendererB, rendererC, rendererD));
|
||||
}
|
||||
|
||||
public void put(@NotNull DiagnosticFactory<?> factory, @NotNull DiagnosticRenderer<?> renderer) {
|
||||
checkMutability();
|
||||
map.put(factory, renderer);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user