diff --git a/ChangeLog.md b/ChangeLog.md index 4f7905ace3a..3732d6cb14d 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,7 +1,7 @@ # CHANGELOG -## 1.4.30-M1 +## 1.4.30 ### Android @@ -13,23 +13,20 @@ - [`KT-42234`](https://youtrack.jetbrains.com/issue/KT-42234) Move LLVM optimization parameters into konan.properties - [`KT-42649`](https://youtrack.jetbrains.com/issue/KT-42649) IndexOutOfBoundsException during InlineClassTransformer lowering - [`KT-42942`](https://youtrack.jetbrains.com/issue/KT-42942) Native: optimize peak backend memory by clearing BindingContext after psi2ir -- [`KT-43198`](https://youtrack.jetbrains.com/issue/KT-43198) init blocks inside inline classes -- [`KT-31072`](https://youtrack.jetbrains.com/issue/KT-31072) Don't use non-reified arguments to specialize type operations in IR inliner - -### Backend. JS -- [`KT-41227`](https://youtrack.jetbrains.com/issue/KT-41227) KJS IR: don't copy to child's prototype references to the function from parent - -### Backend. IR -- [`KT-41227`](https://youtrack.jetbrains.com/issue/KT-41227) KJS IR: don't copy to child's prototype references to the function from parent +- [`KT-43198`](https://youtrack.jetbrains.com/issue/KT-43198) Native: support `init` blocks inside inline classes ### Compiler #### New Features -- [`KT-28055`](https://youtrack.jetbrains.com/issue/KT-28055) Consider supporting `init` blocks inside inline classes +- [`KT-28055`](https://youtrack.jetbrains.com/issue/KT-28055) Support `init` blocks inside inline classes - [`KT-28056`](https://youtrack.jetbrains.com/issue/KT-28056) Consider supporting non-public primary constructors for inline classes +- [`KT-41265`](https://youtrack.jetbrains.com/issue/KT-41265) Support noarg compiler plugin for JVM IR - [`KT-42094`](https://youtrack.jetbrains.com/issue/KT-42094) Allow open callable members in expect interfaces - [`KT-43129`](https://youtrack.jetbrains.com/issue/KT-43129) FIR: Support OverloadResolutionByLambdaReturnType +- [`KT-43592`](https://youtrack.jetbrains.com/issue/KT-43592) Promote JVM IR compiler backend to Beta +- [`KT-43919`](https://youtrack.jetbrains.com/issue/KT-43919) Support loading Java annotations on base classes and implementing interfaces' type arguments +- [`KT-44021`](https://youtrack.jetbrains.com/issue/KT-44021) Enable JVM IR backend by default in 1.5 #### Performance Improvements @@ -40,12 +37,25 @@ #### Fixes +- [`KT-11454`](https://youtrack.jetbrains.com/issue/KT-11454) Load annotations on TYPE_USE/TYPE_PARAMETER positions from Java class-files +- [`KT-11732`](https://youtrack.jetbrains.com/issue/KT-11732) Verify error for generic interface method invocation with default parameters +- [`KT-14612`](https://youtrack.jetbrains.com/issue/KT-14612) "ISE: Recursive call in a lazy value" during processing of a (weakly) recursive type alias +- [`KT-18344`](https://youtrack.jetbrains.com/issue/KT-18344) Upper bound of a typealias type parameter is not reported correctly if it contains the typealias itself +- [`KT-18768`](https://youtrack.jetbrains.com/issue/KT-18768) @Notnull annotation from Java does not work with varargs +- [`KT-20548`](https://youtrack.jetbrains.com/issue/KT-20548) java.lang.IllegalStateException: Illegal class container on simple Java code parsing - [`KT-22465`](https://youtrack.jetbrains.com/issue/KT-22465) Excessive synthetic method for private setter from superclass +- [`KT-23816`](https://youtrack.jetbrains.com/issue/KT-23816) Inline classes: constants and annotations +- [`KT-24158`](https://youtrack.jetbrains.com/issue/KT-24158) AE: No receiver found on incomplete code with $-signs +- [`KT-24392`](https://youtrack.jetbrains.com/issue/KT-24392) Nullability of Java arrays is read incorrectly if @Nullable annotation has both targets TYPE_USE and VALUE_PARAMETER - [`KT-26229`](https://youtrack.jetbrains.com/issue/KT-26229) Lambda/anonymous function argument in parentheses is not supported for callsInPlace effect +- [`KT-29735`](https://youtrack.jetbrains.com/issue/KT-29735) KNPE at `KtEnumEntrySuperclassReferenceExpression.getReferencedElement` with explicit type argument inside enum member constructor +- [`KT-31389`](https://youtrack.jetbrains.com/issue/KT-31389) ClassFormatError with companion object in annotation with @JvmStatic +- [`KT-31907`](https://youtrack.jetbrains.com/issue/KT-31907) ISE: UNIT_EXPECTED_TYPE on parsing array literal inside lambda with Unit return type - [`KT-32228`](https://youtrack.jetbrains.com/issue/KT-32228) Inconsistent boxing/unboxing for inline classes when interface is specialized by object expression - [`KT-32450`](https://youtrack.jetbrains.com/issue/KT-32450) Inline class incorrectly gets re-wrapped when provided to a function - [`KT-35849`](https://youtrack.jetbrains.com/issue/KT-35849) Missing nullability assertion on lambda return value if expected type has generic return value type - [`KT-35902`](https://youtrack.jetbrains.com/issue/KT-35902) Kotlin generates a private parameterless constructor for constructors taking inline class arguments with default values +- [`KT-36399`](https://youtrack.jetbrains.com/issue/KT-36399) Gradually support TYPE_USE nullability annotations read from class-files - [`KT-36769`](https://youtrack.jetbrains.com/issue/KT-36769) JVM IR: Missing LVT entries for inline function (default) parameters at call site - [`KT-36982`](https://youtrack.jetbrains.com/issue/KT-36982) JVM IR: SAM adapter classes are generated as synthetic - [`KT-37007`](https://youtrack.jetbrains.com/issue/KT-37007) JVM IR: extraneous property accessors are generated in multifile facade for InlineOnly property @@ -57,11 +67,18 @@ - [`KT-39709`](https://youtrack.jetbrains.com/issue/KT-39709) [FIR] False positive UNINITIALIZED_VARIABLE in presence of complex graph with jumps - [`KT-39923`](https://youtrack.jetbrains.com/issue/KT-39923) Result.Failure will get wrapped with Success when using with RxJava - [`KT-40198`](https://youtrack.jetbrains.com/issue/KT-40198) '$default' methods in 'kotlin/test/AssertionsKt' generated as non-synthetic by JVM_IR +- [`KT-40200`](https://youtrack.jetbrains.com/issue/KT-40200) IDE: Multiple top-level main functions in different files: broken highlighting, "No descriptor resolved for FUN" - [`KT-40262`](https://youtrack.jetbrains.com/issue/KT-40262) ACC_DEPRECATED flag not generated for property getter delegate in multifile class facade in JVM_IR - [`KT-40282`](https://youtrack.jetbrains.com/issue/KT-40282) Inline class wrapping Any gets double boxed - [`KT-40464`](https://youtrack.jetbrains.com/issue/KT-40464) JVM_IR does not generate LINENUMBER at closing brace of (suspend) lambda +- [`KT-40500`](https://youtrack.jetbrains.com/issue/KT-40500) Warnings reporting by Java nullability annotations doesn't work for not top-level types +- [`KT-40926`](https://youtrack.jetbrains.com/issue/KT-40926) IDE import actions do not add required import for convention `invoke()` extension call - [`KT-40948`](https://youtrack.jetbrains.com/issue/KT-40948) IllegalAccessError while initializing val property in EXACTLY_ONCE lambda that is passed to another function +- [`KT-40991`](https://youtrack.jetbrains.com/issue/KT-40991) NI: UNRESOLVED_REFERENCE_WRONG_RECEIVER instead of FUNCTION_EXPECTED with convention `invoke` call +- [`KT-41163`](https://youtrack.jetbrains.com/issue/KT-41163) Double wrapped value in Result class after map operation +- [`KT-41284`](https://youtrack.jetbrains.com/issue/KT-41284) Spring CGLIB proxies break auto-generated data class componentN and copy methods when using JVM IR - [`KT-41468`](https://youtrack.jetbrains.com/issue/KT-41468) JVM IR: IllegalAccessError on access to abstract base member from another package, from anonymous object inside abstract class +- [`KT-41491`](https://youtrack.jetbrains.com/issue/KT-41491) UNRESOLVED_REFERENCE_WRONG_RECEIVER instead of FUNCTION_EXPECTED when invoking non-functional value as a function - [`KT-41493`](https://youtrack.jetbrains.com/issue/KT-41493) JVM IR: names of classes for local delegated variables contain the variable name twice - [`KT-41792`](https://youtrack.jetbrains.com/issue/KT-41792) [FIR] Introduce & use ConeAttribute.UnsafeVariance - [`KT-41793`](https://youtrack.jetbrains.com/issue/KT-41793) [FIR] Make captured types accessible at the end of resolve @@ -70,13 +87,16 @@ - [`KT-41841`](https://youtrack.jetbrains.com/issue/KT-41841) JVM IR: delegates for private functions with default arguments are generated in multifile classes - [`KT-41857`](https://youtrack.jetbrains.com/issue/KT-41857) Flaky 'ConcurrentModificationException' through `kotlin.serialization.DescriptorSerializer` - [`KT-41903`](https://youtrack.jetbrains.com/issue/KT-41903) JVM IR: do not generate LineNumberTable in auto-generated members of data classes +- [`KT-41911`](https://youtrack.jetbrains.com/issue/KT-41911) JVM IR: nested big-arity function calls are not lowered - [`KT-41957`](https://youtrack.jetbrains.com/issue/KT-41957) JVM IR: step into suspend function goes to the first line of the file - [`KT-41960`](https://youtrack.jetbrains.com/issue/KT-41960) JVM IR: smart step into members implemented with delegation to interface doesn't work - [`KT-41961`](https://youtrack.jetbrains.com/issue/KT-41961) JVM IR: line numbers are not generated in JvmMultifileClass facade declarations - [`KT-41962`](https://youtrack.jetbrains.com/issue/KT-41962) JVM IR: intermittent -1 line numbers in the state machine cause double stepping in the debugger +- [`KT-42001`](https://youtrack.jetbrains.com/issue/KT-42001) Cannot resolve symbol: AssertionError: Module is not contained in his own dependencies - [`KT-42002`](https://youtrack.jetbrains.com/issue/KT-42002) JVM / IR: IllegalStateException: "No mapping for symbol: VAR IR_TEMPORARY_VARIABLE" caused by named arguments - [`KT-42021`](https://youtrack.jetbrains.com/issue/KT-42021) JVM / IR: "IndexOutOfBoundsException: Index 0 out of bounds for length 0" during IR lowering with suspend conversion - [`KT-42033`](https://youtrack.jetbrains.com/issue/KT-42033) JVM IR: accidental override in Map subclass with custom implementations of some members +- [`KT-42036`](https://youtrack.jetbrains.com/issue/KT-42036) IR: "AssertionError: TypeAliasDescriptor expected: deserialized class Nothing" when referencing typealias with @UnsafeVariance - [`KT-42043`](https://youtrack.jetbrains.com/issue/KT-42043) JVM IR: Don't generate collection stubs when implementing methods with more specific return types - [`KT-42044`](https://youtrack.jetbrains.com/issue/KT-42044) Compiler error when lambda with contract surrounded with parentheses - [`KT-42114`](https://youtrack.jetbrains.com/issue/KT-42114) JVM_IR generates stub for 'removeIf' in abstract classes implementing 'List' and 'Set' @@ -103,7 +123,9 @@ - [`KT-42384`](https://youtrack.jetbrains.com/issue/KT-42384) FIR (BE): top-level field has no parent class in BE - [`KT-42496`](https://youtrack.jetbrains.com/issue/KT-42496) FIR resolve: synthetic property is written but has no setter - [`KT-42517`](https://youtrack.jetbrains.com/issue/KT-42517) FIR: exception in BE for recursive inline call +- [`KT-42530`](https://youtrack.jetbrains.com/issue/KT-42530) "AssertionError: No type for resolved lambda argument" on attempting to assign a Pair to a couple of values in a scratch file - [`KT-42601`](https://youtrack.jetbrains.com/issue/KT-42601) [FIR] Inherited declaration clash for stdlib inheritors +- [`KT-42622`](https://youtrack.jetbrains.com/issue/KT-42622) NI: IllegalStateException for if expression with method reference inside flow - [`KT-42642`](https://youtrack.jetbrains.com/issue/KT-42642) ISE: No `getProgressionLastElement` for progression type IntProgressionType - [`KT-42650`](https://youtrack.jetbrains.com/issue/KT-42650) JVM IR: extraneous nullability annotation on a generic function of a flexible type - [`KT-42656`](https://youtrack.jetbrains.com/issue/KT-42656) FIR2IR: unsupported callable reference for Java field @@ -117,6 +139,8 @@ - [`KT-42933`](https://youtrack.jetbrains.com/issue/KT-42933) JVM / IR: "AnalyzerException: Expected an object reference, but found I" with local delegate in inline class - [`KT-43006`](https://youtrack.jetbrains.com/issue/KT-43006) JVM/JVM_IR: do not generate no-arg constructor for constructor with default arguments if there are inline class types in the signature - [`KT-43017`](https://youtrack.jetbrains.com/issue/KT-43017) JVM / IR: AssertionError when callable reference passed into a function requiring a suspendable function +- [`KT-43051`](https://youtrack.jetbrains.com/issue/KT-43051) JVM IR: extraneous methods overridding default (Java 8) collection methods in inline class that extends MutableList +- [`KT-43067`](https://youtrack.jetbrains.com/issue/KT-43067) Inner class declaration inside inline class should be prohibited - [`KT-43068`](https://youtrack.jetbrains.com/issue/KT-43068) JVM IR: no generic signatures for explicitly written methods in a List subclass, whose signature coincides with MutableList methods - [`KT-43132`](https://youtrack.jetbrains.com/issue/KT-43132) JVM / IR: Method name '' in class '...$screenTexts$1$1' cannot be represented in dex format. - [`KT-43145`](https://youtrack.jetbrains.com/issue/KT-43145) JVM IR: $default methods in multi-file facades are generated as non-synthetic final @@ -125,6 +149,7 @@ - [`KT-43199`](https://youtrack.jetbrains.com/issue/KT-43199) JVM IR: synthetic flag for deprecated-hidden is not generated for DeprecatedSinceKotlin and deprecation from override - [`KT-43207`](https://youtrack.jetbrains.com/issue/KT-43207) JVM IR: no collection stub for `iterator` is generated on extending AbstractCollection - [`KT-43217`](https://youtrack.jetbrains.com/issue/KT-43217) JVM_IR: Multiple FAKE_OVERRIDES for java methods using @NonNull Double and java double +- [`KT-43225`](https://youtrack.jetbrains.com/issue/KT-43225) Confusing message of warning NULLABLE_TYPE_PARAMETER_AGAINST_NOT_NULL_TYPE_PARAMETER - [`KT-43226`](https://youtrack.jetbrains.com/issue/KT-43226) "Incompatible stack heights" with non-local return to outer lambda inside suspend lambda - [`KT-43242`](https://youtrack.jetbrains.com/issue/KT-43242) JVM / IR: "AnalyzerException: Expected I, but found R" caused by `when` inside object with @Nullable Integer subject - [`KT-43249`](https://youtrack.jetbrains.com/issue/KT-43249) Wrong code generated for suspend lambdas with inline class parameters @@ -133,25 +158,59 @@ - [`KT-43327`](https://youtrack.jetbrains.com/issue/KT-43327) JVM_IR: No deprecated or synthetic flag for accessors of deprecated-hidden property of unsigned type - [`KT-43332`](https://youtrack.jetbrains.com/issue/KT-43332) FIR: Smart casts lead to false-positive ambiguity - [`KT-43370`](https://youtrack.jetbrains.com/issue/KT-43370) JVM IR: No deprecated flag for getter of deprecated property copied via delegation by interface +- [`KT-43459`](https://youtrack.jetbrains.com/issue/KT-43459) JVM_IR. Wrong signature for synthetic $annotations method for extension property on nullable primitive +- [`KT-43478`](https://youtrack.jetbrains.com/issue/KT-43478) NI: "IndexOutOfBoundsException: Index: 3, Size: 3" caused by `is` check with raw type inside `if` condition with `when` inside +- [`KT-43519`](https://youtrack.jetbrains.com/issue/KT-43519) JVM_IR. External functions generated differently in multi file facades +- [`KT-43524`](https://youtrack.jetbrains.com/issue/KT-43524) JVM_IR. Missed deprecation flag on companion @JvmStatic property accessor - [`KT-43525`](https://youtrack.jetbrains.com/issue/KT-43525) Prohibit JvmOverloads on declarations with inline class types in parameters +- [`KT-43536`](https://youtrack.jetbrains.com/issue/KT-43536) JVM IR: IllegalStateException is not caught by runCatching under Deferred.await() with kotlinx.coroutines - [`KT-43562`](https://youtrack.jetbrains.com/issue/KT-43562) JVM IR: incorrect mangling for Collection.size in unsigned arrays - [`KT-43584`](https://youtrack.jetbrains.com/issue/KT-43584) [FIR] Java annotations with named arguments aren't loaded correctly +- [`KT-43587`](https://youtrack.jetbrains.com/issue/KT-43587) Invalid default parameter value in expect actual declaration on jvm +- [`KT-43630`](https://youtrack.jetbrains.com/issue/KT-43630) "AssertionError: Number of arguments should not be less than number of parameters" during capturing intersection raw type with star projection +- [`KT-43698`](https://youtrack.jetbrains.com/issue/KT-43698) NoSuchMethodError for inline class implementing interface with @JvmDefault methods, -Xjvm-default=enable +- [`KT-43741`](https://youtrack.jetbrains.com/issue/KT-43741) Report error on inline class implementing 'kotlin.Cloneable' +- [`KT-43845`](https://youtrack.jetbrains.com/issue/KT-43845) org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Failed to generate expression: KtBlockExpression +- [`KT-43956`](https://youtrack.jetbrains.com/issue/KT-43956) NI: "Error type encountered – UninferredParameterTypeConstructor" on "try" and other constructs with code block as a value +- [`KT-44055`](https://youtrack.jetbrains.com/issue/KT-44055) Left uninferred type parameter for callable references inside special calls +- [`KT-44113`](https://youtrack.jetbrains.com/issue/KT-44113) Compiler frontend exception: Number of arguments should not be less than number of parameters, but: parameters=2, args=1 +- [`KT-44145`](https://youtrack.jetbrains.com/issue/KT-44145) No highlighting for not initialized base constructor and NoSuchMethodError in Android plugin ### IDE +#### New Features + +- [`KT-44075`](https://youtrack.jetbrains.com/issue/KT-44075) Sealed interfaces: New Kotlin Class/File menu update + +#### Fixes + +- [`KT-29454`](https://youtrack.jetbrains.com/issue/KT-29454) Light class with unexpected name when using obfuscated library - [`KT-31553`](https://youtrack.jetbrains.com/issue/KT-31553) Complete Statement: Wrong auto-insertion of closing curly brace for a code block - [`KT-33466`](https://youtrack.jetbrains.com/issue/KT-33466) IDE generates incorrect `external override` with body for overriding `open external` method - [`KT-39458`](https://youtrack.jetbrains.com/issue/KT-39458) Add CLI support for UL classes - [`KT-40403`](https://youtrack.jetbrains.com/issue/KT-40403) UAST: PsiMethod for invoked extension function/property misses `@receiver:` annotations - [`KT-41406`](https://youtrack.jetbrains.com/issue/KT-41406) Kotlin doesn't report annotations for type arguments (no way to add `@Nls`, `@NonNls` annotations to String collections in Kotlin) - [`KT-41420`](https://youtrack.jetbrains.com/issue/KT-41420) UAST does not return information about type annotations +- [`KT-42194`](https://youtrack.jetbrains.com/issue/KT-42194) OOME: Java heap space from incremental compilation - [`KT-42754`](https://youtrack.jetbrains.com/issue/KT-42754) MPP: no smart cast for Common nullable property used in platform module - [`KT-42821`](https://youtrack.jetbrains.com/issue/KT-42821) MPP, IDE: Platform-specific errors are reported even when build doesn't target that platform +- [`KT-44116`](https://youtrack.jetbrains.com/issue/KT-44116) Add language version 1.5 to the compiler configuration preferences +- [`KT-44523`](https://youtrack.jetbrains.com/issue/KT-44523) IDE notification for trying new JVM backend +- [`KT-44543`](https://youtrack.jetbrains.com/issue/KT-44543) Kotlin's LowMemoryWatcher leaks on Kotlin plugin unload ### IDE. Android - [`KT-42381`](https://youtrack.jetbrains.com/issue/KT-42381) MPP: Bad IDEA dependencies: JVM module depending on built artifact instead of sources of module with Android Plugin applied +### IDE. Completion + +- [`KT-44016`](https://youtrack.jetbrains.com/issue/KT-44016) Code completion: support for "sealed interface" +- [`KT-44250`](https://youtrack.jetbrains.com/issue/KT-44250) Code completion does not work in when expression with sealed type argument + +### IDE. Gradle. Script + +- [`KT-39105`](https://youtrack.jetbrains.com/issue/KT-39105) AE “JvmBuiltins has not been initialized properly” after creating new Gradle/Kotlin-based project via old Project Wizard + ### IDE. Inspections and Intentions #### New Features @@ -162,6 +221,9 @@ - [`KT-34533`](https://youtrack.jetbrains.com/issue/KT-34533) INLINE_CLASS_CONSTRUCTOR_NOT_FINAL_READ_ONLY_PARAMETER: Add quickfix "Add val to parameter" - [`KT-35215`](https://youtrack.jetbrains.com/issue/KT-35215) Quickfix for CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT to remove `const` modifier - [`KT-40251`](https://youtrack.jetbrains.com/issue/KT-40251) Intention action to evaluate compile time expression +- [`KT-44017`](https://youtrack.jetbrains.com/issue/KT-44017) Sealed interfaces: Java side Inspection "implementation of Kotlin sealed interface is forbidden" +- [`KT-43941`](https://youtrack.jetbrains.com/issue/KT-43941) Sealed interfaces: intention to extend class/interface +- [`KT-44043`](https://youtrack.jetbrains.com/issue/KT-44043) Sealed interfaces: quickfix to move class/interface to proper location #### Fixes @@ -200,10 +262,27 @@ - [`KT-43760`](https://youtrack.jetbrains.com/issue/KT-43760) KJS: Debugging Kotlin code for Node.js runtime doesn't work +### IDE. Misc + +- [`KT-44018`](https://youtrack.jetbrains.com/issue/KT-44018) Sealed interfaces: IDE side implementation for hierarchy provider + +### IDE. Multiplatform + +- [`KT-40814`](https://youtrack.jetbrains.com/issue/KT-40814) MISSING_DEPENDENCY_CLASS when consuming native-shared library in a source-set with fewer targets than library has + +### IDE. Run Configurations + +- [`KT-34535`](https://youtrack.jetbrains.com/issue/KT-34535) Unable to run common tests on Android via gutter icon in a multiplatform project + ### IDE. Scratch +- [`KT-25038`](https://youtrack.jetbrains.com/issue/KT-25038) Scratch: Destructuring declaration produces an unresolved reference - [`KT-43415`](https://youtrack.jetbrains.com/issue/KT-43415) Kotlin scratch file could not be run and could lead to dead lock +### IDE. Script + +- [`KT-44117`](https://youtrack.jetbrains.com/issue/KT-44117) IDE / Scripts: custom kotlin script definitions aren't loaded + ### JavaScript #### Fixes @@ -214,35 +293,37 @@ - [`KT-40686`](https://youtrack.jetbrains.com/issue/KT-40686) KJS: Uncaught ReferenceError caused by external class as type inside eventListener in init block - [`KT-40771`](https://youtrack.jetbrains.com/issue/KT-40771) KJS / IR: "ReferenceError: Metadata is not defined" caused by default parameter value in inner class constructor - [`KT-41032`](https://youtrack.jetbrains.com/issue/KT-41032) KJS / IR: "AssertionError: Assertion failed" caused by class that is delegated to inherited interface +- [`KT-41076`](https://youtrack.jetbrains.com/issue/KT-41076) KJS / IR: "AssertionError: Assertion failed" caused by overridden extensiion function in child class - [`KT-41771`](https://youtrack.jetbrains.com/issue/KT-41771) KJS / IR: IndexOutOfBoundsException "Index 0 out of bounds for length 0" caused by inline class with List in primary constructor and vararg in secondary - [`KT-42025`](https://youtrack.jetbrains.com/issue/KT-42025) KJS / IR: IrConstructorCallImpl: No such type argument slot: 0 - [`KT-42112`](https://youtrack.jetbrains.com/issue/KT-42112) KJS: StackOverflowError on @JsExport in case of name clash with function with Enum parameter with star-projection - [`KT-42262`](https://youtrack.jetbrains.com/issue/KT-42262) KJS: `break`-statements without label are ignored in a `when` +- [`KT-42357`](https://youtrack.jetbrains.com/issue/KT-42357) KotlinJS - external class constructor with vararg does not correctly handle spread operator. - [`KT-42364`](https://youtrack.jetbrains.com/issue/KT-42364) KJS: Properties of interface delegate are non-configurable +- [`KT-43212`](https://youtrack.jetbrains.com/issue/KT-43212) JS IR: support `init` blocks inside inline classes - [`KT-43222`](https://youtrack.jetbrains.com/issue/KT-43222) KJS IR: prototype lazy initialization for top-level properties like in JVM - [`KT-43313`](https://youtrack.jetbrains.com/issue/KT-43313) KJS / IR: "Can't find name for declaration FUN" for secondary constructor +- [`KT-43901`](https://youtrack.jetbrains.com/issue/KT-43901) Call to enum values() method from enum companion object leads to non-initialized enum instances ### KMM Plugin - [`KT-41677`](https://youtrack.jetbrains.com/issue/KT-41677) Could not launch iOS project with custom display name -- [`KT-42463`](https://youtrack.jetbrains.com/issue/KT-42463) Launch common tests on local JVM via run gutter +- [`KT-42463`](https://youtrack.jetbrains.com/issue/KT-42463) Launch common tests for Android on local JVM via run gutter - [`KT-43188`](https://youtrack.jetbrains.com/issue/KT-43188) NoSuchMethodError in New Module Wizard of KMM Project ### Libraries - [`KT-41112`](https://youtrack.jetbrains.com/issue/KT-41112) Docs: add more details about bit shift operations +- [`KT-41278`](https://youtrack.jetbrains.com/issue/KT-41278) map.entries.contains can return false if the argument is not MutableEntry - [`KT-41356`](https://youtrack.jetbrains.com/issue/KT-41356) Incorrect documentation for `rangeTo` function +- [`KT-44456`](https://youtrack.jetbrains.com/issue/KT-44456) Introduce locale-agnostic API for case conversions +- [`KT-44458`](https://youtrack.jetbrains.com/issue/KT-44458) Introduce new Char-to-code and Char-to-digit conversions ### Middle-end. IR - [`KT-41765`](https://youtrack.jetbrains.com/issue/KT-41765) [Native/IR] Could not resolveFakeOverride() - [`KT-42054`](https://youtrack.jetbrains.com/issue/KT-42054) Psi2ir: "RuntimeException: IrSimpleFunctionSymbolImpl is already bound" when using result of function with overload resolution by lambda return type -### Native - -- [`KT-42822`](https://youtrack.jetbrains.com/issue/KT-42822) Kotlin/Native Worker leaks ObjC/Swift autorelease references (and indirectly bridged K/N references) on Darwin targets -- [`KT-42397`](https://youtrack.jetbrains.com/issue/KT-42397) Reverse C interop usage of companion object reports spurious leaks - ### Native. C and ObjC Import - [`KT-42412`](https://youtrack.jetbrains.com/issue/KT-42412) [C-interop] Modality of generated property accessors is always FINAL @@ -250,6 +331,7 @@ ### Native. ObjC Export - [`KT-38530`](https://youtrack.jetbrains.com/issue/KT-38530) Native: values() method of enum classes is not exposed to Objective-C/Swift +- [`KT-43599`](https://youtrack.jetbrains.com/issue/KT-43599) K/N: Unbound symbols not allowed ### Native. Platform libraries @@ -265,6 +347,7 @@ ### Native. Stdlib +- [`KT-42172`](https://youtrack.jetbrains.com/issue/KT-42172) Kotlin/Native: StableRef.dispose race condition on Kotlin deinitRuntime - [`KT-42428`](https://youtrack.jetbrains.com/issue/KT-42428) Inconsistent behavior of map.entries on Kotlin.Native ### Reflection @@ -273,6 +356,7 @@ ### Tools. CLI +- [`KT-43294`](https://youtrack.jetbrains.com/issue/KT-43294) Support `-no-stdlib` option for the `kotlin` runner - [`KT-43406`](https://youtrack.jetbrains.com/issue/KT-43406) JVM: produce deterministic jar files if -d option value is a .jar file ### Tools. CLI. Native @@ -283,6 +367,7 @@ - [`KT-41764`](https://youtrack.jetbrains.com/issue/KT-41764) KJS /IR IllegalStateException: "Symbol for public kotlin/arrayOf is unbound" with serialization plugin - [`KT-42976`](https://youtrack.jetbrains.com/issue/KT-42976) kotlinx.serialization + JVM IR: NPE on annotation with @SerialInfo +- [`KT-43725`](https://youtrack.jetbrains.com/issue/KT-43725) Prohibit inner and local classes in kotlin-noarg ### Tools. Gradle @@ -292,6 +377,8 @@ - [`KT-42058`](https://youtrack.jetbrains.com/issue/KT-42058) Support moduleName option in Kotlin Gradle plugin for JVM - [`KT-43054`](https://youtrack.jetbrains.com/issue/KT-43054) Implementation of `AbstractKotlinTarget#buildAdhocComponentsFromKotlinVariants` breaks configuration caching - [`KT-43489`](https://youtrack.jetbrains.com/issue/KT-43489) Incremental compilation - unable to find history files causing full recompilation +- [`KT-43740`](https://youtrack.jetbrains.com/issue/KT-43740) Gradle out-of-process runner fails with unclear diagnostics if build directory does not exist +- [`KT-43895`](https://youtrack.jetbrains.com/issue/KT-43895) Fix cacheability warnings for the Kotlin plugins ### Tools. Gradle. JS @@ -299,6 +386,10 @@ - [`KT-42462`](https://youtrack.jetbrains.com/issue/KT-42462) NPM dependency declaration with Groovy interpolated string - [`KT-42954`](https://youtrack.jetbrains.com/issue/KT-42954) Kotlin/JS: IDE import after changing `kotlin.js.externals.output.format` does not re-generate externals - [`KT-43535`](https://youtrack.jetbrains.com/issue/KT-43535) Common webpack configuration breaks on lambda serialization in some cases +- [`KT-43668`](https://youtrack.jetbrains.com/issue/KT-43668) PackageJson task use file dependencies as is (files and directories), but only files necessary +- [`KT-43793`](https://youtrack.jetbrains.com/issue/KT-43793) nodeArgs in NodeJsExec task +- [`KT-43842`](https://youtrack.jetbrains.com/issue/KT-43842) KJS: Invalid `output.library` support for `null` value +- [`KT-44104`](https://youtrack.jetbrains.com/issue/KT-44104) KJS / Gradle: An ability to pass jvm args to K2JSDce process ### Tools. Gradle. Multiplatform @@ -306,6 +397,7 @@ - [`KT-42413`](https://youtrack.jetbrains.com/issue/KT-42413) [MPP/gradle] `withJava` breaks build on 1.4.20-M1 - [`KT-43141`](https://youtrack.jetbrains.com/issue/KT-43141) Gradle / Configuration cache: NPE from org.jetbrains.kotlin.gradle.tasks.KotlinCompileCommon.getKotlinOptions() on reusing configuration cache for task compileCommonMainKotlinMetadata - [`KT-43329`](https://youtrack.jetbrains.com/issue/KT-43329) Gradle / Configuration cache: IAE “Parameter specified as non-null is null: method KotlinMetadataTargetConfiguratorKt.isCompatibilityMetadataVariantEnabled, parameter $this$isCompatibilityMetadataVariantEnabled” on reusing configuration cache for task compileKotlinMetadata +- [`KT-44298`](https://youtrack.jetbrains.com/issue/KT-44298) Kotlin 1.4.20+ MPP "root" module publication does not include the source JAR that used to be published in the -metadata modules ### Tools. Gradle. Native @@ -315,12 +407,24 @@ - [`KT-42849`](https://youtrack.jetbrains.com/issue/KT-42849) Gradle / Configuration cache: tasks nativeMetadataJar, runReleaseExecutableNative, runDebugExecutableNative are unsupported and fails on reusing configuration cache - [`KT-42938`](https://youtrack.jetbrains.com/issue/KT-42938) CocoaPods Gradle plugin: podBuildDependencies doesn't properly report xcodebuild failures - [`KT-43151`](https://youtrack.jetbrains.com/issue/KT-43151) Gradle / Configuration cache: UPAE “lateinit property binary has not been initialized” on reusing configuration cache for linkDebugExecutableNative, linkDebugTestNative, linkReleaseExecutableNative tasks -- [`KT-40999`](https://youtrack.jetbrains.com/issue/KT-40999) CocoaPods Gradle plugin: Support custom cinterop options when declaring a pod dependency. +- [`KT-43516`](https://youtrack.jetbrains.com/issue/KT-43516) Failed to resolve Kotin library [Multiple Multiplatform modules] + +### Tools. Incremental Compile + +- [`KT-42937`](https://youtrack.jetbrains.com/issue/KT-42937) another compilation fail (problem with compilation caches?) + +### Tools. JPS + +- [`KT-39536`](https://youtrack.jetbrains.com/issue/KT-39536) JPS compilation fails with IOException "storage is already closed" ### Tools. Parcelize - [`KT-41553`](https://youtrack.jetbrains.com/issue/KT-41553) JVM IR, Parcelize: IrStarProjectionImpl cannot be cast to class IrTypeProjection +### Tools. Scripts + +- [`KT-43534`](https://youtrack.jetbrains.com/issue/KT-43534) Allow running "main.kts" script that does not end in a "main.kts" filename (would allow kotlin scripting on GitHub Actions) + ### Tools. kapt - [`KT-34340`](https://youtrack.jetbrains.com/issue/KT-34340) Incremental annotation processor recompile all files (only if KAPT enabled). diff --git a/ReadMe.md b/ReadMe.md index 8168a57e163..3649308040a 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -59,8 +59,8 @@ You also can use [Gradle properties](https://docs.gradle.org/current/userguide/b Note: The JDK 6 for MacOS is not available on Oracle's site. You can install it by ```bash -$ brew tap caskroom/versions -$ brew cask install java6 +$ brew tap homebrew/cask-versions +$ brew install --cask java6 ``` On Windows you might need to add long paths setting to the repo: diff --git a/build.gradle.kts b/build.gradle.kts index 3dc12a70df2..d0c3fccb66e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -130,6 +130,7 @@ extra["JDK_18"] = jdkPath("1.8") extra["JDK_9"] = jdkPath("9") extra["JDK_10"] = jdkPath("10") extra["JDK_11"] = jdkPath("11") +extra["JDK_15"] = jdkPath("15") // allow opening the project without setting up all env variables (see KT-26413) if (!kotlinBuildProperties.isInIdeaSync) { @@ -331,7 +332,6 @@ extra["tasksWithWarnings"] = listOf( ":compiler:fir:checkers:compileKotlin", ":compiler:fir:java:compileKotlin", ":kotlin-scripting-compiler:compileKotlin", - ":kotlin-scripting-compiler:compileTestKotlin", ":plugins:uast-kotlin:compileKotlin", ":plugins:uast-kotlin:compileTestKotlin", ":plugins:uast-kotlin-idea:compileKotlin" diff --git a/buildSrc/src/main/kotlin/jdksFinder.kt b/buildSrc/src/main/kotlin/jdksFinder.kt index 6c2216304e4..3ed259ae7a7 100644 --- a/buildSrc/src/main/kotlin/jdksFinder.kt +++ b/buildSrc/src/main/kotlin/jdksFinder.kt @@ -10,12 +10,12 @@ import net.rubygrapefruit.platform.WindowsRegistry.Key.HKEY_LOCAL_MACHINE import org.gradle.internal.os.OperatingSystem enum class JdkMajorVersion(private val mandatory: Boolean = true) { - JDK_16, JDK_17, JDK_18, JDK_9, JDK_10(false), JDK_11(false); + JDK_16, JDK_17, JDK_18, JDK_9, JDK_10(false), JDK_11(false), /*15.0*/JDK_15(false); fun isMandatory(): Boolean = mandatory } -val jdkAlternativeVarNames = mapOf(JdkMajorVersion.JDK_9 to listOf("JDK_19")) +val jdkAlternativeVarNames = mapOf(JdkMajorVersion.JDK_9 to listOf("JDK_19"), JdkMajorVersion.JDK_15 to listOf("JDK_15_0")) data class JdkId(val explicit: Boolean, val majorVersion: JdkMajorVersion, var version: String, var homeDir: File) diff --git a/compiler/android-tests/build.gradle.kts b/compiler/android-tests/build.gradle.kts index fd8efcf8ecf..e529a5ccdc2 100644 --- a/compiler/android-tests/build.gradle.kts +++ b/compiler/android-tests/build.gradle.kts @@ -19,6 +19,10 @@ dependencies { testCompile(project(":kotlin-reflect")) testCompile(projectTests(":compiler:tests-common")) testCompile(commonDep("junit:junit")) + testApi(projectTests(":compiler:test-infrastructure")) + testApi(projectTests(":compiler:test-infrastructure-utils")) + testApi(projectTests(":compiler:tests-compiler-utils")) + testApi(projectTests(":compiler:tests-common-new")) testCompile(projectTests(":jps-plugin")) testCompile(commonDep("junit:junit")) @@ -37,6 +41,8 @@ dependencies { testCompile(intellijPluginDep("java")) { includeJars("jps-builders") } testCompile(jpsStandalone()) { includeJars("jps-model") } testCompile(jpsBuildTest()) + + testCompile("org.junit.platform:junit-platform-launcher:${commonVer("org.junit.platform", "")}") } sourceSets { diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidTestGenerator.kt b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidTestGenerator.kt index c9216bc2404..a43c45fd4b0 100644 --- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidTestGenerator.kt +++ b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/AndroidTestGenerator.kt @@ -20,7 +20,9 @@ import com.intellij.openapi.util.Ref import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.test.KotlinBaseTest +import org.jetbrains.kotlin.test.model.TestModule +import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.services.sourceFileProvider import java.io.File import java.util.regex.Pattern @@ -34,28 +36,24 @@ private data class OldPackageAndNew(val oldFqName: FqName, val newFqName: FqName internal fun patchFilesAndAddTest( testFile: File, - testFiles: List, + module: TestModule, + services: TestServices, filesHolder: CodegenTestsOnAndroidGenerator.FilesWriter -): FqName? { - if (testFiles.any { it.name.endsWith(".java") }) { - //TODO support java files - return null - } - val ktFiles = testFiles.filter { it.name.endsWith(".kt") } - if (ktFiles.isEmpty()) return null - +): FqName { val newPackagePrefix = testFile.path.replace("\\\\|-|\\.|/".toRegex(), "_") val oldPackage = Ref() val isJvmName = Ref(false) + val testFiles = module.files val isSingle = testFiles.size == 1 val resultFiles = testFiles.map { val fileName = if (isSingle) it.name else testFile.name.substringBeforeLast(".kt") + "/" + it.name + val content = services.sourceFileProvider.getContentOfSourceFile(it) TestClassInfo( fileName, - changePackage(newPackagePrefix, it.content, oldPackage, isJvmName), + changePackage(newPackagePrefix, content, oldPackage, isJvmName), oldPackage.get(), isJvmName.get(), - getGeneratedClassName(File(fileName), it.content, newPackagePrefix, oldPackage.get()) + getGeneratedClassName(File(fileName), content, newPackagePrefix, oldPackage.get()) ) } val packages = diff --git a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt index 174d86088d5..48b9c7d1d21 100644 --- a/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt +++ b/compiler/android-tests/tests/org/jetbrains/kotlin/android/tests/CodegenTestsOnAndroidGenerator.kt @@ -16,12 +16,25 @@ import org.jetbrains.kotlin.codegen.CodegenTestCase import org.jetbrains.kotlin.codegen.CodegenTestFiles import org.jetbrains.kotlin.codegen.GenerationUtils import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime -import org.jetbrains.kotlin.config.CommonConfigurationKeys -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.config.JvmTarget +import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.idea.KotlinFileType +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.* +import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder +import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives +import org.jetbrains.kotlin.test.directives.model.singleOrZeroValue +import org.jetbrains.kotlin.test.model.DependencyKind +import org.jetbrains.kotlin.test.model.FrontendKinds +import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerTest +import org.jetbrains.kotlin.test.services.* +import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator +import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator +import org.jetbrains.kotlin.test.services.impl.BackendKindExtractorImpl +import org.jetbrains.kotlin.test.services.impl.TemporaryDirectoryManagerImpl +import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider +import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFilesProvider +import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider import org.jetbrains.kotlin.test.util.KtTestUtil import org.junit.Assert import java.io.File @@ -237,6 +250,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager } } + @OptIn(TestInfrastructureInternals::class) @Throws(IOException::class) private fun processFiles( files: Array, @@ -290,29 +304,88 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager if (fullFileText.contains("// SKIP_JDK6")) continue if (hasBoxMethod(fullFileText)) { - val testFiles = createTestFiles(file, fullFileText) - val kind = KotlinBaseTest.extractConfigurationKind(testFiles) - val jdkKind = KotlinBaseTest.getTestJdkKind(testFiles) + val testConfiguration = createTestConfiguration(file) + val services = testConfiguration.testServices + + val moduleStructure = try { + testConfiguration.moduleStructureExtractor.splitTestDataByModules( + file.path, + testConfiguration.directives, + ).also { + services.register(TestModuleStructure::class, it) + } + } catch (e: ExceptionFromModuleStructureTransformer) { + continue + } + val module = moduleStructure.modules.singleOrNull() ?: continue + if (module.files.any { it.isJavaFile || it.isKtsFile }) continue + if (module.files.isEmpty()) continue + services.registerDependencyProvider(DependencyProviderImpl(services, moduleStructure.modules)) + val keyConfiguration = CompilerConfiguration() - KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, keyConfiguration) + val configuratorForFlags = JvmEnvironmentConfigurator(services) + with(configuratorForFlags) { + val extractor = DirectiveToConfigurationKeyExtractor() + extractor.provideConfigurationKeys() + extractor.configure(keyConfiguration, module.directives) + } + val kind = configuratorForFlags.extractConfigurationKind(module.directives) + val jdkKind = configuratorForFlags.extractJdkKind(module.directives) + + keyConfiguration.languageVersionSettings = module.languageVersionSettings val key = ConfigurationKey(kind, jdkKind, keyConfiguration.toString()) val compiler = if (kind.withReflection) REFLECT else COMMON + val compilerConfigurationProvider = services.compilerConfigurationProvider as CompilerConfigurationProviderImpl val filesHolder = holders.getOrPut(key) { - FilesWriter(compiler, KotlinTestUtils.newConfiguration(kind, jdkKind, - KtTestUtil.getAnnotationsJar() - ).apply { + FilesWriter(compiler, compilerConfigurationProvider.createCompilerConfiguration(module)).also { println("Creating new configuration by $key") - KotlinBaseTest.updateConfigurationByDirectivesInTestFiles(testFiles, this) - }) + } } - patchFilesAndAddTest(file, testFiles, filesHolder) + patchFilesAndAddTest(file, module, services, filesHolder) } } } } + private fun createTestConfiguration(testDataFile: File): TestConfiguration { + return TestConfigurationBuilder().apply { + testConfiguration() + testInfo = KotlinTestInfo( + "org.jetbrains.kotlin.android.tests.AndroidRunner", + "test${testDataFile.nameWithoutExtension.capitalize()}", + emptySet() + ) + }.build(testDataFile.path) + } + + private val testConfiguration: TestConfigurationBuilder.() -> Unit = { + globalDefaults { + frontend = FrontendKinds.ClassicFrontend + targetBackend = TargetBackend.ANDROID + targetPlatform = JvmPlatforms.defaultJvmPlatform + dependencyKind = DependencyKind.Binary + } + + useConfigurators( + ::CommonEnvironmentConfigurator, + ::JvmEnvironmentConfigurator + ) + + useAdditionalSourceProviders( + ::AdditionalDiagnosticsSourceFilesProvider, + ::CoroutineHelpersSourceFilesProvider, + ::CodegenHelpersSourceFilesProvider, + ) + + assertions = JUnit5Assertions + useAdditionalService(::TemporaryDirectoryManagerImpl) + useAdditionalService(::BackendKindExtractorImpl) + useSourcePreprocessor(*AbstractKotlinCompilerTest.defaultPreprocessors.toTypedArray()) + useDirectives(*AbstractKotlinCompilerTest.defaultDirectiveContainers.toTypedArray()) + } + private fun createTestFiles(file: File, expectedText: String): List = CodegenTestCase.createTestFilesFromFile(file, expectedText, false, TargetBackend.JVM) diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt index d56f5fc657c..9dc44f27ab8 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt @@ -357,6 +357,13 @@ abstract class CommonCompilerArguments : CommonToolArguments() { ) var suppressVersionWarnings: Boolean by FreezableVar(false) + @Argument( + value = "-Xextended-compiler-checks", + description = "Enable additional compiler checks that might provide verbose diagnostic information for certain errors.\n" + + "Warning: this mode is not backward-compatible and might cause compilation errors in previously compiled code." + ) + var extendedCompilerChecks: Boolean by FreezableVar(false) + open fun configureAnalysisFlags(collector: MessageCollector): MutableMap, Any> { return HashMap, Any>().apply { put(AnalysisFlags.skipMetadataVersionCheck, skipMetadataVersionCheck) @@ -375,6 +382,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() { CompilerMessageSeverity.ERROR, "Unknown value for parameter -Xexplicit-api: '$explicitApi'. Value should be one of ${ExplicitApiMode.availableValues()}" ) + put(AnalysisFlags.extendedCompilerChecks, extendedCompilerChecks) } } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CommonCompilerPerformanceManager.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CommonCompilerPerformanceManager.kt index 3085783a6f9..267bb100434 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CommonCompilerPerformanceManager.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CommonCompilerPerformanceManager.kt @@ -22,6 +22,7 @@ abstract class CommonCompilerPerformanceManager(private val presentableName: Str private var startGCData = mutableMapOf() private var irTranslationStart: Long = 0 + private var irLoweringStart: Long = 0 private var irGenerationStart: Long = 0 private var targetDescription: String? = null @@ -88,6 +89,19 @@ abstract class CommonCompilerPerformanceManager(private val presentableName: Str ) } + open fun notifyIRLoweringStarted() { + irLoweringStart = PerformanceCounter.currentTime() + } + + open fun notifyIRLoweringFinished() { + val time = deltaTime(irLoweringStart) + measurements += IRMeasurement( + lines, + TimeUnit.NANOSECONDS.toMillis(time), + IRMeasurement.Kind.LOWERING + ) + } + open fun notifyIRGenerationStarted() { irGenerationStart = PerformanceCounter.currentTime() } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt index d5e0db6b644..74a026062a7 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.* import org.jetbrains.kotlin.codegen.state.IncompatibleClassTrackerImpl +import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.languageVersionSettings @@ -72,6 +73,9 @@ class AnalyzerWithCompilerReport( .append(", unresolved supertypes: ").append(unresolved!!.joinToString()) .append("\n") } + if (!languageVersionSettings.getFlag(AnalysisFlags.extendedCompilerChecks)) { + message.append("Adding -Xextended-compiler-checks argument might provide additional information.\n") + } messageCollector.report(ERROR, message.toString()) } } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/performanceMeasurements.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/performanceMeasurements.kt index cc4c492794b..5771c469aa7 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/performanceMeasurements.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/performanceMeasurements.kt @@ -37,7 +37,7 @@ class IRMeasurement(val lines: Int?, val milliseconds: Long, val kind: Kind) : P override fun render(): String = formatMeasurement("IR $kind", milliseconds, lines) enum class Kind { - TRANSLATION, GENERATION + TRANSLATION, LOWERING, GENERATION } } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java index d46ebc5a4db..cce1bd287c7 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CompileEnvironmentUtil.java @@ -33,7 +33,8 @@ import org.jetbrains.kotlin.utils.ExceptionUtilsKt; import org.jetbrains.kotlin.utils.PathUtil; import java.io.*; -import java.util.*; +import java.util.Calendar; +import java.util.GregorianCalendar; import java.util.jar.*; import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR; @@ -144,11 +145,13 @@ public class CompileEnvironmentUtil { JarEntry e = jis.getNextJarEntry(); if (e == null) break; - if ((!FileUtilRt.extensionEquals(e.getName(), "class") && - !FileUtilRt.extensionEquals(e.getName(), BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION)) || - StringsKt.substringAfterLast(e.getName(), "/", e.getName()).equals("module-info.class")) { + String name = e.getName(); + if (!FileUtilRt.extensionEquals(name, "class") && + !FileUtilRt.extensionEquals(name, BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION) && + !name.startsWith("META-INF/services/")) { continue; } + if (StringsKt.substringAfterLast(name, "/", name).equals("module-info.class")) continue; if (resetJarTimestamps) { e.setTime(DOS_EPOCH); } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt index 867ab0a1bb9..7beaf6b4ffb 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinToJVMBytecodeCompiler.kt @@ -387,10 +387,14 @@ object KotlinToJVMBytecodeCompiler { ProgressIndicatorAndCompilationCanceledStatus.checkCanceled() - performanceManager?.notifyIRGenerationStarted() + performanceManager?.notifyIRLoweringStarted() generationState.beforeCompile() codegenFactory.generateModuleInFrontendIRMode( - generationState, moduleFragment, symbolTable, sourceManager, extensions, FirJvmBackendExtension(session, components) + generationState, moduleFragment, symbolTable, sourceManager, extensions, FirJvmBackendExtension(session, components), + { + performanceManager?.notifyIRLoweringFinished() + performanceManager?.notifyIRGenerationStarted() + } ) CodegenFactory.doCheckCancelled(generationState) generationState.factory.done() diff --git a/compiler/config/src/org/jetbrains/kotlin/config/AnalysisFlags.kt b/compiler/config/src/org/jetbrains/kotlin/config/AnalysisFlags.kt index 3cab8a5ff3a..00e02de39e0 100644 --- a/compiler/config/src/org/jetbrains/kotlin/config/AnalysisFlags.kt +++ b/compiler/config/src/org/jetbrains/kotlin/config/AnalysisFlags.kt @@ -50,4 +50,7 @@ object AnalysisFlags { @JvmStatic val libraryToSourceAnalysis by AnalysisFlag.Delegates.Boolean + + @JvmStatic + val extendedCompilerChecks by AnalysisFlag.Delegates.Boolean } diff --git a/compiler/daemon/daemon-common-new/src/org/jetbrains/kotlin/daemon/common/experimental/CompileServiceClientSideImpl.kt b/compiler/daemon/daemon-common-new/src/org/jetbrains/kotlin/daemon/common/experimental/CompileServiceClientSideImpl.kt index f12cd9d279d..316939c04f9 100644 --- a/compiler/daemon/daemon-common-new/src/org/jetbrains/kotlin/daemon/common/experimental/CompileServiceClientSideImpl.kt +++ b/compiler/daemon/daemon-common-new/src/org/jetbrains/kotlin/daemon/common/experimental/CompileServiceClientSideImpl.kt @@ -56,10 +56,12 @@ class CompileServiceClientSideImpl( while (keepAliveSuccess()) { delay(KEEPALIVE_PERIOD - millisecondsSinceLastUsed()) } - runWithTimeout(timeout = KEEPALIVE_PERIOD / 2) { + val keepAliveAcknowledgement = runWithTimeout(timeout = KEEPALIVE_PERIOD / 2) { val id = sendMessage(keepAliveMessage) readMessage>(id) - } ?: if (!keepAliveSuccess()) readActor.send(StopAllRequests()).also { + } + if (keepAliveAcknowledgement == null && !keepAliveSuccess()) { + readActor.send(StopAllRequests()) } } } diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java index 698661d6ac2..084912af263 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests-gen/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java @@ -139,46 +139,6 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract runTest("compiler/fir/analysis-tests/testData/resolve/enumWithCompanion.kt"); } - @TestMetadata("exhaustiveWhenAndDNNType.kt") - public void testExhaustiveWhenAndDNNType() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndDNNType.kt"); - } - - @TestMetadata("exhaustiveWhenAndFlexibleType.kt") - public void testExhaustiveWhenAndFlexibleType() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndFlexibleType.kt"); - } - - @TestMetadata("exhaustiveness_boolean.kt") - public void testExhaustiveness_boolean() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_boolean.kt"); - } - - @TestMetadata("exhaustiveness_enum.kt") - public void testExhaustiveness_enum() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enum.kt"); - } - - @TestMetadata("exhaustiveness_enumJava.kt") - public void testExhaustiveness_enumJava() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enumJava.kt"); - } - - @TestMetadata("exhaustiveness_sealedClass.kt") - public void testExhaustiveness_sealedClass() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedClass.kt"); - } - - @TestMetadata("exhaustiveness_sealedObject.kt") - public void testExhaustiveness_sealedObject() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedObject.kt"); - } - - @TestMetadata("exhaustiveness_sealedSubClass.kt") - public void testExhaustiveness_sealedSubClass() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedSubClass.kt"); - } - @TestMetadata("extension.kt") public void testExtension() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/extension.kt"); @@ -244,6 +204,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract runTest("compiler/fir/analysis-tests/testData/resolve/implicitTypeInFakeOverride.kt"); } + @TestMetadata("incorrectDataClass.kt") + public void testIncorrectDataClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.kt"); + } + @TestMetadata("incorrectSuperCall.kt") public void testIncorrectSuperCall() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/incorrectSuperCall.kt"); @@ -494,6 +459,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract runTest("compiler/fir/analysis-tests/testData/resolve/whenInference.kt"); } + @TestMetadata("whenWithWhenAsStatement.kt") + public void testWhenWithWhenAsStatement() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/whenWithWhenAsStatement.kt"); + } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/arguments") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -1261,6 +1231,120 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract } } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/exhaustiveness") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Exhaustiveness extends AbstractLazyBodyIsNotTouchedTilContractsPhaseTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInExhaustiveness() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/exhaustiveness"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Negative extends AbstractLazyBodyIsNotTouchedTilContractsPhaseTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInNegative() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("missingBooleanBranch.kt") + public void testMissingBooleanBranch() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.kt"); + } + + @TestMetadata("missingElse.kt") + public void testMissingElse() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.kt"); + } + + @TestMetadata("missingEnumEntry.kt") + public void testMissingEnumEntry() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.kt"); + } + + @TestMetadata("missingSealedInheritor.kt") + public void testMissingSealedInheritor() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.kt"); + } + + @TestMetadata("nonExhaustiveWhenWithoutCoercionToUnit.kt") + public void testNonExhaustiveWhenWithoutCoercionToUnit() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/nonExhaustiveWhenWithoutCoercionToUnit.kt"); + } + } + + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Positive extends AbstractLazyBodyIsNotTouchedTilContractsPhaseTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInPositive() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @TestMetadata("exhaustiveWhenAndDNNType.kt") + public void testExhaustiveWhenAndDNNType() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndDNNType.kt"); + } + + @TestMetadata("exhaustiveWhenAndFlexibleType.kt") + public void testExhaustiveWhenAndFlexibleType() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndFlexibleType.kt"); + } + + @TestMetadata("exhaustiveness_boolean.kt") + public void testExhaustiveness_boolean() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.kt"); + } + + @TestMetadata("exhaustiveness_enum.kt") + public void testExhaustiveness_enum() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.kt"); + } + + @TestMetadata("exhaustiveness_enumJava.kt") + public void testExhaustiveness_enumJava() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt"); + } + + @TestMetadata("exhaustiveness_sealedClass.kt") + public void testExhaustiveness_sealedClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.kt"); + } + + @TestMetadata("exhaustiveness_sealedObject.kt") + public void testExhaustiveness_sealedObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedObject.kt"); + } + + @TestMetadata("exhaustiveness_sealedSubClass.kt") + public void testExhaustiveness_sealedSubClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt"); + } + + @TestMetadata("nestedIfInLambda.kt") + public void testNestedIfInLambda() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nestedIfInLambda.kt"); + } + + @TestMetadata("nonExhaustiveWhenWithCoercionToUnit.kt") + public void testNonExhaustiveWhenWithCoercionToUnit() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nonExhaustiveWhenWithCoercionToUnit.kt"); + } + } + } + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/expresssions") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -2813,6 +2897,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @TestMetadata("booleanElvisBoundSmartcast.kt") + public void testBooleanElvisBoundSmartcast() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/booleanElvisBoundSmartcast.kt"); + } + @TestMetadata("booleanOperators.kt") public void testBooleanOperators() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/booleanOperators.kt"); diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests/org/jetbrains/kotlin/fir/AbstractFirLoadBinariesTest.kt b/compiler/fir/analysis-tests/legacy-fir-tests/tests/org/jetbrains/kotlin/fir/AbstractFirLoadBinariesTest.kt index ceb5259fd88..8ee7857e8f9 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests/org/jetbrains/kotlin/fir/AbstractFirLoadBinariesTest.kt +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests/org/jetbrains/kotlin/fir/AbstractFirLoadBinariesTest.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.fir import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.DescriptorUtils @@ -27,7 +27,7 @@ abstract class AbstractFirLoadBinariesTest : AbstractFirResolveWithSessionTestCa val declarationNames = DescriptorUtils.getAllDescriptors(moduleDescriptor.getPackage(packageFqName).memberScope) .mapTo(sortedSetOf()) { it.name } - val provider = session.firSymbolProvider + val provider = session.symbolProvider val builder = StringBuilder() val firRenderer = FirRenderer(builder) diff --git a/compiler/fir/analysis-tests/legacy-fir-tests/tests/org/jetbrains/kotlin/fir/java/AbstractFirTypeEnhancementTest.kt b/compiler/fir/analysis-tests/legacy-fir-tests/tests/org/jetbrains/kotlin/fir/java/AbstractFirTypeEnhancementTest.kt index 26f76d172a2..cc082c6569b 100644 --- a/compiler/fir/analysis-tests/legacy-fir-tests/tests/org/jetbrains/kotlin/fir/java/AbstractFirTypeEnhancementTest.kt +++ b/compiler/fir/analysis-tests/legacy-fir-tests/tests/org/jetbrains/kotlin/fir/java/AbstractFirTypeEnhancementTest.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.createSession import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName @@ -140,7 +140,7 @@ abstract class AbstractFirTypeEnhancementTest : KtUsefulTestCase() { val javaFirDump = StringBuilder().also { builder -> val renderer = FirRenderer(builder) - val symbolProvider = session.firSymbolProvider as FirCompositeSymbolProvider + val symbolProvider = session.symbolProvider as FirCompositeSymbolProvider val javaProvider = symbolProvider.providers.filterIsInstance().first() val topLevelJavaClasses = topPsiClasses.map { it.classId(FqName.ROOT) } diff --git a/compiler/fir/analysis-tests/testData/resolve/callResolution/safeCallOnTypeAlias.fir.txt b/compiler/fir/analysis-tests/testData/resolve/callResolution/safeCallOnTypeAlias.fir.txt index 23cb5301cc6..0e2211cd68c 100644 --- a/compiler/fir/analysis-tests/testData/resolve/callResolution/safeCallOnTypeAlias.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/callResolution/safeCallOnTypeAlias.fir.txt @@ -1,7 +1,7 @@ FILE: safeCallOnTypeAlias.kt public final typealias MyTypeAlias = R|() -> kotlin/String?| public final fun foo(x: R|MyTypeAlias|): R|kotlin/Unit| { - R|/x|?.{ $subj$.R|kotlin/let| kotlin/String?|, R|kotlin/String|>( = let@fun (y: R|() -> kotlin/String?|): R|kotlin/String| { + R|/x|?.{ $subj$.R|kotlin/let| kotlin/String?|, R|kotlin/String?|>( = let@fun (y: R|() -> kotlin/String?|): R|kotlin/String?| { ^ R|/y|.R|SubstitutionOverride|()?.{ $subj$.R|kotlin/let|( = let@fun (result: R|kotlin/String|): R|kotlin/String| { ^ R|/bar|(R|/result|) } diff --git a/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.kt b/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.kt index 31055eb1267..432065d9201 100644 --- a/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.kt +++ b/compiler/fir/analysis-tests/testData/resolve/cfg/propertiesAndInitBlocks.kt @@ -11,7 +11,7 @@ var x2: Int = 1 field = 1 } -val x3 = run { +val x3 = run { fun foo() { val c = 1 + 1 throw Exception() @@ -25,7 +25,7 @@ val x3 = run { } throw Exception() -} +} get() { class GetterLocalClass { init { diff --git a/compiler/fir/analysis-tests/testData/resolve/delegatedSuperType.fir.txt b/compiler/fir/analysis-tests/testData/resolve/delegatedSuperType.fir.txt index 44fedf60655..750ae3ad097 100644 --- a/compiler/fir/analysis-tests/testData/resolve/delegatedSuperType.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/delegatedSuperType.fir.txt @@ -13,13 +13,12 @@ FILE: delegatedSuperType.kt } public final class C : R|A| { - local final field <$$delegate_0>: R|A| - public constructor(b: R|B|): R|C| { super() - this@R|/C|.R|/<$$delegate_0>| = R|/b| } + local final field <$$delegate_0>: R|A| = R|/b| + public final val b: R|B| = R|/b| public get(): R|B| diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/anonymousObjectByDelegate.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/anonymousObjectByDelegate.fir.txt index d83ecbdb10b..cc3f18011e9 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/anonymousObjectByDelegate.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/anonymousObjectByDelegate.fir.txt @@ -9,25 +9,23 @@ FILE: anonymousObjectByDelegate.kt } public final fun R|A|.test_1(): R|kotlin/Unit| { object : R|B| { - local final field <$$delegate_0>: R|B| - private constructor(): R|| { super() - this@R|/|.R|/<$$delegate_0>| = this@R|/test_1|.R|/A.b| } + local final field <$$delegate_0>: R|B| = this@R|/test_1|.R|/A.b| + } } public final fun R|A|.test_2(): R|kotlin/Unit| { object : R|B| { - local final field <$$delegate_0>: R|B| - private constructor(): R|| { super() - this@R|/|.R|/<$$delegate_0>| = this@R|/test_2|.R|/A.b| } + local final field <$$delegate_0>: R|B| = this@R|/test_2|.R|/A.b| + } } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/delegationInInterface.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/delegationInInterface.fir.txt index daa35ef4ecf..9c39bfa07c9 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/delegationInInterface.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/delegationInInterface.fir.txt @@ -6,7 +6,7 @@ FILE: delegationInInterface.kt } public abstract interface B : R|A| { - local final field <$$delegate_0>: R|A| + local final field <$$delegate_0>: R|A| = # public abstract val a: R|A| public get(): R|A| @@ -15,6 +15,6 @@ FILE: delegationInInterface.kt public final val test: R|A| = R|/A.A|() public get(): R|A| public abstract interface C : R|A| { - local final field <$$delegate_0>: R|A| + local final field <$$delegate_0>: R|A| = R|/test| } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/delegationInInterface.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/delegationInInterface.kt index b212a508b3c..cd5318b99c4 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/delegationInInterface.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/delegationInInterface.kt @@ -1,6 +1,6 @@ class A -interface B : A by a { +interface B : A by a { val a: A } diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/propertyTypeMismatchOnOverride.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/propertyTypeMismatchOnOverride.kt index 5c5c24fb52e..848b59e325a 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/propertyTypeMismatchOnOverride.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/propertyTypeMismatchOnOverride.kt @@ -3,7 +3,7 @@ open class A { } open class B : A { - override var test: Double = 20.0 + override var test: Double = 20.0 } class C() : A() { @@ -15,7 +15,7 @@ open class D() : B() { } class E(val value: T) : B() { - override var test: T = value + override var test: T = value } open class F(val value: T) { diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/sealedSupertype.kt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/sealedSupertype.kt index 6bd11376197..61185630aaa 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/sealedSupertype.kt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/sealedSupertype.kt @@ -29,7 +29,7 @@ sealed class P { class K : P() object B { - class I : P() + class I : P() } fun test() { diff --git a/compiler/fir/analysis-tests/testData/resolve/diagnostics/superCallWithDelegation.fir.txt b/compiler/fir/analysis-tests/testData/resolve/diagnostics/superCallWithDelegation.fir.txt index 728990c69a9..c761b0afb53 100644 --- a/compiler/fir/analysis-tests/testData/resolve/diagnostics/superCallWithDelegation.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/diagnostics/superCallWithDelegation.fir.txt @@ -4,13 +4,12 @@ FILE: superCallWithDelegation.kt } public open class B : R|A| { - local final field <$$delegate_0>: R|A| - public constructor(a: R|A|): R|B| { super() - this@R|/B|.R|/<$$delegate_0>| = R|/a| } + local final field <$$delegate_0>: R|A| = R|/a| + private final val a: R|A| = R|/a| private get(): R|A| diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt new file mode 100644 index 00000000000..8e060626a81 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt @@ -0,0 +1,55 @@ +FILE: missingBooleanBranch.kt + public final fun test_1(cond: R|kotlin/Boolean|): R|kotlin/Unit| { + lval x: R|kotlin/Unit| = when (R|/cond|) { + ==($subj$, Boolean(true)) -> { + Int(1) + } + } + + lval y: R|kotlin/Unit| = when (R|/cond|) { + ==($subj$, Boolean(false)) -> { + Int(2) + } + } + + lval z: R|kotlin/Int| = when (R|/cond|) { + ==($subj$, Boolean(true)) -> { + Int(1) + } + ==($subj$, Boolean(false)) -> { + Int(2) + } + } + + } + public final fun test_2(cond: R|kotlin/Boolean?|): R|kotlin/Unit| { + lval x: R|kotlin/Unit| = when (R|/cond|) { + ==($subj$, Boolean(true)) -> { + Int(1) + } + ==($subj$, Boolean(false)) -> { + Int(2) + } + } + + lval x: R|kotlin/Int| = when (R|/cond|) { + ==($subj$, Boolean(true)) -> { + Int(1) + } + ==($subj$, Boolean(false)) -> { + Int(2) + } + ==($subj$, Null(null)) -> { + Int(3) + } + } + + } + public final fun test_3(cond: R|kotlin/Boolean|): R|kotlin/Unit| { + when (R|/cond|) { + ==($subj$, Boolean(true)) -> { + Int(1) + } + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.kt new file mode 100644 index 00000000000..ddf84b51870 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.kt @@ -0,0 +1,33 @@ +fun test_1(cond: Boolean) { + val x = when (cond) { + true -> 1 + } + + val y = when (cond) { + false -> 2 + } + + val z = when (cond) { + true -> 1 + false -> 2 + } +} + +fun test_2(cond: Boolean?) { + val x = when (cond) { + true -> 1 + false -> 2 + } + + val x = when (cond) { + true -> 1 + false -> 2 + null -> 3 + } +} + +fun test_3(cond: Boolean) { + when (cond) { + true -> 1 + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.fir.txt new file mode 100644 index 00000000000..791d4a1457f --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.fir.txt @@ -0,0 +1,41 @@ +FILE: missingElse.kt + public final fun test(a: R|kotlin/Any|): R|kotlin/Unit| { + lval x: R|kotlin/Unit| = when (R|/a|) { + ($subj$ is R|kotlin/Int|) -> { + Int(1) + } + ($subj$ is R|kotlin/String|) -> { + Int(2) + } + } + + lval y: R|kotlin/Int| = when (R|/a|) { + else -> { + Int(1) + } + } + + lval z: R|kotlin/Int| = when (R|/a|) { + ($subj$ is R|kotlin/Int|) -> { + Int(1) + } + ($subj$ is R|kotlin/String|) -> { + Int(2) + } + else -> { + Int(3) + } + } + + } + public final fun test_2(a: R|kotlin/Any|): R|kotlin/Unit| { + when (R|/a|) { + ($subj$ is R|kotlin/String|) -> { + Int(1) + } + ($subj$ is R|kotlin/Int|) -> { + Int(2) + } + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.kt new file mode 100644 index 00000000000..8b95fcac476 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.kt @@ -0,0 +1,23 @@ +fun test(a: Any) { + val x = when (a) { + is Int -> 1 + is String -> 2 + } + + val y = when (a) { + else -> 1 + } + + val z = when (a) { + is Int -> 1 + is String -> 2 + else -> 3 + } +} + +fun test_2(a: Any) { + when (a) { + is String -> 1 + is Int -> 2 + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.fir.txt new file mode 100644 index 00000000000..ae6201fee17 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.fir.txt @@ -0,0 +1,63 @@ +FILE: missingEnumEntry.kt + public final enum class SomeEnum : R|kotlin/Enum| { + private constructor(): R|SomeEnum| { + super|>() + } + + public final static enum entry A: R|SomeEnum| + public final static enum entry B: R|SomeEnum| + public final static fun values(): R|kotlin/Array| { + } + + public final static fun valueOf(value: R|kotlin/String|): R|SomeEnum| { + } + + } + public final fun test_1(enum: R|SomeEnum|): R|kotlin/Unit| { + lval x: R|kotlin/Unit| = when (R|/enum|) { + ==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> { + Int(1) + } + } + + lval y: R|kotlin/Int| = when (R|/enum|) { + ==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> { + Int(1) + } + ==($subj$, Q|SomeEnum|.R|/SomeEnum.B|) -> { + Int(2) + } + } + + } + public final fun test_2(enum: R|SomeEnum?|): R|kotlin/Unit| { + lval x: R|kotlin/Unit| = when (R|/enum|) { + ==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> { + Int(1) + } + ==($subj$, Q|SomeEnum|.R|/SomeEnum.B|) -> { + Int(2) + } + } + + lval y: R|kotlin/Int| = when (R|/enum|) { + ==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> { + Int(1) + } + ==($subj$, Q|SomeEnum|.R|/SomeEnum.B|) -> { + Int(2) + } + ==($subj$, Null(null)) -> { + Int(3) + } + } + + } + public final fun test_3(enum: R|SomeEnum|): R|kotlin/Unit| { + when (R|/enum|) { + ==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> { + Int(1) + } + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.kt new file mode 100644 index 00000000000..75355434441 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.kt @@ -0,0 +1,33 @@ +enum class SomeEnum { + A, B +} + +fun test_1(enum: SomeEnum) { + val x = when (enum) { + SomeEnum.A -> 1 + } + + val y = when (enum) { + SomeEnum.A -> 1 + SomeEnum.B -> 2 + } +} + +fun test_2(enum: SomeEnum?) { + val x = when (enum) { + SomeEnum.A -> 1 + SomeEnum.B -> 2 + } + + val y = when (enum) { + SomeEnum.A -> 1 + SomeEnum.B -> 2 + null -> 3 + } +} + +fun test_3(enum: SomeEnum) { + when (enum) { + SomeEnum.A -> 1 + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.fir.txt new file mode 100644 index 00000000000..0d11593bd9b --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.fir.txt @@ -0,0 +1,84 @@ +FILE: a.kt + public sealed class Base : R|kotlin/Any| { + private constructor(): R|Base| { + super() + } + + } + public final class A : R|Base| { + public constructor(): R|A| { + super() + } + + } +FILE: b.kt + public final object B : R|Base| { + private constructor(): R|B| { + super() + } + + } +FILE: c.kt + public final fun test_1(base: R|Base|): R|kotlin/Unit| { + lval x: R|kotlin/Unit| = when (R|/base|) { + ($subj$ is R|A|) -> { + Int(1) + } + } + + lval y: R|kotlin/Unit| = when (R|/base|) { + ==($subj$, Q|B|) -> { + Int(1) + } + } + + lval z: R|kotlin/Int| = when (R|/base|) { + ($subj$ is R|A|) -> { + Int(1) + } + ==($subj$, Q|B|) -> { + Int(2) + } + } + + } + public final fun test_2(base: R|Base?|): R|kotlin/Unit| { + lval x: R|kotlin/Unit| = when (R|/base|) { + ($subj$ is R|A|) -> { + Int(1) + } + ($subj$ is R|B|) -> { + Int(2) + } + } + + lval y: R|kotlin/Unit| = when (R|/base|) { + ($subj$ is R|A|) -> { + Int(1) + } + ==($subj$, Q|B|) -> { + Int(2) + } + } + + lval z: R|kotlin/Int| = when (R|/base|) { + ($subj$ is R|A|) -> { + Int(1) + } + ==($subj$, Q|B|) -> { + Int(2) + } + ==($subj$, Null(null)) -> { + Int(3) + } + } + + } + public final fun test_3(base: R|Base|): R|kotlin/Unit| { + when (R|/base|) { + ($subj$ is R|A|) -> { + Int(1) + } + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.kt new file mode 100644 index 00000000000..9300b82cb1f --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.kt @@ -0,0 +1,50 @@ +// FILE: a.kt + +sealed class Base + +class A : Base + +// FILE: b.kt + +object B : Base() + +// FILE: c.kt + +fun test_1(base: Base) { + val x = when (base) { + is A -> 1 + } + + val y = when (base) { + B -> 1 + } + + val z = when (base) { + is A -> 1 + B -> 2 + } +} + +fun test_2(base: Base?) { + val x = when (base) { + is A -> 1 + is B -> 2 + } + + val y = when (base) { + is A -> 1 + B -> 2 + } + + val z = when (base) { + is A -> 1 + B -> 2 + null -> 3 + } +} + +fun test_3(base: Base) { + when (base) { + is A -> 1 + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/nonExhaustiveWhenWithoutCoercionToUnit.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/nonExhaustiveWhenWithoutCoercionToUnit.fir.txt new file mode 100644 index 00000000000..3dbef094d39 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/nonExhaustiveWhenWithoutCoercionToUnit.fir.txt @@ -0,0 +1,15 @@ +FILE: nonExhaustiveWhenWithoutCoercionToUnit.kt + public final fun run(block: R|() -> T|): R|T| { + ^run R|/block|.R|SubstitutionOverride|() + } + public final fun test(a: R|kotlin/Any|): R|kotlin/Unit| { + R|/run|( = run@fun (): R|kotlin/Unit| { + when (R|/a|) { + ($subj$ is R|kotlin/String|) -> { + Int(1) + } + } + + } + ) + } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/nonExhaustiveWhenWithoutCoercionToUnit.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/nonExhaustiveWhenWithoutCoercionToUnit.kt new file mode 100644 index 00000000000..35d276b48ea --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/nonExhaustiveWhenWithoutCoercionToUnit.kt @@ -0,0 +1,10 @@ +fun run(block: () -> T): T = block() + +fun test(a: Any) { + run { + // Should be an error, see KT-44810 + when (a) { + is String -> 1 + } + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndDNNType.dot b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndDNNType.dot similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndDNNType.dot rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndDNNType.dot diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndDNNType.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndDNNType.fir.txt similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndDNNType.fir.txt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndDNNType.fir.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndDNNType.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndDNNType.kt similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndDNNType.kt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndDNNType.kt diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndFlexibleType.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndFlexibleType.fir.txt similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndFlexibleType.fir.txt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndFlexibleType.fir.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndFlexibleType.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndFlexibleType.kt similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndFlexibleType.kt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndFlexibleType.kt diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_boolean.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.fir.txt similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_boolean.fir.txt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.fir.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_boolean.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.kt similarity index 78% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_boolean.kt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.kt index ca517f63c3d..f6a79b2e097 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_boolean.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.kt @@ -1,5 +1,5 @@ fun test_1(b: Boolean) { - val x = when (b) { + val x = when (b) { true -> 1 } val y = when (b) { @@ -13,7 +13,7 @@ fun test_1(b: Boolean) { } fun test_2(b: Boolean?) { - val x = when (b) { + val x = when (b) { true -> 1 false -> 2 } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enum.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.fir.txt similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enum.fir.txt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.fir.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enum.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.kt similarity index 84% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enum.kt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.kt index c502f35e046..ac2e4c7bbb1 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enum.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.kt @@ -3,12 +3,12 @@ enum class Enum { } fun test_1(e: Enum) { - val a = when (e) { + val a = when (e) { Enum.A -> 1 Enum.B -> 2 } - val b = when (e) { + val b = when (e) { Enum.A -> 1 Enum.B -> 2 is String -> 3 @@ -27,7 +27,7 @@ fun test_1(e: Enum) { } fun test_2(e: Enum?) { - val a = when (e) { + val a = when (e) { Enum.A -> 1 Enum.B -> 2 Enum.C -> 3 diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enumJava.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enumJava.fir.txt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enumJava.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt similarity index 89% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enumJava.kt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt index ab00bc6dab8..463216e5e5f 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enumJava.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt @@ -7,12 +7,12 @@ public enum JavaEnum { // FILE: main.kt fun test_1(e: JavaEnum) { - val a = when (e) { + val a = when (e) { JavaEnum.A -> 1 JavaEnum.B -> 2 }.plus(0) - val b = when (e) { + val b = when (e) { JavaEnum.A -> 1 JavaEnum.B -> 2 is String -> 3 @@ -31,7 +31,7 @@ fun test_1(e: JavaEnum) { } fun test_2(e: JavaEnum?) { - val a = when (e) { + val a = when (e) { JavaEnum.A -> 1 JavaEnum.B -> 2 JavaEnum.C -> 3 diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedClass.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.fir.txt similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedClass.fir.txt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.fir.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedClass.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.kt similarity index 86% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedClass.kt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.kt index 78547c73258..c37b08fc716 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.kt @@ -7,12 +7,12 @@ sealed class Base { class C : Base() fun test_1(e: Base) { - val a = when (e) { + val a = when (e) { is Base.A -> 1 is Base.A.B -> 2 } - val b = when (e) { + val b = when (e) { is Base.A -> 1 is Base.A.B -> 2 is String -> 3 @@ -31,7 +31,7 @@ fun test_1(e: Base) { } fun test_2(e: Base?) { - val a = when (e) { + val a = when (e) { is Base.A -> 1 is Base.A.B -> 2 is C -> 3 diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedObject.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedObject.fir.txt similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedObject.fir.txt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedObject.fir.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedObject.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedObject.kt similarity index 100% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedObject.kt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedObject.kt diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedSubClass.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.fir.txt similarity index 96% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedSubClass.fir.txt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.fir.txt index 1e4580f5d2f..db6cbd744a5 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedSubClass.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.fir.txt @@ -107,10 +107,10 @@ FILE: exhaustiveness_sealedSubClass.kt } } .#(Int(0)) - lval d: R|ERROR CLASS: Unresolved name: plus| = when (R|/e|) { + lval d: R|kotlin/Int| = when (R|/e|) { ($subj$ is R|C|) -> { Int(1) } } - .#(Int(0)) + .R|kotlin/Int.plus|(Int(0)) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedSubClass.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt similarity index 85% rename from compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedSubClass.kt rename to compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt index 523b7eca50a..9beeb8a7276 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedSubClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt @@ -32,23 +32,23 @@ fun test_1(e: A) { } fun test_2(e: A) { - val a = when (e) { + val a = when (e) { is D -> 1 is E -> 2 }.plus(0) - val b = when (e) { + val b = when (e) { is B -> 1 is D -> 2 is E -> 3 }.plus(0) - val c = when (e) { + val c = when (e) { is B -> 1 is D -> 2 }.plus(0) val d = when (e) { is C -> 1 - }.plus(0) + }.plus(0) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nestedIfInLambda.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nestedIfInLambda.fir.txt new file mode 100644 index 00000000000..468e5d76177 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nestedIfInLambda.fir.txt @@ -0,0 +1,20 @@ +FILE: nestedIfInLambda.kt + public final fun run(block: R|() -> kotlin/Unit|): R|kotlin/Unit| { + } + public final fun test(b1: R|kotlin/Boolean|, b2: R|kotlin/Boolean|): R|kotlin/Unit| { + lvar result: R|kotlin/Boolean| = Boolean(false) + R|/run|( = run@fun (): R|kotlin/Unit| { + when () { + R|/b1| -> { + when () { + R|/b2| -> { + R|/result| = Boolean(true) + } + } + + } + } + + } + ) + } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nestedIfInLambda.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nestedIfInLambda.kt new file mode 100644 index 00000000000..1464b640c70 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nestedIfInLambda.kt @@ -0,0 +1,10 @@ +fun run(block: () -> Unit) {} + +fun test(b1: Boolean, b2: Boolean) { + var result = false + run { + if (b1) + if (b2) + result = true + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nonExhaustiveWhenWithCoercionToUnit.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nonExhaustiveWhenWithCoercionToUnit.fir.txt new file mode 100644 index 00000000000..3c426b78f6e --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nonExhaustiveWhenWithCoercionToUnit.fir.txt @@ -0,0 +1,21 @@ +FILE: nonExhaustiveWhenWithCoercionToUnit.kt + public final fun run(block: R|() -> T|): R|T| { + ^run R|/block|.R|SubstitutionOverride|() + } + public final fun test(a: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| { + R|/run|( = run@fun (): R|kotlin/Unit| { + when () { + R|/b| -> { + ^@run Unit + } + } + + when (R|/a|) { + ($subj$ is R|kotlin/String|) -> { + Int(1) + } + } + + } + ) + } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nonExhaustiveWhenWithCoercionToUnit.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nonExhaustiveWhenWithCoercionToUnit.kt new file mode 100644 index 00000000000..4e30a814d3c --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nonExhaustiveWhenWithCoercionToUnit.kt @@ -0,0 +1,10 @@ +fun run(block: () -> T): T = block() + +fun test(a: Any, b: Boolean) { + run { + if (b) return@run + when (a) { + is String -> 1 + } + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/expresssions/genericDescriptor.kt b/compiler/fir/analysis-tests/testData/resolve/expresssions/genericDescriptor.kt index 8c23920ad8c..4deb9999bf3 100644 --- a/compiler/fir/analysis-tests/testData/resolve/expresssions/genericDescriptor.kt +++ b/compiler/fir/analysis-tests/testData/resolve/expresssions/genericDescriptor.kt @@ -18,7 +18,7 @@ public interface ResolvedCall { // FILE: test.kt -val Descriptor.name = "123" +val Descriptor.name = "123" fun Descriptor.correct(): Boolean = true fun Descriptor.foo() {} diff --git a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.kt b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.kt index d1ac4a133b3..3ddf6fc5398 100644 --- a/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.kt +++ b/compiler/fir/analysis-tests/testData/resolve/extendedCheckers/RedundantVisibilityModifierChecker.kt @@ -80,7 +80,7 @@ open class J { field = value } - var bar = 0 + var bar = 0 get() = 3.1415926535 set(value) {} } diff --git a/compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.fir.txt b/compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.fir.txt new file mode 100644 index 00000000000..7ba603cf38d --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.fir.txt @@ -0,0 +1,17 @@ +FILE: incorrectDataClass.kt + public final data class Foo : R|kotlin/Any| { + public constructor(a: R|kotlin/Int|, b: R|kotlin/Int|): R|Foo| { + super() + } + + public final val b: R|kotlin/Int| = R|/b| + public get(): R|kotlin/Int| + + public final val c: R|kotlin/Int| = Int(4) + public get(): R|kotlin/Int| + + public final operator fun component1(): R|kotlin/Int| + + public final fun copy(b: R|kotlin/Int| = this@R|/Foo|.R|/Foo.b|): R|Foo| + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.kt b/compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.kt new file mode 100644 index 00000000000..214fca2b270 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.kt @@ -0,0 +1,5 @@ +// ISSUE: KT-44554 + +data class Foo(a: Int, val b: Int) { + val c = 4 +} diff --git a/compiler/fir/analysis-tests/testData/resolve/inference/coercionToUnitWithEarlyReturn.kt b/compiler/fir/analysis-tests/testData/resolve/inference/coercionToUnitWithEarlyReturn.kt index 1739ea41199..17e399120e2 100644 --- a/compiler/fir/analysis-tests/testData/resolve/inference/coercionToUnitWithEarlyReturn.kt +++ b/compiler/fir/analysis-tests/testData/resolve/inference/coercionToUnitWithEarlyReturn.kt @@ -14,6 +14,5 @@ fun main(x: A?) { x?.unit() } - // lambda has a type (() -> Unit?) foo(lambda) } diff --git a/compiler/fir/analysis-tests/testData/resolve/openInInterface.kt b/compiler/fir/analysis-tests/testData/resolve/openInInterface.kt index 863e2cf7e4f..5f2c66adb2a 100644 --- a/compiler/fir/analysis-tests/testData/resolve/openInInterface.kt +++ b/compiler/fir/analysis-tests/testData/resolve/openInInterface.kt @@ -8,7 +8,7 @@ interface Some { open var xx: Int open var yy = 1 - open var zz: Int + open var zz: Int set(value) { field = value } diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/booleanElvisBoundSmartcast.fir.txt b/compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/booleanElvisBoundSmartcast.fir.txt new file mode 100644 index 00000000000..2429c056d0f --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/booleanElvisBoundSmartcast.fir.txt @@ -0,0 +1,35 @@ +FILE: booleanElvisBoundSmartcast.kt + public final class A : R|kotlin/Any| { + public constructor(b: R|kotlin/Boolean|): R|A| { + super() + } + + public final val b: R|kotlin/Boolean| = R|/b| + public get(): R|kotlin/Boolean| + + public final fun foo(): R|kotlin/Unit| { + } + + } + public final fun test_1(a: R|A?|): R|kotlin/Unit| { + when () { + R|/a|?.{ $subj$.R|/A.b| } ?: Boolean(false) -> { + R|/a|.R|/A.foo|() + } + else -> { + R|/a|.#() + } + } + + } + public final fun test_2(a: R|A?|): R|kotlin/Unit| { + when () { + R|/a|?.{ $subj$.R|/A.b| } ?: Boolean(true) -> { + R|/a|.#() + } + else -> { + R|/a|.R|/A.foo|() + } + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/booleanElvisBoundSmartcast.kt b/compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/booleanElvisBoundSmartcast.kt new file mode 100644 index 00000000000..f7e4d049fc3 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/booleanElvisBoundSmartcast.kt @@ -0,0 +1,22 @@ +// !LANGUAGE: +BooleanElvisBoundSmartCasts +// ISSUE: KT-44511, also relates to KT-8492 and KT-26357 + +class A(val b: Boolean) { + fun foo() {} +} + +fun test_1(a: A?) { + if (a?.b ?: false) { + a.foo() // OK + } else { + a.foo() // Error + } +} + +fun test_2(a: A?) { + if (a?.b ?: true) { + a.foo() // Error + } else { + a.foo() // OK + } +} diff --git a/compiler/fir/analysis-tests/testData/resolve/whenElse.kt b/compiler/fir/analysis-tests/testData/resolve/whenElse.kt index 831c7f173ab..8dcd09a23e6 100644 --- a/compiler/fir/analysis-tests/testData/resolve/whenElse.kt +++ b/compiler/fir/analysis-tests/testData/resolve/whenElse.kt @@ -16,12 +16,12 @@ fun get(f: Boolean) = if (f) {A.A1} else {""} fun case2() { val flag: Any = get(false) //string - val l1 = when (flag!!) { // should be NO_ELSE_IN_WHEN + val l1 = when (flag!!) { // should be NO_ELSE_IN_WHEN A.A1 -> B() A.A2 -> B() } - val l2 = when (flag) {// should be NO_ELSE_IN_WHEN + val l2 = when (flag) {// should be NO_ELSE_IN_WHEN A.A1 -> B() A.A2 -> B() } @@ -30,12 +30,12 @@ fun get(f: Boolean) = if (f) {A.A1} else {""} fun case2() { val flag: Any = get(true) //A - val l1 = when (flag!!) {// should be NO_ELSE_IN_WHEN + val l1 = when (flag!!) {// should be NO_ELSE_IN_WHEN A.A1 -> B() A.A2 -> B() } - val l2 = when (flag) {// should be NO_ELSE_IN_WHEN + val l2 = when (flag) {// should be NO_ELSE_IN_WHEN A.A1 -> B() A.A2 -> B() } @@ -44,12 +44,12 @@ fun get(f: Boolean) = if (f) {A.A1} else {""} fun case3() { val flag = "" //A - val l1 = when (flag!!) {// should be NO_ELSE_IN_WHEN + val l1 = when (flag!!) {// should be NO_ELSE_IN_WHEN A.A1 -> B() //should be INCOMPATIBLE_TYPES A.A2 -> B() //should be INCOMPATIBLE_TYPES } - val l2 = when (flag) {// should be NO_ELSE_IN_WHEN + val l2 = when (flag) {// should be NO_ELSE_IN_WHEN A.A1 -> B() //should be INCOMPATIBLE_TYPES A.A2 -> B() //should be INCOMPATIBLE_TYPES } diff --git a/compiler/fir/analysis-tests/testData/resolve/whenWithWhenAsStatement.fir.txt b/compiler/fir/analysis-tests/testData/resolve/whenWithWhenAsStatement.fir.txt new file mode 100644 index 00000000000..6c4ff584b91 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/whenWithWhenAsStatement.fir.txt @@ -0,0 +1,16 @@ +FILE: whenWithWhenAsStatement.kt + public final fun test(value: R|kotlin/Int|): R|kotlin/Unit| { + when (R|/value|) { + ==($subj$, Int(0)) -> { + } + ==($subj$, Int(1)) -> { + when (R|/value|) { + ==($subj$, Int(2)) -> { + Boolean(false) + } + } + + } + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolve/whenWithWhenAsStatement.kt b/compiler/fir/analysis-tests/testData/resolve/whenWithWhenAsStatement.kt new file mode 100644 index 00000000000..2c209a60f98 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/whenWithWhenAsStatement.kt @@ -0,0 +1,8 @@ +fun test(value: Int) { + when (value) { + 0 -> {} + 1 -> when (value) { + 2 -> false + } + } +} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index 92d29a5322b..dc995f11a31 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -158,54 +158,6 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { runTest("compiler/fir/analysis-tests/testData/resolve/enumWithCompanion.kt"); } - @Test - @TestMetadata("exhaustiveWhenAndDNNType.kt") - public void testExhaustiveWhenAndDNNType() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndDNNType.kt"); - } - - @Test - @TestMetadata("exhaustiveWhenAndFlexibleType.kt") - public void testExhaustiveWhenAndFlexibleType() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndFlexibleType.kt"); - } - - @Test - @TestMetadata("exhaustiveness_boolean.kt") - public void testExhaustiveness_boolean() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_boolean.kt"); - } - - @Test - @TestMetadata("exhaustiveness_enum.kt") - public void testExhaustiveness_enum() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enum.kt"); - } - - @Test - @TestMetadata("exhaustiveness_enumJava.kt") - public void testExhaustiveness_enumJava() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enumJava.kt"); - } - - @Test - @TestMetadata("exhaustiveness_sealedClass.kt") - public void testExhaustiveness_sealedClass() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedClass.kt"); - } - - @Test - @TestMetadata("exhaustiveness_sealedObject.kt") - public void testExhaustiveness_sealedObject() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedObject.kt"); - } - - @Test - @TestMetadata("exhaustiveness_sealedSubClass.kt") - public void testExhaustiveness_sealedSubClass() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedSubClass.kt"); - } - @Test @TestMetadata("extension.kt") public void testExtension() throws Exception { @@ -284,6 +236,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { runTest("compiler/fir/analysis-tests/testData/resolve/implicitTypeInFakeOverride.kt"); } + @Test + @TestMetadata("incorrectDataClass.kt") + public void testIncorrectDataClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.kt"); + } + @Test @TestMetadata("incorrectSuperCall.kt") public void testIncorrectSuperCall() throws Exception { @@ -584,6 +542,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { runTest("compiler/fir/analysis-tests/testData/resolve/whenInference.kt"); } + @Test + @TestMetadata("whenWithWhenAsStatement.kt") + public void testWhenWithWhenAsStatement() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/whenWithWhenAsStatement.kt"); + } + @Nested @TestMetadata("compiler/fir/analysis-tests/testData/resolve/arguments") @TestDataPath("$PROJECT_ROOT") @@ -1454,6 +1418,126 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { } } + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/exhaustiveness") + @TestDataPath("$PROJECT_ROOT") + public class Exhaustiveness { + @Test + public void testAllFilesPresentInExhaustiveness() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/exhaustiveness"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative") + @TestDataPath("$PROJECT_ROOT") + public class Negative { + @Test + public void testAllFilesPresentInNegative() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("missingBooleanBranch.kt") + public void testMissingBooleanBranch() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.kt"); + } + + @Test + @TestMetadata("missingElse.kt") + public void testMissingElse() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.kt"); + } + + @Test + @TestMetadata("missingEnumEntry.kt") + public void testMissingEnumEntry() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.kt"); + } + + @Test + @TestMetadata("missingSealedInheritor.kt") + public void testMissingSealedInheritor() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.kt"); + } + + @Test + @TestMetadata("nonExhaustiveWhenWithoutCoercionToUnit.kt") + public void testNonExhaustiveWhenWithoutCoercionToUnit() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/nonExhaustiveWhenWithoutCoercionToUnit.kt"); + } + } + + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive") + @TestDataPath("$PROJECT_ROOT") + public class Positive { + @Test + public void testAllFilesPresentInPositive() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("exhaustiveWhenAndDNNType.kt") + public void testExhaustiveWhenAndDNNType() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndDNNType.kt"); + } + + @Test + @TestMetadata("exhaustiveWhenAndFlexibleType.kt") + public void testExhaustiveWhenAndFlexibleType() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndFlexibleType.kt"); + } + + @Test + @TestMetadata("exhaustiveness_boolean.kt") + public void testExhaustiveness_boolean() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.kt"); + } + + @Test + @TestMetadata("exhaustiveness_enum.kt") + public void testExhaustiveness_enum() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.kt"); + } + + @Test + @TestMetadata("exhaustiveness_enumJava.kt") + public void testExhaustiveness_enumJava() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt"); + } + + @Test + @TestMetadata("exhaustiveness_sealedClass.kt") + public void testExhaustiveness_sealedClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.kt"); + } + + @Test + @TestMetadata("exhaustiveness_sealedObject.kt") + public void testExhaustiveness_sealedObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedObject.kt"); + } + + @Test + @TestMetadata("exhaustiveness_sealedSubClass.kt") + public void testExhaustiveness_sealedSubClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt"); + } + + @Test + @TestMetadata("nestedIfInLambda.kt") + public void testNestedIfInLambda() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nestedIfInLambda.kt"); + } + + @Test + @TestMetadata("nonExhaustiveWhenWithCoercionToUnit.kt") + public void testNonExhaustiveWhenWithCoercionToUnit() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nonExhaustiveWhenWithCoercionToUnit.kt"); + } + } + } + @Nested @TestMetadata("compiler/fir/analysis-tests/testData/resolve/expresssions") @TestDataPath("$PROJECT_ROOT") @@ -3188,6 +3272,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @Test + @TestMetadata("booleanElvisBoundSmartcast.kt") + public void testBooleanElvisBoundSmartcast() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/booleanElvisBoundSmartcast.kt"); + } + @Test @TestMetadata("booleanOperators.kt") public void testBooleanOperators() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index 931d3a4966f..fbdb96cf4b0 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -161,54 +161,6 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/enumWithCompanion.kt"); } - @Test - @TestMetadata("exhaustiveWhenAndDNNType.kt") - public void testExhaustiveWhenAndDNNType() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndDNNType.kt"); - } - - @Test - @TestMetadata("exhaustiveWhenAndFlexibleType.kt") - public void testExhaustiveWhenAndFlexibleType() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveWhenAndFlexibleType.kt"); - } - - @Test - @TestMetadata("exhaustiveness_boolean.kt") - public void testExhaustiveness_boolean() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_boolean.kt"); - } - - @Test - @TestMetadata("exhaustiveness_enum.kt") - public void testExhaustiveness_enum() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enum.kt"); - } - - @Test - @TestMetadata("exhaustiveness_enumJava.kt") - public void testExhaustiveness_enumJava() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_enumJava.kt"); - } - - @Test - @TestMetadata("exhaustiveness_sealedClass.kt") - public void testExhaustiveness_sealedClass() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedClass.kt"); - } - - @Test - @TestMetadata("exhaustiveness_sealedObject.kt") - public void testExhaustiveness_sealedObject() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedObject.kt"); - } - - @Test - @TestMetadata("exhaustiveness_sealedSubClass.kt") - public void testExhaustiveness_sealedSubClass() throws Exception { - runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness_sealedSubClass.kt"); - } - @Test @TestMetadata("extension.kt") public void testExtension() throws Exception { @@ -287,6 +239,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/implicitTypeInFakeOverride.kt"); } + @Test + @TestMetadata("incorrectDataClass.kt") + public void testIncorrectDataClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/incorrectDataClass.kt"); + } + @Test @TestMetadata("incorrectSuperCall.kt") public void testIncorrectSuperCall() throws Exception { @@ -587,6 +545,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/whenInference.kt"); } + @Test + @TestMetadata("whenWithWhenAsStatement.kt") + public void testWhenWithWhenAsStatement() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/whenWithWhenAsStatement.kt"); + } + @Nested @TestMetadata("compiler/fir/analysis-tests/testData/resolve/arguments") @TestDataPath("$PROJECT_ROOT") @@ -1466,6 +1430,129 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos } } + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/exhaustiveness") + @TestDataPath("$PROJECT_ROOT") + @Execution(ExecutionMode.SAME_THREAD) + public class Exhaustiveness { + @Test + public void testAllFilesPresentInExhaustiveness() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/exhaustiveness"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative") + @TestDataPath("$PROJECT_ROOT") + @Execution(ExecutionMode.SAME_THREAD) + public class Negative { + @Test + public void testAllFilesPresentInNegative() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("missingBooleanBranch.kt") + public void testMissingBooleanBranch() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.kt"); + } + + @Test + @TestMetadata("missingElse.kt") + public void testMissingElse() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.kt"); + } + + @Test + @TestMetadata("missingEnumEntry.kt") + public void testMissingEnumEntry() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.kt"); + } + + @Test + @TestMetadata("missingSealedInheritor.kt") + public void testMissingSealedInheritor() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.kt"); + } + + @Test + @TestMetadata("nonExhaustiveWhenWithoutCoercionToUnit.kt") + public void testNonExhaustiveWhenWithoutCoercionToUnit() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/nonExhaustiveWhenWithoutCoercionToUnit.kt"); + } + } + + @Nested + @TestMetadata("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive") + @TestDataPath("$PROJECT_ROOT") + @Execution(ExecutionMode.SAME_THREAD) + public class Positive { + @Test + public void testAllFilesPresentInPositive() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive"), Pattern.compile("^([^.]+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("exhaustiveWhenAndDNNType.kt") + public void testExhaustiveWhenAndDNNType() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndDNNType.kt"); + } + + @Test + @TestMetadata("exhaustiveWhenAndFlexibleType.kt") + public void testExhaustiveWhenAndFlexibleType() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveWhenAndFlexibleType.kt"); + } + + @Test + @TestMetadata("exhaustiveness_boolean.kt") + public void testExhaustiveness_boolean() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.kt"); + } + + @Test + @TestMetadata("exhaustiveness_enum.kt") + public void testExhaustiveness_enum() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.kt"); + } + + @Test + @TestMetadata("exhaustiveness_enumJava.kt") + public void testExhaustiveness_enumJava() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt"); + } + + @Test + @TestMetadata("exhaustiveness_sealedClass.kt") + public void testExhaustiveness_sealedClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.kt"); + } + + @Test + @TestMetadata("exhaustiveness_sealedObject.kt") + public void testExhaustiveness_sealedObject() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedObject.kt"); + } + + @Test + @TestMetadata("exhaustiveness_sealedSubClass.kt") + public void testExhaustiveness_sealedSubClass() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt"); + } + + @Test + @TestMetadata("nestedIfInLambda.kt") + public void testNestedIfInLambda() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nestedIfInLambda.kt"); + } + + @Test + @TestMetadata("nonExhaustiveWhenWithCoercionToUnit.kt") + public void testNonExhaustiveWhenWithCoercionToUnit() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/nonExhaustiveWhenWithCoercionToUnit.kt"); + } + } + } + @Nested @TestMetadata("compiler/fir/analysis-tests/testData/resolve/expresssions") @TestDataPath("$PROJECT_ROOT") @@ -3223,6 +3310,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans"), Pattern.compile("^([^.]+)\\.kt$"), null, true); } + @Test + @TestMetadata("booleanElvisBoundSmartcast.kt") + public void testBooleanElvisBoundSmartcast() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/booleans/booleanElvisBoundSmartcast.kt"); + } + @Test @TestMetadata("booleanOperators.kt") public void testBooleanOperators() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index e0d4ca07cfb..56b9c23c588 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -11835,6 +11835,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/inference/equalitySubstitutionInsideNonInvariantType.kt"); } + @Test + @TestMetadata("errorsOnImplicitInvokeInSimpleCall.kt") + public void testErrorsOnImplicitInvokeInSimpleCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt"); + } + @Test @TestMetadata("expectedTypeAdditionalTest.kt") public void testExpectedTypeAdditionalTest() throws Exception { @@ -24385,6 +24391,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/tests/sealed/inheritorInDifferentModule.kt"); } + @Test + @TestMetadata("kt44316.kt") + public void testKt44316() throws Exception { + runTest("compiler/testData/diagnostics/tests/sealed/kt44316.kt"); + } + @Test @TestMetadata("Local.kt") public void testLocal() throws Exception { @@ -30638,6 +30650,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti runTest("compiler/testData/diagnostics/testsWithStdLib/assignedInSynchronized.kt"); } + @Test + @TestMetadata("buildLazyValueForMap.kt") + public void testBuildLazyValueForMap() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/buildLazyValueForMap.kt"); + } + @Test @TestMetadata("CallCompanionProtectedNonStatic.kt") public void testCallCompanionProtectedNonStatic() throws Exception { diff --git a/compiler/fir/checkers/checkers-component-generator/build.gradle.kts b/compiler/fir/checkers/checkers-component-generator/build.gradle.kts index c6df8b80051..e57d16ffdb9 100644 --- a/compiler/fir/checkers/checkers-component-generator/build.gradle.kts +++ b/compiler/fir/checkers/checkers-component-generator/build.gradle.kts @@ -9,6 +9,14 @@ dependencies { implementation(project(":compiler:fir:tree:tree-generator")) implementation(project(":kotlin-reflect")) implementation(project(":kotlin-reflect-api")) + + /* + We do not need guava in the generator, but because of a bug in the IJ project importing, we need to have a dependency on intellijCoreDep + the same as it is in `:fir:tree:tree-generator` module to the project be imported correctly + */ + compileOnly(intellijCoreDep()) { includeJars("intellij-core", "guava", rootProject = rootProject) } + + implementation(project(":compiler:psi")) } val writeCopyright by task { diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Generator.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Generator.kt index 1732f7aa22b..c755a2c9996 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Generator.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Generator.kt @@ -20,20 +20,11 @@ class Generator( private val packageName: String, private val abstractCheckerName: String ) { - private val generationPath: File - - init { - var path = generationPath - packageName.split(".").forEach { - path = path.resolve(it) - } - path.mkdirs() - this.generationPath = path - } + private val generationPath: File = getGenerationPath(generationPath, packageName) private fun generateAliases() { val filename = "${abstractCheckerName}Aliases.kt" - generationPath.resolve(filename).useSmartPrinter { + generationPath.resolve(filename).writeToFileUsingSmartPrinterIfFileContentChanged { printPackageAndCopyright() printGeneratedMessage() configuration.aliases.keys @@ -52,7 +43,7 @@ class Generator( private fun generateAbstractCheckersComponent() { val filename = "${checkersComponentName}.kt" - generationPath.resolve(filename).useSmartPrinter { + generationPath.resolve(filename).writeToFileUsingSmartPrinterIfFileContentChanged { printPackageAndCopyright() printImports() printGeneratedMessage() @@ -95,7 +86,7 @@ class Generator( private fun generateComposedComponent() { val composedComponentName = "Composed$checkersComponentName" val filename = "${composedComponentName}.kt" - generationPath.resolve(filename).useSmartPrinter { + generationPath.resolve(filename).writeToFileUsingSmartPrinterIfFileContentChanged { printPackageAndCopyright() printImports() printGeneratedMessage() diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/ImportPrinter.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/ImportPrinter.kt new file mode 100644 index 00000000000..69a52ac5c5a --- /dev/null +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/ImportPrinter.kt @@ -0,0 +1,33 @@ +/* + * 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.checkers.generator + +import org.jetbrains.kotlin.fir.tree.generator.printer.SmartPrinter + +private object ImportPrinter { + fun SmartPrinter.printImports(imports: Collection) { + val importsToPrint = imports.filterNot { it.isDefaultImport() }.distinct().sorted() + for (import in importsToPrint) { + println("import $import") + } + } + + private fun String.isDefaultImport() = substringBeforeLast('.') in defaultImportedPackages + + private val defaultImportedPackages = setOf( + "kotlin", + "kotlin.annotation", + "kotlin.collections", + "kotlin.ranges", + "kotlin.sequences", + "kotlin.text", + "kotlin.io", + ) +} + +fun SmartPrinter.printImports(imports: Collection) { + with(ImportPrinter) { printImports(imports) } +} diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt index 0088e1d7b9f..1b7b133ac44 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/Main.kt @@ -5,12 +5,10 @@ package org.jetbrains.kotlin.fir.checkers.generator +import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.DIAGNOSTICS_LIST +import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.generateDiagnostics import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.expressions.FirFunctionCall -import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression -import org.jetbrains.kotlin.fir.expressions.FirStatement -import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment -import org.jetbrains.kotlin.fir.expressions.FirTryExpression +import org.jetbrains.kotlin.fir.expressions.* import java.io.File fun main(args: Array) { @@ -23,6 +21,7 @@ fun main(args: Array) { alias("FunctionCallChecker") alias("VariableAssignmentChecker") alias("TryExpressionChecker") + alias("WhenExpressionChecker") } val declarationPackage = "org.jetbrains.kotlin.fir.analysis.checkers.declaration" @@ -46,6 +45,9 @@ fun main(args: Array) { classFqn = "org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker" ) } + + val diagnosticsPackage = "org.jetbrains.kotlin.fir.analysis.diagnostics" + generateDiagnostics(generationPath, diagnosticsPackage, DIAGNOSTICS_LIST) } /* diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt new file mode 100644 index 00000000000..e880838ec49 --- /dev/null +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticData.kt @@ -0,0 +1,61 @@ +/* + * 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.checkers.generator.diagnostics + +import org.jetbrains.kotlin.diagnostics.Severity +import kotlin.reflect.KType + +data class DiagnosticData( + val severity: Severity, + val name: String, + val sourceElementType: KType, + val psiType: KType, + val parameters: List, + val positioningStrategy: PositioningStrategy, + val group: String?, +) + +data class DiagnosticParameter( + val name: String, + val type: KType +) + +enum class PositioningStrategy(private val strategy: String) { + DEFAULT("DEFAULT"), + VAL_OR_VAR_NODE("VAL_OR_VAR_NODE"), + SECONDARY_CONSTRUCTOR_DELEGATION_CALL("SECONDARY_CONSTRUCTOR_DELEGATION_CALL"), + DECLARATION_NAME("DECLARATION_NAME"), + DECLARATION_SIGNATURE("DECLARATION_SIGNATURE"), + DECLARATION_SIGNATURE_OR_DEFAULT("DECLARATION_SIGNATURE_OR_DEFAULT"), + VISIBILITY_MODIFIER("VISIBILITY_MODIFIER"), + MODALITY_MODIFIER("MODALITY_MODIFIER"), + OPERATOR("OPERATOR"), + PARAMETER_DEFAULT_VALUE("PARAMETER_DEFAULT_VALUE"), + PARAMETER_VARARG_MODIFIER("PARAMETER_VARARG_MODIFIER"), + DECLARATION_RETURN_TYPE("DECLARATION_RETURN_TYPE"), + OVERRIDE_MODIFIER("OVERRIDE_MODIFIER"), + DOT_BY_SELECTOR("DOT_BY_SELECTOR"), + OPEN_MODIFIER("OPEN_MODIFIER"), + WHEN_EXPRESSION("WHEN_EXPRESSION"), + IF_EXPRESSION("IF_EXPRESSION"), + VARIANCE_MODIFIER("VARIANCE_MODIFIER"), + + ; + + val expressionToCreate get() = "SourceElementPositioningStrategies.$strategy" + + companion object { + const val importToAdd = "org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies" + } +} + + +fun DiagnosticData.hasDefaultPositioningStrategy(): Boolean = + positioningStrategy == PositioningStrategy.DEFAULT + +data class DiagnosticList( + val diagnostics: List, +) \ No newline at end of file diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticListBuilder.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticListBuilder.kt new file mode 100644 index 00000000000..f2396db44b6 --- /dev/null +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticListBuilder.kt @@ -0,0 +1,112 @@ +/* + * 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.checkers.generator.diagnostics + +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.diagnostics.Severity +import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.PrivateForInline +import kotlin.properties.PropertyDelegateProvider +import kotlin.properties.ReadOnlyProperty +import kotlin.reflect.KProperty +import kotlin.reflect.KType +import kotlin.reflect.typeOf + +class DiagnosticListBuilder private constructor() { + @PrivateForInline + val diagnostics = mutableListOf() + + @PrivateForInline + var currentGroupName: String? = null + + @OptIn(PrivateForInline::class) + inline fun group(groupName: String, inner: () -> Unit) { + if (currentGroupName != null) { + error("Groups can not be nested ") + } + currentGroupName = groupName + inner() + currentGroupName = null + } + + @OptIn(PrivateForInline::class) + inline fun error( + positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT, + crossinline init: DiagnosticBuilder.() -> Unit = {} + ) = diagnosticDelegateProvider(Severity.ERROR, positioningStrategy, init) + + + @OptIn(PrivateForInline::class) + inline fun warning( + positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT, + crossinline init: DiagnosticBuilder.() -> Unit = {} + ) = diagnosticDelegateProvider(Severity.WARNING, positioningStrategy, init) + + @PrivateForInline + @OptIn(ExperimentalStdlibApi::class) + inline fun diagnosticDelegateProvider( + severity: Severity, + positioningStrategy: PositioningStrategy, + crossinline init: DiagnosticBuilder.() -> Unit = {} + ) = PropertyDelegateProvider { _, property -> + diagnostics += DiagnosticBuilder( + severity, + name = property.name, + sourceElementType = typeOf(), + psiType = typeOf

(), + positioningStrategy, + group = currentGroupName, + ).apply(init).build() + AlwaysReturningUnitPropertyDelegate + } + + @PrivateForInline + object AlwaysReturningUnitPropertyDelegate : ReadOnlyProperty { + override fun getValue(thisRef: Any?, property: KProperty<*>) = Unit + } + + @OptIn(PrivateForInline::class) + private fun build() = DiagnosticList(diagnostics) + + companion object { + fun buildDiagnosticList(init: DiagnosticListBuilder.() -> Unit) = + DiagnosticListBuilder().apply(init).build() + } +} + +class DiagnosticBuilder( + private val severity: Severity, + private val name: String, + private val sourceElementType: KType, + private val psiType: KType, + private val positioningStrategy: PositioningStrategy, + private val group: String? +) { + @PrivateForInline + val parameters = mutableListOf() + + @OptIn(PrivateForInline::class, ExperimentalStdlibApi::class) + inline fun parameter(name: String) { + if (parameters.size == 3) { + error("Diagnostic cannot have more than 3 parameters") + } + parameters += DiagnosticParameter( + name = name, + type = typeOf() + ) + } + + @OptIn(PrivateForInline::class) + fun build() = DiagnosticData( + severity, + name, + sourceElementType, + psiType, + parameters, + positioningStrategy, + group + ) +} \ No newline at end of file diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticListGenerator.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticListGenerator.kt new file mode 100644 index 00000000000..d2da1a8fdb1 --- /dev/null +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticListGenerator.kt @@ -0,0 +1,14 @@ +/* + * 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.checkers.generator.diagnostics + +import org.jetbrains.kotlin.fir.checkers.generator.getGenerationPath +import java.io.File + +fun generateDiagnostics(rootPath: File, packageName: String, diagnosticList: DiagnosticList) { + val generationPath = getGenerationPath(rootPath, packageName) + ErrorListDiagnosticListRenderer.render(generationPath.resolve("FirErrors.kt"), diagnosticList, packageName) +} diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticListRenderer.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticListRenderer.kt new file mode 100644 index 00000000000..0efa0aaf7a2 --- /dev/null +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/DiagnosticListRenderer.kt @@ -0,0 +1,12 @@ +/* + * 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.checkers.generator.diagnostics + +import java.io.File + +abstract class DiagnosticListRenderer { + abstract fun render(file: File, diagnosticList: DiagnosticList, packageName: String) +} \ No newline at end of file diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/ErrorListDiagnosticListRenderer.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/ErrorListDiagnosticListRenderer.kt new file mode 100644 index 00000000000..2d8543a7c08 --- /dev/null +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/ErrorListDiagnosticListRenderer.kt @@ -0,0 +1,138 @@ +/* + * 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.checkers.generator.diagnostics + +import org.jetbrains.kotlin.fir.checkers.generator.* +import org.jetbrains.kotlin.fir.tree.generator.printer.SmartPrinter +import org.jetbrains.kotlin.fir.tree.generator.printer.printCopyright +import org.jetbrains.kotlin.fir.tree.generator.printer.printGeneratedMessage +import org.jetbrains.kotlin.fir.tree.generator.printer.writeToFileUsingSmartPrinterIfFileContentChanged +import java.io.File +import kotlin.reflect.KClass +import kotlin.reflect.KType +import kotlin.reflect.KTypeProjection + +object ErrorListDiagnosticListRenderer : DiagnosticListRenderer() { + override fun render(file: File, diagnosticList: DiagnosticList, packageName: String) { + file.writeToFileUsingSmartPrinterIfFileContentChanged { + render(diagnosticList, packageName) + } + } + + private fun SmartPrinter.render(diagnosticList: DiagnosticList, packageName: String) { + printCopyright() + println("package $packageName") + println() + collectAndPrintImports(diagnosticList) + printGeneratedMessage() + printErrorsObject(diagnosticList) + } + + private fun SmartPrinter.printErrorsObject(diagnosticList: DiagnosticList) { + inBracketsWithIndent("object FirErrors") { + val groups = diagnosticList.diagnostics.groupBy { it.group } + for ((group, diagnostics) in groups) { + printDiagnosticGroup(group, diagnostics) + println() + } + } + } + + private fun SmartPrinter.printDiagnosticGroup( + group: String?, + diagnostics: List + ) { + println("// ${group ?: "NO GROUP"}") + for (it in diagnostics) { + printDiagnostic(it) + } + } + + private fun SmartPrinter.printDiagnostic(diagnostic: DiagnosticData) { + print("val ${diagnostic.name} by ${diagnostic.getFactoryFunction()}") + printTypeArguments(diagnostic.getAllTypeArguments()) + printPositioningStrategy(diagnostic) + println() + } + + private fun SmartPrinter.printPositioningStrategy(diagnostic: DiagnosticData) { + print("(") + if (!diagnostic.hasDefaultPositioningStrategy()) { + print(diagnostic.positioningStrategy.expressionToCreate) + } + print(")") + } + + + @OptIn(ExperimentalStdlibApi::class) + private fun DiagnosticData.getAllTypeArguments(): List = buildList { + add(sourceElementType) + add(psiType) + parameters.mapTo(this) { it.type } + } + + private fun SmartPrinter.printTypeArguments(typeArguments: List) { + print("<") + printSeparatedWithComma(typeArguments) { typeArgument -> + printType(typeArgument) + } + print(">") + } + + private fun SmartPrinter.printType(type: KType) { + print(type.kClass.simpleName!!) + if (type.arguments.isNotEmpty()) { + print("<") + printSeparatedWithComma(type.arguments) { typeArgument -> + printTypeArgument(typeArgument) + } + print(">") + } + } + + private fun SmartPrinter.printTypeArgument(typeArgument: KTypeProjection) { + val typeArgumentType = typeArgument.type + if (typeArgumentType == null) { + print("*") + } else { + printType(typeArgumentType) + } + } + + private fun SmartPrinter.collectAndPrintImports(diagnosticList: DiagnosticList) { + val imports = collectImports(diagnosticList) + printImports(imports) + println() + } + + @OptIn(ExperimentalStdlibApi::class) + private fun collectImports(diagnosticList: DiagnosticList): Collection = buildSet { + diagnosticList.diagnostics.forEach { diagnostic -> + for (typeArgument in diagnostic.getAllTypeArguments()) { + typeArgument.collectClassNamesTo(this) + } + if (!diagnostic.hasDefaultPositioningStrategy()) { + add(PositioningStrategy.importToAdd) + } + } + } + + + private val KType.kClass: KClass<*> + get() = classifier as KClass<*> + + private fun DiagnosticData.getFactoryFunction(): String = + severity.name.toLowerCase() + parameters.size +} + +private inline fun SmartPrinter.printSeparatedWithComma(list: List, printItem: (T) -> Unit) { + list.forEachIndexed { index, element -> + printItem(element) + if (index != list.lastIndex) { + print(", ") + } + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt new file mode 100644 index 00000000000..1738edd5ae3 --- /dev/null +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirDiagnosticsList.kt @@ -0,0 +1,410 @@ +/* + * 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.checkers.generator.diagnostics + +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiTypeElement +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange +import org.jetbrains.kotlin.descriptors.Visibility +import org.jetbrains.kotlin.fir.FirEffectiveVisibility +import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.PrivateForInline +import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration +import org.jetbrains.kotlin.fir.declarations.FirClass +import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.WhenMissingCase +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.KtModifierKeywordToken +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.* + + +@Suppress("UNUSED_VARIABLE", "LocalVariableName") +@OptIn(PrivateForInline::class) +val DIAGNOSTICS_LIST = DiagnosticListBuilder.buildDiagnosticList { + group("Miscellaneous") { + val SYNTAX by error() + val OTHER_ERROR by error() + } + + group("General syntax") { + val ILLEGAL_CONST_EXPRESSION by error() + val ILLEGAL_UNDERSCORE by error() + val EXPRESSION_REQUIRED by error() + val BREAK_OR_CONTINUE_OUTSIDE_A_LOOP by error() + val NOT_A_LOOP_LABEL by error() + val VARIABLE_EXPECTED by error() + val RETURN_NOT_ALLOWED by error() + val DELEGATION_IN_INTERFACE by error() + } + + group("Unresolved") { + val HIDDEN by error { + parameter>("hidden") + } + val UNRESOLVED_REFERENCE by error { + parameter("reference") + } + val UNRESOLVED_LABEL by error() + val DESERIALIZATION_ERROR by error() + val ERROR_FROM_JAVA_RESOLUTION by error() + val UNKNOWN_CALLABLE_KIND by error() + val MISSING_STDLIB_CLASS by error() + val NO_THIS by error() + } + + group("Super") { + val SUPER_IS_NOT_AN_EXPRESSION by error() + val SUPER_NOT_AVAILABLE by error() + val ABSTRACT_SUPER_CALL by error() + val INSTANCE_ACCESS_BEFORE_SUPER_CALL by error { + parameter("target") + } + } + + group("Supertypes") { + val TYPE_PARAMETER_AS_SUPERTYPE by error() + val ENUM_AS_SUPERTYPE by error() + val RECURSION_IN_SUPERTYPES by error() + val NOT_A_SUPERTYPE by error() + val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error() + val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error { + parameter>("otherSuperType") + } + val SUPERTYPE_INITIALIZED_IN_INTERFACE by error() + val INTERFACE_WITH_SUPERCLASS by error() + val CLASS_IN_SUPERTYPE_FOR_ENUM by error() + val SEALED_SUPERTYPE by error() + val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error() + } + + group(" Constructor problems") { + val CONSTRUCTOR_IN_OBJECT by error(PositioningStrategy.DECLARATION_SIGNATURE) + val CONSTRUCTOR_IN_INTERFACE by error(PositioningStrategy.DECLARATION_SIGNATURE) + val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by error() + val NON_PRIVATE_CONSTRUCTOR_IN_SEALED by error() + val CYCLIC_CONSTRUCTOR_DELEGATION_CALL by warning() + val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) + val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning() + val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning() + val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning() + val EXPLICIT_DELEGATION_CALL_REQUIRED by warning(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) + val SEALED_CLASS_CONSTRUCTOR_CALL by error() + } + + group("Annotations") { + val ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR by error() + val ANNOTATION_ARGUMENT_MUST_BE_CONST by error() + val ANNOTATION_ARGUMENT_MUST_BE_ENUM_CONST by error() + val ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL by error() + val ANNOTATION_CLASS_MEMBER by error() + val ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT by error() + val INVALID_TYPE_OF_ANNOTATION_MEMBER by error() + val LOCAL_ANNOTATION_CLASS_ERROR by error() + val MISSING_VAL_ON_ANNOTATION_PARAMETER by error() + val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by error() + val NOT_AN_ANNOTATION_CLASS by error { + parameter("annotationName") + } + val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by error() + val VAR_ANNOTATION_PARAMETER by error(PositioningStrategy.VAL_OR_VAR_NODE) + } + + group("Exposed visibility group") { + val EXPOSED_TYPEALIAS_EXPANDED_TYPE by exposedVisibilityError(PositioningStrategy.DECLARATION_NAME) + val EXPOSED_FUNCTION_RETURN_TYPE by exposedVisibilityError(PositioningStrategy.DECLARATION_NAME) + + val EXPOSED_RECEIVER_TYPE by exposedVisibilityError() + val EXPOSED_PROPERTY_TYPE by exposedVisibilityError(PositioningStrategy.DECLARATION_NAME) + val EXPOSED_PARAMETER_TYPE by exposedVisibilityError(/* // NB: for parameter FE 1.0 reports not on a name for some reason */) + val EXPOSED_SUPER_INTERFACE by exposedVisibilityError() + val EXPOSED_SUPER_CLASS by exposedVisibilityError() + val EXPOSED_TYPE_PARAMETER_BOUND by exposedVisibilityError() + } + + group("Modifiers") { + val INAPPLICABLE_INFIX_MODIFIER by error() + val REPEATED_MODIFIER by error { + parameter("modifier") + } + val REDUNDANT_MODIFIER by error { + parameter("redundantModifier") + parameter("conflictingModifier") + } + val DEPRECATED_MODIFIER_PAIR by error { + parameter("deprecatedModifier") + parameter("conflictingModifier") + } + val INCOMPATIBLE_MODIFIERS by error { + parameter("modifier1") + parameter("modifier2") + } + val REDUNDANT_OPEN_IN_INTERFACE by warning(PositioningStrategy.OPEN_MODIFIER) + } + + group("Applicability") { + val NONE_APPLICABLE by error { + parameter>>("candidates") + } + + val INAPPLICABLE_CANDIDATE by error { + parameter>("candidate") + } + val INAPPLICABLE_LATEINIT_MODIFIER by error { + parameter("reason") + } + } + + group("Ambiguity") { + val AMBIGUITY by error { + parameter>>("candidates") + } + val ASSIGN_OPERATOR_AMBIGUITY by error { + parameter>>("candidates") + } + } + + group("Types & type parameters") { + val TYPE_MISMATCH by error { + parameter("expectedType") + parameter("actualType") + } + val RECURSION_IN_IMPLICIT_TYPES by error() + val INFERENCE_ERROR by error() + val PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT by error() + val UPPER_BOUND_VIOLATED by error { + parameter("typeParameter") + parameter("violatedType") + } + val TYPE_ARGUMENTS_NOT_ALLOWED by error() + val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error { + parameter("expectedCount") + parameter>("classifier") + } + val NO_TYPE_FOR_TYPE_PARAMETER by error() + val TYPE_PARAMETERS_IN_OBJECT by error() + val ILLEGAL_PROJECTION_USAGE by error() + val TYPE_PARAMETERS_IN_ENUM by error() + val CONFLICTING_PROJECTION by error { + parameter("type") // TODO use ConeType instead of String + } + val VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED by error(PositioningStrategy.VARIANCE_MODIFIER) + + val CATCH_PARAMETER_WITH_DEFAULT_VALUE by error() + val REIFIED_TYPE_IN_CATCH_CLAUSE by error() + val TYPE_PARAMETER_IN_CATCH_CLAUSE by error() + val GENERIC_THROWABLE_SUBCLASS by error() + val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error(PositioningStrategy.DECLARATION_NAME) + } + + group("overrides") { + val NOTHING_TO_OVERRIDE by error(PositioningStrategy.OVERRIDE_MODIFIER) { + parameter("declaration") + } + + val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error(PositioningStrategy.VISIBILITY_MODIFIER) { + parameter("overridingVisibility") + parameter>("overridden") + parameter("containingClassName") + } + val CANNOT_CHANGE_ACCESS_PRIVILEGE by error(PositioningStrategy.VISIBILITY_MODIFIER) { + parameter("overridingVisibility") + parameter>("overridden") + parameter("containingClassName") + } + + val OVERRIDING_FINAL_MEMBER by error(PositioningStrategy.OVERRIDE_MODIFIER) { + parameter>("overriddenDeclaration") + parameter("containingClassName") + } + + val RETURN_TYPE_MISMATCH_ON_OVERRIDE by error(PositioningStrategy.DECLARATION_RETURN_TYPE) { + parameter("function") + parameter("superFunction") + } + val PROPERTY_TYPE_MISMATCH_ON_OVERRIDE by error(PositioningStrategy.DECLARATION_RETURN_TYPE) { + parameter("property") + parameter("superProperty") + } + val VAR_TYPE_MISMATCH_ON_OVERRIDE by error(PositioningStrategy.DECLARATION_RETURN_TYPE) { + parameter("variable") + parameter("superVariable") + } + val VAR_OVERRIDDEN_BY_VAL by error(PositioningStrategy.VAL_OR_VAR_NODE) { + parameter("overridingDeclaration") + parameter("overriddenDeclaration") + } + } + + group("Redeclarations") { + val MANY_COMPANION_OBJECTS by error() + val CONFLICTING_OVERLOADS by error(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) { + parameter("conflictingOverloads") // TODO use Collection instead of String + } + val REDECLARATION by error() { + parameter("conflictingDeclaration") // TODO use Collection instead of String + } + val ANY_METHOD_IMPLEMENTED_IN_INTERFACE by error() + } + + group("Invalid local declarations") { + val LOCAL_OBJECT_NOT_ALLOWED by error(PositioningStrategy.DECLARATION_NAME) { + parameter("objectName") + } + val LOCAL_INTERFACE_NOT_ALLOWED by error(PositioningStrategy.DECLARATION_NAME) { + parameter("interfaceName") + } + } + + group("Functions") { + val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error(PositioningStrategy.MODALITY_MODIFIER) { + parameter("function") + parameter("containingClass") // TODO use FirClass instead of FirMemberDeclaration + } + val ABSTRACT_FUNCTION_WITH_BODY by error(PositioningStrategy.MODALITY_MODIFIER) { + parameter("function") + } + val NON_ABSTRACT_FUNCTION_WITH_NO_BODY by error(PositioningStrategy.DECLARATION_SIGNATURE) { + parameter("function") + } + val PRIVATE_FUNCTION_WITH_NO_BODY by error(PositioningStrategy.VISIBILITY_MODIFIER) { + parameter("function") + } + + val NON_MEMBER_FUNCTION_NO_BODY by error(PositioningStrategy.DECLARATION_SIGNATURE) { + parameter("function") + } + + val FUNCTION_DECLARATION_WITH_NO_NAME by error(PositioningStrategy.DECLARATION_SIGNATURE) + + // TODO: val ANONYMOUS_FUNCTION_WITH_NAME by error1(SourceElementPositioningStrategies.DECLARATION_NAME) + val ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE by error(PositioningStrategy.PARAMETER_DEFAULT_VALUE) + val USELESS_VARARG_ON_PARAMETER by warning() + } + + group("Properties & accessors") { + val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error(PositioningStrategy.MODALITY_MODIFIER) { + parameter("property") + parameter("containingClass") // TODO use FirClass instead of FirMemberDeclaration + } + val PRIVATE_PROPERTY_IN_INTERFACE by error(PositioningStrategy.VISIBILITY_MODIFIER) + + val ABSTRACT_PROPERTY_WITH_INITIALIZER by error() + val PROPERTY_INITIALIZER_IN_INTERFACE by error() + val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error(PositioningStrategy.DECLARATION_SIGNATURE) + + val BACKING_FIELD_IN_INTERFACE by error(PositioningStrategy.DECLARATION_SIGNATURE) + val EXTENSION_PROPERTY_WITH_BACKING_FIELD by error() + val PROPERTY_INITIALIZER_NO_BACKING_FIELD by error() + + val ABSTRACT_DELEGATED_PROPERTY by error() + val DELEGATED_PROPERTY_IN_INTERFACE by error() + // TODO: val ACCESSOR_FOR_DELEGATED_PROPERTY by error1() + + val ABSTRACT_PROPERTY_WITH_GETTER by error() + val ABSTRACT_PROPERTY_WITH_SETTER by error() + val PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY by error() + val PRIVATE_SETTER_FOR_OPEN_PROPERTY by error() + val EXPECTED_PRIVATE_DECLARATION by error(PositioningStrategy.VISIBILITY_MODIFIER) + } + + group("Multi-platform projects") { + val EXPECTED_DECLARATION_WITH_BODY by error(PositioningStrategy.DECLARATION_SIGNATURE) + val EXPECTED_PROPERTY_INITIALIZER by error() + // TODO: need to cover `by` as well as delegate expression + val EXPECTED_DELEGATED_PROPERTY by error() + } + + group("Destructuring declaration") { + val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error() + val COMPONENT_FUNCTION_MISSING by error { + parameter("missingFunctionName") + parameter("destructingType") + } + val COMPONENT_FUNCTION_AMBIGUITY by error { + parameter("functionWithAmbiguityName") + parameter>>("candidates") + } + + val COMPONENT_FUNCTION_ON_NULLABLE by error { + parameter("componentFunctionName") + } + + // TODO: val COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH by ... + } + + group("Control flow diagnostics") { + val UNINITIALIZED_VARIABLE by error { + parameter("variable") + } + val WRONG_INVOCATION_KIND by warning { + parameter>("declaration") + parameter("requiredRange") + parameter("actualRange") + } + val LEAKED_IN_PLACE_LAMBDA by error { + parameter>("lambda") + } + val WRONG_IMPLIES_CONDITION by warning() + } + + group("Nullability") { + val UNSAFE_CALL by error(PositioningStrategy.DOT_BY_SELECTOR) { + parameter("receiverType") + } + val UNSAFE_IMPLICIT_INVOKE_CALL by error { + parameter("receiverType") + } + val UNSAFE_INFIX_CALL by error { + parameter("lhs") + parameter("operator") + parameter("rhs") + } + val UNSAFE_OPERATOR_CALL by error { + parameter("lhs") + parameter("operator") + parameter("rhs") + } + // TODO: val UNEXPECTED_SAFE_CALL by ... + } + + group("When expressions") { + val NO_ELSE_IN_WHEN by error(PositioningStrategy.WHEN_EXPRESSION) { + parameter>("missingWhenCases") + } + val INVALID_IF_AS_EXPRESSION by error(PositioningStrategy.IF_EXPRESSION) + } + + group("Extended checkers") { + val REDUNDANT_VISIBILITY_MODIFIER by warning(PositioningStrategy.VISIBILITY_MODIFIER) + val REDUNDANT_MODALITY_MODIFIER by warning(PositioningStrategy.MODALITY_MODIFIER) + val REDUNDANT_RETURN_UNIT_TYPE by warning() + val REDUNDANT_EXPLICIT_TYPE by warning() + val REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE by warning() + val CAN_BE_VAL by warning(PositioningStrategy.VAL_OR_VAR_NODE) + val CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT by warning(PositioningStrategy.OPERATOR) + val REDUNDANT_CALL_OF_CONVERSION_METHOD by warning() + val ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS by warning(PositioningStrategy.OPERATOR) + val EMPTY_RANGE by warning() + val REDUNDANT_SETTER_PARAMETER_TYPE by warning() + val UNUSED_VARIABLE by warning(PositioningStrategy.DECLARATION_NAME) + val ASSIGNED_VALUE_IS_NEVER_READ by warning() + val VARIABLE_INITIALIZER_IS_REDUNDANT by warning() + val VARIABLE_NEVER_READ by warning(PositioningStrategy.DECLARATION_NAME) + val USELESS_CALL_ON_NOT_NULL by warning() + } +} + +private inline fun DiagnosticListBuilder.exposedVisibilityError( + positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT +) = error(positioningStrategy) { + parameter("elementVisibility") + parameter("restrictingDeclaration") + parameter("restrictingVisibility") +} diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/smartPrinterUtils.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/smartPrinterUtils.kt new file mode 100644 index 00000000000..604d176b4f8 --- /dev/null +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/smartPrinterUtils.kt @@ -0,0 +1,15 @@ +/* + * 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.checkers.generator + +import org.jetbrains.kotlin.fir.tree.generator.printer.SmartPrinter +import org.jetbrains.kotlin.fir.tree.generator.printer.withIndent + +inline fun SmartPrinter.inBracketsWithIndent(header: String = "", body: () -> Unit) { + println("$header {") + withIndent(body) + println("}") +} \ No newline at end of file diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/utils.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/utils.kt new file mode 100644 index 00000000000..203734afc22 --- /dev/null +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/utils.kt @@ -0,0 +1,25 @@ +/* + * 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.checkers.generator + +import java.io.File +import kotlin.reflect.KClass +import kotlin.reflect.KType + +fun getGenerationPath(rootPath: File, packageName: String): File = + packageName + .split(".") + .fold(rootPath, File::resolve) + .apply { mkdirs() } + + +@OptIn(ExperimentalStdlibApi::class) +fun KType.collectClassNamesTo(set: MutableSet) { + (classifier as? KClass<*>)?.qualifiedName?.let(set::add) + for (argument in arguments) { + argument.type?.collectClassNamesTo(set) + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ComposedExpressionCheckers.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ComposedExpressionCheckers.kt index f4e8d19e20a..f3e5f53d1bf 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ComposedExpressionCheckers.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ComposedExpressionCheckers.kt @@ -23,12 +23,15 @@ internal class ComposedExpressionCheckers : ExpressionCheckers() { get() = _variableAssignmentCheckers override val tryExpressionCheckers: Set get() = _tryExpressionCheckers + override val whenExpressionCheckers: Set + get() = _whenExpressionCheckers private val _basicExpressionCheckers: MutableSet = mutableSetOf() private val _qualifiedAccessCheckers: MutableSet = mutableSetOf() private val _functionCallCheckers: MutableSet = mutableSetOf() private val _variableAssignmentCheckers: MutableSet = mutableSetOf() private val _tryExpressionCheckers: MutableSet = mutableSetOf() + private val _whenExpressionCheckers: MutableSet = mutableSetOf() @CheckersComponentInternal internal fun register(checkers: ExpressionCheckers) { @@ -37,5 +40,6 @@ internal class ComposedExpressionCheckers : ExpressionCheckers() { _functionCallCheckers += checkers.allFunctionCallCheckers _variableAssignmentCheckers += checkers.allVariableAssignmentCheckers _tryExpressionCheckers += checkers.allTryExpressionCheckers + _whenExpressionCheckers += checkers.allWhenExpressionCheckers } } diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ExpressionCheckers.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ExpressionCheckers.kt index 72e167d29e2..116e76cfb52 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ExpressionCheckers.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/ExpressionCheckers.kt @@ -22,10 +22,12 @@ abstract class ExpressionCheckers { open val functionCallCheckers: Set = emptySet() open val variableAssignmentCheckers: Set = emptySet() open val tryExpressionCheckers: Set = emptySet() + open val whenExpressionCheckers: Set = emptySet() @CheckersComponentInternal internal val allBasicExpressionCheckers: Set get() = basicExpressionCheckers @CheckersComponentInternal internal val allQualifiedAccessCheckers: Set get() = qualifiedAccessCheckers + allBasicExpressionCheckers @CheckersComponentInternal internal val allFunctionCallCheckers: Set get() = functionCallCheckers + allQualifiedAccessCheckers @CheckersComponentInternal internal val allVariableAssignmentCheckers: Set get() = variableAssignmentCheckers + allBasicExpressionCheckers @CheckersComponentInternal internal val allTryExpressionCheckers: Set get() = tryExpressionCheckers + allBasicExpressionCheckers + @CheckersComponentInternal internal val allWhenExpressionCheckers: Set get() = whenExpressionCheckers + allBasicExpressionCheckers } diff --git a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionCheckerAliases.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionCheckerAliases.kt index 3f7f70d9f3d..b0c400b7185 100644 --- a/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionCheckerAliases.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExpressionCheckerAliases.kt @@ -15,9 +15,11 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.FirTryExpression import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment +import org.jetbrains.kotlin.fir.expressions.FirWhenExpression typealias FirBasicExpressionChecker = FirExpressionChecker typealias FirQualifiedAccessChecker = FirExpressionChecker typealias FirFunctionCallChecker = FirExpressionChecker typealias FirVariableAssignmentChecker = FirExpressionChecker typealias FirTryExpressionChecker = FirExpressionChecker +typealias FirWhenExpressionChecker = FirExpressionChecker diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt similarity index 82% rename from compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt rename to compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt index 0ac8ab7e8c9..9d386bcdc7f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt +++ b/compiler/fir/checkers/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/FirErrors.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -11,9 +11,12 @@ import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.FirEffectiveVisibility import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.expressions.WhenMissingCase import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol @@ -21,7 +24,27 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtDestructuringDeclaration +import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.psi.KtFunction +import org.jetbrains.kotlin.psi.KtIfExpression +import org.jetbrains.kotlin.psi.KtModifierListOwner +import org.jetbrains.kotlin.psi.KtNamedDeclaration +import org.jetbrains.kotlin.psi.KtParameter +import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.KtPropertyAccessor +import org.jetbrains.kotlin.psi.KtPropertyDelegate +import org.jetbrains.kotlin.psi.KtTypeParameter +import org.jetbrains.kotlin.psi.KtTypeParameterList +import org.jetbrains.kotlin.psi.KtTypeReference +import org.jetbrains.kotlin.psi.KtWhenExpression + +/* + * This file was generated automatically + * DO NOT MODIFY IT MANUALLY + */ object FirErrors { // Miscellaneous @@ -67,11 +90,11 @@ object FirErrors { val SEALED_SUPERTYPE by error0() val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error0() - // Constructor problems + // Constructor problems val CONSTRUCTOR_IN_OBJECT by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val CONSTRUCTOR_IN_INTERFACE by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) - val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by existing0() - val NON_PRIVATE_CONSTRUCTOR_IN_SEALED by existing0() + val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by error0() + val NON_PRIVATE_CONSTRUCTOR_IN_SEALED by error0() val CYCLIC_CONSTRUCTOR_DELEGATION_CALL by warning0() val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL) val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning0() @@ -81,18 +104,18 @@ object FirErrors { val SEALED_CLASS_CONSTRUCTOR_CALL by error0() // Annotations - val ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR by existing0() - val ANNOTATION_ARGUMENT_MUST_BE_CONST by existing0() - val ANNOTATION_ARGUMENT_MUST_BE_ENUM_CONST by existing0() - val ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL by existing0() - val ANNOTATION_CLASS_MEMBER by existing0() - val ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT by existing0() - val INVALID_TYPE_OF_ANNOTATION_MEMBER by existing0() - val LOCAL_ANNOTATION_CLASS_ERROR by existing0() - val MISSING_VAL_ON_ANNOTATION_PARAMETER by existing0() - val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by existing0() + val ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR by error0() + val ANNOTATION_ARGUMENT_MUST_BE_CONST by error0() + val ANNOTATION_ARGUMENT_MUST_BE_ENUM_CONST by error0() + val ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL by error0() + val ANNOTATION_CLASS_MEMBER by error0() + val ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT by error0() + val INVALID_TYPE_OF_ANNOTATION_MEMBER by error0() + val LOCAL_ANNOTATION_CLASS_ERROR by error0() + val MISSING_VAL_ON_ANNOTATION_PARAMETER by error0() + val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by error0() val NOT_AN_ANNOTATION_CLASS by error1() - val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by existing0() + val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by error0() val VAR_ANNOTATION_PARAMETER by error0(SourceElementPositioningStrategies.VAL_OR_VAR_NODE) // Exposed visibility group @@ -100,7 +123,7 @@ object FirErrors { val EXPOSED_FUNCTION_RETURN_TYPE by error3(SourceElementPositioningStrategies.DECLARATION_NAME) val EXPOSED_RECEIVER_TYPE by error3() val EXPOSED_PROPERTY_TYPE by error3(SourceElementPositioningStrategies.DECLARATION_NAME) - val EXPOSED_PARAMETER_TYPE by error3(/* // NB: for parameter FE 1.0 reports not on a name for some reason */) + val EXPOSED_PARAMETER_TYPE by error3() val EXPOSED_SUPER_INTERFACE by error3() val EXPOSED_SUPER_CLASS by error3() val EXPOSED_TYPE_PARAMETER_BOUND by error3() @@ -142,17 +165,14 @@ object FirErrors { val GENERIC_THROWABLE_SUBCLASS by error0() val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error0(SourceElementPositioningStrategies.DECLARATION_NAME) - // Overrides + // overrides val NOTHING_TO_OVERRIDE by error1(SourceElementPositioningStrategies.OVERRIDE_MODIFIER) - val OVERRIDING_FINAL_MEMBER by error2, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER) - val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error3, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val CANNOT_CHANGE_ACCESS_PRIVILEGE by error3, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) - + val OVERRIDING_FINAL_MEMBER by error2, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER) val RETURN_TYPE_MISMATCH_ON_OVERRIDE by error2(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE) val PROPERTY_TYPE_MISMATCH_ON_OVERRIDE by error2(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE) val VAR_TYPE_MISMATCH_ON_OVERRIDE by error2(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE) - val VAR_OVERRIDDEN_BY_VAL by error2(SourceElementPositioningStrategies.VAL_OR_VAR_NODE) // Redeclarations @@ -166,56 +186,42 @@ object FirErrors { val LOCAL_INTERFACE_NOT_ALLOWED by error1(SourceElementPositioningStrategies.DECLARATION_NAME) // Functions - val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error2(SourceElementPositioningStrategies.ABSTRACT_MODIFIER) - val ABSTRACT_FUNCTION_WITH_BODY by error1(SourceElementPositioningStrategies.ABSTRACT_MODIFIER) + val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error2(SourceElementPositioningStrategies.MODALITY_MODIFIER) + val ABSTRACT_FUNCTION_WITH_BODY by error1(SourceElementPositioningStrategies.MODALITY_MODIFIER) val NON_ABSTRACT_FUNCTION_WITH_NO_BODY by error1(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) - val PRIVATE_FUNCTION_WITH_NO_BODY by error1(SourceElementPositioningStrategies.PRIVATE_MODIFIER) + val PRIVATE_FUNCTION_WITH_NO_BODY by error1(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val NON_MEMBER_FUNCTION_NO_BODY by error1(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) - val FUNCTION_DECLARATION_WITH_NO_NAME by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) - - // TODO: val ANONYMOUS_FUNCTION_WITH_NAME by error1(SourceElementPositioningStrategies.DECLARATION_NAME) val ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE by error0(SourceElementPositioningStrategies.PARAMETER_DEFAULT_VALUE) val USELESS_VARARG_ON_PARAMETER by warning0() // Properties & accessors - val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2(SourceElementPositioningStrategies.ABSTRACT_MODIFIER) - val PRIVATE_PROPERTY_IN_INTERFACE by error0(SourceElementPositioningStrategies.PRIVATE_MODIFIER) - + val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2(SourceElementPositioningStrategies.MODALITY_MODIFIER) + val PRIVATE_PROPERTY_IN_INTERFACE by error0(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val ABSTRACT_PROPERTY_WITH_INITIALIZER by error0() - // TODO: val MUST_BE_INITIALIZED by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) - // TODO: val MUST_BE_INITIALIZED_OR_BE_ABSTRACT by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) - // TODO: val EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) - - // TODO: val EXTENSION_PROPERTY_WITH_BACKING_FIELD by error0() - // TODO: val PROPERTY_INITIALIZER_NO_BACKING_FIELD by error0() - val PROPERTY_INITIALIZER_IN_INTERFACE by error0() val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) - // TODO: val BACKING_FIELD_IN_INTERFACE by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) - + val BACKING_FIELD_IN_INTERFACE by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) + val EXTENSION_PROPERTY_WITH_BACKING_FIELD by error0() + val PROPERTY_INITIALIZER_NO_BACKING_FIELD by error0() val ABSTRACT_DELEGATED_PROPERTY by error0() val DELEGATED_PROPERTY_IN_INTERFACE by error0() - // TODO: val ACCESSOR_FOR_DELEGATED_PROPERTY by error1() - val ABSTRACT_PROPERTY_WITH_GETTER by error0() val ABSTRACT_PROPERTY_WITH_SETTER by error0() val PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY by error0() val PRIVATE_SETTER_FOR_OPEN_PROPERTY by error0() + val EXPECTED_PRIVATE_DECLARATION by error0(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) // Multi-platform projects val EXPECTED_DECLARATION_WITH_BODY by error0(SourceElementPositioningStrategies.DECLARATION_SIGNATURE) val EXPECTED_PROPERTY_INITIALIZER by error0() - // TODO: need to cover `by` as well as delegate expression val EXPECTED_DELEGATED_PROPERTY by error0() - val EXPECTED_PRIVATE_DECLARATION by error0(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) // Destructuring declaration val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0() - val COMPONENT_FUNCTION_MISSING by error2() - val COMPONENT_FUNCTION_AMBIGUITY by error2>>() + val COMPONENT_FUNCTION_MISSING by error2() + val COMPONENT_FUNCTION_AMBIGUITY by error2>>() val COMPONENT_FUNCTION_ON_NULLABLE by error1() - // TODO: val COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH by ... // Control flow diagnostics val UNINITIALIZED_VARIABLE by error1() @@ -225,12 +231,15 @@ object FirErrors { // Nullability val UNSAFE_CALL by error1(SourceElementPositioningStrategies.DOT_BY_SELECTOR) - // TODO: val UNSAFE_IMPLICIT_INVOKE_CALL by error1() - // TODO: val UNSAFE_INFIX_CALL by ... - // TODO: val UNSAFE_OPERATOR_CALL by ... - // TODO: val UNEXPECTED_SAFE_CALL by ... + val UNSAFE_IMPLICIT_INVOKE_CALL by error1() + val UNSAFE_INFIX_CALL by error3() + val UNSAFE_OPERATOR_CALL by error3() - // Extended checkers group + // When expressions + val NO_ELSE_IN_WHEN by error1>(SourceElementPositioningStrategies.WHEN_EXPRESSION) + val INVALID_IF_AS_EXPRESSION by error0(SourceElementPositioningStrategies.IF_EXPRESSION) + + // Extended checkers val REDUNDANT_VISIBILITY_MODIFIER by warning0(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val REDUNDANT_MODALITY_MODIFIER by warning0(SourceElementPositioningStrategies.MODALITY_MODIFIER) val REDUNDANT_RETURN_UNIT_TYPE by warning0() @@ -247,4 +256,5 @@ object FirErrors { val VARIABLE_INITIALIZER_IS_REDUNDANT by warning0() val VARIABLE_NEVER_READ by warning0(SourceElementPositioningStrategies.DECLARATION_NAME) val USELESS_CALL_ON_NOT_NULL by warning0() + } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/FirSourceChild.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/FirSourceChild.kt new file mode 100644 index 00000000000..e173eec7cb2 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/FirSourceChild.kt @@ -0,0 +1,41 @@ +/* + * 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 + +import com.intellij.psi.tree.IElementType +import com.intellij.psi.tree.TokenSet +import org.jetbrains.kotlin.fir.* + +fun FirSourceElement.getChild(type: IElementType, index: Int = 0, depth: Int = -1): FirSourceElement? { + return getChild(setOf(type), index, depth) +} + +fun FirSourceElement.getChild(types: TokenSet, index: Int = 0, depth: Int = -1): FirSourceElement? { + return getChild(types.types.toSet(), index, depth) +} + +fun FirSourceElement.getChild(types: Set, index: Int = 0, depth: Int = -1): FirSourceElement? { + return when (this) { + is FirPsiSourceElement<*> -> { + getChild(types, index, depth) + } + is FirLightSourceElement -> { + getChild(types, index, depth) + } + else -> null + } +} + +private fun FirPsiSourceElement<*>.getChild(types: Set, index: Int, depth: Int): FirSourceElement? { + val visitor = PsiElementFinderByType(types, index, depth) + return visitor.find(psi)?.toFirPsiSourceElement() +} + +private fun FirLightSourceElement.getChild(types: Set, index: Int, depth: Int): FirSourceElement? { + val visitor = LighterTreeElementFinderByType(treeStructure, types, index, depth) + + return visitor.find(lighterASTNode)?.toFirLightSourceElement(treeStructure) +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt index ab254cab222..f2989f19726 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirHelpers.kt @@ -22,23 +22,20 @@ import org.jetbrains.kotlin.fir.expressions.FirFunctionCall import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.expressions.impl.FirEmptyExpressionBlock import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +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.resolve.transformers.firClassLike import org.jetbrains.kotlin.fir.scopes.ProcessorAction import org.jetbrains.kotlin.fir.scopes.processOverriddenFunctions import org.jetbrains.kotlin.fir.scopes.unsubstitutedScope -import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol -import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.typeCheckerContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtModifierList -import org.jetbrains.kotlin.psi.KtObjectLiteralExpression import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -132,7 +129,7 @@ fun ConeKotlinType.toRegularClass(session: FirSession): FirRegularClass? { * or null of something goes wrong. */ fun FirTypeRef.toRegularClass(session: FirSession): FirRegularClass? { - return safeAs()?.type?.toRegularClass(session) + return coneType.toRegularClass(session) } /** @@ -289,18 +286,15 @@ private fun FirDeclaration.hasBody(): Boolean = when (this) { * or null if couldn't find any. */ fun FirClass<*>.findNonInterfaceSupertype(context: CheckerContext): FirTypeRef? { - for (it in superTypeRefs) { - val lookupTag = it.safeAs() - ?.type.safeAs() - ?.lookupTag - ?: continue + for (superTypeRef in superTypeRefs) { + val lookupTag = superTypeRef.coneType.safeAs()?.lookupTag ?: continue val fir = lookupTag.toSymbol(context.session) ?.fir.safeAs>() ?: continue if (fir.classKind != ClassKind.INTERFACE) { - return it + return superTypeRef } } @@ -323,4 +317,4 @@ val FirFunctionCall.isIterator internal fun throwableClassLikeType(session: FirSession) = session.builtinTypes.throwableType.type fun ConeKotlinType.isSubtypeOfThrowable(session: FirSession) = - throwableClassLikeType(session).isSupertypeOf(session.typeCheckerContext, this.fullyExpandedType(session)) \ No newline at end of file + throwableClassLikeType(session).isSupertypeOf(session.typeCheckerContext, this.fullyExpandedType(session)) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt index 577a93cd63e..b82cb04fc20 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirConflictingProjectionChecker.kt @@ -44,6 +44,8 @@ object FirConflictingProjectionChecker : FirBasicDeclarationChecker() { } private fun checkTypeRef(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) { + // TODO: remaining implicit types should be resolved as an error type, along with proper error kind, + // e.g., type mismatch, can't infer parameter type, syntax error, etc. val declaration = typeRef.safeAs() ?.coneTypeSafe() ?.lookupTag diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt index c2da3979e70..6b4ac794100 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDeclarationCheckerUtils.kt @@ -59,11 +59,10 @@ internal fun checkPropertyInitializer( return } - // TODO: not exactly... val backingFieldRequired = property.hasBackingField if (inInterface && backingFieldRequired && property.hasAccessorImplementation) { property.source?.let { - // reporter.reportOn(it, FirErrors.BACKING_FIELD_IN_INTERFACE, context) + reporter.reportOn(it, FirErrors.BACKING_FIELD_IN_INTERFACE, context) } } @@ -80,10 +79,10 @@ internal fun checkPropertyInitializer( reporter.reportOn(it, FirErrors.EXPECTED_PROPERTY_INITIALIZER, context) } !backingFieldRequired -> { - // reporter.reportOn(it, FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD, context) + reporter.reportOn(it, FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD, context) } property.receiverTypeRef != null -> { - // reporter.reportOn(it, FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD, context) + reporter.reportOn(it, FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD, context) } } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt index 5dc5e0205eb..a4e2600f6f4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirDestructuringDeclarationChecker.kt @@ -101,7 +101,7 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() { reporter.report( FirErrors.COMPONENT_FUNCTION_ON_NULLABLE.on( originalDestructuringDeclarationOrInitializerSource, - (diagnostic.candidateSymbol.fir as FirSimpleFunction).name + (diagnostic.candidate.symbol.fir as FirSimpleFunction).name ), context ) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMethodOfAnyImplementedInInterfaceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMethodOfAnyImplementedInInterfaceChecker.kt index e36393679ea..295e05ad245 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMethodOfAnyImplementedInInterfaceChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirMethodOfAnyImplementedInInterfaceChecker.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.utils.addToStdlib.safeAs object FirMethodOfAnyImplementedInInterfaceChecker : FirRegularClassChecker(), FirDeclarationPresenter { @@ -21,7 +21,7 @@ object FirMethodOfAnyImplementedInInterfaceChecker : FirRegularClassChecker(), F private fun getInspector(context: CheckerContext) = inspector ?: FirDeclarationInspector(this).apply { val anyClassId = context.session.builtinTypes.anyType.id - context.session.firSymbolProvider.getClassLikeSymbolByFqName(anyClassId) + context.session.symbolProvider.getClassLikeSymbolByFqName(anyClassId) ?.fir.safeAs() ?.declarations ?.filterIsInstance() diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt index c059eb565ec..8302f1adc3a 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirOverrideChecker.kt @@ -61,13 +61,13 @@ object FirOverrideChecker : FirRegularClassChecker() { private fun ConeKotlinType.substituteAllTypeParameters( overrideDeclaration: FirCallableMemberDeclaration<*>, - baseDeclarationSymbol: FirCallableSymbol<*>, + baseDeclaration: FirCallableDeclaration<*>, ): ConeKotlinType { if (overrideDeclaration.typeParameters.isEmpty()) { return this } - val parametersOwner = baseDeclarationSymbol.fir.safeAs() + val parametersOwner = baseDeclaration.safeAs() ?: return this val map = mutableMapOf() @@ -130,27 +130,34 @@ object FirOverrideChecker : FirRegularClassChecker() { } } + // See [OverrideResolver#isReturnTypeOkForOverride] private fun FirCallableMemberDeclaration<*>.checkReturnType( overriddenSymbols: List>, typeCheckerContext: AbstractTypeCheckerContext, context: CheckerContext, ): FirMemberDeclaration? { - val returnType = returnTypeRef.safeAs()?.type - ?: return null + val overridingReturnType = returnTypeRef.coneType // Don't report *_ON_OVERRIDE diagnostics according to an error return type. That should be reported separately. - if (returnType is ConeKotlinErrorType) { + if (overridingReturnType is ConeKotlinErrorType) { return null } val bounds = overriddenSymbols.map { context.returnTypeCalculator.tryCalculateReturnType(it.fir).coneType.upperBoundIfFlexible() } for (it in bounds.indices) { - val restriction = bounds[it] - .substituteAllTypeParameters(this, overriddenSymbols[it]) + val overriddenDeclaration = overriddenSymbols[it].fir - if (!AbstractTypeChecker.isSubtypeOf(typeCheckerContext, returnType, restriction)) { - return overriddenSymbols[it].fir.safeAs() + val overriddenReturnType = bounds[it].substituteAllTypeParameters(this, overriddenDeclaration) + + val isReturnTypeOkForOverride = + if (overriddenDeclaration is FirProperty && overriddenDeclaration.isVar) + AbstractTypeChecker.equalTypes(typeCheckerContext, overridingReturnType, overriddenReturnType) + else + AbstractTypeChecker.isSubtypeOf(typeCheckerContext, overridingReturnType, overriddenReturnType) + + if (!isReturnTypeOkForOverride) { + return overriddenDeclaration.safeAs() } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt index 73151cf1fc2..35f1d502457 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirSealedSupertypeChecker.kt @@ -11,68 +11,54 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider -import org.jetbrains.kotlin.fir.types.ConeClassLikeType -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef +import org.jetbrains.kotlin.fir.resolve.symbolProvider +import org.jetbrains.kotlin.fir.types.classId +import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.utils.addToStdlib.safeAs object FirSealedSupertypeChecker : FirMemberDeclarationChecker() { override fun check(declaration: FirMemberDeclaration, context: CheckerContext, reporter: DiagnosticReporter) { if (declaration is FirClass<*>) { // only the file declaration is present - when { - context.containingDeclarations.size == 1 -> { - checkTopLevelDeclaration(declaration, context, reporter) - } - declaration.classId.isLocal -> { - checkLocalDeclaration(declaration, context, reporter) - } - else -> { - checkInnerDeclaration(declaration, context, reporter) - } + if (declaration.classId.isLocal) { + checkLocalDeclaration(declaration, context, reporter) + } else { + checkGlobalDeclaration(declaration, context, reporter) } } else if (declaration is FirProperty) { - val initializer = declaration.initializer.safeAs>() - ?: return - + val initializer = declaration.initializer.safeAs>() ?: return checkLocalDeclaration(initializer, context, reporter) } } - private fun checkTopLevelDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) { + private fun checkGlobalDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) { for (it in declaration.superTypeRefs) { - val classId = it.safeAs() - ?.type.safeAs() - ?.lookupTag?.classId - ?: continue + val classId = it.coneType.classId ?: continue if (classId.isLocal) { continue } - val fir = context.session.firSymbolProvider.getClassLikeSymbolByFqName(classId) + val fir = context.session.symbolProvider.getClassLikeSymbolByFqName(classId) ?.fir.safeAs() ?: continue - if (fir.status.modality == Modality.SEALED && classId.outerClassId != null) { + if (fir.status.modality == Modality.SEALED && declaration.classId.packageFqName != fir.classId.packageFqName) { reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE, context) - return + continue } } } private fun checkLocalDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) { for (it in declaration.superTypeRefs) { - val classId = it.safeAs() - ?.type.safeAs() - ?.lookupTag?.classId - ?: continue + val classId = it.coneType.classId ?: continue if (classId.isLocal) { continue } - val fir = context.session.firSymbolProvider.getClassLikeSymbolByFqName(classId) + val fir = context.session.symbolProvider.getClassLikeSymbolByFqName(classId) ?.fir.safeAs() ?: continue @@ -82,26 +68,4 @@ object FirSealedSupertypeChecker : FirMemberDeclarationChecker() { } } } - - private fun checkInnerDeclaration(declaration: FirClass<*>, context: CheckerContext, reporter: DiagnosticReporter) { - for (it in declaration.superTypeRefs) { - val classId = it.safeAs() - ?.type.safeAs() - ?.lookupTag?.classId - ?: continue - - if (classId.isLocal) { - continue - } - - val fir = context.session.firSymbolProvider.getClassLikeSymbolByFqName(classId) - ?.fir.safeAs() - ?: continue - - if (fir.status.modality == Modality.SEALED && !context.containingDeclarations.contains(fir)) { - reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE, context) - return - } - } - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt index b4899e2394b..79970e5eda7 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirCatchParameterChecker.kt @@ -25,6 +25,7 @@ object FirCatchParameterChecker : FirTryExpressionChecker() { } val typeRef = catchParameter.returnTypeRef + // TODO: remaining implicit types should be resolved as an error type, along with proper error kind, most likely syntax error. if (typeRef !is FirResolvedTypeRef) return val coneType = typeRef.type diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExhaustiveWhenChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExhaustiveWhenChecker.kt new file mode 100644 index 00000000000..ace54dbcc92 --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirExhaustiveWhenChecker.kt @@ -0,0 +1,32 @@ +/* + * 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.expression + +import org.jetbrains.kotlin.KtNodeTypes +import org.jetbrains.kotlin.fir.FirSourceElement +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.analysis.diagnostics.reportOn +import org.jetbrains.kotlin.fir.expressions.ExhaustivenessStatus +import org.jetbrains.kotlin.fir.expressions.FirWhenExpression +import org.jetbrains.kotlin.fir.expressions.isExhaustive + +object FirExhaustiveWhenChecker : FirWhenExpressionChecker() { + override fun check(expression: FirWhenExpression, context: CheckerContext, reporter: DiagnosticReporter) { + if (expression.usedAsExpression && !expression.isExhaustive) { + if (expression.source?.isIfExpression == true) { + reporter.reportOn(expression.source, FirErrors.INVALID_IF_AS_EXPRESSION, context) + } else { + val missingCases = (expression.exhaustivenessStatus as ExhaustivenessStatus.NotExhaustive).reasons + reporter.reportOn(expression.source, FirErrors.NO_ELSE_IN_WHEN, missingCases, context) + } + } + } + + private val FirSourceElement.isIfExpression: Boolean + get() = elementType == KtNodeTypes.IF +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt index 6dd050ad8d1..5a684a64e64 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirQualifiedSupertypeExtendedByOtherSupertypeChecker.kt @@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.declarations.FirClass import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.resolve.transformers.firClassLike -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.utils.addToStdlib.safeAs object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccessChecker() { @@ -26,8 +25,8 @@ object FirQualifiedSupertypeExtendedByOtherSupertypeChecker : FirQualifiedAccess ?.takeIf { it.hadExplicitTypeInSource() } ?: return - val explicitType = superReference.superTypeRef.safeAs() - ?.firClassLike(context.session) + val explicitType = superReference.superTypeRef + .firClassLike(context.session) ?.followAllAlias(context.session).safeAs>() ?: return diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt index 3eaf87d9cd9..600d4415e4d 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirSealedClassConstructorCallChecker.kt @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.types.ConeClassLikeType -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef +import org.jetbrains.kotlin.fir.types.coneType import org.jetbrains.kotlin.utils.addToStdlib.safeAs object FirSealedClassConstructorCallChecker : FirQualifiedAccessChecker() { @@ -26,8 +26,8 @@ object FirSealedClassConstructorCallChecker : FirQualifiedAccessChecker() { ?.fir.safeAs() ?: return - val typeFir = constructorFir.returnTypeRef.safeAs() - ?.type.safeAs() + val typeFir = constructorFir.returnTypeRef.coneType + .safeAs() ?.lookupTag?.toSymbol(context.session) ?.fir as? FirRegularClass ?: return diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt index 1b326fa99da..d469fdeaf28 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirUpperBoundViolatedChecker.kt @@ -43,11 +43,11 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { return } - val parameterPairs = mutableMapOf() + val parameterPairs = mutableMapOf() for (it in 0 until count) { expression.typeArguments[it].safeAs() - ?.typeRef.safeAs() + ?.typeRef ?.let { that -> if (that !is FirErrorTypeRef) { parameterPairs[calleeFir.typeParameters[it].symbol] = that @@ -60,7 +60,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { // we substitute actual values to the // type parameters from the declaration val substitutor = substitutorByMap( - parameterPairs.mapValues { it.value.type } + parameterPairs.mapValues { it.value.coneType } ) val typeCheckerContext = context.session.typeContext.newBaseTypeCheckerContext( @@ -74,14 +74,14 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { return@forEach } - if (!satisfiesBounds(proto, actual.type, substitutor, typeCheckerContext)) { - reporter.reportOn(actual.source, proto, actual.type, context) + if (!satisfiesBounds(proto, actual.coneType, substitutor, typeCheckerContext)) { + reporter.reportOn(actual.source, proto, actual.coneType, context) return } // we must analyze nested things like // S, T>() - actual.type.safeAs()?.let { + actual.coneType.safeAs()?.let { val errorOccurred = analyzeTypeParameters(it, context, reporter, typeCheckerContext, actual.source) if (errorOccurred) { @@ -125,8 +125,8 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { val actualConstructor = functionCall.calleeReference.safeAs() ?.resolvedSymbol.safeAs() ?.fir.safeAs() - ?.returnTypeRef.safeAs() - ?.type.safeAs() + ?.returnTypeRef?.coneType + ?.safeAs() ?: return val count = min(protoConstructor.typeParameters.size, actualConstructor.typeArguments.size) @@ -158,7 +158,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { constructorsParameterPairs.forEach { (proto, actual) -> // just in case var intersection = typeCheckerContext.intersectTypes( - proto.fir.bounds.filterIsInstance().map { it.type } + proto.fir.bounds.map { it.coneType } ).safeAs() ?: return@forEach intersection = declarationSiteSubstitutor.substituteOrSelf(intersection) @@ -245,7 +245,7 @@ object FirUpperBoundViolatedChecker : FirQualifiedAccessChecker() { typeCheckerContext: AbstractTypeCheckerContext ): Boolean { var intersection = typeCheckerContext.intersectTypes( - prototypeSymbol.fir.bounds.filterIsInstance().map { it.type } + prototypeSymbol.fir.bounds.map { it.coneType } ).safeAs() ?: return true intersection = substitutor.substituteOrSelf(intersection) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt index 8faa654deff..94b681f2934 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/extended/UselessCallOnNotNullChecker.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol import org.jetbrains.kotlin.fir.types.ConeNullability -import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.fir.types.classId import org.jetbrains.kotlin.fir.types.coneType @@ -37,9 +36,9 @@ object UselessCallOnNotNullChecker : FirQualifiedAccessChecker() { ((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol)?.callableId private fun FirExpression.getPackage() = - (typeRef as? FirResolvedTypeRef)?.coneType?.classId?.packageFqName.toString() + typeRef.coneType.classId?.packageFqName.toString() - private fun FirExpression.getNullability() = (typeRef as FirResolvedTypeRef).type.nullability + private fun FirExpression.getNullability() = typeRef.coneType.nullability private val triggerOn = setOf( diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt index 67af299d2ff..97fe8d669e2 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ErrorNodeDiagnosticCollectorComponent.kt @@ -6,26 +6,21 @@ package org.jetbrains.kotlin.fir.analysis.collectors.components import org.jetbrains.kotlin.KtNodeTypes -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.collectors.AbstractDiagnosticCollector import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0 -import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors +import org.jetbrains.kotlin.fir.analysis.diagnostics.toFirDiagnostic import org.jetbrains.kotlin.fir.declarations.FirErrorFunction -import org.jetbrains.kotlin.fir.diagnostics.* -import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind.* +import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic import org.jetbrains.kotlin.fir.expressions.FirErrorExpression import org.jetbrains.kotlin.fir.expressions.FirErrorLoop import org.jetbrains.kotlin.fir.expressions.FirErrorResolvedQualifier import org.jetbrains.kotlin.fir.references.FirErrorNamedReference -import org.jetbrains.kotlin.fir.resolve.calls.InapplicableWrongReceiver -import org.jetbrains.kotlin.fir.resolve.diagnostics.* -import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.resolve.calls.tower.isSuccess -import org.jetbrains.kotlin.utils.addToStdlib.safeAs +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError +import org.jetbrains.kotlin.fir.types.FirErrorTypeRef class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollector) : AbstractDiagnosticCollectorComponent(collector) { override fun visitErrorLoop(errorLoop: FirErrorLoop, data: CheckerContext) { @@ -77,95 +72,7 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect } } - val coneDiagnostic = when (diagnostic) { - is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.name?.asString() ?: "") - is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.classId.asString()) - is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.name.asString()) - is ConeHiddenCandidateError -> FirErrors.HIDDEN.on(source, diagnostic.candidateSymbol) - is ConeInapplicableCandidateError -> mapInapplicableCandidateError(diagnostic, source) - is ConeAmbiguityError -> if (!diagnostic.applicability.isSuccess) { - FirErrors.NONE_APPLICABLE.on(source, diagnostic.candidates) - } else { - FirErrors.AMBIGUITY.on(source, diagnostic.candidates) - } - is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.on(source, diagnostic.candidates) - is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.on(source) - is ConeTypeMismatchError -> FirErrors.TYPE_MISMATCH.on(source, diagnostic.expectedType, diagnostic.actualType) - is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.on(diagnostic.source.safeAs() ?: source) - is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.on(source, diagnostic.name.asString()) - is ConeWrongNumberOfTypeArgumentsError -> - FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(source, diagnostic.desiredCount, diagnostic.type) - is ConeSimpleDiagnostic -> when { - source.kind is FirFakeSourceElementKind -> null - diagnostic.kind == SymbolNotFound -> FirErrors.UNRESOLVED_REFERENCE.on(source, "") - else -> diagnostic.getFactory().on(source) - } - is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.on(source, diagnostic.target) - is ConeStubDiagnostic -> null - is ConeIntermediateDiagnostic -> null - else -> throw IllegalArgumentException("Unsupported diagnostic type: ${diagnostic.javaClass}") - } + val coneDiagnostic = diagnostic.toFirDiagnostic(source) reporter.report(coneDiagnostic, context) } - - private fun ConeKotlinType.isEffectivelyNotNull(): Boolean { - return when (this) { - is ConeClassLikeType -> !isMarkedNullable - is ConeTypeParameterType -> !isMarkedNullable && lookupTag.typeParameterSymbol.fir.bounds.any { - it.coneTypeSafe()?.isEffectivelyNotNull() == true - } - else -> false - } - } - - private fun mapInapplicableCandidateError( - diagnostic: ConeInapplicableCandidateError, - source: FirSourceElement, - ): FirDiagnostic<*> { - // TODO: Need to distinguish SMARTCAST_IMPOSSIBLE - // TODO: handle other UNSAFE_* variants: invoke, infix, operator - val rootCause = diagnostic.diagnostics.find { it.applicability == diagnostic.applicability } - if (rootCause != null && - rootCause is InapplicableWrongReceiver && - rootCause.actualType?.isNullable == true && - (rootCause.expectedType == null || !rootCause.expectedType!!.isMarkedNullable) - ) { - val expectedType = rootCause.expectedType - - if (expectedType == null || expectedType.isEffectivelyNotNull()) { - return FirErrors.UNSAFE_CALL.on(source, rootCause.actualType!!) - } - } - return FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidateSymbol) - } - - private fun ConeSimpleDiagnostic.getFactory(): FirDiagnosticFactory0 { - @Suppress("UNCHECKED_CAST") - return when (kind) { - Syntax -> FirErrors.SYNTAX - ReturnNotAllowed -> FirErrors.RETURN_NOT_ALLOWED - UnresolvedLabel -> FirErrors.UNRESOLVED_LABEL - NoThis -> FirErrors.NO_THIS - IllegalConstExpression -> FirErrors.ILLEGAL_CONST_EXPRESSION - IllegalUnderscore -> FirErrors.ILLEGAL_UNDERSCORE - DeserializationError -> FirErrors.DESERIALIZATION_ERROR - InferenceError -> FirErrors.INFERENCE_ERROR - TypeParameterAsSupertype -> FirErrors.TYPE_PARAMETER_AS_SUPERTYPE - EnumAsSupertype -> FirErrors.ENUM_AS_SUPERTYPE - RecursionInSupertypes -> FirErrors.RECURSION_IN_SUPERTYPES - RecursionInImplicitTypes -> FirErrors.RECURSION_IN_IMPLICIT_TYPES - Java -> FirErrors.ERROR_FROM_JAVA_RESOLUTION - SuperNotAllowed -> FirErrors.SUPER_IS_NOT_AN_EXPRESSION - ExpressionRequired -> FirErrors.EXPRESSION_REQUIRED - JumpOutsideLoop -> FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP - NotLoopLabel -> FirErrors.NOT_A_LOOP_LABEL - VariableExpected -> FirErrors.VARIABLE_EXPECTED - NoTypeForTypeParameter -> FirErrors.NO_TYPE_FOR_TYPE_PARAMETER - UnknownCallableKind -> FirErrors.UNKNOWN_CALLABLE_KIND - IllegalProjectionUsage -> FirErrors.ILLEGAL_PROJECTION_USAGE - MissingStdlibClass -> FirErrors.MISSING_STDLIB_CLASS - Other -> FirErrors.OTHER_ERROR - else -> throw IllegalArgumentException("Unsupported diagnostic kind: $kind at $javaClass") - } - } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt index ba5376b9c2a..ba53b856b84 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/collectors/components/ExpressionCheckersDiagnosticComponent.kt @@ -53,7 +53,7 @@ class ExpressionCheckersDiagnosticComponent(collector: AbstractDiagnosticCollect } override fun visitWhenExpression(whenExpression: FirWhenExpression, data: CheckerContext) { - checkers.basicExpressionCheckers.check(whenExpression, data, reporter) + checkers.whenExpressionCheckers.check(whenExpression, data, reporter) } override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: CheckerContext) { diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt index d62a2cd707d..6c4d88dc6c3 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDefaultErrorMessages.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap 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 import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING @@ -18,6 +19,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMB import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOLS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.TO_STRING import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.VISIBILITY +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.WHEN_MISSING_CASES import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_DELEGATED_PROPERTY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_FUNCTION_WITH_BODY @@ -34,6 +36,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANY_METHOD_IMPLEM import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGNED_VALUE_IS_NEVER_READ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ASSIGN_OPERATOR_AMBIGUITY +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BACKING_FIELD_IN_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_CHANGE_ACCESS_PRIVILEGE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CANNOT_WEAKEN_ACCESS_PRIVILEGE @@ -70,6 +73,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_CLA import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_SUPER_INTERFACE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPEALIAS_EXPANDED_TYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPOSED_TYPE_PARAMETER_BOUND +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXTENSION_PROPERTY_WITH_BACKING_FIELD import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUNCTION_DECLARATION_WITH_NO_NAME import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.GENERIC_THROWABLE_SUBCLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HIDDEN @@ -84,6 +88,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INITIALIZER_REQUI import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_WITH_SUPERCLASS +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_IF_AS_EXPRESSION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LEAKED_IN_PLACE_LAMBDA import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.LOCAL_ANNOTATION_CLASS_ERROR @@ -100,6 +105,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOTHING_TO_OVERRI import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION_CLASS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_LOOP_LABEL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_SUPERTYPE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ELSE_IN_WHEN import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_THIS import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_TYPE_FOR_TYPE_PARAMETER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER @@ -113,6 +119,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIVATE_SETTER_FO import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIVATE_SETTER_FOR_OPEN_PROPERTY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_INITIALIZER_IN_INTERFACE +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_INITIALIZER_NO_BACKING_FIELD import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_TYPE_MISMATCH_ON_OVERRIDE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PROPERTY_WITH_NO_TYPE_NO_INITIALIZER import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE @@ -151,6 +158,9 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_VAR import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_LABEL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_REFERENCE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_CALL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_INFIX_CALL +import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_OPERATOR_CALL import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNUSED_VARIABLE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLATED import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER @@ -437,11 +447,16 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { map.put(PRIVATE_PROPERTY_IN_INTERFACE, "Abstract property in an interface cannot be private") map.put(ABSTRACT_PROPERTY_WITH_INITIALIZER, "Property with initializer cannot be abstract") + + map.put(EXTENSION_PROPERTY_WITH_BACKING_FIELD, "Extension property cannot be initialized because it has no backing field") + map.put(PROPERTY_INITIALIZER_NO_BACKING_FIELD, "Initializer is not allowed here because this property has no backing field") + map.put(PROPERTY_INITIALIZER_IN_INTERFACE, "Property initializers are not allowed in interfaces") map.put( PROPERTY_WITH_NO_TYPE_NO_INITIALIZER, "This property must either have a type annotation, be initialized or be delegated" ) + map.put(BACKING_FIELD_IN_INTERFACE, "Property in an interface cannot have a backing field") map.put(ABSTRACT_DELEGATED_PROPERTY, "Delegated property cannot be abstract") map.put(DELEGATED_PROPERTY_IN_INTERFACE, "Delegated properties are not allowed in interfaces") @@ -495,11 +510,30 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { "Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type {0}", RENDER_TYPE ) - //map.put( - // UNSAFE_IMPLICIT_INVOKE_CALL, - // "Reference has a nullable type ''{0}'', use explicit \"?.invoke\" to make a function-like call instead.", - // RENDER_TYPE - //) + map.put( + UNSAFE_IMPLICIT_INVOKE_CALL, + "Reference has a nullable type ''{0}'', use explicit \"?.invoke\" to make a function-like call instead.", + RENDER_TYPE + ) + map.put( + UNSAFE_INFIX_CALL, + "Infix call corresponds to a dot-qualified call ''{0}.{1}({2})'' which is not allowed on a nullable receiver ''{0}''. " + + "Use ''?.''-qualified call instead", + FIR, + TO_STRING, + FIR + ) + map.put( + UNSAFE_OPERATOR_CALL, + "Operator call corresponds to a dot-qualified call ''{0}.{1}({2})'' which is not allowed on a nullable receiver ''{0}''. ", + FIR, + TO_STRING, + FIR + ) + + // When expressions + map.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", WHEN_MISSING_CASES) + map.put(INVALID_IF_AS_EXPRESSION, "'if' must have both main and 'else' branches if used as an expression") // Extended checkers group map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier") diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt index 21fdf5540c6..0d71bc61be4 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticFactoryDsl.kt @@ -59,25 +59,6 @@ fun error3( return DiagnosticFactory3DelegateProvider(Severity.ERROR, positioningStrategy) } -/** - * Note that those functions can be applicable only for factories - * that takes `PsiElement` as first type parameter - */ -fun existing0(): DiagnosticFactory0DelegateProvider { - return DiagnosticFactory0DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT) -} - -fun existing1(): DiagnosticFactory1DelegateProvider { - return DiagnosticFactory1DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT) -} - -fun existing2(): DiagnosticFactory2DelegateProvider { - return DiagnosticFactory2DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT) -} - -fun existing3(): DiagnosticFactory3DelegateProvider { - return DiagnosticFactory3DelegateProvider(Severity.ERROR, SourceElementPositioningStrategy.DEFAULT) -} // ------------------------------ Providers ------------------------------ diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt index 3e35205c1a9..b0627cd5e12 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/FirDiagnosticRenderers.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.diagnostics.rendering.Renderer import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.expressions.WhenMissingCase import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.renderWithType import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol @@ -88,4 +89,16 @@ object FirDiagnosticRenderers { SYMBOL.render(symbol) } } + + private const val WHEN_MISSING_LIMIT = 7 + + val WHEN_MISSING_CASES = Renderer { missingCases: List -> + if (missingCases.firstOrNull() == WhenMissingCase.Unknown) { + "'else' branch" + } else { + val list = missingCases.joinToString(", ", limit = WHEN_MISSING_LIMIT) { "'$it'" } + val branches = if (missingCases.size > 1) "branches" else "branch" + "$list $branches or 'else' branch instead" + } + } } diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt index dd80267b25a..f4b21c77cbb 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/LightTreePositioningStrategies.kt @@ -334,6 +334,28 @@ object LightTreePositioningStrategies { return super.mark(node, startOffset, endOffset, tree) } } + + val WHEN_EXPRESSION = object : LightTreePositioningStrategy() { + override fun mark( + node: LighterASTNode, + startOffset: Int, + endOffset: Int, + tree: FlyweightCapableTreeStructure + ): List { + return markElement(tree.whenKeyword(node) ?: node, startOffset, endOffset, tree, node) + } + } + + val IF_EXPRESSION = object : LightTreePositioningStrategy() { + override fun mark( + node: LighterASTNode, + startOffset: Int, + endOffset: Int, + tree: FlyweightCapableTreeStructure + ): List { + return markElement(tree.ifKeyword(node) ?: node, startOffset, endOffset, tree, node) + } + } } fun FirSourceElement.hasValOrVar(): Boolean = @@ -354,6 +376,12 @@ private fun FlyweightCapableTreeStructure.dotOperator(node: Ligh private fun FlyweightCapableTreeStructure.initKeyword(node: LighterASTNode): LighterASTNode? = findChildByType(node, KtTokens.INIT_KEYWORD) +private fun FlyweightCapableTreeStructure.whenKeyword(node: LighterASTNode): LighterASTNode? = + findChildByType(node, KtTokens.WHEN_KEYWORD) + +private fun FlyweightCapableTreeStructure.ifKeyword(node: LighterASTNode): LighterASTNode? = + findChildByType(node, KtTokens.IF_KEYWORD) + private fun FlyweightCapableTreeStructure.nameIdentifier(node: LighterASTNode): LighterASTNode? = findChildByType(node, KtTokens.IDENTIFIER) diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt index 86c42f79947..4d4e326d73f 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/SourceElementPositioningStrategies.kt @@ -102,4 +102,14 @@ object SourceElementPositioningStrategies { LightTreePositioningStrategies.DOT_BY_SELECTOR, PositioningStrategies.DOT_BY_SELECTOR ) -} \ No newline at end of file + + val WHEN_EXPRESSION = SourceElementPositioningStrategy( + LightTreePositioningStrategies.WHEN_EXPRESSION, + PositioningStrategies.WHEN_EXPRESSION + ) + + val IF_EXPRESSION = SourceElementPositioningStrategy( + LightTreePositioningStrategies.IF_EXPRESSION, + PositioningStrategies.IF_EXPRESSION + ) +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt new file mode 100644 index 00000000000..e0cd577497c --- /dev/null +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/diagnostics/coneDiagnosticToFirDiagnostic.kt @@ -0,0 +1,127 @@ +/* + * 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.diagnostics + +import org.jetbrains.kotlin.KtNodeTypes +import org.jetbrains.kotlin.fir.FirFakeSourceElementKind +import org.jetbrains.kotlin.fir.FirSourceElement +import org.jetbrains.kotlin.fir.analysis.getChild +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction +import org.jetbrains.kotlin.fir.declarations.isInfix +import org.jetbrains.kotlin.fir.declarations.isOperator +import org.jetbrains.kotlin.fir.diagnostics.* +import org.jetbrains.kotlin.fir.resolve.calls.InapplicableWrongReceiver +import org.jetbrains.kotlin.fir.resolve.diagnostics.* +import org.jetbrains.kotlin.fir.types.* +import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.resolve.calls.tower.isSuccess +import org.jetbrains.kotlin.utils.addToStdlib.safeAs + +fun ConeDiagnostic.toFirDiagnostic(source: FirSourceElement): FirDiagnostic? = when (this) { + is ConeUnresolvedReferenceError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.name?.asString() ?: "") + is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.classId.asString()) + is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.on(source, this.name.asString()) + is ConeHiddenCandidateError -> FirErrors.HIDDEN.on(source, this.candidateSymbol) + is ConeInapplicableCandidateError -> mapInapplicableCandidateError(this, source) + is ConeAmbiguityError -> if (!this.applicability.isSuccess) { + FirErrors.NONE_APPLICABLE.on(source, this.candidates) + } else { + FirErrors.AMBIGUITY.on(source, this.candidates) + } + is ConeOperatorAmbiguityError -> FirErrors.ASSIGN_OPERATOR_AMBIGUITY.on(source, this.candidates) + is ConeVariableExpectedError -> FirErrors.VARIABLE_EXPECTED.on(source) + is ConeTypeMismatchError -> FirErrors.TYPE_MISMATCH.on(source, this.expectedType, this.actualType) + is ConeUnexpectedTypeArgumentsError -> FirErrors.TYPE_ARGUMENTS_NOT_ALLOWED.on(this.source.safeAs() ?: source) + is ConeIllegalAnnotationError -> FirErrors.NOT_AN_ANNOTATION_CLASS.on(source, this.name.asString()) + is ConeWrongNumberOfTypeArgumentsError -> + FirErrors.WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(source, this.desiredCount, this.type) + is ConeSimpleDiagnostic -> when { + source.kind is FirFakeSourceElementKind -> null + this.kind == DiagnosticKind.SymbolNotFound -> FirErrors.UNRESOLVED_REFERENCE.on(source, "") + else -> this.getFactory().on(source) + } + is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.on(source, this.target) + is ConeStubDiagnostic -> null + is ConeIntermediateDiagnostic -> null + else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}") +} + +private fun ConeKotlinType.isEffectivelyNotNull(): Boolean { + return when (this) { + is ConeClassLikeType -> !isMarkedNullable + is ConeTypeParameterType -> !isMarkedNullable && lookupTag.typeParameterSymbol.fir.bounds.any { + it.coneTypeSafe()?.isEffectivelyNotNull() == true + } + else -> false + } +} + +private fun mapInapplicableCandidateError( + diagnostic: ConeInapplicableCandidateError, + source: FirSourceElement, +): FirDiagnostic<*> { + // TODO: Need to distinguish SMARTCAST_IMPOSSIBLE + val rootCause = diagnostic.candidate.diagnostics.find { it.applicability == diagnostic.applicability } + if (rootCause != null && + rootCause is InapplicableWrongReceiver && + rootCause.actualType?.isNullable == true && + (rootCause.expectedType == null || rootCause.expectedType!!.isEffectivelyNotNull()) + ) { + if (diagnostic.candidate.callInfo.isImplicitInvoke) { + return FirErrors.UNSAFE_IMPLICIT_INVOKE_CALL.on(source, rootCause.actualType!!) + } + + val candidateFunction = diagnostic.candidate.symbol.fir as? FirSimpleFunction + val candidateFunctionName = candidateFunction?.name + val left = diagnostic.candidate.callInfo.explicitReceiver + val right = diagnostic.candidate.callInfo.argumentList.arguments.singleOrNull() + if (left != null && right != null && + source.elementType == KtNodeTypes.OPERATION_REFERENCE && + (candidateFunction?.isOperator == true || candidateFunction?.isInfix == true) + ) { + val operationToken = source.getChild(KtTokens.IDENTIFIER) + if (candidateFunction.isInfix && operationToken?.elementType == KtTokens.IDENTIFIER) { + return FirErrors.UNSAFE_INFIX_CALL.on(source, left, candidateFunctionName!!.asString(), right) + } + if (candidateFunction.isOperator && operationToken == null) { + return FirErrors.UNSAFE_OPERATOR_CALL.on(source, left, candidateFunctionName!!.asString(), right) + } + } + + return FirErrors.UNSAFE_CALL.on(source, rootCause.actualType!!) + } + return FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidate.symbol) +} + +private fun ConeSimpleDiagnostic.getFactory(): FirDiagnosticFactory0 { + @Suppress("UNCHECKED_CAST") + return when (kind) { + DiagnosticKind.Syntax -> FirErrors.SYNTAX + DiagnosticKind.ReturnNotAllowed -> FirErrors.RETURN_NOT_ALLOWED + DiagnosticKind.UnresolvedLabel -> FirErrors.UNRESOLVED_LABEL + DiagnosticKind.NoThis -> FirErrors.NO_THIS + DiagnosticKind.IllegalConstExpression -> FirErrors.ILLEGAL_CONST_EXPRESSION + DiagnosticKind.IllegalUnderscore -> FirErrors.ILLEGAL_UNDERSCORE + DiagnosticKind.DeserializationError -> FirErrors.DESERIALIZATION_ERROR + DiagnosticKind.InferenceError -> FirErrors.INFERENCE_ERROR + DiagnosticKind.TypeParameterAsSupertype -> FirErrors.TYPE_PARAMETER_AS_SUPERTYPE + DiagnosticKind.EnumAsSupertype -> FirErrors.ENUM_AS_SUPERTYPE + DiagnosticKind.RecursionInSupertypes -> FirErrors.RECURSION_IN_SUPERTYPES + DiagnosticKind.RecursionInImplicitTypes -> FirErrors.RECURSION_IN_IMPLICIT_TYPES + DiagnosticKind.Java -> FirErrors.ERROR_FROM_JAVA_RESOLUTION + DiagnosticKind.SuperNotAllowed -> FirErrors.SUPER_IS_NOT_AN_EXPRESSION + DiagnosticKind.ExpressionRequired -> FirErrors.EXPRESSION_REQUIRED + DiagnosticKind.JumpOutsideLoop -> FirErrors.BREAK_OR_CONTINUE_OUTSIDE_A_LOOP + DiagnosticKind.NotLoopLabel -> FirErrors.NOT_A_LOOP_LABEL + DiagnosticKind.VariableExpected -> FirErrors.VARIABLE_EXPECTED + DiagnosticKind.NoTypeForTypeParameter -> FirErrors.NO_TYPE_FOR_TYPE_PARAMETER + DiagnosticKind.UnknownCallableKind -> FirErrors.UNKNOWN_CALLABLE_KIND + DiagnosticKind.IllegalProjectionUsage -> FirErrors.ILLEGAL_PROJECTION_USAGE + DiagnosticKind.MissingStdlibClass -> FirErrors.MISSING_STDLIB_CLASS + DiagnosticKind.Other -> FirErrors.OTHER_ERROR + else -> throw IllegalArgumentException("Unsupported diagnostic kind: $kind at $javaClass") + } +} \ No newline at end of file diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt index e2683df9291..7062e884af3 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/ConeTypeUtils.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.types +import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.types.Variance @@ -55,3 +56,22 @@ fun ConeClassLikeType.replaceArgumentsWithStarProjections(): ConeClassLikeType { val newArguments = Array(typeArguments.size) { ConeStarProjection } return withArguments(newArguments) } + +val ConeKotlinType.isAny: Boolean get() = isBuiltinType(StandardClassIds.Any, false) +val ConeKotlinType.isNullableAny: Boolean get() = isBuiltinType(StandardClassIds.Any, true) +val ConeKotlinType.isNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, false) +val ConeKotlinType.isNullableNothing: Boolean get() = isBuiltinType(StandardClassIds.Nothing, true) +val ConeKotlinType.isUnit: Boolean get() = isBuiltinType(StandardClassIds.Unit, false) +val ConeKotlinType.isBoolean: Boolean get() = isBuiltinType(StandardClassIds.Boolean, false) +val ConeKotlinType.isEnum: Boolean get() = isBuiltinType(StandardClassIds.Enum, false) +val ConeKotlinType.isArrayType: Boolean + get() { + return isBuiltinType(StandardClassIds.Array, false) || + StandardClassIds.primitiveArrayTypeByElementType.values.any { isBuiltinType(it, false) } + } + +private fun ConeKotlinType.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean { + + if (this !is ConeClassLikeType) return false + return lookupTag.classId == classId && type.isNullable == isNullable +} diff --git a/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt b/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt index afaaf000399..a5eb04a7cdd 100644 --- a/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt +++ b/compiler/fir/dump/src/org/jetbrains/kotlin/fir/dump/HtmlFirDump.kt @@ -1231,9 +1231,9 @@ class HtmlFirDump internal constructor(private var linkResolver: FirLinkResolver private fun FlowContent.generate(diagnostic: ConeDiagnostic) { when (diagnostic) { is ConeInapplicableCandidateError -> { - describeVerbose(diagnostic.candidateSymbol) + describeVerbose(diagnostic.candidate.symbol) br - diagnostic.errors.forEach { callDiagnostic -> + diagnostic.candidate.system.errors.forEach { callDiagnostic -> when (callDiagnostic) { is NewConstraintError -> { ident() diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt index 4ffda04a3ec..fb52cf9a047 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/checkers/CommonExpressionCheckers.kt @@ -28,4 +28,8 @@ object CommonExpressionCheckers : ExpressionCheckers() { override val tryExpressionCheckers: Set = setOf( FirCatchParameterChecker ) + + override val whenExpressionCheckers: Set = setOf( + FirExhaustiveWhenChecker + ) } diff --git a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt index 5c0b05b084b..478fba4b5ba 100644 --- a/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt +++ b/compiler/fir/fir-deserialization/src/org/jetbrains/kotlin/fir/deserialization/ClassDeserialization.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusIm import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider.Companion.CLONE import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCloneableSymbolProvider.Companion.CLONEABLE_CLASS_ID -import org.jetbrains.kotlin.fir.resolve.transformers.sealedInheritors import org.jetbrains.kotlin.fir.scopes.FirScopeProvider import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt index a9e641b8747..010aed0fe88 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt @@ -24,12 +24,11 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.calls.varargElementType -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType import org.jetbrains.kotlin.fir.resolve.inference.suspendFunctionTypeToFunctionTypeWithContinuation import org.jetbrains.kotlin.fir.resolve.toSymbol -import org.jetbrains.kotlin.fir.resolve.transformers.sealedInheritors import org.jetbrains.kotlin.fir.serialization.constant.EnumValue import org.jetbrains.kotlin.fir.serialization.constant.IntValue import org.jetbrains.kotlin.fir.serialization.constant.StringValue @@ -891,7 +890,7 @@ class FirElementSerializer private constructor( ): FirElementSerializer { val parentClassId = klass.symbol.classId.outerClassId val parent = if (parentClassId != null && !parentClassId.isLocal) { - val parentClass = klass.session.firSymbolProvider.getClassLikeSymbolByFqName(parentClassId)!!.fir as FirRegularClass + val parentClass = klass.session.symbolProvider.getClassLikeSymbolByFqName(parentClassId)!!.fir as FirRegularClass parentSerializer ?: create(parentClass, extension, null, typeApproximator) } else { createTopLevel(klass.session, extension, typeApproximator) diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/ConstantValue.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/ConstantValue.kt index fce1b1b9886..a95c28f3c07 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/ConstantValue.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/constant/ConstantValue.kt @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.resolve.defaultType -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name @@ -138,7 +138,7 @@ internal class KClassValue(value: Value) : ConstantValue(valu is Value.LocalClass -> return value.type is Value.NormalClass -> { val (classId, arrayDimensions) = value.value - val klass = session.firSymbolProvider.getClassLikeSymbolByFqName(classId)?.fir as? FirRegularClass ?: return null + val klass = session.symbolProvider.getClassLikeSymbolByFqName(classId)?.fir as? FirRegularClass ?: return null var type: ConeKotlinType = klass.defaultType().replaceArgumentsWithStarProjections() repeat(arrayDimensions) { type = type.createArrayType() diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmBackendClassResolver.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmBackendClassResolver.kt index 09b17e8e2b8..6a2dcc9d4a6 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmBackendClassResolver.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmBackendClassResolver.kt @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.codegen.JvmBackendClassResolver import org.jetbrains.kotlin.codegen.classId import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.fir.backend.Fir2IrComponents -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.org.objectweb.asm.Type @@ -19,9 +19,9 @@ class FirJvmBackendClassResolver(val components: Fir2IrComponents) : JvmBackendC override fun resolveToClassDescriptors(type: Type): List { if (type.sort != Type.OBJECT) return emptyList() - val symbol = components.session.firSymbolProvider.getClassLikeSymbolByFqName(type.classId) ?: return emptyList() + val symbol = components.session.symbolProvider.getClassLikeSymbolByFqName(type.classId) ?: return emptyList() require(symbol is FirClassSymbol<*>) return listOf(components.classifierStorage.getIrClassSymbol(symbol).descriptor) } -} \ No newline at end of file +} diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmMangleComputer.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmMangleComputer.kt index 32f7ebd5eb6..272be1cc857 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmMangleComputer.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmMangleComputer.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.backend.common.serialization.mangle.MangleMode import org.jetbrains.kotlin.backend.common.serialization.mangle.collectForMangler import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +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.impl.FirClassSymbol @@ -79,7 +79,7 @@ open class FirJvmMangleComputer( else -> return } if (parentClassId != null && !parentClassId.isLocal) { - val parentClassLike = this@FirJvmMangleComputer.session.firSymbolProvider.getClassLikeSymbolByFqName(parentClassId)?.fir + val parentClassLike = this@FirJvmMangleComputer.session.symbolProvider.getClassLikeSymbolByFqName(parentClassId)?.fir ?: error("Attempt to find parent ($parentClassId) for probably-local declaration!") if (parentClassLike is FirRegularClass || parentClassLike is FirTypeAlias) { parentClassLike.accept(this@FirJvmMangleComputer, false) diff --git a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmTypeMapper.kt b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmTypeMapper.kt index ab8b39b178f..4650709cff2 100644 --- a/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmTypeMapper.kt +++ b/compiler/fir/fir2ir/jvm-backend/src/org/jetbrains/kotlin/fir/backend/jvm/FirJvmTypeMapper.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.defaultType -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.inference.* import org.jetbrains.kotlin.fir.resolve.toSymbol @@ -101,7 +101,7 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext.toSymbol( session: FirSession, classifierStorage: Fir2IrClassifierStorage, - typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT + typeContext: ConversionTypeContext = ConversionTypeContext.DEFAULT, + handleAnnotations: ((List) -> Unit)? = null ): IrClassifierSymbol { return when (this) { is FirTypeParameterSymbol -> { classifierStorage.getIrTypeParameterSymbol(this, typeContext) } is FirTypeAliasSymbol -> { - val typeAlias = fir - val coneClassLikeType = typeAlias.expandedTypeRef.coneType as ConeClassLikeType - coneClassLikeType.lookupTag.toSymbol(session)!!.toSymbol(session, classifierStorage) + handleAnnotations?.invoke(fir.expandedTypeRef.annotations) + val coneClassLikeType = fir.expandedTypeRef.coneType as ConeClassLikeType + coneClassLikeType.lookupTag.toSymbol(session)!!.toSymbol(session, classifierStorage, typeContext, handleAnnotations) } is FirClassSymbol -> { classifierStorage.getIrClassSymbol(this) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrBuiltIns.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrBuiltIns.kt index 81c951dd015..00bed03959b 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrBuiltIns.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrBuiltIns.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.backend -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.types.CompilerConeAttributes import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.expressions.IrConstructorCall @@ -38,10 +38,10 @@ class Fir2IrBuiltIns( flexibleNullabilityAnnotationSymbol?.toConstructorCall() private fun annotationSymbolById(id: ClassId): IrClassSymbol? = - provider?.getClassSymbolById(id) ?: session.firSymbolProvider.getClassLikeSymbolByFqName(id)?.toSymbol( + provider?.getClassSymbolById(id) ?: session.symbolProvider.getClassLikeSymbolByFqName(id)?.toSymbol( session, classifierStorage, ConversionTypeContext.DEFAULT ) as? IrClassSymbol private fun IrClassSymbol.toConstructorCall(): IrConstructorCallImpl = IrConstructorCallImpl.fromSymbolOwner(defaultType, owner.declarations.firstIsInstance().symbol) -} \ No newline at end of file +} diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt index 3b8ba3a879a..6fd9b8b5781 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrClassifierStorage.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass import org.jetbrains.kotlin.fir.resolve.firProvider -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.* import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl @@ -435,7 +435,7 @@ class Fir2IrClassifierStorage( firClass as FirRegularClass val classId = firClassSymbol.classId val parentId = classId.outerClassId - val parentClass = parentId?.let { session.firSymbolProvider.getClassLikeSymbolByFqName(it) } + val parentClass = parentId?.let { session.symbolProvider.getClassLikeSymbolByFqName(it) } val irParent = declarationStorage.findIrParent(classId.packageFqName, parentClass?.toLookupTag(), firClassSymbol)!! val symbol = Fir2IrClassSymbol(signature) val irClass = firClass.convertWithOffsets { startOffset, endOffset -> diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt index 06c56ba98ec..b679005a6d2 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConversionScope.kt @@ -59,10 +59,10 @@ class Fir2IrConversionScope { return function } - private val propertyStack = mutableListOf() + private val propertyStack = mutableListOf>() - fun withProperty(property: IrProperty, f: IrProperty.() -> Unit): IrProperty { - propertyStack += property + fun withProperty(property: IrProperty, firProperty: FirProperty? = null, f: IrProperty.() -> Unit): IrProperty { + propertyStack += (property to firProperty) property.f() propertyStack.removeAt(propertyStack.size - 1) return property @@ -99,6 +99,15 @@ class Fir2IrConversionScope { val irTarget = (firTarget as? FirFunction)?.let { when (it) { is FirConstructor -> declarationStorage.getCachedIrConstructor(it) + is FirPropertyAccessor -> { + for ((property, firProperty) in propertyStack.asReversed()) { + if (firProperty?.getter === firTarget) { + return@let property.getter + } else if (firProperty?.setter === firTarget) { + return@let property.setter + } + } + } else -> declarationStorage.getCachedIrFunction(it) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index a07d8e84ec4..dcb27fa4ade 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -93,7 +93,7 @@ class Fir2IrConverter( } val processedCallableNames = mutableSetOf() val classes = mutableListOf() - for (declaration in sortBySynthetic(anonymousObject.declarations)) { + for (declaration in syntheticPropertiesLast(anonymousObject.declarations)) { val irDeclaration = if (declaration is FirRegularClass) { classes += declaration registerClassAndNestedClasses(declaration, irClass) @@ -129,7 +129,7 @@ class Fir2IrConverter( irClass.declarations += irConstructor } val allDeclarations = regularClass.declarations.toMutableList() - for (declaration in sortBySynthetic(regularClass.declarations)) { + for (declaration in syntheticPropertiesLast(regularClass.declarations)) { val irDeclaration = processMemberDeclaration(declaration, regularClass, irClass) ?: continue irClass.declarations += irDeclaration } @@ -167,8 +167,8 @@ class Fir2IrConverter( // Sort declarations so that all non-synthetic declarations are before synthetic ones. // This is needed because converting synthetic fields for implementation delegation needs to know // existing declarations in the class to avoid adding redundant delegated members. - private fun sortBySynthetic(declarations: List): Iterable { - return declarations.sortedBy { it.isSynthetic } + private fun syntheticPropertiesLast(declarations: List): Iterable { + return declarations.sortedBy { it !is FirField && it.isSynthetic } } private fun registerClassAndNestedClasses(regularClass: FirRegularClass, parent: IrDeclarationParent): IrClass { @@ -273,7 +273,7 @@ class Fir2IrConverter( val classifierStorage = Fir2IrClassifierStorage(components) val converter = Fir2IrConverter(moduleDescriptor, sourceManager, components) val fir2irVisitor = Fir2IrVisitor(converter, components, conversionScope) - val declarationStorage = Fir2IrDeclarationStorage(components, fir2irVisitor, moduleDescriptor) + val declarationStorage = Fir2IrDeclarationStorage(components, moduleDescriptor) val typeConverter = Fir2IrTypeConverter(components) val builtIns = Fir2IrBuiltIns(components, specialSymbolProvider) val annotationGenerator = AnnotationGenerator(components) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index d1c4e41dcb1..8e876b364cc 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -39,7 +39,6 @@ import org.jetbrains.kotlin.ir.builders.declarations.UNDEFINED_PARAMETER_INDEX import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass -import org.jetbrains.kotlin.ir.descriptors.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrSyntheticBodyKind import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl @@ -56,7 +55,6 @@ import org.jetbrains.kotlin.serialization.deserialization.descriptors.Deserializ @OptIn(ObsoleteDescriptorBasedAPI::class) class Fir2IrDeclarationStorage( private val components: Fir2IrComponents, - private val visitor: Fir2IrVisitor, private val moduleDescriptor: FirModuleDescriptor ) : Fir2IrComponents by components { @@ -754,32 +752,29 @@ class Fir2IrDeclarationStorage( val delegate = property.delegate val getter = property.getter val setter = property.setter - if (property.isConst || (property.modality != Modality.ABSTRACT && (irParent !is IrClass || !irParent.isInterface))) { - if (property.hasBackingField) { - backingField = if (delegate != null) { - createBackingField( - property, IrDeclarationOrigin.PROPERTY_DELEGATE, descriptor, - components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility), - Name.identifier("${property.name}\$delegate"), true, delegate - ) - } else { - createBackingField( - property, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, descriptor, - components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility), - property.name, property.isVal, initializer, type - ).also { field -> - if (initializer is FirConstExpression<*>) { - // TODO: Normally we shouldn't have error type here - val constType = initializer.typeRef.toIrType().takeIf { it !is IrErrorType } ?: type - field.initializer = factory.createExpressionBody(initializer.toIrConst(constType)) - } + if (delegate != null || property.hasBackingField) { + backingField = if (delegate != null) { + createBackingField( + property, IrDeclarationOrigin.PROPERTY_DELEGATE, descriptor, + components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility), + Name.identifier("${property.name}\$delegate"), true, delegate + ) + } else { + createBackingField( + property, IrDeclarationOrigin.PROPERTY_BACKING_FIELD, descriptor, + components.visibilityConverter.convertToDescriptorVisibility(property.fieldVisibility), + property.name, property.isVal, initializer, type + ).also { field -> + if (initializer is FirConstExpression<*>) { + // TODO: Normally we shouldn't have error type here + val constType = initializer.typeRef.toIrType().takeIf { it !is IrErrorType } ?: type + field.initializer = factory.createExpressionBody(initializer.toIrConst(constType)) } } } - if (irParent != null) { - backingField?.parent = irParent - } - + } + if (irParent != null) { + backingField?.parent = irParent } this.getter = createIrPropertyAccessor( getter, property, this, type, irParent, thisReceiverOwner, false, @@ -850,12 +845,11 @@ class Fir2IrDeclarationStorage( isExternal = false, isStatic = field.isStatic ).apply { - field.initializer?.let { - val expression = visitor.convertToIrExpression(it) - expression.type = type - initializer = irFactory.createExpressionBody(expression) - } fieldCache[field] = this + val initializer = field.initializer + if (initializer is FirConstExpression<*>) { + this.initializer = factory.createExpressionBody(initializer.toIrConst(type)) + } } } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt index 688e77225cd..18138333a5e 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrTypeConverter.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.expressions.classId import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.StandardClassIds +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.* import org.jetbrains.kotlin.ir.expressions.IrConstructorCall @@ -19,6 +20,7 @@ import org.jetbrains.kotlin.ir.types.IrTypeArgument import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.types.Variance @@ -84,13 +86,13 @@ class Fir2IrTypeConverter( return when (this) { is ConeKotlinErrorType -> createErrorType() is ConeLookupTagBasedType -> { - val classId = this.classId - val irSymbol = getBuiltInClassSymbol(classId) ?: run { - val firSymbol = this.lookupTag.toSymbol(session) ?: return createErrorType() - firSymbol.toSymbol(session, classifierStorage, typeContext) - } - val typeAnnotations: MutableList = mutableListOf() + val typeAnnotations = mutableListOf() typeAnnotations += with(annotationGenerator) { annotations.toIrAnnotations() } + val irSymbol = getBuiltInClassSymbol(classId) + ?: lookupTag.toSymbol(session)?.toSymbol(session, classifierStorage, typeContext) { + typeAnnotations += with(annotationGenerator) { it.toIrAnnotations() } + } + ?: return createErrorType() if (hasEnhancedNullability) { builtIns.enhancedNullabilityAnnotationConstructorCall()?.let { typeAnnotations += it diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 8b418059d09..84ae8b8a250 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -67,7 +67,9 @@ class Fir2IrVisitor( override fun visitField(field: FirField, data: Any?): IrField { if (field.isSynthetic) { - return declarationStorage.getCachedIrField(field)!! + return declarationStorage.getCachedIrField(field)!!.apply { + memberGenerator.convertFieldContent(this, field) + } } else { throw AssertionError("Unexpected field: ${field.render()}") } @@ -269,7 +271,7 @@ class Fir2IrVisitor( override fun visitProperty(property: FirProperty, data: Any?): IrElement { if (property.isLocal) return visitLocalVariable(property) val irProperty = declarationStorage.getCachedIrProperty(property)!! - return conversionScope.withProperty(irProperty) { + return conversionScope.withProperty(irProperty, property) { memberGenerator.convertPropertyContent(irProperty, property, containingClass = conversionScope.containerFirClass()) } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 4657a143edf..50463b06569 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.backend.generators +import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.declarations.* @@ -731,7 +732,23 @@ class CallAndReferenceGenerator( symbol.owner as? IrFunction ?: (symbol.owner as? IrProperty)?.getter if (ownerFunction?.dispatchReceiverParameter != null) { - dispatchReceiver = qualifiedAccess.findIrDispatchReceiver(explicitReceiverExpression) + val baseDispatchReceiver = qualifiedAccess.findIrDispatchReceiver(explicitReceiverExpression) + dispatchReceiver = + if (!ownerFunction.isMethodOfAny() || baseDispatchReceiver?.type?.classOrNull?.owner?.isInterface != true) { + baseDispatchReceiver + } else { + // NB: for FE 1.0, this type cast is added by InterfaceObjectCallsLowering + // However, it doesn't work for FIR due to different f/o structure + // (FIR calls Any method directly, but FE 1.0 calls its interface f/o instead) + IrTypeOperatorCallImpl( + baseDispatchReceiver.startOffset, + baseDispatchReceiver.endOffset, + irBuiltIns.anyType, + IrTypeOperator.IMPLICIT_CAST, + irBuiltIns.anyType, + baseDispatchReceiver + ) + } } if (ownerFunction?.extensionReceiverParameter != null) { extensionReceiver = qualifiedAccess.findIrExtensionReceiver(explicitReceiverExpression)?.let { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt index aa43ea3c266..0b709411cfb 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt @@ -174,6 +174,18 @@ internal class ClassMemberGenerator( return irProperty } + fun convertFieldContent(irField: IrField, field: FirField): IrField { + conversionScope.withParent(irField) { + declarationStorage.enterScope(irField) + val initializerExpression = field.initializer + if (irField.initializer == null && initializerExpression != null) { + irField.initializer = irFactory.createExpressionBody(visitor.convertToIrExpression(initializerExpression)) + } + declarationStorage.leaveScope(irField) + } + return irField + } + private fun IrProperty.initializeBackingField( property: FirProperty, initializerExpression: FirExpression? diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt index f3c2639dfce..18602971925 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/FakeOverrideGenerator.kt @@ -41,7 +41,7 @@ class FakeOverrideGenerator( } private fun IrProperty.withProperty(f: IrProperty.() -> Unit): IrProperty { - return conversionScope.withProperty(this, f) + return conversionScope.withProperty(this, firProperty = null, f) } private fun FirCallableMemberDeclaration<*>.allowsToHaveFakeOverrideIn(klass: FirClass<*>): Boolean { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/descriptors/FirModuleDescriptor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/descriptors/FirModuleDescriptor.kt index d6a4f8ce3b1..e33a4c70893 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/descriptors/FirModuleDescriptor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/descriptors/FirModuleDescriptor.kt @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.platform.TargetPlatform @@ -27,7 +27,7 @@ class FirModuleDescriptor(val session: FirSession) : ModuleDescriptor { get() = null override fun getPackage(fqName: FqName): PackageViewDescriptor { - val symbolProvider = session.firSymbolProvider + val symbolProvider = session.symbolProvider if (symbolProvider.getPackage(fqName) != null) { return FirPackageViewDescriptor(fqName, this) } diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index eb521be52a6..483e39195d3 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -13644,6 +13644,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/elvis/nullNullOk.kt"); } + @Test + @TestMetadata("ofNonNullableResultType.kt") + public void testOfNonNullableResultType() throws Exception { + runTest("compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt"); + } + @Test @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { @@ -14623,6 +14629,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT public void testPropertySetter() throws Exception { runTest("compiler/testData/codegen/box/fakeOverride/propertySetter.kt"); } + + @Test + @TestMetadata("varianceOverload.kt") + public void testVarianceOverload() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/varianceOverload.kt"); + } } @Nested @@ -14834,12 +14846,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/fir/FakeOverrideBuilder.kt"); } + @Test + @TestMetadata("Fir2IrClassifierStorage.kt") + public void testFir2IrClassifierStorage() throws Exception { + runTest("compiler/testData/codegen/box/fir/Fir2IrClassifierStorage.kt"); + } + @Test @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { runTest("compiler/testData/codegen/box/fir/IrBuiltIns.kt"); } + @Test + @TestMetadata("LookupTags.kt") + public void testLookupTags() throws Exception { + runTest("compiler/testData/codegen/box/fir/LookupTags.kt"); + } + @Test @TestMetadata("NameHighlighter.kt") public void testNameHighlighter() throws Exception { @@ -16936,6 +16960,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inlineClasses/conformToComparableAndCallInterfaceMethod.kt"); } + @Test + @TestMetadata("constructorCallableReference.kt") + public void testConstructorCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt"); + } + @Test @TestMetadata("constructorImplVisibility.kt") public void testConstructorImplVisibility() throws Exception { @@ -38760,6 +38790,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); } + @Test + @TestMetadata("extensionFunction.kt") + public void testExtensionFunction() throws Exception { + runTest("compiler/testData/codegen/box/typealias/extensionFunction.kt"); + } + @Test @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxInlineCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxInlineCodegenTestGenerated.java index 78cc475b292..c9b99edc41d 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxInlineCodegenTestGenerated.java @@ -1020,6 +1020,46 @@ public class FirBlackBoxInlineCodegenTestGenerated extends AbstractFirBlackBoxIn runTest("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); } + @Nested + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/adaptedReferences") + @TestDataPath("$PROJECT_ROOT") + public class AdaptedReferences { + @Test + public void testAllFilesPresentInAdaptedReferences() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("inlineBound.kt") + public void testInlineBound() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt"); + } + + @Test + @TestMetadata("inlineDefault.kt") + public void testInlineDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt"); + } + + @Test + @TestMetadata("inlineVararg.kt") + public void testInlineVararg() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt"); + } + + @Test + @TestMetadata("inlineVarargAndDefault.kt") + public void testInlineVarargAndDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt"); + } + + @Test + @TestMetadata("inlineVarargInts.kt") + public void testInlineVarargInts() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java index 03704c65aac..6c0c63e55c0 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/ir/Fir2IrTextTestGenerated.java @@ -2116,6 +2116,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/firProblems/deprecated.kt"); } + @Test + @TestMetadata("Fir2IrClassifierStorage.kt") + public void testFir2IrClassifierStorage() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.kt"); + } + @Test @TestMetadata("FirBuilder.kt") public void testFirBuilder() throws Exception { @@ -2182,6 +2188,12 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/firProblems/recursiveCapturedTypeInPropertyReference.kt"); } + @Test + @TestMetadata("SafeLetWithReturn.kt") + public void testSafeLetWithReturn() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt"); + } + @Test @TestMetadata("SameJavaFieldReferences.kt") public void testSameJavaFieldReferences() throws Exception { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt index 671723f4fe6..ecec05abe0f 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaScopeProvider.kt @@ -208,7 +208,7 @@ class JavaScopeProvider( return lazyNestedClassifierScope( klass.classId, (klass as FirJavaClass).existingNestedClassifierNames, - useSiteSession.firSymbolProvider + useSiteSession.symbolProvider ) } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index 8251fc7d84b..179ce39b4c1 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.java import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope +import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities @@ -316,6 +317,13 @@ class JavaSymbolProvider( valueParametersForAnnotationConstructor = valueParametersForAnnotationConstructor ) } + }.apply { + if (modality == Modality.SEALED) { + sealedInheritors = javaClass.permittedTypes.mapNotNull { classifierType -> + val classifier = classifierType.classifier as? JavaClass + classifier?.let { JavaToKotlinClassMap.mapJavaToKotlin(it.fqName!!) } + } + } } private fun convertJavaFieldToFir( diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt index 79f82b3c134..368ae99b351 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolv import org.jetbrains.kotlin.fir.resolve.bindSymbolToLookupTag import org.jetbrains.kotlin.fir.resolve.defaultType import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbols import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.expectedConeType @@ -63,6 +63,14 @@ internal val JavaModifierListOwner.modality: Modality else -> Modality.OPEN } +internal val JavaClass.modality: Modality + get() = when { + isSealed -> Modality.SEALED + isAbstract -> Modality.ABSTRACT + isFinal -> Modality.FINAL + else -> Modality.OPEN + } + internal val JavaClass.classKind: ClassKind get() = when { isAnnotationType -> ClassKind.ANNOTATION_CLASS @@ -385,7 +393,7 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound( ) } - val classSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol + val classSymbol = session.symbolProvider.getClassLikeSymbolByFqName(classId) as? FirRegularClassSymbol val mappedTypeArguments = if (isRaw) { val defaultArgs = (1..classifier.typeParameters.size).map { ConeStarProjection } @@ -436,7 +444,7 @@ private fun FirRegularClass.createRawArguments( private fun buildEnumCall(session: FirSession, classId: ClassId?, entryName: Name?) = buildFunctionCall { val calleeReference = if (classId != null && entryName != null) { - session.firSymbolProvider.getClassDeclaredPropertySymbols(classId, entryName) + session.symbolProvider.getClassDeclaredPropertySymbols(classId, entryName) .firstOrNull()?.let { propertySymbol -> buildResolvedNamedReference { name = entryName @@ -503,7 +511,7 @@ private fun buildArgumentMapping( if (annotationArguments.none { it.name != null }) { return null } - val annotationClassSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(lookupTag.classId).also { + val annotationClassSymbol = session.symbolProvider.getClassLikeSymbolByFqName(lookupTag.classId).also { lookupTag.bindSymbolToLookupTag(session, it) } ?: return null val annotationConstructor = diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt index e2c5c420af1..723e21bf066 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/declarations/FirJavaField.kt @@ -148,7 +148,6 @@ internal class FirJavaFieldBuilder : FirFieldBuilder() { var modality: Modality? = null lateinit var visibility: Visibility var isStatic: Boolean by Delegates.notNull() - var initializer: FirExpression? = null lateinit var annotationBuilder: () -> List override var resolvePhase: FirResolvePhase = FirResolvePhase.ANALYZED_DEPENDENCIES diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt index 8df4b2e9244..cfae7fe2866 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/AnnotationsLoader.kt @@ -18,7 +18,7 @@ import org.jetbrains.kotlin.fir.java.createConstantOrError import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbols import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLikeLookupTagImpl @@ -55,7 +55,7 @@ internal class AnnotationsLoader(private val session: FirSession) { private fun ClassId.toEnumEntryReferenceExpression(name: Name): FirExpression { return buildFunctionCall { val entryPropertySymbol = - session.firSymbolProvider.getClassDeclaredPropertySymbols( + session.symbolProvider.getClassDeclaredPropertySymbols( this@toEnumEntryReferenceExpression, name, ).firstOrNull() @@ -162,4 +162,4 @@ internal class AnnotationsLoader(private val session: FirSession) { buildResolvedTypeRef { type = constructClassType(emptyArray(), isNullable = false) } -} \ No newline at end of file +} diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt index 1f420bc49cd..f5be29cdc0a 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmBinaryAnnotationDeserializer.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.deserialization.AbstractAnnotationDeserializer import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass @@ -317,4 +317,4 @@ private fun FirSession.loadMemberAnnotations(kotlinBinaryClass: KotlinJvmBinaryC }, byteContent) return MemberAnnotations(memberAnnotations) -} \ No newline at end of file +} diff --git a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaClassMapper.kt b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaClassMapper.kt index da107a5fdcf..44b5cffa088 100644 --- a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaClassMapper.kt +++ b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/FirJavaClassMapper.kt @@ -15,6 +15,6 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass class FirJavaClassMapper(private val session: FirSession) : FirPlatformClassMapper() { override fun getCorrespondingPlatformClass(declaration: FirClassLikeDeclaration<*>): FirRegularClass? { val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(declaration.symbol.classId.asSingleFqName().toUnsafe()) - return javaClassId?.let { session.firSymbolProvider.getClassLikeSymbolByFqName(it)?.fir } as? FirRegularClass + return javaClassId?.let { session.symbolProvider.getClassLikeSymbolByFqName(it)?.fir } as? FirRegularClass } } diff --git a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt index e9d75ab0c29..5c22fe3a15f 100644 --- a/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt +++ b/compiler/fir/jvm/src/org/jetbrains/kotlin/fir/resolve/scopes/JvmMappedScopes.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.declarations.classId import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.constructType -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.wrapSubstitutionScopeIfNeed import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.jvm.JvmMappedScope @@ -31,7 +31,7 @@ fun wrapScopeWithJvmMapped( val kotlinUnsafeFqName = classId.asSingleFqName().toUnsafe() val javaClassId = JavaToKotlinClassMap.mapKotlinToJava(kotlinUnsafeFqName) ?: return declaredMemberScope - val symbolProvider = useSiteSession.firSymbolProvider + val symbolProvider = useSiteSession.symbolProvider val javaClass = symbolProvider.getClassLikeSymbolByFqName(javaClassId)?.fir as? FirRegularClass ?: return declaredMemberScope val preparedSignatures = JvmMappedScope.prepareSignatures(javaClass, JavaToKotlinClassMap.isMutable(kotlinUnsafeFqName)) diff --git a/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FullPipelineModularizedTest.kt b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FullPipelineModularizedTest.kt index b918a6ec6fe..4d2d061d344 100644 --- a/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FullPipelineModularizedTest.kt +++ b/compiler/fir/modularized-tests/tests/org/jetbrains/kotlin/fir/FullPipelineModularizedTest.kt @@ -30,11 +30,12 @@ class FullPipelineModularizedTest : AbstractModularizedTest() { val gcInfo: Map, val analysis: Long, val translation: Long, + val lowering: Long, val generation: Long, val files: Int, val lines: Int ) { - constructor() : this(emptyMap(), 0, 0, 0, 0, 0) + constructor() : this(emptyMap(), 0, 0, 0, 0, 0, 0) operator fun plus(other: CumulativeTime): CumulativeTime { return CumulativeTime( @@ -43,13 +44,14 @@ class FullPipelineModularizedTest : AbstractModularizedTest() { }, analysis + other.analysis, translation + other.translation, + lowering + other.lowering, generation + other.generation, files + other.files, lines + other.lines ) } - fun totalTime() = analysis + translation + generation + fun totalTime() = analysis + translation + lowering + generation } private lateinit var totalPassResult: CumulativeTime @@ -126,6 +128,7 @@ class FullPipelineModularizedTest : AbstractModularizedTest() { } phase("Analysis", total.analysis, total.files, total.lines) phase("Translation", total.translation, total.files, total.lines) + phase("Lowering", total.lowering, total.files, total.lines) phase("Generation", total.generation, total.files, total.lines) separator() @@ -264,6 +267,7 @@ class FullPipelineModularizedTest : AbstractModularizedTest() { gcInfo, analysisMeasurement?.milliseconds ?: 0, irMeasurements.firstOrNull { it.kind == IRMeasurement.Kind.TRANSLATION }?.milliseconds ?: 0, + irMeasurements.firstOrNull { it.kind == IRMeasurement.Kind.LOWERING }?.milliseconds ?: 0, irMeasurements.firstOrNull { it.kind == IRMeasurement.Kind.GENERATION }?.milliseconds ?: 0, files ?: 0, lines ?: 0 diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt index 283b1afb22b..e4acbaa0b71 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/DeclarationsConverter.kt @@ -37,12 +37,9 @@ import org.jetbrains.kotlin.fir.lightTree.fir.modifier.Modifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeModifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeParameterModifier import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeProjectionModifier -import org.jetbrains.kotlin.fir.references.builder.buildImplicitThisReference -import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolvedAnnotations import org.jetbrains.kotlin.fir.scopes.FirScopeProvider -import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.LocalCallableIdConstructor import org.jetbrains.kotlin.fir.symbols.impl.* @@ -432,10 +429,9 @@ class DeclarationsConverter( val selfType = classNode.toDelegatedSelfType(this) registerSelfType(selfType) - val delegationSpecifiers = superTypeList?.let { convertDelegationSpecifiers(it, symbol, selfType) } + val delegationSpecifiers = superTypeList?.let { convertDelegationSpecifiers(it) } var delegatedSuperTypeRef: FirTypeRef? = delegationSpecifiers?.delegatedSuperTypeRef val delegatedConstructorSource: FirLightSourceElement? = delegationSpecifiers?.delegatedConstructorSource - delegationSpecifiers?.delegateFields?.map { declarations += it } val superTypeCallEntry = delegationSpecifiers?.delegatedConstructorArguments.orEmpty() val superTypeRefs = mutableListOf() @@ -479,11 +475,11 @@ class DeclarationsConverter( ) //parse primary constructor val primaryConstructorWrapper = convertPrimaryConstructor( - primaryConstructor, selfType.source, classWrapper, delegatedConstructorSource, - delegationSpecifiers?.primaryConstructorBody + primaryConstructor, selfType.source, classWrapper, delegatedConstructorSource ) val firPrimaryConstructor = primaryConstructorWrapper?.firConstructor firPrimaryConstructor?.let { declarations += it } + delegationSpecifiers?.delegateFields?.map { declarations += it } val properties = mutableListOf() if (primaryConstructor != null && firPrimaryConstructor != null) { @@ -558,19 +554,17 @@ class DeclarationsConverter( var classBody: LighterASTNode? = null var delegatedConstructorSource: FirLightSourceElement? = null var delegateFields: List? = null - var primaryConstructorBody: FirBlock? = null objectLiteral.getChildNodesByType(OBJECT_DECLARATION).first().forEachChildren { when (it.tokenType) { MODIFIER_LIST -> modifiers = convertModifierList(it) PRIMARY_CONSTRUCTOR -> primaryConstructor = it - SUPER_TYPE_LIST -> convertDelegationSpecifiers(it, symbol, delegatedSelfType).let { - delegatedSuperTypeRef = it.delegatedSuperTypeRef - superTypeRefs += it.superTypesRef - superTypeCallEntry += it.delegatedConstructorArguments - delegatedConstructorSource = it.delegatedConstructorSource - delegateFields = it.delegateFields - primaryConstructorBody = it.primaryConstructorBody + SUPER_TYPE_LIST -> convertDelegationSpecifiers(it).let { specifiers -> + delegatedSuperTypeRef = specifiers.delegatedSuperTypeRef + superTypeRefs += specifiers.superTypesRef + superTypeCallEntry += specifiers.delegatedConstructorArguments + delegatedConstructorSource = specifiers.delegatedConstructorSource + delegateFields = specifiers.delegateFields } CLASS_BODY -> classBody = it } @@ -586,7 +580,6 @@ class DeclarationsConverter( this.superTypeRefs += superTypeRefs typeRef = delegatedSelfType - delegateFields?.map { this.declarations += it } val classWrapper = ClassWrapper( SpecialNames.NO_NAME_PROVIDED, modifiers, ClassKind.OBJECT, this, hasPrimaryConstructor = false, @@ -597,8 +590,10 @@ class DeclarationsConverter( superTypeCallEntry = superTypeCallEntry ) //parse primary constructor - convertPrimaryConstructor(primaryConstructor, typeRef.source, classWrapper, delegatedConstructorSource, primaryConstructorBody) - ?.let { this.declarations += it.firConstructor } + convertPrimaryConstructor( + primaryConstructor, typeRef.source, classWrapper, delegatedConstructorSource + )?.let { this.declarations += it.firConstructor } + delegateFields?.let { this.declarations += it } //parse declarations classBody?.let { @@ -724,7 +719,6 @@ class DeclarationsConverter( selfTypeSource: FirSourceElement?, classWrapper: ClassWrapper, delegatedConstructorSource: FirLightSourceElement?, - body: FirBlock? = null ): PrimaryConstructor? { if (primaryConstructor == null && !classWrapper.isEnumEntry() && classWrapper.hasSecondaryConstructor) return null if (classWrapper.isInterface()) return null @@ -768,7 +762,7 @@ class DeclarationsConverter( typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters) this.valueParameters += valueParameters.map { it.firValueParameter } delegatedConstructor = firDelegatedCall - this.body = body + this.body = null }.apply { containingClassAttr = currentDispatchReceiverType()!!.lookupTag }, valueParameters @@ -1437,21 +1431,14 @@ class DeclarationsConverter( val delegatedConstructorArguments: List, val delegatedConstructorSource: FirLightSourceElement?, val delegateFields: List, - val primaryConstructorBody: FirBlock? ) - private fun convertDelegationSpecifiers( - delegationSpecifiers: LighterASTNode, - containerSymbol: AbstractFirBasedSymbol<*>, - delegatedTypeRef: FirTypeRef - ): DelegationSpecifiers { + private fun convertDelegationSpecifiers(delegationSpecifiers: LighterASTNode): DelegationSpecifiers { val superTypeRefs = mutableListOf() val superTypeCallEntry = mutableListOf() var delegatedSuperTypeRef: FirTypeRef? = null var delegateConstructorSource: FirLightSourceElement? = null val delegateFields = mutableListOf() - val initializeDelegateStatements = mutableListOf() - var delegateNumber = 0 delegationSpecifiers.forEachChildren { when (it.tokenType) { SUPER_TYPE_ENTRY -> { @@ -1464,28 +1451,12 @@ class DeclarationsConverter( delegateConstructorSource = it.toFirSourceElement(FirFakeSourceElementKind.DelegatingConstructorCall) } DELEGATED_SUPER_TYPE_ENTRY -> { - superTypeRefs += convertExplicitDelegation( - it, - delegateNumber, - delegateFields, - initializeDelegateStatements, - containerSymbol, - delegatedTypeRef - ) - delegateNumber++ + superTypeRefs += convertExplicitDelegation(it, delegateFields) } } } - val body = if (initializeDelegateStatements.isNotEmpty()) { - buildBlock { - for (statement in initializeDelegateStatements) { - statements += statement - } - } - } else null return DelegationSpecifiers( - delegatedSuperTypeRef, superTypeRefs, superTypeCallEntry, delegateConstructorSource, - delegateFields, body + delegatedSuperTypeRef, superTypeRefs, superTypeCallEntry, delegateConstructorSource, delegateFields ) } @@ -1515,14 +1486,7 @@ class DeclarationsConverter( * : userType "by" element * ; */ - private fun convertExplicitDelegation( - explicitDelegation: LighterASTNode, - delegateNumber: Int, - delegateFields: MutableList, - initializeDelegateStatements: MutableList, - containerSymbol: AbstractFirBasedSymbol<*>, - delegatedSelfTypeRef: FirTypeRef - ): FirTypeRef { + private fun convertExplicitDelegation(explicitDelegation: LighterASTNode, delegateFields: MutableList): FirTypeRef { lateinit var firTypeRef: FirTypeRef var firExpression: FirExpression? = buildErrorExpression( explicitDelegation.toFirSourceElement(), ConeSimpleDiagnostic("Should have delegate", DiagnosticKind.Syntax) @@ -1534,7 +1498,7 @@ class DeclarationsConverter( } } - val delegateName = Name.special("<\$\$delegate_$delegateNumber>") + val delegateName = Name.special("<\$\$delegate_${delegateFields.size}>") delegateFields.add( buildField { source = firExpression!!.source @@ -1545,24 +1509,7 @@ class DeclarationsConverter( symbol = FirFieldSymbol(@OptIn(LocalCallableIdConstructor::class) CallableId(name)) isVar = false status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL) - } - ) - initializeDelegateStatements.add( - buildVariableAssignment { - source = firExpression!!.source - calleeReference = - buildResolvedNamedReference { - name = delegateName - resolvedSymbol = delegateFields[delegateNumber].symbol - } - rValue = firExpression!! - dispatchReceiver = buildThisReceiverExpression { - source = firExpression!!.source - calleeReference = buildImplicitThisReference { - boundSymbol = containerSymbol - } - typeRef = delegatedSelfTypeRef - } + initializer = firExpression } ) return firTypeRef diff --git a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt index d95bd4e607c..394b650ec39 100644 --- a/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt +++ b/compiler/fir/raw-fir/light-tree2fir/src/org/jetbrains/kotlin/fir/lightTree/converter/ExpressionsConverter.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.lightTree.converter import com.intellij.lang.LighterASTNode import com.intellij.psi.TokenType import com.intellij.util.diff.FlyweightCapableTreeStructure +import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.KtNodeTypes.* import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities @@ -664,6 +665,7 @@ class ExpressionsConverter( source = whenExpression.toFirSourceElement() this.subject = subjectExpression this.subjectVariable = subjectVariable + usedAsExpression = whenExpression.usedAsExpression for (entry in whenEntries) { val branch = entry.firBlock branches += if (!entry.isElse) { @@ -1082,6 +1084,7 @@ class ExpressionsConverter( } return buildWhenExpression { + source = ifExpression.toFirSourceElement() val trueBranch = convertLoopBody(thenBlock) branches += buildWhenBranch { source = thenBlock?.toFirSourceElement() @@ -1095,11 +1098,27 @@ class ExpressionsConverter( condition = buildElseIfTrueCondition() result = elseBranch } - } + usedAsExpression = ifExpression.usedAsExpression } } + private val LighterASTNode.usedAsExpression: Boolean + get() { + var parent = getParent() ?: return true + if (parent.elementType == ANNOTATED_EXPRESSION) { + parent = parent.getParent() ?: return true + } + val parentTokenType = parent.tokenType + if (parentTokenType == BLOCK) return false + if (parentTokenType == THEN || parentTokenType == ELSE || parentTokenType == WHEN_ENTRY) { + return parent.getParent()?.usedAsExpression ?: true + } + if (parentTokenType != BODY) return true + val type = parent.getParent()?.tokenType ?: return true + return !(type == FOR || type == WHILE || type == DO_WHILE) + } + /** * @see org.jetbrains.kotlin.parsing.KotlinExpressionParsing.parseJump * @see org.jetbrains.kotlin.fir.builder.RawFirBuilder.Visitor.visitBreakExpression diff --git a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt index 7c23143efdb..e45a001a557 100644 --- a/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt +++ b/compiler/fir/raw-fir/psi2fir/src/org/jetbrains/kotlin/fir/builder/RawFirBuilder.kt @@ -28,7 +28,6 @@ import org.jetbrains.kotlin.fir.expressions.builder.* import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock import org.jetbrains.kotlin.fir.references.builder.* import org.jetbrains.kotlin.fir.scopes.FirScopeProvider -import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.CallableId import org.jetbrains.kotlin.fir.symbols.LocalCallableIdConstructor import org.jetbrains.kotlin.fir.symbols.impl.* @@ -544,13 +543,11 @@ class RawFirBuilder( delegatedSelfTypeRef: FirTypeRef?, delegatedEnumSuperTypeRef: FirTypeRef?, classKind: ClassKind, - containerTypeParameters: List, - containerSymbol: AbstractFirBasedSymbol<*> + containerTypeParameters: List ): FirTypeRef { var superTypeCallEntry: KtSuperTypeCallEntry? = null var delegatedSuperTypeRef: FirTypeRef? = null - var delegateNumber = 0 - val initializeDelegateStatements = mutableListOf() + val delegateFields = mutableListOf() for (superTypeListEntry in superTypeListEntries) { when (superTypeListEntry) { is KtSuperTypeEntry -> { @@ -565,7 +562,7 @@ class RawFirBuilder( val type = superTypeListEntry.typeReference.toFirOrErrorType() val delegateExpression = { superTypeListEntry.delegateExpression }.toFirExpression("Should have delegate") container.superTypeRefs += type - val delegateName = Name.special("<\$\$delegate_$delegateNumber>") + val delegateName = Name.special("<\$\$delegate_${delegateFields.size}>") val delegateSource = superTypeListEntry.delegateExpression?.toFirSourceElement() val delegateField = buildField { source = delegateSource @@ -576,28 +573,9 @@ class RawFirBuilder( symbol = FirFieldSymbol(@OptIn(LocalCallableIdConstructor::class) CallableId(name)) isVar = false status = FirDeclarationStatusImpl(Visibilities.Local, Modality.FINAL) + initializer = delegateExpression } - initializeDelegateStatements.add( - buildVariableAssignment { - source = delegateSource - calleeReference = - buildResolvedNamedReference { - source = delegateSource - name = delegateName - resolvedSymbol = delegateField.symbol - } - rValue = delegateExpression - dispatchReceiver = buildThisReceiverExpression { - source = delegateSource - calleeReference = buildImplicitThisReference { - boundSymbol = containerSymbol - } - delegatedSelfTypeRef?.let { typeRef = it } - } - } - ) - container.declarations.add(delegateField) - delegateNumber++ + delegateFields.add(delegateField) } } } @@ -637,27 +615,22 @@ class RawFirBuilder( container.superTypeRefs += implicitAnyType delegatedSuperTypeRef = implicitAnyType } - if (this is KtClass && this.isInterface()) return delegatedSuperTypeRef ?: implicitAnyType // TODO: in case we have no primary constructor, // it may be not possible to determine delegated super type right here delegatedSuperTypeRef = delegatedSuperTypeRef ?: defaultDelegatedSuperTypeRef - if (!this.hasPrimaryConstructor()) return delegatedSuperTypeRef - - val firPrimaryConstructor = primaryConstructor.toFirConstructor( - superTypeCallEntry, - delegatedSuperTypeRef, - delegatedSelfTypeRef ?: delegatedSuperTypeRef, - owner = this, - containerTypeParameters, - body = if (initializeDelegateStatements.isNotEmpty()) buildBlock { - for (statement in initializeDelegateStatements) { - statements += statement - } - } else null - ) - - container.declarations += firPrimaryConstructor + if ((this !is KtClass || !this.isInterface()) && this.hasPrimaryConstructor()) { + val firPrimaryConstructor = primaryConstructor.toFirConstructor( + superTypeCallEntry, + delegatedSuperTypeRef, + delegatedSelfTypeRef ?: delegatedSuperTypeRef, + owner = this, + containerTypeParameters, + body = null + ) + container.declarations += firPrimaryConstructor + } + container.declarations += delegateFields return delegatedSuperTypeRef } @@ -861,8 +834,7 @@ class RawFirBuilder( delegatedSelfType, null, classKind, - typeParameters, - symbol + typeParameters ) val primaryConstructor = classOrObject.primaryConstructor @@ -890,9 +862,7 @@ class RawFirBuilder( } if (classOrObject.hasModifier(DATA_KEYWORD) && firPrimaryConstructor != null) { - val zippedParameters = classOrObject.primaryConstructorParameters.zip( - declarations.filterIsInstance(), - ) + val zippedParameters = classOrObject.primaryConstructorParameters.filter { it.hasValOrVar() } zip declarations.filterIsInstance() DataClassMembersGenerator( baseSession, classOrObject, @@ -905,7 +875,7 @@ class RawFirBuilder( // just making a shallow copy isn't enough type ref may be a function type ref // and contain value parameters inside withDefaultSourceElementKind(newKind) { - (property.returnTypeRef.psi as KtTypeReference).toFirOrImplicitType() + (property.returnTypeRef.psi as KtTypeReference?).toFirOrImplicitType() } }, ).generate() @@ -947,8 +917,7 @@ class RawFirBuilder( delegatedSelfType, null, ClassKind.CLASS, - containerTypeParameters = emptyList(), - symbol + containerTypeParameters = emptyList() ) typeRef = delegatedSelfType @@ -1577,6 +1546,7 @@ class RawFirBuilder( result = expression.`else`.toFirBlock() } } + usedAsExpression = expression.usedAsExpression } } @@ -1614,6 +1584,7 @@ class RawFirBuilder( source = expression.toFirSourceElement() this.subject = subjectExpression this.subjectVariable = subjectVariable + usedAsExpression = expression.usedAsExpression for (entry in expression.entries) { val entrySource = entry.toFirSourceElement() @@ -1652,6 +1623,24 @@ class RawFirBuilder( } } + private val KtExpression.usedAsExpression: Boolean + get() { + var parent = parent + if (parent.elementType == KtNodeTypes.ANNOTATED_EXPRESSION) { + parent = parent.parent + } + if (parent is KtBlockExpression) return false + when (parent.elementType) { + KtNodeTypes.THEN, KtNodeTypes.ELSE, KtNodeTypes.WHEN_ENTRY -> { + return (parent.parent as? KtExpression)?.usedAsExpression ?: true + } + } + // Here we check that when used is a single statement of a loop + if (parent !is KtContainerNodeForControlStructureBody) return true + val type = parent.parent.elementType + return !(type == KtNodeTypes.FOR || type == KtNodeTypes.WHILE || type == KtNodeTypes.DO_WHILE) + } + override fun visitDoWhileExpression(expression: KtDoWhileExpression, data: Unit): FirElement { return FirDoWhileLoopBuilder().apply { source = expression.toFirSourceElement() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt index 7221a374a20..cab6f986109 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt @@ -137,6 +137,8 @@ fun FirWhenExpression.copy( branches += this@copy.branches typeRef = resultType this.annotations += annotations + usedAsExpression = this@copy.usedAsExpression + exhaustivenessStatus = this@copy.exhaustivenessStatus } fun FirTryExpression.copy( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityResolverImpl.kt index e9a30612e26..8c4d7230bc3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirEffectiveVisibilityResolverImpl.kt @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -103,8 +103,8 @@ open class FirEffectiveVisibilityResolverImpl(private val session: FirSession) : if (!succeededToGetSymbol) { if (parentClassId?.isLocal == false) { // ?: is needed to get enum from enum entry - parentSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(parentClassId) - ?: parentClassId.outerClassId?.let { session.firSymbolProvider.getClassLikeSymbolByFqName(it) } + parentSymbol = session.symbolProvider.getClassLikeSymbolByFqName(parentClassId) + ?: parentClassId.outerClassId?.let { session.symbolProvider.getClassLikeSymbolByFqName(it) } parentSymbol?.fir.safeAs()?.let { parentEffectiveVisibility = resolveFor(it, null, scopeSession) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt index b4777c7ccbc..ee99dc3c589 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirQualifiedNameResolver.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.transformers.PackageOrClass import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.resolve.transformers.resolveToPackageOrClass @@ -64,7 +64,7 @@ class FirQualifiedNameResolver(private val components: BodyResolveComponents) { if (qualifierStack.isEmpty()) { return null } - val symbolProvider = session.firSymbolProvider + val symbolProvider = session.symbolProvider var qualifierParts = qualifierStack.asReversed().map { it.name.asString() } var resolved: PackageOrClass? do { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt index 719f95c1c95..d2531c45207 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/FirVisibilityChecker.kt @@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.calls.Candidate import org.jetbrains.kotlin.fir.resolve.calls.ReceiverValue import org.jetbrains.kotlin.fir.resolve.firProvider -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.fullyExpandedType import org.jetbrains.kotlin.fir.resolve.lookupSuperTypes import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol @@ -65,17 +65,24 @@ abstract class FirVisibilityChecker : FirSessionComponent { Visibilities.Private, Visibilities.PrivateToThis -> { val ownerId = symbol.getOwnerId() if (declaration.session == session) { - if (ownerId == null || declaration is FirConstructor && declaration.isFromSealedClass) { - val candidateFile = when (symbol) { - is FirClassLikeSymbol<*> -> provider.getFirClassifierContainerFileIfAny(symbol) - is FirCallableSymbol<*> -> provider.getFirCallableContainerFile(symbol) - else -> null + when { + ownerId == null -> { + val candidateFile = when (symbol) { + is FirClassLikeSymbol<*> -> provider.getFirClassifierContainerFileIfAny(symbol) + is FirCallableSymbol<*> -> provider.getFirCallableContainerFile(symbol) + else -> null + } + // Top-level: visible in file + candidateFile == useSiteFile + } + declaration is FirConstructor && declaration.isFromSealedClass -> { + // Sealed class constructor: visible in same package + declaration.symbol.callableId.packageName == useSiteFile.packageFqName + } + else -> { + // Member: visible inside parent class, including all its member classes + canSeePrivateMemberOf(containingDeclarations, ownerId, session) } - // Top-level: visible in file - candidateFile == useSiteFile - } else { - // Member: visible inside parent class, including all its member classes - canSeePrivateMemberOf(containingDeclarations, ownerId, session) } } else { declaration is FirSimpleFunction && declaration.isAllowedToBeAccessedFromOutside() @@ -133,7 +140,7 @@ abstract class FirVisibilityChecker : FirSessionComponent { private fun ClassId.ownerIfCompanion(session: FirSession): ClassId? { if (outerClassId == null || isLocal) return null - val ownerSymbol = session.firSymbolProvider.getClassLikeSymbolByFqName(this) as? FirRegularClassSymbol + val ownerSymbol = session.symbolProvider.getClassLikeSymbolByFqName(this) as? FirRegularClassSymbol return outerClassId.takeIf { ownerSymbol?.fir?.isCompanion == true } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirOuterClassManager.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirOuterClassManager.kt index 3c0646521b9..e7eff05da5e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirOuterClassManager.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirOuterClassManager.kt @@ -17,7 +17,7 @@ class FirOuterClassManager( private val session: FirSession, private val outerLocalClassForNested: Map, FirClassLikeSymbol<*>>, ) { - private val symbolProvider = session.firSymbolProvider + private val symbolProvider = session.symbolProvider fun outerClass(classSymbol: FirClassLikeSymbol<*>): FirClassLikeSymbol<*>? { if (classSymbol !is FirClassSymbol<*>) return null diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt index f127007a411..d24c64d1e60 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/LookupTagUtils.kt @@ -25,7 +25,7 @@ fun ConeClassLikeLookupTag.toSymbol(useSiteSession: FirSession): FirClassLikeSym if (this is ConeClassLookupTagWithFixedSymbol) { return this.symbol } - val firSymbolProvider = useSiteSession.firSymbolProvider + val firSymbolProvider = useSiteSession.symbolProvider (this as? ConeClassLikeLookupTagImpl)?.boundSymbol?.takeIf { it.key === useSiteSession }?.let { return it.value } return firSymbolProvider.getClassLikeSymbolByFqName(classId).also { @@ -40,7 +40,7 @@ fun ConeClassLikeLookupTag.toSymbolOrError(useSiteSession: FirSession): FirClass fun ConeClassLikeLookupTag.toFirRegularClass(session: FirSession): FirRegularClass? = - session.firSymbolProvider.getSymbolByLookupTag(this)?.fir as? FirRegularClass + session.symbolProvider.getSymbolByLookupTag(this)?.fir as? FirRegularClass @OptIn(LookupTagInternals::class) fun ConeClassLikeLookupTagImpl.bindSymbolToLookupTag(session: FirSession, symbol: FirClassLikeSymbol<*>?) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/MainSessionComponents.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/MainSessionComponents.kt index 04f2ea1f08c..5c051b81ff2 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/MainSessionComponents.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/MainSessionComponents.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.scopes.impl.FirDeclaredMemberScopeProvider import org.jetbrains.kotlin.fir.types.FirCorrespondingSupertypesCache -val FirSession.firSymbolProvider: FirSymbolProvider by FirSession.sessionComponentAccessor() +val FirSession.symbolProvider: FirSymbolProvider by FirSession.sessionComponentAccessor() val FirSession.firProvider: FirProvider by FirSession.sessionComponentAccessor() val FirSession.correspondingSupertypesCache: FirCorrespondingSupertypesCache by FirSession.sessionComponentAccessor() val FirSession.declaredMemberScopeProvider: FirDeclaredMemberScopeProvider by FirSession.sessionComponentAccessor() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/PersistentImplicitReceiverStack.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/PersistentImplicitReceiverStack.kt index b449cc0a153..d7be8b91e7d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/PersistentImplicitReceiverStack.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/PersistentImplicitReceiverStack.kt @@ -37,7 +37,7 @@ class PersistentImplicitReceiverStack private constructor( fun add(name: Name?, value: ImplicitReceiverValue<*>): PersistentImplicitReceiverStack { val stack = stack.add(value) - val originalTypes = originalTypes.add(value.type) + val originalTypes = originalTypes.add(value.originalType) val index = stack.size - 1 val indexesPerLabel = name?.let { indexesPerLabel.put(it, index) } ?: indexesPerLabel val indexesPerSymbol = indexesPerSymbol.put(value.boundSymbol, index) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt index 44d33bb116f..e7a0251a093 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolutionMode.kt @@ -26,6 +26,11 @@ sealed class ResolutionMode { fun withExpectedType(expectedTypeRef: FirTypeRef?): ResolutionMode = expectedTypeRef?.let { ResolutionMode.WithExpectedType(it) } ?: ResolutionMode.ContextDependent +@JvmName("withExpectedTypeNullable") +fun withExpectedType(coneType: ConeKotlinType?): ResolutionMode { + return coneType?.let { withExpectedType(it) } ?: ResolutionMode.ContextDependent +} + fun withExpectedType(coneType: ConeKotlinType): ResolutionMode { val typeRef = buildResolvedTypeRef { type = coneType diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt index eb7923544b8..9aeaaf3d4db 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/ResolveUtils.kt @@ -283,7 +283,7 @@ fun CallableId.isIterator(): Boolean = callableName.asString() == "iterator" && packageName.asString() in arrayOf("kotlin.collections", "kotlin.ranges") fun FirAnnotationCall.fqName(session: FirSession): FqName? { - val symbol = session.firSymbolProvider.getSymbolByTypeRef(annotationTypeRef) ?: return null + val symbol = session.symbolProvider.getSymbolByTypeRef(annotationTypeRef) ?: return null return symbol.classId.asSingleFqName() } @@ -327,7 +327,7 @@ fun FirAnnotationCall.getCorrespondingClassSymbolOrNull(session: FirSession): Fi // TODO: How to retrieve local annotaiton's constructor? null } else { - (session.firSymbolProvider.getClassLikeSymbolByFqName(it) as? FirRegularClassSymbol) + (session.symbolProvider.getClassLikeSymbolByFqName(it) as? FirRegularClassSymbol) } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt index d53b24c2d44..4ae71033773 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/SamResolution.kt @@ -241,7 +241,7 @@ private fun FirRegularClass.computeSamCandidateNames(session: FirSession): Set() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt index 3fcf7709d64..c7c0e2ce9a4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CallableReferenceResolution.kt @@ -226,7 +226,7 @@ private fun BodyResolveComponents.getCallableReferenceAdaptation( } } - val coercionStrategy = if (returnExpectedType.isUnit && !function.returnTypeRef.isUnit) + val coercionStrategy = if (returnExpectedType.isUnitOrFlexibleUnit && !function.returnTypeRef.isUnit) CoercionStrategy.COERCION_TO_UNIT else CoercionStrategy.NO_COERCION @@ -288,7 +288,7 @@ private enum class VarargMappingState { private fun FirFunction<*>.indexOf(valueParameter: FirValueParameter): Int = valueParameters.indexOf(valueParameter) -val ConeKotlinType.isUnit: Boolean +val ConeKotlinType.isUnitOrFlexibleUnit: Boolean get() { val type = this.lowerBoundIfFlexible() if (type.isNullable) return false diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/SuperCalls.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/SuperCalls.kt index 02a97a20dde..4e3a683cc93 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/SuperCalls.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/SuperCalls.kt @@ -36,12 +36,13 @@ fun BodyResolveComponents.findTypesForSuperCandidates( containingCall: FirQualifiedAccess, ): Collection { val supertypes = superTypeRefs.map { (it as FirResolvedTypeRef).type } - if (supertypes.size <= 1) return supertypes + val isMethodOfAny = containingCall is FirFunctionCall && isCallingMethodOfAny(containingCall) + if (supertypes.size <= 1 && !isMethodOfAny) return supertypes return when (containingCall) { is FirFunctionCall -> { val calleeName = containingCall.calleeReference.name - if (isCallingMethodOfAny(containingCall)) { + if (isMethodOfAny) { resolveSupertypesForMethodOfAny(supertypes, calleeName) } else { resolveSupertypesByCalleeName(supertypes, calleeName) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirInvokeResolveTowerExtension.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirInvokeResolveTowerExtension.kt index fc0138efa64..a06f03705ca 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirInvokeResolveTowerExtension.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirInvokeResolveTowerExtension.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.fir.resolve.calls.tower -import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.builder.FirQualifiedAccessExpressionBuilder @@ -156,7 +155,9 @@ internal class FirInvokeResolveTowerExtension( val invokeFunctionInfo = info.copy( - explicitReceiver = invokeReceiverExpression, name = OperatorNameConventions.INVOKE, + explicitReceiver = invokeReceiverExpression, + name = OperatorNameConventions.INVOKE, + isImplicitInvoke = true, candidateForCommonInvokeReceiver = invokeReceiverCandidate.takeUnless { invokeBuiltinExtensionMode } ).let { when { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt index 73e60d9c20b..856ff5f835f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt @@ -197,7 +197,7 @@ class ScopeTowerLevel( private fun dispatchReceiverValue(candidate: FirCallableSymbol<*>): ReceiverValue? { candidate.fir.importedFromObjectData?.let { data -> val objectClassId = data.objectClassId - val symbol = session.firSymbolProvider.getClassLikeSymbolByFqName(objectClassId) + val symbol = session.symbolProvider.getClassLikeSymbolByFqName(objectClassId) if (symbol is FirRegularClassSymbol) { val resolvedQualifier = buildResolvedQualifier { packageFqName = objectClassId.packageFqName diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt index 58e5d30c9b8..84b0db2b66d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.resolve.dfa +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.PrivateForInline import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription @@ -14,6 +15,7 @@ import org.jetbrains.kotlin.fir.contracts.description.ConeConstantReference import org.jetbrains.kotlin.fir.contracts.description.ConeReturnsEffectDeclaration import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.languageVersionSettings import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.PersistentImplicitReceiverStack @@ -26,6 +28,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBod import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.resultType import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.CallableId +import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.name.FqName @@ -268,6 +271,18 @@ abstract class FirDataFlowAnalyzer( return graph } + // ----------------------------------- Field ----------------------------------- + + fun enterField(field: FirField) { + graphBuilder.enterField(field)?.mergeIncomingFlow() + } + + fun exitField(field: FirField): ControlFlowGraph? { + val (node, graph) = graphBuilder.exitField(field) ?: return null + node.mergeIncomingFlow() + return graph + } + // ----------------------------------- Delegate ----------------------------------- fun enterDelegateExpression() { @@ -570,7 +585,7 @@ abstract class FirDataFlowAnalyzer( syntheticElseNode.mergeIncomingFlow() } } - whenExitNode.mergeIncomingFlow(updateReceivers = true) + whenExitNode.mergeIncomingFlow() } // ----------------------------------- While Loop ----------------------------------- @@ -663,7 +678,7 @@ abstract class FirDataFlowAnalyzer( fun enterFinallyBlock() { // NB: fork to isolate effects inside the finally block // Otherwise, changes in the finally block could affect the previous nodes: try main block and catch clauses. - graphBuilder.enterFinallyBlock().mergeIncomingFlow(shouldForkFlow = true) + graphBuilder.enterFinallyBlock().mergeIncomingFlow(updateReceivers = true, shouldForkFlow = true) } fun exitFinallyBlock(tryExpression: FirTryExpression) { @@ -1111,8 +1126,23 @@ abstract class FirDataFlowAnalyzer( } } - fun exitElvis() { - graphBuilder.exitElvis().mergeIncomingFlow() + fun exitElvis(elvisExpression: FirElvisExpression) { + val node = graphBuilder.exitElvis().mergeIncomingFlow() + if (!components.session.languageVersionSettings.supportsFeature(LanguageFeature.BooleanElvisBoundSmartCasts)) return + val lhs = elvisExpression.lhs + val rhs = elvisExpression.rhs + if (rhs is FirConstExpression<*> && rhs.kind == ConstantValueKind.Boolean) { + if (lhs.typeRef.coneType.classId != StandardClassIds.Boolean) return + + val flow = node.flow + // a ?: false == true -> a != null + // a ?: true == false -> a != null + val elvisVariable = variableStorage.getOrCreateVariable(flow, elvisExpression) + val lhsVariable = variableStorage.getOrCreateVariable(flow, lhs) + + val value = rhs.value as Boolean + flow.addImplication(elvisVariable.eq(!value) implies (lhsVariable.notEq(null))) + } } // Callable reference @@ -1132,15 +1162,28 @@ abstract class FirDataFlowAnalyzer( private val CFGNode<*>.origin: CFGNode<*> get() = if (this is StubNode) firstPreviousNode else this private fun > T.mergeIncomingFlow( + // This flag should be set true if we're changing flow branches from one to another (e.g. in when, try->catch) updateReceivers: Boolean = false, shouldForkFlow: Boolean = false ): T = this.also { node -> - val previousFlows = if (node.isDead) - node.previousNodes.mapNotNull { runIf(!node.incomingEdges.getValue(it).kind.isBack) { it.flow } } - else - node.previousNodes.mapNotNull { prev -> prev.takeIf { node.incomingEdges.getValue(it).kind.usedInDfa }?.flow } + val previousFlows = mutableListOf() + var deadForwardCount = 0 + for (previousNode in previousNodes) { + val incomingEdgeKind = node.incomingEdges.getValue(previousNode).kind + if (node.isDead) { + if (!incomingEdgeKind.isBack) { + previousFlows += previousNode.flow + } + } else if (incomingEdgeKind.usedInDfa) { + previousFlows += previousNode.flow + } + if (incomingEdgeKind == EdgeKind.DeadForward) { + deadForwardCount++ + } + } var flow = logicSystem.joinFlow(previousFlows) - if (updateReceivers) { + // deadForwardCount should be added due to cases like merge after 'if (...) return else ...' + if (updateReceivers || previousFlows.size + deadForwardCount > 1) { logicSystem.updateAllReceivers(flow) } if (shouldForkFlow) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/PersistentLogicSystem.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/PersistentLogicSystem.kt index 567f9226ffa..61aaa618a76 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/PersistentLogicSystem.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/PersistentLogicSystem.kt @@ -138,9 +138,6 @@ abstract class PersistentLogicSystem(context: ConeInferenceContext) : LogicSyste } commonFlow.addVariableAliases(aliasedVariablesThatDontChangeAlias) - - updateAllReceivers(commonFlow) - return commonFlow } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt index 2a81173d62d..d344fd43af6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNode.kt @@ -280,6 +280,27 @@ class PropertyInitializerExitNode(owner: ControlFlowGraph, override val fir: Fir } } +// ----------------------------------- Field ----------------------------------- + +class FieldInitializerEnterNode(owner: ControlFlowGraph, override val fir: FirField, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { + init { + owner.enterNode = this + } + + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitFieldInitializerEnterNode(this, data) + } +} +class FieldInitializerExitNode(owner: ControlFlowGraph, override val fir: FirField, level: Int, id: Int) : CFGNode(owner, level, id), ExitNodeMarker { + init { + owner.exitNode = this + } + + override fun accept(visitor: ControlFlowGraphVisitor, data: D): R { + return visitor.visitFieldInitializerExitNode(this, data) + } +} + // ----------------------------------- Init ----------------------------------- class InitBlockEnterNode(owner: ControlFlowGraph, override val fir: FirAnonymousInitializer, level: Int, id: Int) : CFGNode(owner, level, id), EnterNodeMarker { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt index 9dd65782c22..f73f78bf965 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/CFGNodeRenderer.kt @@ -85,6 +85,8 @@ fun CFGNode<*>.render(): String = is PartOfClassInitializationNode -> "Part of class initialization" is PropertyInitializerEnterNode -> "Enter property" is PropertyInitializerExitNode -> "Exit property" + is FieldInitializerEnterNode -> "Enter field" + is FieldInitializerExitNode -> "Exit field" is InitBlockEnterNode -> "Enter init block" is InitBlockExitNode -> "Exit init block" is AnnotationEnterNode -> "Enter annotation" diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt index 7d21f20d2de..699fcbefd99 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraph.kt @@ -80,6 +80,7 @@ class ControlFlowGraph(val declaration: FirDeclaration?, val name: String, val k AnonymousFunction(withBody = true), ClassInitializer(withBody = true), PropertyInitializer(withBody = true), + FieldInitializer(withBody = true), TopLevel(withBody = false), AnnotationCall(withBody = true), DefaultArgument(withBody = false), diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt index 3a3e2ac5653..f9b62f6427b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt @@ -58,7 +58,7 @@ class ControlFlowGraphBuilder { private val shouldPassFlowFromInplaceLambda: Stack = stackOf(true) private enum class Mode { - Function, TopLevel, Body, ClassInitializer, PropertyInitializer + Function, TopLevel, Body, ClassInitializer, PropertyInitializer, FieldInitializer } // ----------------------------------- Node caches ----------------------------------- @@ -133,7 +133,6 @@ class ControlFlowGraphBuilder { fun CFGNode<*>.extractArgument(): FirElement? = when (this) { is FunctionEnterNode, is TryMainBlockEnterNode, is CatchClauseEnterNode -> null - is ExitSafeCallNode -> lastPreviousNode.extractArgument() is StubNode, is BlockExitNode -> firstPreviousNode.extractArgument() else -> fir.extractArgument() } @@ -523,6 +522,35 @@ class ControlFlowGraphBuilder { return exitNode to graph } + // ----------------------------------- Field ----------------------------------- + + fun enterField(field: FirField): FieldInitializerEnterNode? { + if (field.initializer == null) return null + + val graph = ControlFlowGraph(field, "val ${field.name}", ControlFlowGraph.Kind.FieldInitializer) + pushGraph(graph, Mode.FieldInitializer) + + val enterNode = createFieldInitializerEnterNode(field) + val exitNode = createFieldInitializerExitNode(field) + exitTargetsForTry.push(exitNode) + + enterToLocalClassesMembers[field.symbol]?.let { + addEdge(it, enterNode, preferredKind = EdgeKind.DfgForward) + } + + lastNodes.push(enterNode) + return enterNode + } + + fun exitField(field: FirField): Pair? { + if (field.initializer == null) return null + val exitNode = exitTargetsForTry.pop() as FieldInitializerExitNode + popAndAddEdge(exitNode) + val graph = popGraph() + assert(exitNode == graph.exitNode) + return exitNode to graph + } + // ----------------------------------- Delegate ----------------------------------- fun enterDelegateExpression() { @@ -1090,8 +1118,9 @@ class ControlFlowGraphBuilder { * lastNode -> exitNode * instead of * lastNode -> enterNode -> exitNode - * because of we need to fork flow on `enterNode`, so `exitNode` + * because we need to fork flow before `enterNode`, so `exitNode` * will have unchanged flow from `lastNode` + * which corresponds to a path with nullable receiver. */ val lastNode = lastNodes.pop() val enterNode = createEnterSafeCallNode(safeCall) @@ -1104,6 +1133,12 @@ class ControlFlowGraphBuilder { } fun exitSafeCall(): ExitSafeCallNode { + // There will be two paths towards this exit safe call node: + // one from the node prior to the enclosing safe call, and + // the other from the selector part in the enclosing safe call. + // Note that *neither* points to the safe call directly. + // So, when it comes to the real exit of the enclosing block/function, + // the safe call bound to this exit safe call node should be retrieved. return exitSafeCallNodes.pop().also { addNewSimpleNode(it) it.updateDeadStatus() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt index 2d8a69826d3..551984f9e0c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphNodeBuilder.kt @@ -58,6 +58,12 @@ fun ControlFlowGraphBuilder.createPropertyInitializerExitNode(fir: FirProperty): fun ControlFlowGraphBuilder.createPropertyInitializerEnterNode(fir: FirProperty): PropertyInitializerEnterNode = PropertyInitializerEnterNode(currentGraph, fir, levelCounter, createId()) +fun ControlFlowGraphBuilder.createFieldInitializerExitNode(fir: FirField): FieldInitializerExitNode = + FieldInitializerExitNode(currentGraph, fir, levelCounter, createId()) + +fun ControlFlowGraphBuilder.createFieldInitializerEnterNode(fir: FirField): FieldInitializerEnterNode = + FieldInitializerEnterNode(currentGraph, fir, levelCounter, createId()) + fun ControlFlowGraphBuilder.createFunctionEnterNode(fir: FirFunction<*>): FunctionEnterNode = FunctionEnterNode(currentGraph, fir, levelCounter, createId()).also { currentGraph.enterNode = it diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt index cb5fc522cc6..a8c9d98eafe 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphVisitor.kt @@ -80,6 +80,16 @@ abstract class ControlFlowGraphVisitor { return visitNode(node, data) } + // ----------------------------------- Field ----------------------------------- + + open fun visitFieldInitializerEnterNode(node: FieldInitializerEnterNode, data: D): R { + return visitNode(node, data) + } + + open fun visitFieldInitializerExitNode(node: FieldInitializerExitNode, data: D): R { + return visitNode(node, data) + } + // ----------------------------------- Init ----------------------------------- open fun visitInitBlockEnterNode(node: InitBlockEnterNode, data: D): R { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt index 8555107a894..34cb331bcf6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/diagnostics/FirDiagnostics.kt @@ -38,20 +38,11 @@ class ConeHiddenCandidateError( override val reason: String get() = "HIDDEN: ${describeSymbol(candidateSymbol)} is invisible" } -class ConeInapplicableCandidateError private constructor( +class ConeInapplicableCandidateError( val applicability: CandidateApplicability, - val candidateSymbol: AbstractFirBasedSymbol<*>, - val diagnostics: List, - val errors: List + val candidate: Candidate, ) : ConeDiagnostic() { - constructor(applicability: CandidateApplicability, candidate: Candidate) : this( - applicability, - candidate.symbol, - candidate.diagnostics, - candidate.system.errors - ) - - override val reason: String get() = "Inapplicable($applicability): ${describeSymbol(candidateSymbol)}" + override val reason: String get() = "Inapplicable($applicability): ${describeSymbol(candidate.symbol)}" } class ConeAmbiguityError(val name: Name, val applicability: CandidateApplicability, val candidates: Collection>) : ConeDiagnostic() { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt index 5bba7ca49e6..1e5395e994e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/PostponedArgumentsAnalyzer.kt @@ -168,14 +168,14 @@ class PostponedArgumentsAnalyzer( val lastExpression = lambda.atom.body?.statements?.lastOrNull() as? FirExpression var hasExpressionInReturnArguments = false // No constraint for return expressions of lambda if it has Unit return type. - val lambdaReturnType = lambda.returnType.let(substitute).takeUnless { it.isUnit } + val lambdaReturnType = lambda.returnType.let(substitute).takeUnless { it.isUnitOrFlexibleUnit } returnArguments.forEach { if (it !is FirExpression) return@forEach hasExpressionInReturnArguments = true // If it is the last expression, and the expected type is Unit, that expression will be coerced to Unit. // If the last expression is of Unit type, of course it's not coercion-to-Unit case. val lastExpressionCoercedToUnit = - it == lastExpression && expectedReturnType?.isUnit == true && !it.typeRef.coneType.isUnit + it == lastExpression && expectedReturnType?.isUnitOrFlexibleUnit == true && !it.typeRef.coneType.isUnitOrFlexibleUnit // No constraint for the last expression of lambda if it will be coerced to Unit. if (!lastExpressionCoercedToUnit) { candidate.resolveArgumentExpression( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirDependenciesSymbolProviderImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirDependenciesSymbolProviderImpl.kt index 833837538fb..e8a75128e7b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirDependenciesSymbolProviderImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirDependenciesSymbolProviderImpl.kt @@ -9,7 +9,7 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.ThreadSafeMutableState import org.jetbrains.kotlin.fir.caches.* import org.jetbrains.kotlin.fir.dependenciesWithoutSelf -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals import org.jetbrains.kotlin.fir.symbols.CallableId @@ -34,7 +34,7 @@ open class FirDependenciesSymbolProviderImpl(session: FirSession) : FirSymbolPro protected open val dependencyProviders by lazy { val moduleInfo = session.moduleInfo ?: return@lazy emptyList() moduleInfo.dependenciesWithoutSelf().mapNotNull { - session.sessionProvider?.getSession(it)?.firSymbolProvider + session.sessionProvider?.getSession(it)?.symbolProvider }.toList() } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirQualifierResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirQualifierResolverImpl.kt index 4c2fb7a4e2f..747080b6ad7 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirQualifierResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirQualifierResolverImpl.kt @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.providers.impl import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.NoMutableState import org.jetbrains.kotlin.fir.resolve.FirQualifierResolver -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.types.FirQualifierPart import org.jetbrains.kotlin.name.ClassId @@ -18,7 +18,7 @@ import org.jetbrains.kotlin.name.FqName class FirQualifierResolverImpl(val session: FirSession) : FirQualifierResolver() { override fun resolveSymbolWithPrefix(parts: List, prefix: ClassId): FirClassifierSymbol<*>? { - val symbolProvider = session.firSymbolProvider + val symbolProvider = session.symbolProvider val fqName = ClassId( prefix.packageFqName, @@ -29,7 +29,7 @@ class FirQualifierResolverImpl(val session: FirSession) : FirQualifierResolver() } override fun resolveSymbol(parts: List): FirClassifierSymbol<*>? { - val firProvider = session.firSymbolProvider + val firProvider = session.symbolProvider if (parts.isNotEmpty()) { val lastPart = mutableListOf() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt index 232e6ec133c..3f87e66f80b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt @@ -30,7 +30,7 @@ import org.jetbrains.kotlin.name.ClassId class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { private val symbolProvider by lazy { - session.firSymbolProvider + session.symbolProvider } private data class ClassIdInSession(val session: FirSession, val id: ClassId) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirImportResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirImportResolveTransformer.kt index 35793c30fad..cc0e15fd84a 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirImportResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirImportResolveTransformer.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.builder.buildResolvedImport import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.compose @@ -34,7 +34,7 @@ open class FirImportResolveTransformer protected constructor( constructor(session: FirSession) : this(session, FirResolvePhase.IMPORTS) - private val symbolProvider: FirSymbolProvider = session.firSymbolProvider + private val symbolProvider: FirSymbolProvider = session.symbolProvider override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult { checkSessionConsistency(file) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirLegacySealedClassInheritorsTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirLegacySealedClassInheritorsTransformer.kt new file mode 100644 index 00000000000..bc813056e6d --- /dev/null +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirLegacySealedClassInheritorsTransformer.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.resolve.transformers + +import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.declarations.FirDeclaration +import org.jetbrains.kotlin.fir.declarations.FirFile +import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult +import org.jetbrains.kotlin.fir.visitors.FirTransformer +import org.jetbrains.kotlin.fir.visitors.compose +import org.jetbrains.kotlin.name.ClassId + +/* + * This processor is needed only for IDE until there won't be proper IDE implementation + * for detecting sealed inheritors in multiple files + */ +class FirLegacySealedClassInheritorsProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) { + override val transformer = FirLegacySealedClassInheritorsTransformer() +} + +class FirLegacySealedClassInheritorsTransformer : FirTransformer() { + override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { + throw IllegalStateException("Should not be there") + } + + override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult { + val sealedClassInheritorsMap = mutableMapOf>() + file.accept(FirSealedClassInheritorsProcessor.InheritorsCollector, sealedClassInheritorsMap) + if (sealedClassInheritorsMap.isEmpty()) return file.compose() + return file.transform(FirSealedClassInheritorsProcessor.InheritorsTransformer(sealedClassInheritorsMap), null) + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirResolveProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirResolveProcessor.kt index 8778c428a0c..b24c5a4e1ed 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirResolveProcessor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirResolveProcessor.kt @@ -16,7 +16,7 @@ annotation class AdapterForResolveProcessor sealed class FirResolveProcessor(val session: FirSession, val scopeSession: ScopeSession) abstract class FirGlobalResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirResolveProcessor(session, scopeSession) { - abstract fun process() + abstract fun process(files: Collection) } abstract class FirTransformerBasedResolveProcessor( @@ -28,4 +28,4 @@ abstract class FirTransformerBasedResolveProcessor( fun processFile(file: FirFile) { file.transform(transformer, null) } -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSealedClassInheritorsTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSealedClassInheritorsProcessor.kt similarity index 69% rename from compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSealedClassInheritorsTransformer.kt rename to compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSealedClassInheritorsProcessor.kt index c5296dd5079..2254c96a831 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSealedClassInheritorsTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSealedClassInheritorsProcessor.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * 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. */ @@ -11,38 +11,69 @@ import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider -import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider +import org.jetbrains.kotlin.fir.resolve.firProvider import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag +import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol import org.jetbrains.kotlin.fir.types.ConeLookupTagBasedType import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.coneType -import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult -import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor -import org.jetbrains.kotlin.fir.visitors.FirTransformer -import org.jetbrains.kotlin.fir.visitors.compose +import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.name.ClassId -class FirSealedClassInheritorsProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) { - override val transformer = FirSealedClassInheritorsTransformer() -} - -class FirSealedClassInheritorsTransformer : FirTransformer() { - override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { - throw IllegalStateException("Should not be there") - } - - override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult { +class FirSealedClassInheritorsProcessor( + session: FirSession, + scopeSession: ScopeSession +) : FirGlobalResolveProcessor(session, scopeSession) { + override fun process(files: Collection) { val sealedClassInheritorsMap = mutableMapOf>() - file.accept(InheritorsCollector, sealedClassInheritorsMap) - if (sealedClassInheritorsMap.isEmpty()) return file.compose() - return file.transform(InheritorsTransformer(sealedClassInheritorsMap), null) + files.forEach { it.accept(InheritorsCollector, sealedClassInheritorsMap) } + files.forEach { it.transformSingle(InheritorsTransformer(sealedClassInheritorsMap), null) } } - private class InheritorsTransformer(private val inheritorsMap: MutableMap>) : FirTransformer() { + object InheritorsCollector : FirDefaultVisitor>>() { + override fun visitElement(element: FirElement, data: MutableMap>) {} + + override fun visitFile(file: FirFile, data: MutableMap>) { + file.declarations.forEach { it.accept(this, data) } + } + + override fun visitRegularClass(regularClass: FirRegularClass, data: MutableMap>) { + regularClass.declarations.forEach { it.accept(this, data) } + + if (regularClass.modality == Modality.SEALED) { + data.computeIfAbsent(regularClass) { mutableListOf() } + } + + val symbolProvider = regularClass.session.symbolProvider + + for (typeRef in regularClass.superTypeRefs) { + val parent = extractClassFromTypeRef(symbolProvider, typeRef).takeIf { it?.modality == Modality.SEALED } ?: continue + // Inheritors of sealed class are allowed only in same package + if (parent.classId.packageFqName != regularClass.classId.packageFqName) continue + val inheritors = data.computeIfAbsent(parent) { mutableListOf() } + inheritors += regularClass.symbol.classId + } + } + + private fun extractClassFromTypeRef(symbolProvider: FirSymbolProvider, typeRef: FirTypeRef): FirRegularClass? { + val lookupTag = (typeRef.coneType as? ConeLookupTagBasedType)?.lookupTag ?: return null + val classLikeSymbol: FirClassifierSymbol<*> = symbolProvider.getSymbolByLookupTag(lookupTag) ?: return null + return when (classLikeSymbol) { + is FirRegularClassSymbol -> classLikeSymbol.fir + is FirTypeAliasSymbol -> { + classLikeSymbol.ensureResolved(FirResolvePhase.SUPER_TYPES, symbolProvider.session) + extractClassFromTypeRef(symbolProvider, classLikeSymbol.fir.expandedTypeRef) + } + else -> null + } + } + } + + class InheritorsTransformer(private val inheritorsMap: MutableMap>) : FirTransformer() { override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { return element.compose() } @@ -63,44 +94,4 @@ class FirSealedClassInheritorsTransformer : FirTransformer() { } } - private object InheritorsCollector : FirDefaultVisitor>>() { - override fun visitElement(element: FirElement, data: MutableMap>) {} - - override fun visitFile(file: FirFile, data: MutableMap>) { - file.declarations.forEach { it.accept(this, data) } - } - - override fun visitRegularClass(regularClass: FirRegularClass, data: MutableMap>) { - regularClass.declarations.forEach { it.accept(this, data) } - - if (regularClass.modality == Modality.SEALED) { - data.computeIfAbsent(regularClass) { mutableListOf() } - } - - val symbolProvider = regularClass.session.firSymbolProvider - - for (typeRef in regularClass.superTypeRefs) { - val parent = extractClassFromTypeRef(symbolProvider, typeRef).takeIf { it?.modality == Modality.SEALED } ?: continue - val inheritors = data.computeIfAbsent(parent) { mutableListOf() } - inheritors += regularClass.symbol.classId - } - } - - private fun extractClassFromTypeRef(symbolProvider: FirSymbolProvider, typeRef: FirTypeRef): FirRegularClass? { - val lookupTag = (typeRef.coneType as? ConeLookupTagBasedType)?.lookupTag ?: return null - val classLikeSymbol: FirClassifierSymbol<*> = symbolProvider.getSymbolByLookupTag(lookupTag) ?: return null - return when (classLikeSymbol) { - is FirRegularClassSymbol -> classLikeSymbol.fir - is FirTypeAliasSymbol -> { - classLikeSymbol.ensureResolved(FirResolvePhase.SUPER_TYPES, symbolProvider.session) - extractClassFromTypeRef(symbolProvider, classLikeSymbol.fir.expandedTypeRef) - } - else -> null - } - } - } } - -object SealedClassInheritorsKey : FirDeclarationDataKey() - -var FirRegularClass.sealedInheritors: List? by FirDeclarationDataRegistry.data(SealedClassInheritorsKey) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt index 08ba47d5a25..462d29f5f04 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirStatusResolveTransformer.kt @@ -11,9 +11,8 @@ import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirStatement import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.dfa.symbol import org.jetbrains.kotlin.fir.resolve.firProvider -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.LocalClassesNavigationInfo import org.jetbrains.kotlin.fir.scopes.FirCompositeScope import org.jetbrains.kotlin.fir.scopes.FirScope @@ -224,7 +223,7 @@ abstract class AbstractFirStatusResolveTransformer( protected val containingClass: FirClass<*>? get() = classes.lastOrNull() private val firProvider = session.firProvider - private val symbolProvider = session.firSymbolProvider + private val symbolProvider = session.symbolProvider protected abstract fun FirDeclaration.needResolveMembers(): Boolean protected abstract fun FirDeclaration.needResolveNestedClassifiers(): Boolean diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt index 17ec0cd3524..a385324ff3b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTotalResolveProcessor.kt @@ -24,7 +24,7 @@ class FirTotalResolveProcessor(session: FirSession) { } } is FirGlobalResolveProcessor -> { - processor.process() + processor.process(files) } } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index 426637818ff..64bbe27c43f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -19,7 +19,10 @@ import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.compose -class FirTypeResolveProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) { +class FirTypeResolveProcessor( + session: FirSession, + scopeSession: ScopeSession +) : FirTransformerBasedResolveProcessor(session, scopeSession) { override val transformer = FirTypeResolveTransformer(session, scopeSession) } @@ -116,6 +119,14 @@ class FirTypeResolveTransformer( } } + override fun transformField(field: FirField, data: Nothing?): CompositeTransformResult { + return withScopeCleanup { + field.replaceResolvePhase(FirResolvePhase.TYPES) + field.transformReturnTypeRef(this, data).transformAnnotations(this, data) + field.compose() + } + } + override fun transformSimpleFunction(simpleFunction: FirSimpleFunction, data: Nothing?): CompositeTransformResult { return withScopeCleanup { simpleFunction.addTypeParametersScope() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt index f9097aa2c3d..238d60a951c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirWhenExhaustivenessTransformer.kt @@ -8,229 +8,316 @@ package org.jetbrains.kotlin.fir.resolve.transformers import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirElement +import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.expressions.LogicOperationKind.OR import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition -import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents -import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag -import org.jetbrains.kotlin.fir.resolve.toSymbol -import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag +import org.jetbrains.kotlin.fir.resolve.fullyExpandedType +import org.jetbrains.kotlin.fir.resolve.symbolProvider +import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol +import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.fir.visitors.* -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.utils.addToStdlib.runIf +import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult +import org.jetbrains.kotlin.fir.visitors.FirTransformer +import org.jetbrains.kotlin.fir.visitors.FirVisitor +import org.jetbrains.kotlin.fir.visitors.compose class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyResolveComponents) : FirTransformer() { + companion object { + private val exhaustivenessCheckers = listOf( + WhenOnBooleanExhaustivenessChecker, + WhenOnEnumExhaustivenessChecker, + WhenOnSealedClassExhaustivenessChecker + ) + } + override fun transformElement(element: E, data: Nothing?): CompositeTransformResult { throw IllegalArgumentException("Should not be there") } override fun transformWhenExpression(whenExpression: FirWhenExpression, data: Nothing?): CompositeTransformResult { - val resultExpression = processExhaustivenessCheck(whenExpression) ?: whenExpression - return resultExpression.compose() + processExhaustivenessCheck(whenExpression) + return whenExpression.compose() } - private fun processExhaustivenessCheck(whenExpression: FirWhenExpression): FirWhenExpression? { + @OptIn(ExperimentalStdlibApi::class) + private fun processExhaustivenessCheck(whenExpression: FirWhenExpression) { if (whenExpression.branches.any { it.condition is FirElseIfTrueCondition }) { - whenExpression.replaceIsExhaustive(true) - return whenExpression + whenExpression.replaceExhaustivenessStatus(ExhaustivenessStatus.Exhaustive) + return } - val typeRef = whenExpression.subjectVariable?.returnTypeRef - ?: whenExpression.subject?.typeRef - ?: return null - - // TODO: add some report logic about flexible type (see WHEN_ENUM_CAN_BE_NULL_IN_JAVA diagnostic in old frontend) - val type = typeRef.coneType.lowerBoundIfFlexible() - val lookupTag = (type as? ConeLookupTagBasedType)?.lookupTag ?: return null - val nullable = type.nullability == ConeNullability.NULLABLE - val isExhaustive = when { - ((lookupTag as? ConeClassLikeLookupTag)?.classId == bodyResolveComponents.session.builtinTypes.booleanType.id) -> { - checkBooleanExhaustiveness(whenExpression, nullable) - } - - whenExpression.branches.isEmpty() -> false - - else -> { - val klass = lookupTag.toSymbol(bodyResolveComponents.session)?.fir as? FirRegularClass ?: return null - when { - klass.classKind == ClassKind.ENUM_CLASS -> checkEnumExhaustiveness(whenExpression, klass, nullable) - klass.modality == Modality.SEALED -> checkSealedClassExhaustiveness(whenExpression, klass, nullable) - else -> return null - } - } - } - - return runIf(isExhaustive) { - whenExpression.replaceIsExhaustive(true) - whenExpression - } - } - - // ------------------------ Enum exhaustiveness ------------------------ - - private fun checkEnumExhaustiveness(whenExpression: FirWhenExpression, enum: FirRegularClass, nullable: Boolean): Boolean { - val data = EnumExhaustivenessData( - enum.collectEnumEntries().map { it.symbol }.toMutableSet(), - !nullable - ) - for (branch in whenExpression.branches) { - branch.condition.accept(EnumExhaustivenessVisitor, data) - } - return data.containsNull && data.remainingEntries.isEmpty() - } - - private class EnumExhaustivenessData(val remainingEntries: MutableSet>, var containsNull: Boolean) - - private object EnumExhaustivenessVisitor : FirVisitor() { - override fun visitElement(element: FirElement, data: EnumExhaustivenessData) {} - - override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: EnumExhaustivenessData) { - if (equalityOperatorCall.operation.let { it == FirOperation.EQ || it == FirOperation.IDENTITY }) { - when (val argument = equalityOperatorCall.arguments[1]) { - is FirConstExpression<*> -> { - if (argument.value == null) { - data.containsNull = true - } - } - is FirQualifiedAccessExpression -> { - val reference = argument.calleeReference as? FirResolvedNamedReference ?: return - val symbol = (reference.resolvedSymbol.fir as? FirEnumEntry)?.symbol ?: return - - data.remainingEntries.remove(symbol) - } - } - } - } - - override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: EnumExhaustivenessData) { - if (binaryLogicExpression.kind == LogicOperationKind.OR) { - binaryLogicExpression.acceptChildren(this, data) - } - } - } - - // ------------------------ Sealed class exhaustiveness ------------------------ - - private fun checkSealedClassExhaustiveness( - whenExpression: FirWhenExpression, - sealedClass: FirRegularClass, - nullable: Boolean - ): Boolean { - if (sealedClass.sealedInheritors.isNullOrEmpty()) return true - - val data = SealedExhaustivenessData(sealedClass, !nullable) - for (branch in whenExpression.branches) { - branch.condition.accept(SealedExhaustivenessVisitor, data) - } - return data.isExhaustive() - } - - private inner class SealedExhaustivenessData(regularClass: FirRegularClass, var containsNull: Boolean) { - val symbolProvider = bodyResolveComponents.symbolProvider - private val rootNode = SealedClassInheritors(regularClass.classId, regularClass.sealedInheritors.mapToSealedInheritors()) - - private fun List?.mapToSealedInheritors(): MutableSet? { - if (this.isNullOrEmpty()) return null - - return this.mapNotNull { - val inheritor = symbolProvider.getClassLikeSymbolByFqName(it)?.fir as? FirRegularClass ?: return@mapNotNull null - SealedClassInheritors(inheritor.classId, inheritor.sealedInheritors.mapToSealedInheritors()) - }.takeIf { it.isNotEmpty() }?.toMutableSet() - } - - fun removeInheritor(classId: ClassId) { - if (rootNode.classId == classId) { - rootNode.inheritors?.clear() + val subjectType = whenExpression.subjectVariable?.returnTypeRef?.coneType + ?: whenExpression.subject?.typeRef?.coneType + ?: run { + whenExpression.replaceExhaustivenessStatus(ExhaustivenessStatus.NotExhaustive.NO_ELSE_BRANCH) return } - rootNode.removeInheritor(classId) - } + val session = bodyResolveComponents.session + val cleanSubjectType = subjectType.fullyExpandedType(session).lowerBoundIfFlexible() - fun isExhaustive() = containsNull && rootNode.isEmpty() - } - - private data class SealedClassInheritors(val classId: ClassId, val inheritors: MutableSet? = null) { - fun removeInheritor(classId: ClassId): Boolean { - return inheritors != null && (inheritors.removeIf { it.classId == classId } || inheritors.any { it.removeInheritor(classId) }) - } - - fun isEmpty(): Boolean { - return inheritors != null && inheritors.all { it.isEmpty() } - } - } - - private object SealedExhaustivenessVisitor : FirDefaultVisitor() { - override fun visitElement(element: FirElement, data: SealedExhaustivenessData) {} - - override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: SealedExhaustivenessData) { - if (typeOperatorCall.operation == FirOperation.IS) { - typeOperatorCall.conversionTypeRef.accept(this, data) + val checkers = buildList { + exhaustivenessCheckers.filterTo(this) { it.isApplicable(cleanSubjectType, session) } + if (isNotEmpty() && cleanSubjectType.isMarkedNullable) { + add(WhenOnNullableExhaustivenessChecker) } } - override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: SealedExhaustivenessData) { - if (equalityOperatorCall.operation.let { it == FirOperation.EQ || it == FirOperation.IDENTITY }) { - when (val argument = equalityOperatorCall.arguments[1]) { - is FirConstExpression<*> -> { - if (argument.value == null) { - data.containsNull = true - } - } - - is FirResolvedQualifier -> { - argument.typeRef.accept(this, data) - } - } - } + if (checkers.isEmpty()) { + whenExpression.replaceExhaustivenessStatus(ExhaustivenessStatus.NotExhaustive.NO_ELSE_BRANCH) + return + } + val whenMissingCases = mutableListOf() + for (checker in checkers) { + checker.computeMissingCases(whenExpression, cleanSubjectType, session, whenMissingCases) + } + if (whenMissingCases.isEmpty() && whenExpression.branches.isEmpty()) { + whenMissingCases.add(WhenMissingCase.Unknown) } - override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: SealedExhaustivenessData) { - val lookupTag = (resolvedTypeRef.type as? ConeLookupTagBasedType)?.lookupTag ?: return - val symbol = data.symbolProvider.getSymbolByLookupTag(lookupTag) as? FirClassSymbol ?: return - data.removeInheritor(symbol.classId) + val status = if (whenMissingCases.isEmpty()) { + ExhaustivenessStatus.Exhaustive + } else { + ExhaustivenessStatus.NotExhaustive(whenMissingCases) + } + whenExpression.replaceExhaustivenessStatus(status) + } +} + +private sealed class WhenExhaustivenessChecker { + abstract fun isApplicable(subjectType: ConeKotlinType, session: FirSession): Boolean + abstract fun computeMissingCases( + whenExpression: FirWhenExpression, + subjectType: ConeKotlinType, + session: FirSession, + destination: MutableCollection + ) + + protected abstract class AbstractConditionChecker : FirVisitor() { + override fun visitElement(element: FirElement, data: D) {} + + override fun visitWhenExpression(whenExpression: FirWhenExpression, data: D) { + whenExpression.branches.forEach { it.accept(this, data) } } - override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: SealedExhaustivenessData) { - if (binaryLogicExpression.kind == LogicOperationKind.OR) { + override fun visitWhenBranch(whenBranch: FirWhenBranch, data: D) { + whenBranch.condition.accept(this, data) + } + + override fun visitBinaryLogicExpression(binaryLogicExpression: FirBinaryLogicExpression, data: D) { + if (binaryLogicExpression.kind == OR) { binaryLogicExpression.acceptChildren(this, data) } } } +} - // ------------------------ Boolean exhaustiveness ------------------------ - - private fun checkBooleanExhaustiveness(whenExpression: FirWhenExpression, nullable: Boolean): Boolean { - val flags = BooleanExhaustivenessFlags(!nullable) - for (branch in whenExpression.branches) { - branch.condition.accept(BooleanExhaustivenessVisitor, flags) - } - return flags.containsTrue && flags.containsFalse && flags.containsNull +private object WhenOnNullableExhaustivenessChecker : WhenExhaustivenessChecker() { + override fun isApplicable(subjectType: ConeKotlinType, session: FirSession): Boolean { + return subjectType.isNullable } - private class BooleanExhaustivenessFlags(var containsNull: Boolean) { + override fun computeMissingCases( + whenExpression: FirWhenExpression, + subjectType: ConeKotlinType, + session: FirSession, + destination: MutableCollection + ) { + val flags = Flags() + whenExpression.accept(ConditionChecker, flags) + if (!flags.containsNull) { + destination.add(WhenMissingCase.NullIsMissing) + } + } + + private class Flags { + var containsNull = false + } + + private object ConditionChecker : AbstractConditionChecker() { + override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: Flags) { + val argument = equalityOperatorCall.arguments[1] + if (argument.typeRef.isNullableNothing) { + data.containsNull = true + } + } + + override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Flags) { + if (typeOperatorCall.conversionTypeRef.coneType.isNullable) { + data.containsNull = true + } + } + } +} + +private object WhenOnBooleanExhaustivenessChecker : WhenExhaustivenessChecker() { + override fun isApplicable(subjectType: ConeKotlinType, session: FirSession): Boolean { + return subjectType.classId == StandardClassIds.Boolean + } + + private class Flags { var containsTrue = false var containsFalse = false } - private object BooleanExhaustivenessVisitor : FirVisitor() { - override fun visitElement(element: FirElement, data: BooleanExhaustivenessFlags) {} + override fun computeMissingCases( + whenExpression: FirWhenExpression, + subjectType: ConeKotlinType, + session: FirSession, + destination: MutableCollection + ) { + val flags = Flags() + whenExpression.accept(ConditionChecker, flags) + if (!flags.containsFalse) { + destination.add(WhenMissingCase.BooleanIsMissing.False) + } + if (!flags.containsTrue) { + destination.add(WhenMissingCase.BooleanIsMissing.True) + } + } - override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: BooleanExhaustivenessFlags) { + private object ConditionChecker : AbstractConditionChecker() { + override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: Flags) { if (equalityOperatorCall.operation.let { it == FirOperation.EQ || it == FirOperation.IDENTITY }) { val argument = equalityOperatorCall.arguments[1] if (argument is FirConstExpression<*>) { when (argument.value) { true -> data.containsTrue = true false -> data.containsFalse = true - null -> data.containsNull = true } } } } } } + +private object WhenOnEnumExhaustivenessChecker : WhenExhaustivenessChecker() { + override fun isApplicable(subjectType: ConeKotlinType, session: FirSession): Boolean { + val symbol = subjectType.toSymbol(session) as? FirRegularClassSymbol ?: return false + return symbol.fir.classKind == ClassKind.ENUM_CLASS + } + + override fun computeMissingCases( + whenExpression: FirWhenExpression, + subjectType: ConeKotlinType, + session: FirSession, + destination: MutableCollection + ) { + val enumClass = (subjectType.toSymbol(session) as FirRegularClassSymbol).fir + val allEntries = enumClass.declarations.mapNotNullTo(mutableSetOf()) { it as? FirEnumEntry } + val checkedEntries = mutableSetOf() + whenExpression.accept(ConditionChecker, checkedEntries) + val notCheckedEntries = allEntries - checkedEntries + notCheckedEntries.mapTo(destination) { WhenMissingCase.EnumCheckIsMissing(it.symbol.callableId) } + } + + private object ConditionChecker : AbstractConditionChecker>() { + override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: MutableSet) { + if (!equalityOperatorCall.operation.let { it == FirOperation.EQ || it == FirOperation.IDENTITY }) return + val argument = equalityOperatorCall.arguments[1] + val symbol = argument.toResolvedCallableReference()?.resolvedSymbol as? FirVariableSymbol<*> ?: return + val checkedEnumEntry = symbol.fir as? FirEnumEntry ?: return + data.add(checkedEnumEntry) + } + } +} + +private object WhenOnSealedClassExhaustivenessChecker : WhenExhaustivenessChecker() { + override fun isApplicable(subjectType: ConeKotlinType, session: FirSession): Boolean { + return (subjectType.toSymbol(session)?.fir as? FirRegularClass)?.modality == Modality.SEALED + } + + override fun computeMissingCases( + whenExpression: FirWhenExpression, + subjectType: ConeKotlinType, + session: FirSession, + destination: MutableCollection + ) { + val allSubclasses = subjectType.toSymbol(session)?.collectAllSubclasses(session) ?: return + val checkedSubclasses = mutableSetOf>() + whenExpression.accept(ConditionChecker, Flags(allSubclasses, checkedSubclasses, session)) + (allSubclasses - checkedSubclasses).mapNotNullTo(destination) { + when (it) { + is FirClassSymbol<*> -> WhenMissingCase.IsTypeCheckIsMissing(it.classId, it.fir.classKind.isSingleton) + is FirVariableSymbol<*> -> WhenMissingCase.EnumCheckIsMissing(it.callableId) + else -> null + } + } + } + + private class Flags( + val allSubclasses: Set>, + val checkedSubclasses: MutableSet>, + val session: FirSession + ) + + private object ConditionChecker : AbstractConditionChecker() { + override fun visitEqualityOperatorCall(equalityOperatorCall: FirEqualityOperatorCall, data: Flags) { + val isNegated = when (equalityOperatorCall.operation) { + FirOperation.EQ, FirOperation.IDENTITY -> false + FirOperation.NOT_EQ, FirOperation.NOT_IDENTITY -> true + else -> return + } + + val symbol = when (val argument = equalityOperatorCall.arguments[1]) { + is FirResolvedQualifier -> { + val firClass = (argument.symbol as? FirRegularClassSymbol)?.fir + if (firClass?.classKind == ClassKind.OBJECT) { + firClass.symbol + } else { + firClass?.companionObject?.symbol + } + } + else -> { + argument.toResolvedCallableSymbol()?.takeIf { it.fir is FirEnumEntry } + } + } ?: return + processBranch(symbol, isNegated, data) + } + + override fun visitTypeOperatorCall(typeOperatorCall: FirTypeOperatorCall, data: Flags) { + val isNegated = when (typeOperatorCall.operation) { + FirOperation.IS -> false + FirOperation.NOT_IS -> true + else -> return + } + val symbol = typeOperatorCall.conversionTypeRef.coneType.fullyExpandedType(data.session).toSymbol(data.session) ?: return + processBranch(symbol, isNegated, data) + } + + private fun processBranch(symbolToCheck: AbstractFirBasedSymbol<*>, isNegated: Boolean, flags: Flags) { + val subclassesOfType = symbolToCheck.collectAllSubclasses(flags.session) + if (subclassesOfType.none { it in flags.allSubclasses }) { + return + } + val checkedSubclasses = if (isNegated) flags.allSubclasses - subclassesOfType else subclassesOfType + flags.checkedSubclasses.addAll(checkedSubclasses) + } + } + + + private fun AbstractFirBasedSymbol<*>.collectAllSubclasses(session: FirSession): Set> { + return mutableSetOf>().apply { collectAllSubclassesTo(this, session) } + } + + private fun AbstractFirBasedSymbol<*>.collectAllSubclassesTo(destination: MutableSet>, session: FirSession) { + if (this !is FirRegularClassSymbol) { + destination.add(this) + return + } + when { + fir.modality == Modality.SEALED -> fir.sealedInheritors?.forEach { + val symbol = session.symbolProvider.getClassLikeSymbolByFqName(it) as? FirRegularClassSymbol + symbol?.collectAllSubclassesTo(destination, session) + } + fir.classKind == ClassKind.ENUM_CLASS -> fir.collectEnumEntries().mapTo(destination) { it.symbol } + else -> destination.add(this) + } + } +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ResolvePhaseUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ResolvePhaseUtils.kt index ab4467a3462..a4e76d1a194 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ResolvePhaseUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/ResolvePhaseUtils.kt @@ -50,7 +50,7 @@ fun FirResolvePhase.createTransformerBasedProcessorByPhase( CLASS_GENERATION -> FirDummyTransformerBasedProcessor(session, scopeSession) // TODO: remove IMPORTS -> FirImportResolveProcessor(session, scopeSession) SUPER_TYPES -> FirSupertypeResolverProcessor(session, scopeSession) - SEALED_CLASS_INHERITORS -> FirSealedClassInheritorsProcessor(session, scopeSession) + SEALED_CLASS_INHERITORS -> FirLegacySealedClassInheritorsProcessor(session, scopeSession) TYPES -> FirTypeResolveProcessor(session, scopeSession) ARGUMENTS_OF_PLUGIN_ANNOTATIONS -> FirAnnotationArgumentsResolveProcessor(session, scopeSession) EXTENSION_STATUS_UPDATE -> FirTransformerBasedExtensionStatusProcessor(session, scopeSession) @@ -74,4 +74,4 @@ private class FirDummyTransformerBasedProcessor( return element.compose() } } -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt index b2d3da6bd55..ece2ccc7434 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveUtils.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.fir.expressions.FirBlock import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirNamedArgumentExpression import org.jetbrains.kotlin.fir.expressions.builder.buildVarargArgumentsExpression -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol import org.jetbrains.kotlin.fir.symbols.StandardClassIds import org.jetbrains.kotlin.fir.types.* @@ -108,7 +108,7 @@ fun FirBlock.writeResultType(session: FirSession) { fun ConstantValueKind<*>.expectedConeType(session: FirSession): ConeKotlinType { fun constructLiteralType(classId: ClassId, isNullable: Boolean = false): ConeKotlinType { - val symbol = session.firSymbolProvider.getClassLikeSymbolByFqName(classId) + val symbol = session.symbolProvider.getClassLikeSymbolByFqName(classId) ?: return ConeClassErrorType(ConeSimpleDiagnostic("Missing stdlib class: $classId", DiagnosticKind.MissingStdlibClass)) return symbol.toLookupTag().constructClassType(emptyArray(), isNullable) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt index a6e34ba1512..401ae73af04 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirAbstractBodyResolveTransformer.kt @@ -127,7 +127,7 @@ abstract class FirAbstractBodyResolveTransformer(phase: FirResolvePhase) : FirAb override val container: FirDeclaration get() = context.containerIfAny!! override val noExpectedType: FirTypeRef = buildImplicitTypeRef() - override val symbolProvider: FirSymbolProvider = session.firSymbolProvider + override val symbolProvider: FirSymbolProvider = session.symbolProvider override val resolutionStageRunner: ResolutionStageRunner = ResolutionStageRunner() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt index d127e062ea9..976f182f23c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt @@ -259,6 +259,10 @@ open class FirBodyResolveTransformer( return declarationsTransformer.transformProperty(property, data) } + override fun transformField(field: FirField, data: ResolutionMode): CompositeTransformResult { + return declarationsTransformer.transformField(field, data) + } + override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): CompositeTransformResult { return declarationsTransformer.transformRegularClass(regularClass, data) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt index 3864150cf6e..57fb8188b3c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.fir.resolve.transformers.body.resolve -import org.jetbrains.kotlin.fir.FirFakeSourceElementKind import org.jetbrains.kotlin.fir.FirTargetElement import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind @@ -18,7 +17,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirSyntheticCallGenerator import org.jetbrains.kotlin.fir.resolve.transformers.FirWhenExhaustivenessTransformer import org.jetbrains.kotlin.fir.resolve.withExpectedType import org.jetbrains.kotlin.fir.resolvedTypeFromPrototype -import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef +import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult import org.jetbrains.kotlin.fir.visitors.compose @@ -228,12 +227,14 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran ): CompositeTransformResult { if (elvisExpression.calleeReference is FirResolvedNamedReference) return elvisExpression.compose() elvisExpression.transformAnnotations(transformer, data) - val expectedArgumentType = - if (data is ResolutionMode.WithExpectedType && data.expectedType !is FirImplicitTypeRef) data - else ResolutionMode.ContextDependent - elvisExpression.transformLhs(transformer, expectedArgumentType) + + val expectedType = data.expectedType?.coneTypeSafe() + val resolutionModeForLhs = withExpectedType(expectedType?.withNullability(ConeNullability.NULLABLE)) + elvisExpression.transformLhs(transformer, resolutionModeForLhs) dataFlowAnalyzer.exitElvisLhs(elvisExpression) - elvisExpression.transformRhs(transformer, expectedArgumentType) + + val resolutionModeForRhs = withExpectedType(expectedType) + elvisExpression.transformRhs(transformer, resolutionModeForRhs) val result = syntheticCallGenerator.generateCalleeForElvisExpression(elvisExpression, resolutionContext)?.let { callCompleter.completeCall(it, data.expectedType).result @@ -243,7 +244,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirBodyResolveTran } } - dataFlowAnalyzer.exitElvis() + dataFlowAnalyzer.exitElvis(elvisExpression) return result.compose() } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 6fc9b4397a9..93905dbcd98 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef +import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult @@ -159,6 +160,36 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor } } + override fun transformField(field: FirField, data: ResolutionMode): CompositeTransformResult { + val returnTypeRef = field.returnTypeRef + if (implicitTypeOnly) return field.compose() + if (field.resolvePhase == transformerPhase) return field.compose() + if (field.resolvePhase == FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE && transformerPhase == FirResolvePhase.BODY_RESOLVE) { + transformer.replaceDeclarationResolvePhaseIfNeeded(field, transformerPhase) + return field.compose() + } + dataFlowAnalyzer.enterField(field) + return withFullBodyResolve { + withLocalScopeCleanup { + val primaryConstructorParametersScope = context.getPrimaryConstructorAllParametersScope() + context.withTowerDataContext(context.getTowerDataContextForConstructorResolution()) { + context.withContainer(field) { + withLocalScopeCleanup { + addLocalScope(primaryConstructorParametersScope) + field.transformChildren(transformer, withExpectedType(returnTypeRef)) + } + if (field.initializer != null) { + storeVariableReturnType(field) + } + } + } + transformer.replaceDeclarationResolvePhaseIfNeeded(field, transformerPhase) + dataFlowAnalyzer.exitField(field) + field.compose() + } + } + } + private fun FirFunctionCall.replacePropertyReferenceTypeInDelegateAccessors(property: FirProperty) { // var someProperty: SomeType // get() = delegate.getValue(thisRef, kProperty: KProperty0/1/2<..., SomeType>) @@ -780,13 +811,28 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor dataFlowAnalyzer, ) lambda.transformSingle(writer, expectedTypeRef.coneTypeSafe()?.toExpectedType()) - val returnTypes = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(lambda) - .mapNotNull { (it as? FirExpression)?.resultType?.coneType } - lambda.replaceReturnTypeRef( - lambda.returnTypeRef.resolvedTypeFromPrototype( - inferenceComponents.ctx.commonSuperTypeOrNull(returnTypes) ?: session.builtinTypes.unitType.type - ) - ) + + val returnStatements = dataFlowAnalyzer.returnExpressionsOfAnonymousFunction(lambda) + val returnExpressionsExceptLast = + if (returnStatements.size > 1) + returnStatements - lambda.body?.statements?.lastOrNull() + else + returnStatements + val implicitReturns = returnExpressionsExceptLast.filter { + (it as? FirExpression)?.typeRef is FirImplicitUnitTypeRef + } + val returnType = + if (implicitReturns.isNotEmpty()) { + // i.e., early return, e.g., l@{ ... return@l ... } + // Note that the last statement will be coerced to Unit if needed. + session.builtinTypes.unitType.type + } else { + // Otherwise, compute the common super type of all possible return expressions + inferenceComponents.ctx.commonSuperTypeOrNull( + returnStatements.mapNotNull { (it as? FirExpression)?.resultType?.coneType } + ) ?: session.builtinTypes.unitType.type + } + lambda.replaceReturnTypeRef(lambda.returnTypeRef.resolvedTypeFromPrototype(returnType)) lambda.replaceTypeRef( lambda.constructFunctionalTypeRef( isSuspend = expectedTypeRef.coneTypeSafe()?.isSuspendFunctionType(session) == true diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformer.kt index 8d459fcd262..695041b861d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/FirContractResolveTransformer.kt @@ -102,6 +102,11 @@ open class FirContractResolveTransformer( return property.compose() } + override fun transformField(field: FirField, data: ResolutionMode): CompositeTransformResult { + field.updatePhase() + return field.compose() + } + private fun transformPropertyAccessor( propertyAccessor: FirPropertyAccessor, owner: FirProperty diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalClassGenerationProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalClassGenerationProcessor.kt index 0d68e6e606b..0c17a548ff3 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalClassGenerationProcessor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalClassGenerationProcessor.kt @@ -20,7 +20,7 @@ class FirGlobalClassGenerationProcessor( session: FirSession, scopeSession: ScopeSession ) : FirGlobalResolveProcessor(session, scopeSession) { - override fun process() { + override fun process(files: Collection) { val extensions = session.extensionService.declarationGenerators if (extensions.isEmpty()) return val provider = session.predicateBasedProvider diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalExtensionStatusProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalExtensionStatusProcessor.kt index 45fb485117e..9305d649427 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalExtensionStatusProcessor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalExtensionStatusProcessor.kt @@ -24,7 +24,7 @@ class FirGlobalExtensionStatusProcessor( session: FirSession, scopeSession: ScopeSession ) : FirGlobalResolveProcessor(session, scopeSession) { - override fun process() { + override fun process(files: Collection) { val extensions = session.extensionService.statusTransformerExtensions if (extensions.isEmpty()) return val provider = session.predicateBasedProvider diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalNewMemberGenerationProcessor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalNewMemberGenerationProcessor.kt index 964d51b927e..24614ebd0b1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalNewMemberGenerationProcessor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirGlobalNewMemberGenerationProcessor.kt @@ -26,7 +26,7 @@ class FirGlobalNewMemberGenerationProcessor( private val index = session.generatedClassIndex private val provider = session.predicateBasedProvider - override fun process() { + override fun process(files: Collection) { val extensions = session.extensionService.declarationGenerators if (extensions.isEmpty()) return for (extension in extensions) { @@ -64,4 +64,4 @@ class FirGlobalNewMemberGenerationProcessor( } } } -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractProviderBasedScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractProviderBasedScope.kt index 34c235f892e..fb4bcc1667b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractProviderBasedScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractProviderBasedScope.kt @@ -6,17 +6,17 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.providers.impl.FirCompositeSymbolProvider import org.jetbrains.kotlin.fir.resolve.providers.impl.FirDependenciesSymbolProviderImpl import org.jetbrains.kotlin.fir.scopes.FirScope abstract class FirAbstractProviderBasedScope(val session: FirSession, lookupInFir: Boolean = true) : FirScope() { - val provider = when (val symbolProvider = session.firSymbolProvider) { + val provider = when (val symbolProvider = session.symbolProvider) { is FirCompositeSymbolProvider -> symbolProvider.takeIf { !lookupInFir }?.providers?.find { it is FirDependenciesSymbolProviderImpl } ?: symbolProvider else -> symbolProvider } -} \ No newline at end of file +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractSimpleImportingScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractSimpleImportingScope.kt index 71dcf49a767..9091f302220 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractSimpleImportingScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirAbstractSimpleImportingScope.kt @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirResolvedImport import org.jetbrains.kotlin.fir.resolve.ScopeSession -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.symbols.impl.FirClassifierSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol @@ -27,7 +27,7 @@ abstract class FirAbstractSimpleImportingScope( override fun processClassifiersByNameWithSubstitution(name: Name, processor: (FirClassifierSymbol<*>, ConeSubstitutor) -> Unit) { val imports = simpleImports[name] ?: return if (imports.isEmpty()) return - val provider = session.firSymbolProvider + val provider = session.symbolProvider for (import in imports) { val importedName = import.importedName ?: continue val classId = diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassDeclaredMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassDeclaredMemberScope.kt index 9d85dfc5f7d..c5ee12605ad 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassDeclaredMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirClassDeclaredMemberScope.kt @@ -34,7 +34,7 @@ class FirClassDeclaredMemberScope( is FirCallableMemberDeclaration<*> -> { val name = when (declaration) { is FirConstructor -> CONSTRUCTOR_NAME - is FirVariable<*> -> declaration.name + is FirVariable<*> -> if (declaration.isSynthetic) continue@loop else declaration.name is FirSimpleFunction -> declaration.name else -> continue@loop } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirPackageMemberScope.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirPackageMemberScope.kt index 6b895a5e9df..b2c72878612 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirPackageMemberScope.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/scopes/impl/FirPackageMemberScope.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.fir.scopes.impl import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.transformers.ensureResolvedForCalls import org.jetbrains.kotlin.fir.scopes.FirScope @@ -16,7 +16,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name class FirPackageMemberScope(val fqName: FqName, val session: FirSession) : FirScope() { - private val symbolProvider = session.firSymbolProvider + private val symbolProvider = session.symbolProvider private val classifierCache: MutableMap?> = mutableMapOf() private val functionCache: MutableMap> = mutableMapOf() private val propertyCache: MutableMap> = mutableMapOf() diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt index eafd1ba2afb..18d9d81ec8b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/ConeInferenceContext.kt @@ -29,7 +29,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeContext { - val symbolProvider: FirSymbolProvider get() = session.firSymbolProvider + val symbolProvider: FirSymbolProvider get() = session.symbolProvider override fun nullableNothingType(): SimpleTypeMarker { return session.builtinTypes.nullableNothingType.type//StandardClassIds.Nothing(symbolProvider).constructType(emptyArray(), true) @@ -472,7 +472,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo val classId = if (isSuspend) StandardNames.getSuspendFunctionClassId(parametersNumber) else StandardNames.getFunctionClassId(parametersNumber) - return session.firSymbolProvider.getClassLikeSymbolByFqName(classId)?.toLookupTag() + return session.symbolProvider.getClassLikeSymbolByFqName(classId)?.toLookupTag() ?: error("Can't find Function type") } @@ -480,7 +480,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo val classId = if (isSuspend) StandardNames.getKSuspendFunctionClassId(parametersNumber) else StandardNames.getKFunctionClassId(parametersNumber) - return session.firSymbolProvider.getClassLikeSymbolByFqName(classId)?.toLookupTag() + return session.symbolProvider.getClassLikeSymbolByFqName(classId)?.toLookupTag() ?: error("Can't find KFunction type") } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index 7b2e341b402..b43f0ee261d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -7,13 +7,12 @@ package org.jetbrains.kotlin.fir.types import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility -import org.jetbrains.kotlin.fir.FirFakeSourceElementKind -import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.classId import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic -import org.jetbrains.kotlin.fir.fakeElement -import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.resolve.fullyExpandedType +import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.ConeClassLookupTagWithFixedSymbol import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef @@ -184,6 +183,10 @@ fun ConeKotlinType.isUnsafeVarianceType(session: FirSession): Boolean { return type.attributes.unsafeVarianceType != null } +fun ConeKotlinType.toSymbol(session: FirSession): AbstractFirBasedSymbol<*>? { + return (this as? ConeLookupTagBasedType)?.lookupTag?.toSymbol(session) +} + fun FirTypeRef.isUnsafeVarianceType(session: FirSession): Boolean { return coneTypeSafe()?.isUnsafeVarianceType(session) == true } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirFieldBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirFieldBuilder.kt index eeec5befdb9..a4e41f30d4e 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirFieldBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirFieldBuilder.kt @@ -43,6 +43,7 @@ open class FirFieldBuilder : FirAnnotationContainerBuilder { open lateinit var returnTypeRef: FirTypeRef open lateinit var name: Name open lateinit var symbol: FirVariableSymbol + open var initializer: FirExpression? = null open var isVar: Boolean by kotlin.properties.Delegates.notNull() override val annotations: MutableList = mutableListOf() open val typeParameters: MutableList = mutableListOf() @@ -60,6 +61,7 @@ open class FirFieldBuilder : FirAnnotationContainerBuilder { returnTypeRef, name, symbol, + initializer, isVar, annotations, typeParameters, diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt index 2ce4ce50aa6..532753588ff 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirFieldImpl.kt @@ -38,6 +38,7 @@ internal class FirFieldImpl( override var returnTypeRef: FirTypeRef, override val name: Name, override val symbol: FirVariableSymbol, + override var initializer: FirExpression?, override val isVar: Boolean, override val annotations: MutableList, override val typeParameters: MutableList, @@ -46,7 +47,6 @@ internal class FirFieldImpl( override val dispatchReceiverType: ConeKotlinType?, ) : FirField() { override val receiverTypeRef: FirTypeRef? get() = null - override val initializer: FirExpression? get() = null override val delegate: FirExpression? get() = null override val delegateFieldSymbol: FirDelegateFieldSymbol? get() = null override val isVal: Boolean get() = !isVar @@ -60,6 +60,7 @@ internal class FirFieldImpl( override fun acceptChildren(visitor: FirVisitor, data: D) { returnTypeRef.accept(visitor, data) + initializer?.accept(visitor, data) annotations.forEach { it.accept(visitor, data) } typeParameters.forEach { it.accept(visitor, data) } status.accept(visitor, data) @@ -67,6 +68,7 @@ internal class FirFieldImpl( override fun transformChildren(transformer: FirTransformer, data: D): FirFieldImpl { transformReturnTypeRef(transformer, data) + transformInitializer(transformer, data) transformTypeParameters(transformer, data) transformStatus(transformer, data) transformOtherChildren(transformer, data) @@ -83,6 +85,7 @@ internal class FirFieldImpl( } override fun transformInitializer(transformer: FirTransformer, data: D): FirFieldImpl { + initializer = initializer?.transformSingle(transformer, data) return this } @@ -128,5 +131,7 @@ internal class FirFieldImpl( override fun replaceReceiverTypeRef(newReceiverTypeRef: FirTypeRef?) {} - override fun replaceInitializer(newInitializer: FirExpression?) {} + override fun replaceInitializer(newInitializer: FirExpression?) { + initializer = newInitializer + } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirWhenExpression.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirWhenExpression.kt index b8f1338dd76..54dcb8c6247 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirWhenExpression.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/FirWhenExpression.kt @@ -24,7 +24,8 @@ abstract class FirWhenExpression : FirExpression(), FirResolvable { abstract val subject: FirExpression? abstract val subjectVariable: FirVariable<*>? abstract val branches: List - abstract val isExhaustive: Boolean + abstract val exhaustivenessStatus: ExhaustivenessStatus? + abstract val usedAsExpression: Boolean override fun accept(visitor: FirVisitor, data: D): R = visitor.visitWhenExpression(this, data) @@ -32,7 +33,7 @@ abstract class FirWhenExpression : FirExpression(), FirResolvable { abstract override fun replaceCalleeReference(newCalleeReference: FirReference) - abstract fun replaceIsExhaustive(newIsExhaustive: Boolean) + abstract fun replaceExhaustivenessStatus(newExhaustivenessStatus: ExhaustivenessStatus?) abstract override fun transformAnnotations(transformer: FirTransformer, data: D): FirWhenExpression diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirWhenExpressionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirWhenExpressionBuilder.kt index 1c7b74c6554..8c1f741507e 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirWhenExpressionBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/builder/FirWhenExpressionBuilder.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.declarations.FirVariable +import org.jetbrains.kotlin.fir.expressions.ExhaustivenessStatus import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirWhenBranch @@ -36,7 +37,8 @@ class FirWhenExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBui var subject: FirExpression? = null var subjectVariable: FirVariable<*>? = null val branches: MutableList = mutableListOf() - var isExhaustive: Boolean = false + var exhaustivenessStatus: ExhaustivenessStatus? = null + var usedAsExpression: Boolean by kotlin.properties.Delegates.notNull() override fun build(): FirWhenExpression { return FirWhenExpressionImpl( @@ -47,14 +49,15 @@ class FirWhenExpressionBuilder : FirAnnotationContainerBuilder, FirExpressionBui subject, subjectVariable, branches, - isExhaustive, + exhaustivenessStatus, + usedAsExpression, ) } } @OptIn(ExperimentalContracts::class) -inline fun buildWhenExpression(init: FirWhenExpressionBuilder.() -> Unit = {}): FirWhenExpression { +inline fun buildWhenExpression(init: FirWhenExpressionBuilder.() -> Unit): FirWhenExpression { contract { callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE) } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirWhenExpressionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirWhenExpressionImpl.kt index 7b0074e048d..adbc9991a88 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirWhenExpressionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/expressions/impl/FirWhenExpressionImpl.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.expressions.impl import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.declarations.FirVariable +import org.jetbrains.kotlin.fir.expressions.ExhaustivenessStatus import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirExpression import org.jetbrains.kotlin.fir.expressions.FirWhenBranch @@ -28,7 +29,8 @@ internal class FirWhenExpressionImpl( override var subject: FirExpression?, override var subjectVariable: FirVariable<*>?, override val branches: MutableList, - override var isExhaustive: Boolean, + override var exhaustivenessStatus: ExhaustivenessStatus?, + override val usedAsExpression: Boolean, ) : FirWhenExpression() { override fun acceptChildren(visitor: FirVisitor, data: D) { typeRef.accept(visitor, data) @@ -90,7 +92,7 @@ internal class FirWhenExpressionImpl( calleeReference = newCalleeReference } - override fun replaceIsExhaustive(newIsExhaustive: Boolean) { - isExhaustive = newIsExhaustive + override fun replaceExhaustivenessStatus(newExhaustivenessStatus: ExhaustivenessStatus?) { + exhaustivenessStatus = newExhaustivenessStatus } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCacheWithPostCompute.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCacheWithPostCompute.kt index 2921e4f95bf..328c748da70 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCacheWithPostCompute.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCacheWithPostCompute.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.fir.caches -abstract class FirCache { - abstract fun getValue(key: KEY, context: CONTEXT): VALUE - abstract fun getValueIfComputed(key: KEY): VALUE? +abstract class FirCache { + abstract fun getValue(key: K, context: CONTEXT): V + abstract fun getValueIfComputed(key: K): V? } @Suppress("NOTHING_TO_INLINE") -inline fun FirCache.getValue(key: KEY): VALUE = +inline fun FirCache.getValue(key: K): V = getValue(key, null) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCachesFactory.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCachesFactory.kt index 4cc8d948c0f..14bce79dc4c 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCachesFactory.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirCachesFactory.kt @@ -18,12 +18,12 @@ abstract class FirCachesFactory : FirSessionComponent { * Where: * [CONTEXT] -- type of value which be used to create value by [createValue] */ - abstract fun createCache(createValue: (KEY, CONTEXT) -> VALUE): FirCache + abstract fun createCache(createValue: (K, CONTEXT) -> V): FirCache /** * Creates a cache with returns a caches value on demand if it is computed * Otherwise computes the value in two phases: - * - [createValue] -- creates values and stores [VALUE] to cache and passes [VALUE] & [DATA] to [postCompute] + * - [createValue] -- creates values and stores value of type [V] to cache and passes [V] & [DATA] to [postCompute] * - [postCompute] -- performs some operations on computed value after it placed into map * * [FirCache.getValue] can be safely called in postCompute from the same thread and correct value computed by [createValue] will be returned @@ -33,40 +33,40 @@ abstract class FirCachesFactory : FirSessionComponent { * [CONTEXT] -- type of value which be used to create value by [createValue] * [DATA] -- type of additional data which will be passed from [createValue] to [postCompute] */ - abstract fun createCacheWithPostCompute( - createValue: (KEY, CONTEXT) -> Pair, - postCompute: (KEY, VALUE, DATA) -> Unit - ): FirCache + abstract fun createCacheWithPostCompute( + createValue: (K, CONTEXT) -> Pair, + postCompute: (K, V, DATA) -> Unit + ): FirCache } val FirSession.firCachesFactory: FirCachesFactory by FirSession.sessionComponentAccessor() -inline fun FirCachesFactory.createCache( - crossinline createValue: (KEY) -> VALUE, -): FirCache = createCache( +inline fun FirCachesFactory.createCache( + crossinline createValue: (K) -> V, +): FirCache = createCache( createValue = { key, _ -> createValue(key) }, ) -inline fun FirCachesFactory.createCacheWithPostCompute( - crossinline createValue: (KEY, CONTEXT) -> VALUE, - crossinline postCompute: (KEY, VALUE) -> Unit -): FirCache = createCacheWithPostCompute( +inline fun FirCachesFactory.createCacheWithPostCompute( + crossinline createValue: (K, CONTEXT) -> V, + crossinline postCompute: (K, V) -> Unit +): FirCache = createCacheWithPostCompute( createValue = { key, context -> createValue(key, context) to null }, postCompute = { key, value, _ -> postCompute(key, value) } ) -inline fun FirCachesFactory.createCacheWithPostCompute( - crossinline createValue: (KEY) -> VALUE, - crossinline postCompute: (KEY, VALUE) -> Unit -): FirCache = createCacheWithPostCompute( +inline fun FirCachesFactory.createCacheWithPostCompute( + crossinline createValue: (K) -> V, + crossinline postCompute: (K, V) -> Unit +): FirCache = createCacheWithPostCompute( createValue = { key, _ -> createValue(key) to null }, postCompute = { key, value, _ -> postCompute(key, value) } ) -inline fun FirCachesFactory.createCacheWithPostCompute( - crossinline createValue: (KEY) -> Pair, - crossinline postCompute: (KEY, VALUE, DATA) -> Unit -): FirCache = createCacheWithPostCompute( +inline fun FirCachesFactory.createCacheWithPostCompute( + crossinline createValue: (K) -> Pair, + crossinline postCompute: (K, V, DATA) -> Unit +): FirCache = createCacheWithPostCompute( createValue = { key, _ -> createValue(key) }, postCompute = { key, value, data -> postCompute(key, value, data) } ) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirThreadUnsafeCachesFactory.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirThreadUnsafeCachesFactory.kt index 5532f99dfbc..7c166625ac8 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirThreadUnsafeCachesFactory.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/caches/FirThreadUnsafeCachesFactory.kt @@ -6,41 +6,41 @@ package org.jetbrains.kotlin.fir.caches object FirThreadUnsafeCachesFactory : FirCachesFactory() { - override fun createCache(createValue: (KEY, CONTEXT) -> VALUE): FirCache = + override fun createCache(createValue: (K, CONTEXT) -> V): FirCache = FirThreadUnsafeCache(createValue) - override fun createCacheWithPostCompute( - createValue: (KEY, CONTEXT) -> Pair, - postCompute: (KEY, VALUE, DATA) -> Unit - ): FirCache = + override fun createCacheWithPostCompute( + createValue: (K, CONTEXT) -> Pair, + postCompute: (K, V, DATA) -> Unit + ): FirCache = FirThreadUnsafeCacheWithPostCompute(createValue, postCompute) } @Suppress("UNCHECKED_CAST") -private class FirThreadUnsafeCache( - private val createValue: (KEY, CONTEXT) -> VALUE -) : FirCache() { - private val map = NullableMap() +private class FirThreadUnsafeCache( + private val createValue: (K, CONTEXT) -> V +) : FirCache() { + private val map = NullableMap() - override fun getValue(key: KEY, context: CONTEXT): VALUE = + override fun getValue(key: K, context: CONTEXT): V = map.getOrElse(key) { createValue(key, context).also { createdValue -> map[key] = createdValue } } - override fun getValueIfComputed(key: KEY): VALUE? = - map.getOrElse(key) { null as VALUE } + override fun getValueIfComputed(key: K): V? = + map.getOrElse(key) { null as V } } -private class FirThreadUnsafeCacheWithPostCompute( - private val createValue: (KEY, CONTEXT) -> Pair, - private val postCompute: (KEY, VALUE, DATA) -> Unit -) : FirCache() { - private val map = NullableMap() +private class FirThreadUnsafeCacheWithPostCompute( + private val createValue: (K, CONTEXT) -> Pair, + private val postCompute: (K, V, DATA) -> Unit +) : FirCache() { + private val map = NullableMap() - override fun getValue(key: KEY, context: CONTEXT): VALUE = + override fun getValue(key: K, context: CONTEXT): V = map.getOrElse(key) { val (createdValue, data) = createValue(key, context) map[key] = createdValue @@ -50,6 +50,6 @@ private class FirThreadUnsafeCacheWithPostCompute return false + FirDeclarationOrigin.IntersectionOverride -> return false + FirDeclarationOrigin.Delegated -> return false + else -> { + val getter = getter ?: return true + if (isVar && setter == null) return true + if (setter?.hasBody == false) return true + if (!getter.hasBody) return true + + return isReferredViaField == true + } + } + } inline val FirDeclaration.isFromLibrary: Boolean get() = origin == FirDeclarationOrigin.Library diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/SealedClassInheritors.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/SealedClassInheritors.kt new file mode 100644 index 00000000000..e16a6ad3498 --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/SealedClassInheritors.kt @@ -0,0 +1,12 @@ +/* + * 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.declarations + +import org.jetbrains.kotlin.name.ClassId + +object SealedClassInheritorsKey : FirDeclarationDataKey() + +var FirRegularClass.sealedInheritors: List? by FirDeclarationDataRegistry.data(SealedClassInheritorsKey) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/ExhaustivenessStatus.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/ExhaustivenessStatus.kt new file mode 100644 index 00000000000..ddac6cf5b4f --- /dev/null +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/ExhaustivenessStatus.kt @@ -0,0 +1,66 @@ +/* + * 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.expressions + +import org.jetbrains.kotlin.fir.symbols.CallableId +import org.jetbrains.kotlin.name.ClassId + +sealed class ExhaustivenessStatus { + object Exhaustive : ExhaustivenessStatus() + class NotExhaustive(val reasons: List) : ExhaustivenessStatus() { + companion object { + val NO_ELSE_BRANCH = NotExhaustive(listOf(WhenMissingCase.Unknown)) + } + } +} + +sealed class WhenMissingCase() { + abstract val branchConditionText: String + + object Unknown : WhenMissingCase() { + override fun toString(): String = "unknown" + + override val branchConditionText: String = "else" + } + + object NullIsMissing : WhenMissingCase() { + override val branchConditionText: String = "null" + } + + sealed class BooleanIsMissing(val value: Boolean) : WhenMissingCase() { + object True : BooleanIsMissing(true) + object False : BooleanIsMissing(false) + + override val branchConditionText: String = value.toString() + } + + class IsTypeCheckIsMissing(val classId: ClassId, val isSingleton: Boolean) : WhenMissingCase() { + override val branchConditionText: String = run { + val fqName = classId.asSingleFqName().toString() + if (isSingleton) fqName else "is $fqName" + } + + override fun toString(): String { + val name = classId.shortClassName.identifier + return if (isSingleton) name else "is $name" + } + } + + class EnumCheckIsMissing(val callableId: CallableId) : WhenMissingCase() { + override val branchConditionText: String = callableId.asFqNameForDebugInfo().toString() + + override fun toString(): String { + return callableId.callableName.identifier + } + } + + override fun toString(): String { + return branchConditionText + } +} + +val FirWhenExpression.isExhaustive: Boolean + get() = exhaustivenessStatus == ExhaustivenessStatus.Exhaustive diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralTypeImpl.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralTypeImpl.kt index 5a49bb42ab0..6c6d17ae232 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralTypeImpl.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/types/ConeIntegerLiteralTypeImpl.kt @@ -62,7 +62,7 @@ class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType { override val supertypes: List by lazy { listOf( - NUMBER_TYPE, + createType(StandardClassIds.Number), ConeClassLikeTypeImpl(COMPARABLE_TAG, arrayOf(ConeKotlinTypeProjectionIn(this)), false) ) } @@ -83,8 +83,6 @@ class ConeIntegerLiteralTypeImpl : ConeIntegerLiteralType { return ConeClassLikeTypeImpl(ConeClassLikeLookupTagImpl(classId), emptyArray(), false) } - private val NUMBER_TYPE = createType(StandardClassIds.Number) - private val INT_RANGE = Int.MIN_VALUE.toLong()..Int.MAX_VALUE.toLong() private val BYTE_RANGE = Byte.MIN_VALUE.toLong()..Byte.MAX_VALUE.toLong() private val SHORT_RANGE = Short.MIN_VALUE.toLong()..Short.MAX_VALUE.toLong() diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt index 20501be0b0a..9bf147a98e3 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/BuilderConfigurator.kt @@ -219,7 +219,7 @@ object BuilderConfigurator : AbstractBuilderConfigurator(FirTree } builder(whenExpression) { - defaultFalse("isExhaustive") + defaultNull("exhaustivenessStatus") default("calleeReference", "FirStubReference") useTypes(stubReferenceType) } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt index c51fe91e63c..c705a4ce8af 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/ImplementationConfigurator.kt @@ -210,7 +210,7 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator() withGetter = true } - defaultNull("delegateFieldSymbol", "receiverTypeRef", "initializer", "delegate", "getter", "setter", withGetter = true) + defaultNull("delegateFieldSymbol", "receiverTypeRef", "delegate", "getter", "setter", withGetter = true) } impl(enumEntry) { diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index ae47709304d..d655c4b4282 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -587,7 +587,8 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild +field("subject", expression, nullable = true).withTransform() +field("subjectVariable", variable.withArgs("F" to "*"), nullable = true) +fieldList("branches", whenBranch).withTransform() - +booleanField("isExhaustive", withReplace = true) + +field("exhaustivenessStatus", exhaustivenessStatusType, nullable = true, withReplace = true) + +booleanField("usedAsExpression") needTransformOtherChildren() } diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt index 2be2eeb4e63..38e16b2f88b 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt @@ -84,3 +84,5 @@ val firImplementationDetailType = generatedType("FirImplementationDetail") val declarationOriginType = generatedType("declarations", "FirDeclarationOrigin") val declarationAttributesType = generatedType("declarations", "FirDeclarationAttributes") val annotationResolveStatusType = generatedType("expressions", "FirAnnotationResolveStatus") + +val exhaustivenessStatusType = generatedType("expressions", "ExhaustivenessStatus") diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/SmartPrinter.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/SmartPrinter.kt index 19254441427..6d19739eef3 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/SmartPrinter.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/printer/SmartPrinter.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.tree.generator.printer +import org.jetbrains.kotlin.generators.util.GeneratorsFileUtil import java.io.File import java.lang.Appendable @@ -38,6 +39,9 @@ class SmartPrinter(appendable: Appendable) { fun popIndent() { printer.popIndent() } + + fun getCurrentIndentInUnits() = printer.currentIndentLengthInUnits + fun getIndentUnit() = printer.indentUnitLength } inline fun SmartPrinter.withIndent(block: () -> Unit) { @@ -46,6 +50,7 @@ inline fun SmartPrinter.withIndent(block: () -> Unit) { popIndent() } -inline fun File.useSmartPrinter(block: SmartPrinter.() -> Unit) { - writer().use { SmartPrinter(it).block() } -} \ No newline at end of file +inline fun File.writeToFileUsingSmartPrinterIfFileContentChanged(block: SmartPrinter.() -> Unit) { + val newText = buildString { SmartPrinter(this).block() } + GeneratorsFileUtil.writeFileIfContentChanged(this, newText, logNotChanged = false) +} diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt index 14fd5581a38..65684cefd04 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/PositioningStrategies.kt @@ -507,6 +507,13 @@ object PositioningStrategies { } } + @JvmField + val IF_EXPRESSION: PositioningStrategy = object : PositioningStrategy() { + override fun mark(element: KtIfExpression): List { + return markElement(element.ifKeyword) + } + } + @JvmField val WHEN_CONDITION_IN_RANGE: PositioningStrategy = object : PositioningStrategy() { override fun mark(element: KtWhenConditionInRange): List { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt index 68d5d6a23a2..20b936b0438 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt @@ -134,9 +134,10 @@ fun createContainerForBodyResolve( statementFilter: StatementFilter, analyzerServices: PlatformDependentAnalyzerServices, languageVersionSettings: LanguageVersionSettings, - moduleStructureOracle: ModuleStructureOracle + moduleStructureOracle: ModuleStructureOracle, + sealedProvider: SealedClassInheritorsProvider = CliSealedClassInheritorsProvider ): StorageComponentContainer = createContainer("BodyResolve", analyzerServices) { - configureModule(moduleContext, platform, analyzerServices, bindingTrace, languageVersionSettings) + configureModule(moduleContext, platform, analyzerServices, bindingTrace, languageVersionSettings, sealedProvider) useInstance(statementFilter) @@ -156,10 +157,10 @@ fun createContainerForLazyBodyResolve( analyzerServices: PlatformDependentAnalyzerServices, languageVersionSettings: LanguageVersionSettings, moduleStructureOracle: ModuleStructureOracle, - mainFunctionDetectorFactory: MainFunctionDetector.Factory + mainFunctionDetectorFactory: MainFunctionDetector.Factory, + sealedProvider: SealedClassInheritorsProvider = CliSealedClassInheritorsProvider ): StorageComponentContainer = createContainer("LazyBodyResolve", analyzerServices) { - configureModule(moduleContext, platform, analyzerServices, bindingTrace, languageVersionSettings) - + configureModule(moduleContext, platform, analyzerServices, bindingTrace, languageVersionSettings, sealedProvider) useInstance(mainFunctionDetectorFactory) useInstance(kotlinCodeAnalyzer) useInstance(kotlinCodeAnalyzer.fileScopeProvider) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt index 4827e3e4d9a..7398559c52d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/DiagnosticReporterByTrackingStrategy.kt @@ -446,8 +446,14 @@ class DiagnosticReporterByTrackingStrategy( if (isDiagnosticRedundant) return val expression = when (val atom = error.resolvedAtom.atom) { - is PSIKotlinCallForInvoke -> (atom.psiCall as? CallTransformer.CallForImplicitInvoke)?.outerCall?.calleeExpression - is PSIKotlinCall -> atom.psiCall.calleeExpression + is PSIKotlinCall -> { + val psiCall = atom.psiCall + if (psiCall is CallTransformer.CallForImplicitInvoke) { + psiCall.outerCall.calleeExpression + } else { + psiCall.calleeExpression + } + } is PSIKotlinCallArgument -> atom.valueArgument.getArgumentExpression() else -> call.calleeExpression } ?: return diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencySupertypeChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencySupertypeChecker.kt index cd5c71e2d89..f3fad310494 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencySupertypeChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencySupertypeChecker.kt @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.resolve.checkers import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.config.AnalysisFlags +import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.psi.KtDeclaration @@ -48,7 +50,11 @@ object MissingDependencySupertypeChecker { descriptor.dispatchReceiverParameter?.declaration, reportOn, context.trace, context.missingSupertypesResolver ) - if (descriptor !is ConstructorDescriptor && descriptor !is FakeCallableDescriptorForObject && !errorReported) { + + val eagerChecksAllowed = context.languageVersionSettings.getFlag(AnalysisFlags.extendedCompilerChecks) + val unresolvedLazySupertypesByDefault = descriptor is ConstructorDescriptor || descriptor is FakeCallableDescriptorForObject + + if (eagerChecksAllowed || !unresolvedLazySupertypesByDefault && !errorReported) { // The constructed class' own supertypes are not resolved after constructor call, // so its containing declaration should not be checked. // Dispatch receiver is checked before for case of inner class constructor call. diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/declarations/AbstractPsiBasedDeclarationProvider.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/declarations/AbstractPsiBasedDeclarationProvider.kt index 3b970c0baf0..70a17de9e55 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/declarations/AbstractPsiBasedDeclarationProvider.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/declarations/AbstractPsiBasedDeclarationProvider.kt @@ -88,8 +88,13 @@ abstract class AbstractPsiBasedDeclarationProvider(storageManager: StorageManage internal fun toInfoString() = toString() + ": " + index().toString() - override fun getDeclarations(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List = - index().allDeclarations + override fun getDeclarations(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): List { + val allDeclarations = index().allDeclarations + if (kindFilter == DescriptorKindFilter.CLASSIFIERS) { + return allDeclarations.filter { it is KtClassOrObject || it is KtTypeAlias } + } + return allDeclarations + } override fun getFunctionDeclarations(name: Name): List = index().functions[name.safeNameForLazyResolve()].toList() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt index a58ac3c2ca5..6cb62886d62 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt @@ -70,10 +70,26 @@ open class LazyClassMemberScope( result.toList() } + private val allClassifierDescriptors = storageManager.createLazyValue { + val result = LinkedHashSet( + computeDescriptorsFromDeclaredElements( + DescriptorKindFilter.CLASSIFIERS, + MemberScope.ALL_NAME_FILTER, + NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS + ) + ) + addSyntheticCompanionObject(result, NoLookupLocation.FOR_ALREADY_TRACKED) + addSyntheticNestedClasses(result, NoLookupLocation.FOR_ALREADY_TRACKED) + result.toList() + } + override fun getContributedDescriptors( kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean - ): Collection = allDescriptors() + ): Collection = when (kindFilter) { + DescriptorKindFilter.CLASSIFIERS -> allClassifierDescriptors() + else -> allDescriptors() + } protected open fun computeExtraDescriptors(location: LookupLocation): Collection { val result = ArrayList() diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContext.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContext.kt index 858c8b57d38..633580fe3f6 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContext.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContext.kt @@ -10,7 +10,9 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.builders.IrGeneratorContext +import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable import org.jetbrains.kotlin.ir.util.TypeTranslator @@ -51,4 +53,7 @@ interface IrPluginContext : IrGeneratorContext { fun referenceConstructors(classFqn: FqName): Collection fun referenceFunctions(fqName: FqName): Collection fun referenceProperties(fqName: FqName): Collection + + // temporary solution to load synthetic top-level declaration + fun referenceTopLevel(signature: IdSignature, kind: IrDeserializer.TopLevelSymbolKind, moduleDescriptor: ModuleDescriptor): IrSymbol? } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContextImpl.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContextImpl.kt index bf8da2ef0ba..7de0210fbff 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContextImpl.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/extensions/IrPluginContextImpl.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IrMessageLogger import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable import org.jetbrains.kotlin.ir.util.TypeTranslator @@ -134,4 +135,14 @@ open class IrPluginContextImpl constructor( descriptors.map { st.referenceProperty(it) } } } + + override fun referenceTopLevel( + signature: IdSignature, + kind: IrDeserializer.TopLevelSymbolKind, + moduleDescriptor: ModuleDescriptor + ): IrSymbol? { + val symbol = linker.resolveBySignatureInModule(signature, kind, moduleDescriptor.name) + linker.postProcess() + return symbol + } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt index 1a29f8e91c9..0691b6792c5 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/inline/FunctionInlining.kt @@ -225,8 +225,6 @@ class FunctionInlining( else (copyIrElement.copy(argument) as IrExpression) } - //-----------------------------------------------------------------// - override fun visitCall(expression: IrCall): IrExpression { if (!isLambdaCall(expression)) return super.visitCall(expression) @@ -236,119 +234,133 @@ class FunctionInlining( if ((dispatchReceiver.symbol.owner as? IrValueParameter)?.isNoinline == true) return super.visitCall(expression) - if (functionArgument is IrFunctionReference) { - functionArgument.transformChildrenVoid(this) - - val function = functionArgument.symbol.owner - val functionParameters = function.explicitParameters - val boundFunctionParameters = functionArgument.getArgumentsWithIr() - val unboundFunctionParameters = functionParameters - boundFunctionParameters.map { it.first } - val boundFunctionParametersMap = boundFunctionParameters.associate { it.first to it.second } - - var unboundIndex = 0 - val unboundArgsSet = unboundFunctionParameters.toSet() - val valueParameters = expression.getArgumentsWithIr().drop(1) // Skip dispatch receiver. - - val superType = functionArgument.type as IrSimpleType - val superTypeArgumentsMap = expression.symbol.owner.parentAsClass.typeParameters.associate { typeParam -> - typeParam.symbol to superType.arguments[typeParam.index].typeOrNull!! - } - - val immediateCall = with(expression) { - when (function) { - is IrConstructor -> { - val classTypeParametersCount = function.parentAsClass.typeParameters.size - IrConstructorCallImpl.fromSymbolOwner( - startOffset, - endOffset, - function.returnType, - function.symbol, - classTypeParametersCount - ) - } - is IrSimpleFunction -> - IrCallImpl( - startOffset, - endOffset, - function.returnType, - function.symbol, - function.typeParameters.size, - function.valueParameters.size - ) - else -> - error("Unknown function kind : ${function.render()}") - } - }.apply { - for (parameter in functionParameters) { - val argument = - if (parameter !in unboundArgsSet) { - val arg = boundFunctionParametersMap[parameter]!! - if (arg is IrGetValueWithoutLocation) - arg.withLocation(expression.startOffset, expression.endOffset) - else arg - } else { - if (unboundIndex == valueParameters.size && parameter.defaultValue != null) - copyIrElement.copy(parameter.defaultValue!!.expression) as IrExpression - else if (!parameter.isVararg) { - assert(unboundIndex < valueParameters.size) { - "Attempt to use unbound parameter outside of the callee's value parameters" - } - valueParameters[unboundIndex++].second - } else { - val elements = mutableListOf() - while (unboundIndex < valueParameters.size) { - val (param, value) = valueParameters[unboundIndex++] - val substitutedParamType = param.type.substitute(superTypeArgumentsMap) - if (substitutedParamType == parameter.varargElementType!!) - elements += value - else - elements += IrSpreadElementImpl(expression.startOffset, expression.endOffset, value) - } - IrVarargImpl( - expression.startOffset, expression.endOffset, - parameter.type, - parameter.varargElementType!!, - elements - ) - } - } - when (parameter) { - function.dispatchReceiverParameter -> - this.dispatchReceiver = argument.implicitCastIfNeededTo(function.dispatchReceiverParameter!!.type) - - function.extensionReceiverParameter -> - this.extensionReceiver = argument.implicitCastIfNeededTo(function.extensionReceiverParameter!!.type) - - else -> - putValueArgument( - parameter.index, - argument.implicitCastIfNeededTo(function.valueParameters[parameter.index].type) - ) - } - } - assert(unboundIndex == valueParameters.size) { "Not all arguments of the callee are used" } - for (index in 0 until functionArgument.typeArgumentsCount) - putTypeArgument(index, functionArgument.getTypeArgument(index)) - }.implicitCastIfNeededTo(expression.type) - return this@FunctionInlining.visitExpression(super.visitExpression(immediateCall)) + return when { + functionArgument is IrFunctionReference -> inlineFunctionReference(expression, functionArgument) + functionArgument.isAdaptedFunctionReference() -> inlineAdaptedFunctionReference(expression, functionArgument as IrBlock) + functionArgument is IrFunctionExpression -> inlineFunctionExpression(expression, functionArgument) + else -> super.visitCall(expression) } - if (functionArgument !is IrFunctionExpression) - return super.visitCall(expression) + } + fun inlineFunctionExpression(irCall: IrCall, irFunctionExpression: IrFunctionExpression): IrExpression { // Inline the lambda. Lambda parameters will be substituted with lambda arguments. val newExpression = inlineFunction( - expression, - functionArgument.function, + irCall, + irFunctionExpression.function, false ) // Substitute lambda arguments with target function arguments. - return newExpression.transform( - this, - null + return newExpression.transform(this, null) + } + + fun inlineAdaptedFunctionReference(irCall: IrCall, irBlock: IrBlock): IrExpression { + val irFunction = irBlock.statements[0] as IrFunction + irFunction.transformChildrenVoid(this) + val irFunctionReference = irBlock.statements[1] as IrFunctionReference + val inlinedFunctionReference = inlineFunctionReference(irCall, irFunctionReference) + return IrBlockImpl( + irCall.startOffset, irCall.endOffset, + inlinedFunctionReference.type, origin = null, + statements = listOf(irFunction, inlinedFunctionReference) ) } - //-----------------------------------------------------------------// + fun inlineFunctionReference(irCall: IrCall, irFunctionReference: IrFunctionReference): IrExpression { + irFunctionReference.transformChildrenVoid(this) + + val function = irFunctionReference.symbol.owner + val functionParameters = function.explicitParameters + val boundFunctionParameters = irFunctionReference.getArgumentsWithIr() + val unboundFunctionParameters = functionParameters - boundFunctionParameters.map { it.first } + val boundFunctionParametersMap = boundFunctionParameters.associate { it.first to it.second } + + var unboundIndex = 0 + val unboundArgsSet = unboundFunctionParameters.toSet() + val valueParameters = irCall.getArgumentsWithIr().drop(1) // Skip dispatch receiver. + + val superType = irFunctionReference.type as IrSimpleType + val superTypeArgumentsMap = irCall.symbol.owner.parentAsClass.typeParameters.associate { typeParam -> + typeParam.symbol to superType.arguments[typeParam.index].typeOrNull!! + } + + val immediateCall = with(irCall) { + when (function) { + is IrConstructor -> { + val classTypeParametersCount = function.parentAsClass.typeParameters.size + IrConstructorCallImpl.fromSymbolOwner( + startOffset, + endOffset, + function.returnType, + function.symbol, + classTypeParametersCount + ) + } + is IrSimpleFunction -> + IrCallImpl( + startOffset, + endOffset, + function.returnType, + function.symbol, + function.typeParameters.size, + function.valueParameters.size + ) + else -> + kotlin.error("Unknown function kind : ${function.render()}") + } + }.apply { + for (parameter in functionParameters) { + val argument = + if (parameter !in unboundArgsSet) { + val arg = boundFunctionParametersMap[parameter]!! + if (arg is IrGetValueWithoutLocation) + arg.withLocation(irCall.startOffset, irCall.endOffset) + else arg + } else { + if (unboundIndex == valueParameters.size && parameter.defaultValue != null) + copyIrElement.copy(parameter.defaultValue!!.expression) as IrExpression + else if (!parameter.isVararg) { + assert(unboundIndex < valueParameters.size) { + "Attempt to use unbound parameter outside of the callee's value parameters" + } + valueParameters[unboundIndex++].second + } else { + val elements = mutableListOf() + while (unboundIndex < valueParameters.size) { + val (param, value) = valueParameters[unboundIndex++] + val substitutedParamType = param.type.substitute(superTypeArgumentsMap) + if (substitutedParamType == parameter.varargElementType!!) + elements += value + else + elements += IrSpreadElementImpl(irCall.startOffset, irCall.endOffset, value) + } + IrVarargImpl( + irCall.startOffset, irCall.endOffset, + parameter.type, + parameter.varargElementType!!, + elements + ) + } + } + when (parameter) { + function.dispatchReceiverParameter -> + this.dispatchReceiver = argument.implicitCastIfNeededTo(function.dispatchReceiverParameter!!.type) + + function.extensionReceiverParameter -> + this.extensionReceiver = argument.implicitCastIfNeededTo(function.extensionReceiverParameter!!.type) + + else -> + putValueArgument( + parameter.index, + argument.implicitCastIfNeededTo(function.valueParameters[parameter.index].type) + ) + } + } + assert(unboundIndex == valueParameters.size) { "Not all arguments of the callee are used" } + for (index in 0 until irFunctionReference.typeArgumentsCount) + putTypeArgument(index, irFunctionReference.getTypeArgument(index)) + }.implicitCastIfNeededTo(irCall.type) + return this@FunctionInlining.visitExpression(super.visitExpression(immediateCall)) + } override fun visitElement(element: IrElement) = element.accept(this, null) } @@ -369,7 +381,8 @@ class FunctionInlining( && irCall.dispatchReceiver is IrGetValue } - //-------------------------------------------------------------------------// + private fun IrExpression.isAdaptedFunctionReference() = + this is IrBlock && this.origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE private inner class ParameterToArgument( val parameter: IrValueParameter, @@ -379,7 +392,8 @@ class FunctionInlining( val isInlinableLambdaArgument: Boolean get() = parameter.isInlineParameter() && (argumentExpression is IrFunctionReference - || argumentExpression is IrFunctionExpression) + || argumentExpression is IrFunctionExpression + || argumentExpression.isAdaptedFunctionReference()) val isImmutableVariableLoad: Boolean get() = argumentExpression.let { argument -> diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt index abbe7072fc8..114c32d9826 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/export/ExportModelGenerator.kt @@ -6,12 +6,15 @@ package org.jetbrains.kotlin.ir.backend.js.export import org.jetbrains.kotlin.backend.common.ir.isExpect +import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities -import org.jetbrains.kotlin.ir.backend.js.* -import org.jetbrains.kotlin.ir.backend.js.lower.ES6AddInternalParametersToConstructorPhase.* +import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext +import org.jetbrains.kotlin.ir.backend.js.JsLoweredDeclarationOrigin +import org.jetbrains.kotlin.ir.backend.js.lower.ES6AddInternalParametersToConstructorPhase.ES6_INIT_BOX_PARAMETER +import org.jetbrains.kotlin.ir.backend.js.lower.ES6AddInternalParametersToConstructorPhase.ES6_RESULT_TYPE_PARAMETER import org.jetbrains.kotlin.ir.backend.js.utils.getJsNameOrKotlinName import org.jetbrains.kotlin.ir.backend.js.utils.isJsExport import org.jetbrains.kotlin.ir.backend.js.utils.sanitizeName @@ -80,7 +83,7 @@ class ExportModelGenerator(val context: JsIrBackendContext) { private fun exportConstructor(constructor: IrConstructor): ExportedDeclaration? { if (!constructor.isPrimary) return null val allValueParameters = listOfNotNull(constructor.extensionReceiverParameter) + - constructor.valueParameters.filterNot { it.origin === ES6_RESULT_TYPE_PARAMETER || it.origin === ES6_INIT_BOX_PARAMETER } + constructor.valueParameters.filterNot { it.origin === ES6_RESULT_TYPE_PARAMETER || it.origin === ES6_INIT_BOX_PARAMETER } return ExportedConstructor(allValueParameters.map { exportParameter(it) }) } @@ -192,7 +195,7 @@ class ExportModelGenerator(val context: JsIrBackendContext) { ?.let { exportType(it).takeIf { it !is ExportedType.ErrorType } } val superInterfaces = klass.superTypes - .filter {it.classifierOrFail.isInterface } + .filter { it.classifierOrFail.isInterface } .map { exportType(it) } .filter { it !is ExportedType.ErrorType } @@ -398,6 +401,17 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont if (context?.additionalExportedDeclarations?.contains(declaration) == true) return true + if (declaration is IrSimpleFunction) { + val overriddenNonEmpty = declaration + .overriddenSymbols + .isNotEmpty() + + if (overriddenNonEmpty) { + return declaration.isOverriddenExported(context) || + declaration.isMethodOfAny() // Handle names for special functions + } + } + if (declaration.isJsExport()) return true @@ -408,6 +422,10 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont } } +private fun IrSimpleFunction.isOverriddenExported(context: JsIrBackendContext?): Boolean = + overriddenSymbols + .any { shouldDeclarationBeExported(it.owner, context) } + fun IrDeclaration.isExported(context: JsIrBackendContext?): Boolean { val candidate = getExportCandidate(this) ?: return false return shouldDeclarationBeExported(candidate, context) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt index 2f597d3dddc..1cc9a52545f 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/utils/misc.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.isNullableAny import org.jetbrains.kotlin.ir.util.isEffectivelyExternal import org.jetbrains.kotlin.ir.util.isTopLevelDeclaration -import org.jetbrains.kotlin.ir.util.parentClassOrNull import org.jetbrains.kotlin.name.Name fun TODO(element: IrElement): Nothing = TODO(element::class.java.simpleName + " is not supported yet here") diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt index 51a4cb98c19..04e314f7f3b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt @@ -49,6 +49,7 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory val irProviders: List, val extensions: JvmGeneratorExtensions, val backendExtension: JvmBackendExtension, + val notifyCodegenStart: () -> Unit, ) override fun generateModule(state: GenerationState, files: Collection) { @@ -158,6 +159,7 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory irProviders, extensions, JvmBackendExtension.Default, + {}, ) } @@ -173,7 +175,7 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory } fun doGenerateFilesInternal(input: JvmIrBackendInput) { - val (state, irModuleFragment, symbolTable, sourceManager, phaseConfig, irProviders, extensions, backendExtension) = input + val (state, irModuleFragment, symbolTable, sourceManager, phaseConfig, irProviders, extensions, backendExtension, notifyCodegenStart) = input val context = JvmBackendContext( state, sourceManager, irModuleFragment.irBuiltins, irModuleFragment, symbolTable, phaseConfig, extensions, backendExtension @@ -189,6 +191,8 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory JvmLower(context).lower(irModuleFragment) + notifyCodegenStart() + for (generateMultifileFacade in listOf(true, false)) { for (irFile in irModuleFragment.files) { // Generate multifile facades first, to compute and store JVM signatures of const properties which are later used @@ -221,10 +225,11 @@ class JvmIrCodegenFactory(private val phaseConfig: PhaseConfig) : CodegenFactory sourceManager: PsiSourceManager, extensions: JvmGeneratorExtensions, backendExtension: JvmBackendExtension, + notifyCodegenStart: () -> Unit ) { val irProviders = configureBuiltInsAndgenerateIrProvidersInFrontendIRMode(irModuleFragment, symbolTable, extensions) doGenerateFilesInternal( - JvmIrBackendInput(state, irModuleFragment, symbolTable, sourceManager, phaseConfig, irProviders, extensions, backendExtension) + JvmIrBackendInput(state, irModuleFragment, symbolTable, sourceManager, phaseConfig, irProviders, extensions, backendExtension, notifyCodegenStart) ) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CollectionStubMethodLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CollectionStubMethodLowering.kt index 66a88db287d..9b627b0a39a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CollectionStubMethodLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/CollectionStubMethodLowering.kt @@ -313,7 +313,10 @@ internal class CollectionStubMethodLowering(val context: JvmBackendContext) : Cl .flatMap { createStubFuns(irClass, it) } .mapTo(HashSet()) { it.toJvmSignature() } - return classStubFuns.filter { it.toJvmSignature() !in superClassStubSignatures } + return classStubFuns + .filter { it.toJvmSignature() !in superClassStubSignatures } + .associateBy { it.toJvmSignature() } + .values.toList() } private fun createStubFuns(irClass: IrClass, stubs: StubsForCollectionClass): List { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt index 629179bf7c9..5f85b89f619 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/inlineclasses/MemoizedInlineClassReplacements.kt @@ -59,7 +59,8 @@ class MemoizedInlineClassReplacements( it.origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA || (it.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR && it.visibility == DescriptorVisibilities.LOCAL) || it.isStaticInlineClassReplacement || - it.origin.isSynthetic -> + it.origin.isSynthetic || + it.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE -> null it.isInlineClassFieldGetter -> diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyFunction.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyFunction.kt index c71ef05c1ab..890485c8c2e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyFunction.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/declarations/lazy/IrLazyFunction.kt @@ -44,10 +44,6 @@ class IrLazyFunction( override val stubGenerator: DeclarationStubGenerator, override val typeTranslator: TypeTranslator, ) : IrSimpleFunction(), IrLazyFunctionBase { - init { - @Suppress("UNUSED_VARIABLE") val x = 1 - } - override var parent: IrDeclarationParent by createLazyParent() override var annotations: List by createLazyAnnotations() diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/IrDeserializer.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/IrDeserializer.kt index c6a4407ef6b..015911d9dc8 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/IrDeserializer.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/linkage/IrDeserializer.kt @@ -9,6 +9,8 @@ import org.jetbrains.kotlin.ir.builders.TranslationPluginContext import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.util.IdSignature +import org.jetbrains.kotlin.name.Name interface IrDeserializer : IrProvider { @@ -16,6 +18,14 @@ interface IrDeserializer : IrProvider { fun resolveSymbol(symbol: IrSymbol, context: TranslationPluginContext): IrDeclaration? = null } + enum class TopLevelSymbolKind { + FUNCTION_SYMBOL, + CLASS_SYMBOL, + PROPERTY_SYMBOL, + TYPEALIAS_SYMBOL; + } + fun init(moduleFragment: IrModuleFragment?, extensions: Collection) {} + fun resolveBySignatureInModule(signature: IdSignature, kind: TopLevelSymbolKind, moduleName: Name): IrSymbol fun postProcess() {} } diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt index 795946150b4..29d5c1ad670 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSubstitutor.kt @@ -7,41 +7,29 @@ package org.jetbrains.kotlin.ir.types import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol +import org.jetbrains.kotlin.ir.types.impl.IrCapturedType import org.jetbrains.kotlin.ir.types.impl.buildSimpleType import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection import org.jetbrains.kotlin.ir.types.impl.toBuilder import org.jetbrains.kotlin.ir.util.render +import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker -class IrTypeSubstitutor( - typeParameters: List, - typeArguments: List, - private val irBuiltIns: IrBuiltIns -): TypeSubstitutorMarker { - init { - assert(typeParameters.size == typeArguments.size) { - "Unexpected number of type arguments: ${typeArguments.size}\n" + - "Type parameters are:\n" + - typeParameters.joinToString(separator = "\n") { it.owner.render() } + - "Type arguments are:\n" + - typeArguments.joinToString(separator = "\n") { it.render() } - } - } +abstract class AbstractIrTypeSubstitutor(private val irBuiltIns: IrBuiltIns) : TypeSubstitutorMarker { - private val substitution = typeParameters.zip(typeArguments).toMap() private fun IrType.typeParameterConstructor(): IrTypeParameterSymbol? { return if (this is IrSimpleType) classifier as? IrTypeParameterSymbol else null } - private fun getSubstitutionArgument(typeParameter: IrTypeParameterSymbol): IrTypeArgument = - substitution[typeParameter] - ?: throw AssertionError("Unsubstituted type parameter: ${typeParameter.owner.render()}") + abstract fun getSubstitutionArgument(typeParameter: IrTypeParameterSymbol): IrTypeArgument + + abstract fun isEmptySubstitution(): Boolean fun substitute(type: IrType): IrType { - if (substitution.isEmpty()) return type + if (isEmptySubstitution()) return type return type.typeParameterConstructor()?.let { when (val typeArgument = getSubstitutionArgument(it)) { @@ -84,3 +72,53 @@ class IrTypeSubstitutor( return makeTypeProjection(substituteType(typeArgument.type), typeArgument.variance) } } + + +class IrTypeSubstitutor( + typeParameters: List, + typeArguments: List, + irBuiltIns: IrBuiltIns +) : AbstractIrTypeSubstitutor(irBuiltIns) { + + init { + assert(typeParameters.size == typeArguments.size) { + "Unexpected number of type arguments: ${typeArguments.size}\n" + + "Type parameters are:\n" + + typeParameters.joinToString(separator = "\n") { it.owner.render() } + + "Type arguments are:\n" + + typeArguments.joinToString(separator = "\n") { it.render() } + } + } + + private val substitution = typeParameters.zip(typeArguments).toMap() + + override fun getSubstitutionArgument(typeParameter: IrTypeParameterSymbol): IrTypeArgument = + substitution[typeParameter] + ?: throw AssertionError("Unsubstituted type parameter: ${typeParameter.owner.render()}") + + override fun isEmptySubstitution(): Boolean = substitution.isEmpty() +} + +class IrCapturedTypeSubstitutor( + typeParameters: List, + typeArguments: List, + capturedTypes: List, + irBuiltIns: IrBuiltIns +) : AbstractIrTypeSubstitutor(irBuiltIns) { + + init { + assert(typeArguments.size == typeParameters.size) + assert(capturedTypes.size == typeParameters.size) + } + + private val oldSubstitution = typeParameters.zip(typeArguments).toMap() + private val capturedSubstitution = typeParameters.zip(capturedTypes).toMap() + + override fun getSubstitutionArgument(typeParameter: IrTypeParameterSymbol): IrTypeArgument { + return capturedSubstitution[typeParameter]?.let { makeTypeProjection(it, Variance.INVARIANT) } + ?: oldSubstitution[typeParameter] + ?: throw AssertionError("Unsubstituted type parameter: ${typeParameter.owner.render()}") + } + + override fun isEmptySubstitution(): Boolean = oldSubstitution.isEmpty() +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt index 2b89a9ab30e..7eca8a677a8 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/IrTypeSystemContext.kt @@ -5,12 +5,11 @@ package org.jetbrains.kotlin.ir.types -import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.PrimitiveType +import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities -import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns @@ -71,7 +70,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon } } - override fun SimpleTypeMarker.asCapturedType(): CapturedTypeMarker? = null + override fun SimpleTypeMarker.asCapturedType(): CapturedTypeMarker? = this as? IrCapturedType override fun SimpleTypeMarker.asDefinitelyNotNullType(): DefinitelyNotNullTypeMarker? = null @@ -83,19 +82,24 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon else simpleType.run { IrSimpleTypeImpl(classifier, nullable, arguments, annotations) } } - override fun SimpleTypeMarker.typeConstructor() = (this as IrSimpleType).classifier + override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker = when (this) { + is IrCapturedType -> constructor + is IrSimpleType -> classifier + else -> error("Unknown type constructor") + } override fun CapturedTypeMarker.typeConstructor(): CapturedTypeConstructorMarker = - error("Captured types should be used for IrTypes") + (this as IrCapturedType).constructor - override fun CapturedTypeMarker.isProjectionNotNull(): Boolean = - error("Captured types should be used for IrTypes") + // Note: `isProjectionNotNull` is used inside inference along with intersection types. + // IrTypes are not used in type inference and do not have intersection type so implemenation is default (false) + override fun CapturedTypeMarker.isProjectionNotNull(): Boolean = false override fun CapturedTypeMarker.captureStatus(): CaptureStatus = - error("Captured types should be used for IrTypes") + (this as IrCapturedType).captureStatus override fun CapturedTypeConstructorMarker.projection(): TypeArgumentMarker = - error("Captured types should be used for IrTypes") + (this as IrCapturedType.Constructor).argument override fun KotlinTypeMarker.argumentsCount(): Int = when (this) { @@ -116,7 +120,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun KotlinTypeMarker.asTypeArgument() = this as IrTypeArgument - override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? = error("Captured Type is not valid for IrTypes") + override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? = (this as IrCapturedType).lowerType override fun TypeArgumentMarker.isStarProjection() = this is IrStarProjection @@ -139,6 +143,7 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun TypeConstructorMarker.supertypes(): Collection { return when (this) { + is IrCapturedType.Constructor -> superTypes is IrClassSymbol -> owner.superTypes is IrTypeParameterSymbol -> owner.superTypes else -> error("unsupported type constructor") @@ -159,11 +164,12 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon override fun TypeParameterMarker.getTypeConstructor() = this as IrTypeParameterSymbol - override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker) = FqNameEqualityChecker.areEqual( - c1 as IrClassifierSymbol, c2 as IrClassifierSymbol - ) + override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean = + if (c1 is IrClassifierSymbol && c2 is IrClassifierSymbol) { + FqNameEqualityChecker.areEqual(c1 , c2) + } else c1 === c2 - override fun TypeConstructorMarker.isDenotable() = true + override fun TypeConstructorMarker.isDenotable() = this !is IrCapturedType.Constructor override fun TypeConstructorMarker.isCommonFinalClassConstructor(): Boolean { val classSymbol = this as? IrClassSymbol ?: return false @@ -178,13 +184,15 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon * * In this case Captured Type of `y` would be `Array` * - * See https://jetbrains.github.io/kotlin-spec/#type-capturing + * See https://kotlinlang.org/spec/type-system.html#type-capturing */ override fun captureFromArguments(type: SimpleTypeMarker, status: CaptureStatus): SimpleTypeMarker? { // TODO: is that correct? require(type is IrSimpleType) + if (type is IrCapturedType) return null + val classifier = type.classifier as? IrClassSymbol ?: return null val typeArguments = type.arguments @@ -196,23 +204,49 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon if (typeArguments.all { it is IrTypeProjection && it.variance == Variance.INVARIANT }) return type - val newArguments = mutableListOf() + val capturedTypes = ArrayList(typeArguments.size) + for (index in typeArguments.indices) { - val argument = typeArguments[index] val parameter = typeParameters[index] + val argument = typeArguments[index] if (argument is IrTypeProjection && argument.variance == Variance.INVARIANT) { - newArguments += argument - continue + capturedTypes.add(null) + } else { + val lowerType = if (argument is IrTypeProjection && argument.variance == Variance.IN_VARIANCE) { + argument.type + } else null + + capturedTypes.add(IrCapturedType(status, lowerType, argument, parameter)) } + } - val additionalBounds = - if (argument is IrTypeProjection && argument.variance == Variance.OUT_VARIANCE) listOf(argument.type) else emptyList() + val newArguments = ArrayList(typeArguments.size) - newArguments += makeTypeProjection( - makeTypeIntersection(parameter.superTypes + additionalBounds), - Variance.INVARIANT - ) + val typeSubstitutor = IrCapturedTypeSubstitutor(typeParameters.map { it.symbol }, typeArguments, capturedTypes, irBuiltIns) + + for (index in typeArguments.indices) { + val oldArgument = typeArguments[index] + val parameter = typeParameters[index] + val capturedType = capturedTypes[index] + + if (capturedType == null) { + assert(oldArgument is IrTypeProjection && oldArgument.variance == Variance.INVARIANT) + newArguments.add(oldArgument) + } else { + val capturedSuperTypes = mutableListOf() + parameter.superTypes.mapTo(capturedSuperTypes) { + typeSubstitutor.substitute(it) + } + + if (oldArgument is IrTypeProjection && oldArgument.variance == Variance.OUT_VARIANCE) { + capturedSuperTypes += oldArgument.type + } + + capturedType.constructor.initSuperTypes(capturedSuperTypes) + + newArguments.add(makeTypeProjection(capturedType, Variance.INVARIANT)) + } } return IrSimpleTypeImpl(type.classifier, type.hasQuestionMark, newArguments, type.annotations) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt index daecddcd6fd..dac83e8297e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrSimpleTypeImpl.kt @@ -95,6 +95,7 @@ class IrTypeProjectionImpl internal constructor( fun makeTypeProjection(type: IrType, variance: Variance): IrTypeProjection = when { + type is IrCapturedType -> IrTypeProjectionImpl(type, variance) type is IrTypeProjection && type.variance == variance -> type type is IrSimpleType -> type.toBuilder().apply { this.variance = variance }.buildTypeProjection() type is IrDynamicType -> IrDynamicTypeImpl(null, type.annotations, variance) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt index 7bbc6f0859d..edc84085d34 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/impl/IrTypeBase.kt @@ -6,11 +6,15 @@ package org.jetbrains.kotlin.ir.types.impl import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrTypeParameter import org.jetbrains.kotlin.ir.expressions.IrConstructorCall +import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.Variance +import org.jetbrains.kotlin.types.model.CaptureStatus +import org.jetbrains.kotlin.types.model.CapturedTypeConstructorMarker +import org.jetbrains.kotlin.types.model.CapturedTypeMarker import org.jetbrains.kotlin.utils.addToStdlib.safeAs abstract class IrTypeBase(val kotlinType: KotlinType?) : IrType, IrTypeProjection { @@ -69,3 +73,49 @@ object IrUninitializedType : IrType { class ReturnTypeIsNotInitializedException(function: IrFunction) : IllegalStateException( "Return type is not initialized for function '${function.name}'" ) + + +// Please note this type is not denotable which means it could only exist inside type system +class IrCapturedType( + val captureStatus: CaptureStatus, + val lowerType: IrType?, + projection: IrTypeArgument, + typeParameter: IrTypeParameter +) : IrSimpleType, CapturedTypeMarker { + + class Constructor(val argument: IrTypeArgument, val typeParameter: IrTypeParameter) : + CapturedTypeConstructorMarker { + + private var _superTypes: List = emptyList() + + val superTypes: List get() = _superTypes + + fun initSuperTypes(superTypes: List) { + _superTypes = superTypes + } + } + + val constructor: Constructor = Constructor(projection, typeParameter) + + override val classifier: IrClassifierSymbol get() = error("Captured Type does not have a classifier") + override val arguments: List get() = emptyList() + override val abbreviation: IrTypeAbbreviation? get () = null + override val hasQuestionMark: Boolean get() = false + override val annotations: List get() = emptyList() + + override fun equals(other: Any?): Boolean { + return other is IrCapturedType + && captureStatus == other.captureStatus + && lowerType == other.lowerType + && constructor.argument == other.constructor.argument + && constructor.typeParameter == other.constructor.typeParameter + && constructor.superTypes == other.constructor.superTypes + } + + override fun hashCode(): Int { + return (((captureStatus.hashCode() * 31 + + (lowerType?.hashCode() ?: 0)) * 31 + + constructor.argument.hashCode()) * 31 + + constructor.typeParameter.hashCode()) + constructor.superTypes.hashCode() + } +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index 432fd54ea8c..177775d8b70 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.library.IrLibrary import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.protobuf.CodedInputStream import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite.newInstance import org.jetbrains.kotlin.resolve.descriptorUtil.module @@ -64,6 +65,7 @@ abstract class KotlinIrLinker( private val modulesWithReachableTopLevels = mutableSetOf() + // TODO: replace with Map protected val deserializersForModules = mutableMapOf() abstract val fakeOverrideBuilder: FakeOverrideBuilder @@ -665,6 +667,23 @@ abstract class KotlinIrLinker( // symbolTable.noUnboundLeft("unbound after fake overrides:") } + private fun topLevelKindToSymbolKind(kind: IrDeserializer.TopLevelSymbolKind): BinarySymbolData.SymbolKind { + return when (kind) { + IrDeserializer.TopLevelSymbolKind.CLASS_SYMBOL -> BinarySymbolData.SymbolKind.CLASS_SYMBOL + IrDeserializer.TopLevelSymbolKind.PROPERTY_SYMBOL -> BinarySymbolData.SymbolKind.PROPERTY_SYMBOL + IrDeserializer.TopLevelSymbolKind.FUNCTION_SYMBOL -> BinarySymbolData.SymbolKind.FUNCTION_SYMBOL + IrDeserializer.TopLevelSymbolKind.TYPEALIAS_SYMBOL -> BinarySymbolData.SymbolKind.TYPEALIAS_SYMBOL + } + } + + override fun resolveBySignatureInModule(signature: IdSignature, kind: IrDeserializer.TopLevelSymbolKind, moduleName: Name): IrSymbol { + val moduleDeserializer = + deserializersForModules.entries.find { it.key.name == moduleName }?.value ?: error("No module for name '$moduleName' found") + assert(signature == signature.topLevelSignature()) { "Signature '$signature' has to be top level" } + if (signature !in moduleDeserializer) error("No signature $signature in module $moduleName") + return moduleDeserializer.deserializeIrSymbol(signature, topLevelKindToSymbolKind(kind)) + } + // The issue here is that an expect can not trigger its actual deserialization by reachability // because the expect can not see the actual higher in the module dependency dag. // So we force deserialization of actuals for all deserialized expect symbols here. diff --git a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt index 36e21b29d5d..5186b68ab8f 100644 --- a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt +++ b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/directives/LanguageSettingsDirectives.kt @@ -68,6 +68,12 @@ object LanguageSettingsDirectives : SimpleDirectivesContainer() { ) val ENABLE_JVM_PREVIEW by directive("Enable JVM preview features") + val EMIT_JVM_TYPE_ANNOTATIONS by directive("Enable emitting jvm type annotations") + val NO_OPTIMIZED_CALLABLE_REFERENCES by directive("Don't optimize callable references") + val DISABLE_PARAM_ASSERTIONS by directive("Disable assertions on parameters") + val DISABLE_CALL_ASSERTIONS by directive("Disable assertions on calls") + val NO_UNIFIED_NULL_CHECKS by directive("No unified null checks") + val PARAMETERS_METADATA by directive("Add parameters metadata for 1.8 reflection") // --------------------- Utils --------------------- diff --git a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/EnvironmentConfigurator.kt b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/EnvironmentConfigurator.kt index cacb9169004..cef605df6e1 100644 --- a/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/EnvironmentConfigurator.kt +++ b/compiler/test-infrastructure/tests/org/jetbrains/kotlin/test/services/EnvironmentConfigurator.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.test.services -import com.intellij.mock.MockProject import org.jetbrains.kotlin.config.AnalysisFlag import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfigurationKey @@ -22,20 +21,19 @@ abstract class EnvironmentConfigurator(protected val testServices: TestServices) protected val moduleStructure: TestModuleStructure get() = testServices.moduleStructure - protected open fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule, project: MockProject) {} + protected open fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {} fun configureCompileConfigurationWithAdditionalConfigurationKeys( configuration: CompilerConfiguration, module: TestModule, - project: MockProject ) { - configureCompilerConfiguration(configuration, module, project) val extractor = DirectiveToConfigurationKeyExtractor() extractor.provideConfigurationKeys() extractor.configure(configuration, module.directives) + configureCompilerConfiguration(configuration, module) } - protected open fun DirectiveToConfigurationKeyExtractor.provideConfigurationKeys() {} + open fun DirectiveToConfigurationKeyExtractor.provideConfigurationKeys() {} open fun provideAdditionalAnalysisFlags(directives: RegisteredDirectives): Map, Any?> { return emptyMap() diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 766636dd930..b6134d27332 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -44,6 +44,8 @@ where advanced options include: -Xexplicit-api={strict|warning|disable} Force compiler to report errors on all public API declarations without explicit visibility or return type. Use 'warning' level to issue warnings instead of errors. + -Xextended-compiler-checks Enable additional compiler checks that might provide verbose diagnostic information for certain errors. + Warning: this mode is not backward-compatible and might cause compilation errors in previously compiled code. -Xinference-compatibility Enable compatibility changes for generic type inference algorithm -Xinline-classes Enable experimental inline classes -Xintellij-plugin-root= Path to the kotlin-compiler.jar or directory where IntelliJ configuration files can be found diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 8c5061724e1..374d9ca8499 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -152,6 +152,8 @@ where advanced options include: -Xexplicit-api={strict|warning|disable} Force compiler to report errors on all public API declarations without explicit visibility or return type. Use 'warning' level to issue warnings instead of errors. + -Xextended-compiler-checks Enable additional compiler checks that might provide verbose diagnostic information for certain errors. + Warning: this mode is not backward-compatible and might cause compilation errors in previously compiled code. -Xinference-compatibility Enable compatibility changes for generic type inference algorithm -Xinline-classes Enable experimental inline classes -Xintellij-plugin-root= Path to the kotlin-compiler.jar or directory where IntelliJ configuration files can be found diff --git a/compiler/testData/codegen/box/annotations/divisionByZeroInJava.kt b/compiler/testData/codegen/box/annotations/divisionByZeroInJava.kt index 9efe9d0b395..bab5445979f 100644 --- a/compiler/testData/codegen/box/annotations/divisionByZeroInJava.kt +++ b/compiler/testData/codegen/box/annotations/divisionByZeroInJava.kt @@ -1,5 +1,5 @@ // DONT_TARGET_EXACT_BACKEND: JS JS_IR JS_IR_ES6 WASM NATIVE -// KOTLIN_CONFIGURATION_FLAGS: +JVM.USE_PSI_CLASS_FILES_READING +// USE_PSI_CLASS_FILES_READING // MODULE: lib // FILE: J.java diff --git a/compiler/testData/codegen/box/annotations/syntheticMethodForProperty.kt b/compiler/testData/codegen/box/annotations/syntheticMethodForProperty.kt index e61db0ef6ba..925a11aee8c 100644 --- a/compiler/testData/codegen/box/annotations/syntheticMethodForProperty.kt +++ b/compiler/testData/codegen/box/annotations/syntheticMethodForProperty.kt @@ -32,7 +32,7 @@ fun check(clazz: Class<*>, expected: Boolean = true) { assertTrue(Modifier.isStatic(method.modifiers)) assertTrue(Modifier.isPublic(method.modifiers)) val str = method.declaredAnnotations.single().toString() - assertTrue("@test.Anno\\(value=\"?OK\"?\\)".toRegex().matches(str), str) + assertTrue("@test.Anno\\((value=)?\"?OK\"?\\)".toRegex().matches(str), str) return } } diff --git a/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt b/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt index 6023ecf9244..a121fa9b997 100644 --- a/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt +++ b/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturn.kt @@ -1,4 +1,4 @@ -// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// EMIT_JVM_TYPE_ANNOTATIONS // TARGET_BACKEND: JVM // IGNORE_BACKEND_FIR: JVM_IR // JVM_TARGET: 1.8 diff --git a/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturnAgainstCompiled.kt b/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturnAgainstCompiled.kt index f59f598b264..2da713e5688 100644 --- a/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturnAgainstCompiled.kt +++ b/compiler/testData/codegen/box/annotations/typeAnnotations/implicitReturnAgainstCompiled.kt @@ -1,5 +1,5 @@ // DONT_TARGET_EXACT_BACKEND: JS JS_IR JS_IR_ES6 WASM NATIVE -// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// EMIT_JVM_TYPE_ANNOTATIONS // TARGET_BACKEND: JVM // IGNORE_BACKEND_FIR: JVM_IR // JVM_TARGET: 1.8 diff --git a/compiler/testData/codegen/box/annotations/typeAnnotations/kt41484.kt b/compiler/testData/codegen/box/annotations/typeAnnotations/kt41484.kt index 73e2000475f..8830ea504cb 100644 --- a/compiler/testData/codegen/box/annotations/typeAnnotations/kt41484.kt +++ b/compiler/testData/codegen/box/annotations/typeAnnotations/kt41484.kt @@ -1,4 +1,4 @@ -// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// EMIT_JVM_TYPE_ANNOTATIONS // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // FULL_JDK diff --git a/compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt b/compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt index f7ee4f6423d..04a4d9a1cb5 100644 --- a/compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt +++ b/compiler/testData/codegen/box/annotations/typeAnnotations/methodParameters.kt @@ -1,4 +1,4 @@ -// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// EMIT_JVM_TYPE_ANNOTATIONS // TARGET_BACKEND: JVM // IGNORE_BACKEND: ANDROID // JVM_TARGET: 1.8 diff --git a/compiler/testData/codegen/box/annotations/typeAnnotations/typeAnnotationTarget6.kt b/compiler/testData/codegen/box/annotations/typeAnnotations/typeAnnotationTarget6.kt index a849dfc7adb..a882e99ff8f 100644 --- a/compiler/testData/codegen/box/annotations/typeAnnotations/typeAnnotationTarget6.kt +++ b/compiler/testData/codegen/box/annotations/typeAnnotations/typeAnnotationTarget6.kt @@ -1,4 +1,4 @@ -// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// EMIT_JVM_TYPE_ANNOTATIONS // TARGET_BACKEND: JVM // No virtual method getAnnotatedReturnType()Ljava/lang/reflect/AnnotatedType diff --git a/compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt b/compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt index a9f24c24c2d..40aec28cc1a 100644 --- a/compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt +++ b/compiler/testData/codegen/box/annotations/typeAnnotations/typeUseAnnotation.kt @@ -1,4 +1,4 @@ -// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// EMIT_JVM_TYPE_ANNOTATIONS // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_REFLECT diff --git a/compiler/testData/codegen/box/annotations/useTypeParameterAnnotationFromJava.kt b/compiler/testData/codegen/box/annotations/useTypeParameterAnnotationFromJava.kt index 1f656d25d54..9866f803646 100644 --- a/compiler/testData/codegen/box/annotations/useTypeParameterAnnotationFromJava.kt +++ b/compiler/testData/codegen/box/annotations/useTypeParameterAnnotationFromJava.kt @@ -9,14 +9,14 @@ public class A<@Anno(1) T> {} // FILE: Anno.kt -import kotlin.test.assertEquals +import kotlin.test.assertTrue @Target(AnnotationTarget.TYPE_PARAMETER) annotation class Anno(val value: Int = 0) fun box(): String { val typeParameter = A::class.java.typeParameters.single() - assertEquals("[@Anno(value=1)]", typeParameter.annotations.toList().toString()) - + val parametertoString = typeParameter.annotations.toList().toString() + assertTrue("\\[@Anno\\((value=)?1\\)\\]".toRegex().matches(parametertoString), parametertoString) return "OK" } diff --git a/compiler/testData/codegen/box/annotations/useTypeUseAnnotationFromJava.kt b/compiler/testData/codegen/box/annotations/useTypeUseAnnotationFromJava.kt index 800fc34202e..969b298b622 100644 --- a/compiler/testData/codegen/box/annotations/useTypeUseAnnotationFromJava.kt +++ b/compiler/testData/codegen/box/annotations/useTypeUseAnnotationFromJava.kt @@ -14,17 +14,19 @@ public class A { // FILE: Anno.kt import java.lang.reflect.AnnotatedParameterizedType -import kotlin.test.assertEquals +import kotlin.test.assertTrue @Target(AnnotationTarget.TYPE) annotation class Anno(val value: Int = 0) fun box(): String { val method = A::class.java.declaredMethods.single() - assertEquals("[@Anno(value=1)]", method.annotatedReturnType.annotations.toList().toString()) - + val methodToString = method.annotatedReturnType.annotations.toList().toString() + assertTrue("\\[@Anno\\((value=)?1\\)\\]".toRegex().matches(methodToString), methodToString) + val parameterType = method.parameters.single().annotatedType as AnnotatedParameterizedType - assertEquals("[@Anno(value=2)]", parameterType.annotatedActualTypeArguments.single().annotations.toList().toString()) + val parameterToString = parameterType.annotatedActualTypeArguments.single().annotations.toList().toString() + assertTrue("\\[@Anno\\((value=)?2\\)\\]".toRegex().matches(parameterToString), parameterToString) return "OK" } diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/noAdaptedReferencesIfNoOptimizedReferencesEnabled.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/noAdaptedReferencesIfNoOptimizedReferencesEnabled.kt index 231cd324f84..7cf551ee397 100644 --- a/compiler/testData/codegen/box/callableReference/adaptedReferences/noAdaptedReferencesIfNoOptimizedReferencesEnabled.kt +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/noAdaptedReferencesIfNoOptimizedReferencesEnabled.kt @@ -1,6 +1,6 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME -// KOTLIN_CONFIGURATION_FLAGS: +JVM.NO_OPTIMIZED_CALLABLE_REFERENCES +// NO_OPTIMIZED_CALLABLE_REFERENCES class A { fun target(): Int = 42 diff --git a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/typeAnnotations/implicitReturn.kt b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/typeAnnotations/implicitReturn.kt index 22192d5c3b9..a3810a8b2bc 100644 --- a/compiler/testData/codegen/box/compileKotlinAgainstKotlin/typeAnnotations/implicitReturn.kt +++ b/compiler/testData/codegen/box/compileKotlinAgainstKotlin/typeAnnotations/implicitReturn.kt @@ -1,5 +1,5 @@ // IGNORE_BACKEND_FIR: JVM_IR -// KOTLIN_CONFIGURATION_FLAGS: +JVM.EMIT_JVM_TYPE_ANNOTATIONS +// EMIT_JVM_TYPE_ANNOTATIONS // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_REFLECT diff --git a/compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt b/compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt new file mode 100644 index 00000000000..0564ce69ccd --- /dev/null +++ b/compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt @@ -0,0 +1,7 @@ +fun f(): T? = "OK" as? T + +fun g(): Nothing = throw RuntimeException("fail") + +fun h(): T = run { f() } ?: run { g() } + +fun box(): String = h() diff --git a/compiler/testData/codegen/box/fakeOverride/varianceOverload.kt b/compiler/testData/codegen/box/fakeOverride/varianceOverload.kt new file mode 100644 index 00000000000..fa9a4698c7c --- /dev/null +++ b/compiler/testData/codegen/box/fakeOverride/varianceOverload.kt @@ -0,0 +1,63 @@ + +// MODULE: lib +// FILE: lib.kt +// KT-43831 + + +var result = "FAIL" + +class Change : IsChange { + + override fun qux(select: RPPG1): IsChange? { + result = "" + return null + } + + override fun foo(select: RPPG1, sss: RPPG1): Change? { + result += "O" + return null + } + + override fun bar(a: RPPG2>, b: RPPG3, out AC3>): Change? { + result += "K" + return null + } + +} + +interface IsChange { + fun qux(select: RPPG1): IsChange? + + fun foo(select: RPPG1, sss: RPPG1): IsChange? + + + fun bar(a: RPPG2>, b: RPPG3, out AC3>): IsChange? +} + +abstract class AC1 : BAC1() +abstract class AC2 : BAC2() +abstract class AC3 : BAC3() + +interface I1 +interface I2 +interface I3 + +abstract class BAC1 : I1 +abstract class BAC2 : I2 +abstract class BAC3 : I3 + +class RPPG1 +class RPPG2 +class RPPG3 + +// MODULE: main(lib) +// FILE: main.kt + +fun box(): String { + val c = Change() + c.qux(RPPG1()) + c.foo(RPPG1(), RPPG1()) + c.bar(RPPG2(), RPPG3()) + return result + +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/fir/Fir2IrClassifierStorage.kt b/compiler/testData/codegen/box/fir/Fir2IrClassifierStorage.kt new file mode 100644 index 00000000000..9eae51c0c5c --- /dev/null +++ b/compiler/testData/codegen/box/fir/Fir2IrClassifierStorage.kt @@ -0,0 +1,28 @@ +// TARGET_BACKEND: JVM + +class FirSession(val name: String) + +interface Fir2IrComponents { + val session: FirSession + val classifierStorage: Fir2IrClassifierStorage +} + +class Fir2IrComponentsStorage( + override val session: FirSession +) : Fir2IrComponents { + override lateinit var classifierStorage: Fir2IrClassifierStorage +} + +class Fir2IrClassifierStorage( + private val components: Fir2IrComponents +) : Fir2IrComponents by components { + private val name = session.name +} + +fun box(): String { + val session = FirSession("OK") + val components = Fir2IrComponentsStorage(session) + val classifierStorage = Fir2IrClassifierStorage(components) + components.classifierStorage = classifierStorage + return classifierStorage.session.name +} diff --git a/compiler/testData/codegen/box/fir/LookupTags.kt b/compiler/testData/codegen/box/fir/LookupTags.kt new file mode 100644 index 00000000000..4a22d1e8754 --- /dev/null +++ b/compiler/testData/codegen/box/fir/LookupTags.kt @@ -0,0 +1,39 @@ +// TARGET_BACKEND: JVM + +abstract class ConeClassLikeLookupTag { + abstract val status: String +} + +class ConeClassLikeLookupTagImpl : ConeClassLikeLookupTag() { + override var status: String = "" + private set + + fun change(newStatus: String) { + status = newStatus + } +} + +class ConeClassLikeErrorLookupTag : ConeClassLikeLookupTag() { + override val status: String + get() = "ERROR" +} + +fun ConeClassLikeLookupTag.foo(): String { + (this as? ConeClassLikeLookupTagImpl)?.status?.takeIf { it == "OK" }?.let { return it } + return status.also { + (this as? ConeClassLikeLookupTagImpl)?.bar(it) + } +} + +fun ConeClassLikeLookupTagImpl.bar(s: String) { + change(s) +} + +fun box(): String { + val tag = ConeClassLikeErrorLookupTag() + tag.foo() + val tag2 = ConeClassLikeLookupTagImpl() + tag2.change("OK") + tag2.foo() + return tag2.status +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/funInterface/noOptimizedCallableReferences.kt b/compiler/testData/codegen/box/funInterface/noOptimizedCallableReferences.kt index 91f6cd5af8f..d54b147db33 100644 --- a/compiler/testData/codegen/box/funInterface/noOptimizedCallableReferences.kt +++ b/compiler/testData/codegen/box/funInterface/noOptimizedCallableReferences.kt @@ -1,6 +1,6 @@ // DONT_TARGET_EXACT_BACKEND: WASM // WASM_MUTE_REASON: SAM_CONVERSIONS -// KOTLIN_CONFIGURATION_FLAGS: +JVM.NO_OPTIMIZED_CALLABLE_REFERENCES +// NO_OPTIMIZED_CALLABLE_REFERENCES fun interface P { fun get(): String diff --git a/compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt b/compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt new file mode 100644 index 00000000000..8aa0e078d1c --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt @@ -0,0 +1,15 @@ +// WITH_RUNTIME +// KJS_FULL_RUNTIME +// IGNORE_BACKEND: WASM + +interface I { + companion object { + val default: IC by lazy(::IC) + } +} + +inline class IC(val ok: String = "OK") : I + +fun box(): String { + return I.default.ok +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/notNullAssertions/callAssertions.kt b/compiler/testData/codegen/box/notNullAssertions/callAssertions.kt index 6f7e7530a4a..d89575fa449 100644 --- a/compiler/testData/codegen/box/notNullAssertions/callAssertions.kt +++ b/compiler/testData/codegen/box/notNullAssertions/callAssertions.kt @@ -1,6 +1,6 @@ // DONT_TARGET_EXACT_BACKEND: JS JS_IR JS_IR_ES6 WASM NATIVE // IGNORE_BACKEND_FIR: JVM_IR -// KOTLIN_CONFIGURATION_FLAGS: +JVM.DISABLE_PARAM_ASSERTIONS +// DISABLE_PARAM_ASSERTIONS // MODULE: lib // FILE: A.java diff --git a/compiler/testData/codegen/box/notNullAssertions/doGenerateParamAssertions.kt b/compiler/testData/codegen/box/notNullAssertions/doGenerateParamAssertions.kt index 0720bcb81d0..9dbadc6e9cb 100644 --- a/compiler/testData/codegen/box/notNullAssertions/doGenerateParamAssertions.kt +++ b/compiler/testData/codegen/box/notNullAssertions/doGenerateParamAssertions.kt @@ -1,5 +1,5 @@ // DONT_TARGET_EXACT_BACKEND: JS JS_IR JS_IR_ES6 WASM NATIVE -// KOTLIN_CONFIGURATION_FLAGS: +JVM.DISABLE_CALL_ASSERTIONS +// DISABLE_CALL_ASSERTIONS // MODULE: lib // FILE: C.java package test; diff --git a/compiler/testData/codegen/box/notNullAssertions/noCallAssertions.kt b/compiler/testData/codegen/box/notNullAssertions/noCallAssertions.kt index df29dc2408b..14e450c29b2 100644 --- a/compiler/testData/codegen/box/notNullAssertions/noCallAssertions.kt +++ b/compiler/testData/codegen/box/notNullAssertions/noCallAssertions.kt @@ -1,5 +1,6 @@ // DONT_TARGET_EXACT_BACKEND: JS JS_IR JS_IR_ES6 WASM NATIVE -// KOTLIN_CONFIGURATION_FLAGS: +JVM.DISABLE_PARAM_ASSERTIONS, +JVM.DISABLE_CALL_ASSERTIONS +// DISABLE_PARAM_ASSERTIONS +// DISABLE_CALL_ASSERTIONS // MODULE: lib // FILE: A.java diff --git a/compiler/testData/codegen/box/nullCheckOptimization/exclExclThrowsKnpe_1_3.kt b/compiler/testData/codegen/box/nullCheckOptimization/exclExclThrowsKnpe_1_3.kt index d562f04c1ee..54063d52397 100644 --- a/compiler/testData/codegen/box/nullCheckOptimization/exclExclThrowsKnpe_1_3.kt +++ b/compiler/testData/codegen/box/nullCheckOptimization/exclExclThrowsKnpe_1_3.kt @@ -1,4 +1,4 @@ -// KOTLIN_CONFIGURATION_FLAGS: +JVM.NO_UNIFIED_NULL_CHECKS +// NO_UNIFIED_NULL_CHECKS // WITH_RUNTIME // TARGET_BACKEND: JVM diff --git a/compiler/testData/codegen/box/nullCheckOptimization/javaNullCheckThrowsIse_1_3.kt b/compiler/testData/codegen/box/nullCheckOptimization/javaNullCheckThrowsIse_1_3.kt index 72131e10f67..302bc34812a 100644 --- a/compiler/testData/codegen/box/nullCheckOptimization/javaNullCheckThrowsIse_1_3.kt +++ b/compiler/testData/codegen/box/nullCheckOptimization/javaNullCheckThrowsIse_1_3.kt @@ -1,4 +1,4 @@ -// KOTLIN_CONFIGURATION_FLAGS: +JVM.NO_UNIFIED_NULL_CHECKS +// NO_UNIFIED_NULL_CHECKS // TARGET_BACKEND: JVM // FILE: A.java diff --git a/compiler/testData/codegen/box/nullCheckOptimization/parameterNullCheckThrowsIae_1_3.kt b/compiler/testData/codegen/box/nullCheckOptimization/parameterNullCheckThrowsIae_1_3.kt index 82258a5c33c..5102b9e355b 100644 --- a/compiler/testData/codegen/box/nullCheckOptimization/parameterNullCheckThrowsIae_1_3.kt +++ b/compiler/testData/codegen/box/nullCheckOptimization/parameterNullCheckThrowsIae_1_3.kt @@ -1,4 +1,4 @@ -// KOTLIN_CONFIGURATION_FLAGS: +JVM.NO_UNIFIED_NULL_CHECKS +// NO_UNIFIED_NULL_CHECKS // TARGET_BACKEND: JVM // FILE: A.java diff --git a/compiler/testData/codegen/box/parametersMetadata/defaultImpls.kt b/compiler/testData/codegen/box/parametersMetadata/defaultImpls.kt index fb669181576..855d9314608 100644 --- a/compiler/testData/codegen/box/parametersMetadata/defaultImpls.kt +++ b/compiler/testData/codegen/box/parametersMetadata/defaultImpls.kt @@ -2,7 +2,7 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK -// KOTLIN_CONFIGURATION_FLAGS: +JVM.PARAMETERS_METADATA +// PARAMETERS_METADATA interface Test { fun test(OK: String) = "123" @@ -18,4 +18,4 @@ fun box(): String { if (parameters[1].modifiers != 0) return "wrong modifier on value parameter: ${parameters[1].modifiers}" return parameters[1].name -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/parametersMetadata/delegation.kt b/compiler/testData/codegen/box/parametersMetadata/delegation.kt index d1635e5111d..e740188f137 100644 --- a/compiler/testData/codegen/box/parametersMetadata/delegation.kt +++ b/compiler/testData/codegen/box/parametersMetadata/delegation.kt @@ -2,7 +2,7 @@ // WITH_RUNTIME // FULL_JDK // JAVAC_OPTIONS: -parameters -// KOTLIN_CONFIGURATION_FLAGS: +JVM.PARAMETERS_METADATA +// PARAMETERS_METADATA // JVM_TARGET: 1.8 // FILE: JavaInterface.java diff --git a/compiler/testData/codegen/box/parametersMetadata/enum.kt b/compiler/testData/codegen/box/parametersMetadata/enum.kt index 4008e1dfa34..2693b9becff 100644 --- a/compiler/testData/codegen/box/parametersMetadata/enum.kt +++ b/compiler/testData/codegen/box/parametersMetadata/enum.kt @@ -2,7 +2,7 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK -// KOTLIN_CONFIGURATION_FLAGS: +JVM.PARAMETERS_METADATA +// PARAMETERS_METADATA enum class A(val OK: String) { @@ -21,4 +21,4 @@ fun box(): String { if (parameters[2].modifiers != 0) return "wrong modifier on value parameter: ${parameters[2].modifiers}" return parameters[2].name -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/parametersMetadata/extensionFunction.kt b/compiler/testData/codegen/box/parametersMetadata/extensionFunction.kt index 4f76781e1c7..f98eea2dc29 100644 --- a/compiler/testData/codegen/box/parametersMetadata/extensionFunction.kt +++ b/compiler/testData/codegen/box/parametersMetadata/extensionFunction.kt @@ -2,7 +2,7 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK -// KOTLIN_CONFIGURATION_FLAGS: +JVM.PARAMETERS_METADATA +// PARAMETERS_METADATA class A() { fun String.test(OK: String) { @@ -18,4 +18,4 @@ fun box(): String { if (!parameters[0].isImplicit() || parameters[0].isSynthetic()) return "wrong modifier on receiver parameter: ${parameters[0].modifiers}" return parameters[1].name -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/parametersMetadata/function.kt b/compiler/testData/codegen/box/parametersMetadata/function.kt index fb989de805a..8bbf65d0a7c 100644 --- a/compiler/testData/codegen/box/parametersMetadata/function.kt +++ b/compiler/testData/codegen/box/parametersMetadata/function.kt @@ -2,7 +2,7 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK -// KOTLIN_CONFIGURATION_FLAGS: +JVM.PARAMETERS_METADATA +// PARAMETERS_METADATA class A() { fun test(OK: String) { @@ -17,4 +17,4 @@ fun box(): String { if (parameters[0].modifiers != 0) return "wrong modifier on value parameter: ${parameters[0].modifiers}" return parameters[0].name -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/parametersMetadata/inlineClassMethodParameterModifiers.kt b/compiler/testData/codegen/box/parametersMetadata/inlineClassMethodParameterModifiers.kt index 1759e684870..f73e51561b0 100644 --- a/compiler/testData/codegen/box/parametersMetadata/inlineClassMethodParameterModifiers.kt +++ b/compiler/testData/codegen/box/parametersMetadata/inlineClassMethodParameterModifiers.kt @@ -2,7 +2,7 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK -// KOTLIN_CONFIGURATION_FLAGS: +JVM.PARAMETERS_METADATA +// PARAMETERS_METADATA // FILE: A.kt @@ -25,4 +25,4 @@ fun box(): String { return "wrong modifier (not implicit) on extension receiver parameter: ${extensionMethodParameters[0].modifiers}" return "OK" -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/parametersMetadata/inlineClassMethodParameterNames.kt b/compiler/testData/codegen/box/parametersMetadata/inlineClassMethodParameterNames.kt index 92a2fd71951..13c029ef9a2 100644 --- a/compiler/testData/codegen/box/parametersMetadata/inlineClassMethodParameterNames.kt +++ b/compiler/testData/codegen/box/parametersMetadata/inlineClassMethodParameterNames.kt @@ -2,7 +2,7 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK -// KOTLIN_CONFIGURATION_FLAGS: +JVM.PARAMETERS_METADATA +// PARAMETERS_METADATA // FILE: A.kt @@ -24,4 +24,4 @@ fun box(): String { return "wrong name on extension receiver parameter: ${extensionMethodParameters[0].name}" return "OK" -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/parametersMetadata/innerClass.kt b/compiler/testData/codegen/box/parametersMetadata/innerClass.kt index 7d6d6cd9ef9..b68f41b0b2d 100644 --- a/compiler/testData/codegen/box/parametersMetadata/innerClass.kt +++ b/compiler/testData/codegen/box/parametersMetadata/innerClass.kt @@ -2,7 +2,7 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK -// KOTLIN_CONFIGURATION_FLAGS: +JVM.PARAMETERS_METADATA +// PARAMETERS_METADATA class A { inner class B @@ -17,4 +17,4 @@ fun box(): String { if (!parameters[0].isImplicit() || parameters[0].isSynthetic()) return "wrong outer flags: ${parameters[0].modifiers}" return "OK" -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/parametersMetadata/superParams.kt b/compiler/testData/codegen/box/parametersMetadata/superParams.kt index 3441bcdde9f..56aabbb4458 100644 --- a/compiler/testData/codegen/box/parametersMetadata/superParams.kt +++ b/compiler/testData/codegen/box/parametersMetadata/superParams.kt @@ -2,7 +2,7 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK -// KOTLIN_CONFIGURATION_FLAGS: +JVM.PARAMETERS_METADATA +// PARAMETERS_METADATA open class A(val s: String) @@ -17,4 +17,4 @@ fun box(): String { if (!parameters[0].isSynthetic() || parameters[0].isImplicit()) return "wrong modifier on value parameter: ${parameters[0].modifiers}" return value.s -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/parametersMetadata/suspendFunction.kt b/compiler/testData/codegen/box/parametersMetadata/suspendFunction.kt index b79a3386c7b..4a020ea1cec 100644 --- a/compiler/testData/codegen/box/parametersMetadata/suspendFunction.kt +++ b/compiler/testData/codegen/box/parametersMetadata/suspendFunction.kt @@ -2,7 +2,7 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME // FULL_JDK -// KOTLIN_CONFIGURATION_FLAGS: +JVM.PARAMETERS_METADATA +// PARAMETERS_METADATA import kotlin.coroutines.* import kotlin.coroutines.intrinsics.* diff --git a/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt b/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt index f3e631af95d..f918b969953 100644 --- a/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt +++ b/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt @@ -23,7 +23,7 @@ class C { } fun box(): String { - assertTrue("\\[@Anno\\(value=void(\\.class)?\\)\\]".toRegex().matches(C::f1.annotations.toString())) - assertTrue("\\[@Anno\\(value=(class )?java.lang.Void(\\.class)?\\)\\]".toRegex().matches(C::f2.annotations.toString())) + assertTrue("\\[@Anno\\((value=)?void(\\.class)?\\)\\]".toRegex().matches(C::f1.annotations.toString())) + assertTrue("\\[@Anno\\((value=)?(class )?java.lang.Void(\\.class)?\\)\\]".toRegex().matches(C::f2.annotations.toString())) return "OK" } diff --git a/compiler/testData/codegen/box/reflection/builtins/enumNameOrdinal.kt b/compiler/testData/codegen/box/reflection/builtins/enumNameOrdinal.kt index b9e1340b5dc..e53e8fd6cef 100644 --- a/compiler/testData/codegen/box/reflection/builtins/enumNameOrdinal.kt +++ b/compiler/testData/codegen/box/reflection/builtins/enumNameOrdinal.kt @@ -3,11 +3,12 @@ // WITH_REFLECT import kotlin.test.assertEquals +import kotlin.test.assertTrue enum class E { X, Y, Z } fun box(): String { - assertEquals(11, E::class.members.size) + assertTrue(E::class.members.size in 11..12, "" + E::class.members.size) assertEquals("Y", E::name.call(E.Y)) assertEquals(2, E::ordinal.call(E.Z)) return "OK" diff --git a/compiler/testData/codegen/box/reflection/genericSignature/kt11121.kt b/compiler/testData/codegen/box/reflection/genericSignature/kt11121.kt index 3d12e88a93c..4c677b3f486 100644 --- a/compiler/testData/codegen/box/reflection/genericSignature/kt11121.kt +++ b/compiler/testData/codegen/box/reflection/genericSignature/kt11121.kt @@ -19,10 +19,12 @@ interface A> { fun box(): String { val defaultImpls = Class.forName("test.A\$DefaultImpls") val declaredMethod = defaultImpls.getDeclaredMethod("p", A::class.java, Any::class.java) - if (declaredMethod.toGenericString() != "public static T test.A\$DefaultImpls.p(test.A,T)") return "fail 1: ${declaredMethod.toGenericString()}" + if (declaredMethod.toGenericString() != "public static T test.A\$DefaultImpls.p(test.A,T)" && + declaredMethod.toGenericString() != "public static ,T,L> T test.A\$DefaultImpls.p(test.A,T)") return "fail 1: ${declaredMethod.toGenericString()}" val declaredProperty = defaultImpls.getDeclaredMethod("getZ", A::class.java, Any::class.java) - if (declaredProperty.toGenericString() != "public static T test.A\$DefaultImpls.getZ(test.A,T)") return "fail 2: ${declaredProperty.toGenericString()}" + if (declaredProperty.toGenericString() != "public static T test.A\$DefaultImpls.getZ(test.A,T)" && + declaredProperty.toGenericString() != "public static ,T> T test.A\$DefaultImpls.getZ(test.A,T)") return "fail 2: ${declaredProperty.toGenericString()}" return "OK" } diff --git a/compiler/testData/codegen/box/sealed/multipleFiles_enabled.kt b/compiler/testData/codegen/box/sealed/multipleFiles_enabled.kt index ff712206259..a54e80d1569 100644 --- a/compiler/testData/codegen/box/sealed/multipleFiles_enabled.kt +++ b/compiler/testData/codegen/box/sealed/multipleFiles_enabled.kt @@ -1,5 +1,4 @@ // ISSUE: KT-13495 -// IGNORE_BACKEND_FIR: JVM_IR // !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage // FILE: Base.kt diff --git a/compiler/testData/codegen/box/typealias/extensionFunction.kt b/compiler/testData/codegen/box/typealias/extensionFunction.kt new file mode 100644 index 00000000000..7c1bda54df3 --- /dev/null +++ b/compiler/testData/codegen/box/typealias/extensionFunction.kt @@ -0,0 +1,8 @@ +typealias F = T.() -> R + +inline fun T.myRun(f: F) = f() + +fun box(): String { + val x = "K" + return "O".myRun { this + x } +} diff --git a/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt b/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt new file mode 100644 index 00000000000..f381f4f6c99 --- /dev/null +++ b/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt @@ -0,0 +1,17 @@ +// DONT_TARGET_EXACT_BACKEND: WASM +// WASM_MUTE_REASON: BINDING_RECEIVERS + +// FILE: 1.kt +package test + +inline fun foo(x: () -> Unit): String { + x() + return "OK" +} + +inline fun String.id(s: String = this, vararg xs: Int): String = s + +// FILE: 2.kt +import test.* + +fun box(): String = foo("Fail"::id) diff --git a/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt b/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt new file mode 100644 index 00000000000..bd8f565ec9a --- /dev/null +++ b/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt @@ -0,0 +1,19 @@ +// DONT_TARGET_EXACT_BACKEND: WASM +// WASM_MUTE_REASON: STDLIB_TEXT +// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType +// WITH_RUNTIME +// KJS_WITH_FULL_RUNTIME + +// FILE: 1.kt +package test + +inline fun foo(mkString: () -> String): String = + mkString() + +inline fun bar (xs: CharArray = charArrayOf('O','K')) = + String(xs) + +// FILE: 2.kt +import test.* + +fun box(): String = foo(::bar) diff --git a/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt b/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt new file mode 100644 index 00000000000..eb009f99f26 --- /dev/null +++ b/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt @@ -0,0 +1,20 @@ +// DONT_TARGET_EXACT_BACKEND: WASM +// WASM_MUTE_REASON: IGNORED_IN_JS +// !LANGUAGE: +NewInference + +// FILE: 1.kt +package test + +inline fun foo(f: (Int, Int) -> Int): Int = + f(42, 117) + +inline fun bar (vararg xs: Int): Int { + var sum = 0 + for (x in xs) sum += x + return sum +} + +// FILE: 2.kt +import test.* + +fun box(): String = if (foo(::bar) == 159) "OK" else "fail" diff --git a/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt b/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt new file mode 100644 index 00000000000..f3e286ce301 --- /dev/null +++ b/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt @@ -0,0 +1,14 @@ +// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType + +// FILE: 1.kt +package test + +inline fun foo(vararg l: Long, s: String = "OK"): String = + if (l.size == 0) s else "Fail" + +inline fun bar(f: () -> String): String = f() + +// FILE: 2.kt +import test.* + +fun box(): String = bar(::foo) diff --git a/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt b/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt new file mode 100644 index 00000000000..58f41020c96 --- /dev/null +++ b/compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt @@ -0,0 +1,18 @@ +// !LANGUAGE: +NewInference +// WITH_RUNTIME +// KJS_WITH_FULL_RUNTIME + +// FILE: 1.kt +package test + +inline fun foo(x: (Int, Int) -> Int): Int = + x(120,3) + +inline fun bar(vararg x: Int): Int = + x.sum() + +// FILE: 2.kt +import test.* + +fun box(): String = + if (foo(::bar) == 123) "OK" else "FAIL" diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/fromInterfaceDefaultGetter.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/fromInterfaceDefaultGetter.kt index 3931a5b00e5..8f2b2734c17 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/fromInterfaceDefaultGetter.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/fromInterfaceDefaultGetter.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/nonLocalReturns/propertyAccessors.kt b/compiler/testData/codegen/boxInline/nonLocalReturns/propertyAccessors.kt index c7229da93c3..275024ae34f 100644 --- a/compiler/testData/codegen/boxInline/nonLocalReturns/propertyAccessors.kt +++ b/compiler/testData/codegen/boxInline/nonLocalReturns/propertyAccessors.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: 1.kt package test diff --git a/compiler/testData/codegen/boxInline/reified/checkCast/simple_1_3.kt b/compiler/testData/codegen/boxInline/reified/checkCast/simple_1_3.kt index ab0a88e0b46..ffea2f99c22 100644 --- a/compiler/testData/codegen/boxInline/reified/checkCast/simple_1_3.kt +++ b/compiler/testData/codegen/boxInline/reified/checkCast/simple_1_3.kt @@ -1,5 +1,5 @@ // WITH_RUNTIME -// KOTLIN_CONFIGURATION_FLAGS: +JVM.NO_UNIFIED_NULL_CHECKS +// NO_UNIFIED_NULL_CHECKS // TARGET_BACKEND: JVM // FILE: 1.kt package test diff --git a/compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet.kt b/compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet.kt new file mode 100644 index 00000000000..b43f15d7bfe --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME +// FULL_JDK + +import java.util.* + +class ListSet : List, Set { + override val size: Int get() = TODO() + override fun isEmpty(): Boolean = TODO() + override fun get(index: Int): E = TODO() + override fun contains(element: @UnsafeVariance E): Boolean = TODO() + override fun containsAll(elements: Collection<@UnsafeVariance E>): Boolean = TODO() + override fun indexOf(element: @UnsafeVariance E): Int = TODO() + override fun lastIndexOf(element: @UnsafeVariance E): Int = TODO() + override fun iterator(): Iterator = TODO() + override fun listIterator(): ListIterator = TODO() + override fun listIterator(index: Int): ListIterator = TODO() + override fun spliterator(): Spliterator<@UnsafeVariance E> = TODO() + override fun subList(fromIndex: Int, toIndex: Int): List = TODO() +} diff --git a/compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet.txt b/compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet.txt new file mode 100644 index 00000000000..9e889e63227 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet.txt @@ -0,0 +1,32 @@ +@kotlin.Metadata +public final class ListSet { + // source: 'ListAndSet.kt' + public method (): void + public method add(p0: int, p1: java.lang.Object): void + public method add(p0: java.lang.Object): boolean + public method addAll(p0: int, p1: java.util.Collection): boolean + public method addAll(p0: java.util.Collection): boolean + public method clear(): void + public method contains(@org.jetbrains.annotations.NotNull p0: java.lang.Object): boolean + public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean + public @org.jetbrains.annotations.NotNull method get(p0: int): java.lang.Object + public method getSize(): int + public method indexOf(@org.jetbrains.annotations.NotNull p0: java.lang.Object): int + public method isEmpty(): boolean + public @org.jetbrains.annotations.NotNull method iterator(): java.util.Iterator + public method lastIndexOf(@org.jetbrains.annotations.NotNull p0: java.lang.Object): int + public @org.jetbrains.annotations.NotNull method listIterator(): java.util.ListIterator + public @org.jetbrains.annotations.NotNull method listIterator(p0: int): java.util.ListIterator + public method remove(p0: int): java.lang.Object + public method remove(p0: java.lang.Object): boolean + public method removeAll(p0: java.util.Collection): boolean + public method replaceAll(p0: java.util.function.UnaryOperator): void + public method retainAll(p0: java.util.Collection): boolean + public method set(p0: int, p1: java.lang.Object): java.lang.Object + public bridge final method size(): int + public method sort(p0: java.util.Comparator): void + public @org.jetbrains.annotations.NotNull method spliterator(): java.util.Spliterator + public @org.jetbrains.annotations.NotNull method subList(p0: int, p1: int): java.util.List + public method toArray(): java.lang.Object[] + public method toArray(p0: java.lang.Object[]): java.lang.Object[] +} diff --git a/compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet_ir.txt b/compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet_ir.txt new file mode 100644 index 00000000000..547b26a7d2a --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet_ir.txt @@ -0,0 +1,32 @@ +@kotlin.Metadata +public final class ListSet { + // source: 'ListAndSet.kt' + public method (): void + public method add(p0: int, p1: java.lang.Object): void + public method add(p0: java.lang.Object): boolean + public method addAll(p0: int, p1: java.util.Collection): boolean + public method addAll(p0: java.util.Collection): boolean + public method clear(): void + public method contains(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean + public method containsAll(@org.jetbrains.annotations.NotNull p0: java.util.Collection): boolean + public @org.jetbrains.annotations.NotNull method get(p0: int): java.lang.Object + public method getSize(): int + public method indexOf(@org.jetbrains.annotations.Nullable p0: java.lang.Object): int + public method isEmpty(): boolean + public @org.jetbrains.annotations.NotNull method iterator(): java.util.Iterator + public method lastIndexOf(@org.jetbrains.annotations.Nullable p0: java.lang.Object): int + public @org.jetbrains.annotations.NotNull method listIterator(): java.util.ListIterator + public @org.jetbrains.annotations.NotNull method listIterator(p0: int): java.util.ListIterator + public method remove(p0: int): java.lang.Object + public method remove(p0: java.lang.Object): boolean + public method removeAll(p0: java.util.Collection): boolean + public method replaceAll(p0: java.util.function.UnaryOperator): void + public method retainAll(p0: java.util.Collection): boolean + public method set(p0: int, p1: java.lang.Object): java.lang.Object + public bridge final method size(): int + public method sort(p0: java.util.Comparator): void + public @org.jetbrains.annotations.NotNull method spliterator(): java.util.Spliterator + public @org.jetbrains.annotations.NotNull method subList(p0: int, p1: int): java.util.List + public method toArray(): java.lang.Object[] + public method toArray(p0: java.lang.Object[]): java.lang.Object[] +} diff --git a/compiler/testData/codegen/bytecodeText/hashCode/interfaceHashCode.kt b/compiler/testData/codegen/bytecodeText/hashCode/interfaceHashCode.kt index c6758916d84..c236203d714 100644 --- a/compiler/testData/codegen/bytecodeText/hashCode/interfaceHashCode.kt +++ b/compiler/testData/codegen/bytecodeText/hashCode/interfaceHashCode.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR val x: () -> Unit = {} val y = x.hashCode() diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyErrorPositions/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyErrorPositions/output.txt index 98c12b14fef..ea5ffd56f74 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyErrorPositions/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyErrorPositions/output.txt @@ -1,5 +1,6 @@ error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath: class test.Sub, unresolved supertypes: test.Super +Adding -Xextended-compiler-checks argument might provide additional information. compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyErrorPositions/source.kt:3:1: error: cannot access 'test.Super' which is a supertype of 'SubSub'. Check your module classpath for missing or conflicting dependencies class SubSub : Sub() diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInJava/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInJava/output.txt index c92ccf9dfb0..5c1236ca777 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInJava/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInJava/output.txt @@ -1,5 +1,6 @@ error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath: class test.Sub, unresolved supertypes: test.Super +Adding -Xextended-compiler-checks argument might provide additional information. compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInJava/source.kt:3:1: error: cannot access 'test.Super' which is a supertype of 'SubSub'. Check your module classpath for missing or conflicting dependencies class SubSub : Sub() diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInKotlin/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInKotlin/output.txt index faeca3c57dc..8171f0c3fed 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInKotlin/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInKotlin/output.txt @@ -1,5 +1,6 @@ error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath: class test.Sub, unresolved supertypes: test.Super +Adding -Xextended-compiler-checks argument might provide additional information. compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInKotlin/source.kt:3:1: error: cannot access 'test.Super' which is a supertype of 'SubSub'. Check your module classpath for missing or conflicting dependencies class SubSub : Sub() diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyMissingInterface/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyMissingInterface/output.txt index 71b5795f63e..29fad2bbc02 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyMissingInterface/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyMissingInterface/output.txt @@ -1,5 +1,6 @@ error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath: class test.B, unresolved supertypes: test.A +Adding -Xextended-compiler-checks argument might provide additional information. compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyMissingInterface/source.kt:5:15: error: cannot access 'test.A' which is a supertype of 'test.B'. Check your module classpath for missing or conflicting dependencies D.m(B.n()) diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyOfEnclosingClass/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyOfEnclosingClass/output.txt index 0c1c50f7b34..c6a2ae58a40 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyOfEnclosingClass/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyOfEnclosingClass/output.txt @@ -1,6 +1,7 @@ error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath: class test.SubClass, unresolved supertypes: test.Super class test.SubObject, unresolved supertypes: test.Super +Adding -Xextended-compiler-checks argument might provide additional information. compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyOfEnclosingClass/source.kt:6:16: error: cannot access 'test.Super' which is a supertype of 'test.SubClass'. Check your module classpath for missing or conflicting dependencies SubClass().Inner() // Error - dispatch receiver misses supertype diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/library/test/Sub.java b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/library/test/Sub.java new file mode 100644 index 00000000000..aa08b2fb540 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/library/test/Sub.java @@ -0,0 +1,5 @@ +package test; + +public class Sub extends Super { + +} \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/library/test/SubKt.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/library/test/SubKt.kt new file mode 100644 index 00000000000..e14b52fe04f --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/library/test/SubKt.kt @@ -0,0 +1,11 @@ +package test + +class SubKt : Super() { + companion object { + fun companionMethod() = "OK" + } + + object InnerObject { + fun objectMethod() = "OK" + } +} \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/library/test/Super.java b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/library/test/Super.java new file mode 100644 index 00000000000..56493e0dee6 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/library/test/Super.java @@ -0,0 +1,7 @@ +package test; + +public class Super { + String foo() { + return "Super"; + } +} \ No newline at end of file diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/output.txt new file mode 100644 index 00000000000..2ff691d93aa --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/output.txt @@ -0,0 +1,20 @@ +error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath: + class test.Sub, unresolved supertypes: test.Super + class test.SubKt, unresolved supertypes: test.Super + +compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/source.kt:12:32: error: cannot access 'test.Super' which is a supertype of 'Sub'. Check your module classpath for missing or conflicting dependencies +fun simpleFun(arg: Sub): Sub = Sub() + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/source.kt:19:18: error: cannot access 'test.Super' which is a supertype of 'Sub'. Check your module classpath for missing or conflicting dependencies + val x: Sub = Sub() + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/source.kt:21:18: error: cannot access 'test.Super' which is a supertype of 'Sub'. Check your module classpath for missing or conflicting dependencies + useCallRef(::Sub) + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/source.kt:22:15: error: cannot access 'test.Super' which is a supertype of 'Sub'. Check your module classpath for missing or conflicting dependencies + simpleFun(Sub()) + ^ +compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/source.kt:23:20: error: cannot access 'test.Super' which is a supertype of 'Sub'. Check your module classpath for missing or conflicting dependencies + inlineFun(Sub()) + ^ +COMPILATION_ERROR diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/source.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/source.kt new file mode 100644 index 00000000000..d68fac51dae --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyWithExtendedCompilerChecks/source.kt @@ -0,0 +1,26 @@ +import test.Sub as MySub +import test.SubKt + +typealias Sub = MySub + +class Test + +@Suppress("UNUSED_PARAMETER") +fun useCallRef(ref: Any?) {} + +@Suppress("UNUSED_PARAMETER") +fun simpleFun(arg: Sub): Sub = Sub() + +inline fun inlineFun(t: T) = t + +// In conservative mode without -Xextended-compiler-checks flag these usages don't cause compilation error +fun test() { + @Suppress("UNUSED_VARIABLE") + val x: Sub = Sub() + Test() + useCallRef(::Sub) + simpleFun(Sub()) + inlineFun(Sub()) + SubKt.companionMethod() + SubKt.InnerObject.objectMethod() +} diff --git a/compiler/testData/diagnostics/tests/Abstract.fir.kt b/compiler/testData/diagnostics/tests/Abstract.fir.kt index 7fcfaf02691..5582acd2514 100644 --- a/compiler/testData/diagnostics/tests/Abstract.fir.kt +++ b/compiler/testData/diagnostics/tests/Abstract.fir.kt @@ -17,7 +17,7 @@ package MyPackage abstract var c3: Int = 0; set(v: Int) { field = v } val e: Int get() = a - val e1: Int = 0; get() = a + val e1: Int = 0; get() = a abstract val e2: Int get() = a abstract val e3: Int = 0; get() = a diff --git a/compiler/testData/diagnostics/tests/AbstractInAbstractClass.fir.kt b/compiler/testData/diagnostics/tests/AbstractInAbstractClass.fir.kt index a5c0060cc34..974bcb1a127 100644 --- a/compiler/testData/diagnostics/tests/AbstractInAbstractClass.fir.kt +++ b/compiler/testData/diagnostics/tests/AbstractInAbstractClass.fir.kt @@ -18,7 +18,7 @@ abstract class MyAbstractClass() { abstract var c3: Int = 0; set(v: Int) { field = v } val e: Int get() = a - val e1: Int = 0; get() = a + val e1: Int = 0; get() = a abstract val e2: Int get() = a abstract val e3: Int = 0; get() = a diff --git a/compiler/testData/diagnostics/tests/AbstractInClass.fir.kt b/compiler/testData/diagnostics/tests/AbstractInClass.fir.kt index 4de56d72753..d15460e0529 100644 --- a/compiler/testData/diagnostics/tests/AbstractInClass.fir.kt +++ b/compiler/testData/diagnostics/tests/AbstractInClass.fir.kt @@ -18,7 +18,7 @@ class MyClass() { abstract var c3: Int = 0; set(v: Int) { field = v } val e: Int get() = a - val e1: Int = 0; get() = a + val e1: Int = 0; get() = a abstract val e2: Int get() = a abstract val e3: Int = 0; get() = a diff --git a/compiler/testData/diagnostics/tests/AbstractInTrait.fir.kt b/compiler/testData/diagnostics/tests/AbstractInTrait.fir.kt index d047654732f..74eab4a6220 100644 --- a/compiler/testData/diagnostics/tests/AbstractInTrait.fir.kt +++ b/compiler/testData/diagnostics/tests/AbstractInTrait.fir.kt @@ -12,8 +12,8 @@ interface MyTrait { abstract var b2: Int private set abstract var b3: Int = 0; private set - var c: Int set(v: Int) { field = v } - var c1: Int = 0; set(v: Int) { field = v } + var c: Int set(v: Int) { field = v } + var c1: Int = 0; set(v: Int) { field = v } abstract var c2: Int set(v: Int) { field = v } abstract var c3: Int = 0; set(v: Int) { field = v } @@ -32,8 +32,8 @@ interface MyTrait { var i: Int abstract get abstract set var i1: Int = 0; abstract get abstract set - var j: Int get() = i; abstract set - var j1: Int = 0; get() = i; abstract set + var j: Int get() = i; abstract set + var j1: Int = 0; get() = i; abstract set var k: Int abstract set var k1: Int = 0; abstract set @@ -41,5 +41,5 @@ interface MyTrait { var l: Int abstract get abstract set var l1: Int = 0; abstract get abstract set - var n: Int abstract get abstract set(v: Int) {} + var n: Int abstract get abstract set(v: Int) {} } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/Constructors.fir.kt b/compiler/testData/diagnostics/tests/Constructors.fir.kt index b891906c1c2..b5b60357796 100644 --- a/compiler/testData/diagnostics/tests/Constructors.fir.kt +++ b/compiler/testData/diagnostics/tests/Constructors.fir.kt @@ -29,7 +29,7 @@ class WithCPI(x : Int) { class NoCPI { val a = 1 - var ab = 1 + var ab = 1 get() = 1 set(v) {} } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.fir.kt b/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.fir.kt index 6a62617d900..14ccbb2caa7 100644 --- a/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.fir.kt +++ b/compiler/testData/diagnostics/tests/FunctionCalleeExpressions.fir.kt @@ -72,7 +72,7 @@ fun main1() { 1."sdf" 1.{} - 1.if (true) {} + 1.if (true) {} } fun test() { diff --git a/compiler/testData/diagnostics/tests/FunctionReturnTypes.fir.kt b/compiler/testData/diagnostics/tests/FunctionReturnTypes.fir.kt index 628041e7526..8a956ae6273 100644 --- a/compiler/testData/diagnostics/tests/FunctionReturnTypes.fir.kt +++ b/compiler/testData/diagnostics/tests/FunctionReturnTypes.fir.kt @@ -70,7 +70,7 @@ fun blockReturnValueTypeMatch1() : Int { return if (1 > 2) 1.0 else 2.0 } fun blockReturnValueTypeMatch2() : Int { - return if (1 > 2) 1 + return if (1 > 2) 1 } fun blockReturnValueTypeMatch3() : Int { return if (1 > 2) else 1 @@ -106,7 +106,7 @@ fun blockReturnValueTypeMatch9() : Int { 1.0 } fun blockReturnValueTypeMatch10() : Int { - return if (1 > 2) + return if (1 > 2) 1 } fun blockReturnValueTypeMatch11() : Int { diff --git a/compiler/testData/diagnostics/tests/Properties.fir.kt b/compiler/testData/diagnostics/tests/Properties.fir.kt index ba5fcedde03..1ea464765d3 100644 --- a/compiler/testData/diagnostics/tests/Properties.fir.kt +++ b/compiler/testData/diagnostics/tests/Properties.fir.kt @@ -5,11 +5,11 @@ var x : Int = 1 + x field = 1.toLong() } - val xx : Int = 1 + x + val xx : Int = 1 + x get() : Int = 1 set(value : Long) {} - val p : Int = 1 + val p : Int = 1 get() = 1 class Test() { diff --git a/compiler/testData/diagnostics/tests/backingField/ExtensionProperty.fir.kt b/compiler/testData/diagnostics/tests/backingField/ExtensionProperty.fir.kt deleted file mode 100644 index f74a893bd70..00000000000 --- a/compiler/testData/diagnostics/tests/backingField/ExtensionProperty.fir.kt +++ /dev/null @@ -1,17 +0,0 @@ -// See KT-9303: synthetic field variable does not exist for extension properties -val String.foo: Int - get() { - // No shadowing here - val field = 42 - return field - } - -val String.bar: Int = 13 - // Error - get() = field - -class My { - val String.x: Int = 7 - // Error - get() = field -} diff --git a/compiler/testData/diagnostics/tests/backingField/ExtensionProperty.kt b/compiler/testData/diagnostics/tests/backingField/ExtensionProperty.kt index 27858f2148b..210c99b5452 100644 --- a/compiler/testData/diagnostics/tests/backingField/ExtensionProperty.kt +++ b/compiler/testData/diagnostics/tests/backingField/ExtensionProperty.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // See KT-9303: synthetic field variable does not exist for extension properties val String.foo: Int get() { diff --git a/compiler/testData/diagnostics/tests/backingField/FieldInInterface.fir.kt b/compiler/testData/diagnostics/tests/backingField/FieldInInterface.fir.kt deleted file mode 100644 index 18688620953..00000000000 --- a/compiler/testData/diagnostics/tests/backingField/FieldInInterface.fir.kt +++ /dev/null @@ -1,4 +0,0 @@ -interface My { - val x: Int = 0 - get() = field -} diff --git a/compiler/testData/diagnostics/tests/backingField/FieldInInterface.kt b/compiler/testData/diagnostics/tests/backingField/FieldInInterface.kt index 33118847789..fed3bd4e6b9 100644 --- a/compiler/testData/diagnostics/tests/backingField/FieldInInterface.kt +++ b/compiler/testData/diagnostics/tests/backingField/FieldInInterface.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface My { val x: Int = 0 get() = field diff --git a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt1185enums.fir.kt b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt1185enums.fir.kt index 80b24b11bdc..48a32d9ed13 100644 --- a/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt1185enums.fir.kt +++ b/compiler/testData/diagnostics/tests/controlFlowAnalysis/kt1185enums.fir.kt @@ -29,7 +29,7 @@ fun foo(d: Direction) = when(d) { //no 'else' should be requested Direction.EAST -> 4 } -fun foo1(d: Direction) = when(d) { +fun foo1(d: Direction) = when(d) { Direction.NORTH -> 1 Direction.SOUTH -> 2 Direction.WEST -> 3 @@ -41,7 +41,7 @@ fun bar(c: Color) = when (c) { Color.BLUE -> 3 } -fun bar1(c: Color) = when (c) { +fun bar1(c: Color) = when (c) { Color.RED -> 1 Color.GREEN -> 2 -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/controlStructures/emptyIf.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/emptyIf.fir.kt deleted file mode 100644 index 5da2c7adbbe..00000000000 --- a/compiler/testData/diagnostics/tests/controlStructures/emptyIf.fir.kt +++ /dev/null @@ -1,16 +0,0 @@ -fun foo(x: Unit) = x - -fun test() { - if (false); - if (true); - - val x = if (false); - foo(x) - - val y: Unit = if (false); - foo(y) - - foo({if (1==1);}()) - - return if (true); -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/controlStructures/emptyIf.kt b/compiler/testData/diagnostics/tests/controlStructures/emptyIf.kt index 13ce5412108..e12b774f2dd 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/emptyIf.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/emptyIf.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL fun foo(x: Unit) = x fun test() { diff --git a/compiler/testData/diagnostics/tests/controlStructures/ifWhenToAnyComplexExpressions.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/ifWhenToAnyComplexExpressions.fir.kt index bd173b19cde..280f15a6478 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/ifWhenToAnyComplexExpressions.fir.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/ifWhenToAnyComplexExpressions.fir.kt @@ -11,7 +11,7 @@ fun testMixedIfAndWhen() = else 1 true -> if (true) 42 else println() - else -> if (true) println() + else -> if (true) println() } else println() @@ -28,4 +28,4 @@ fun testWrappedExpressions() = } else { (((((42)) + 1))) - } \ No newline at end of file + } diff --git a/compiler/testData/diagnostics/tests/controlStructures/ifWhenWithoutElse.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/ifWhenWithoutElse.fir.kt index ee00a4e882d..263daaaa536 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/ifWhenWithoutElse.fir.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/ifWhenWithoutElse.fir.kt @@ -11,21 +11,21 @@ val mlist = MList() fun work() {} -val xx1 = if (true) 42 -val xx2: Unit = if (true) 42 -val xx3 = idAny(if (true) 42) -val xx4 = id(if (true) 42) -val xx5 = idUnit(if (true) 42) -val xx6 = null ?: if (true) 42 -val xx7 = "" + if (true) 42 +val xx1 = if (true) 42 +val xx2: Unit = if (true) 42 +val xx3 = idAny(if (true) 42) +val xx4 = id(if (true) 42) +val xx5 = idUnit(if (true) 42) +val xx6 = null ?: if (true) 42 +val xx7 = "" + if (true) 42 -val wxx1 = when { true -> 42 } -val wxx2: Unit = when { true -> 42 } -val wxx3 = idAny(when { true -> 42 }) -val wxx4 = id(when { true -> 42 }) -val wxx5 = idUnit(when { true -> 42 }) -val wxx6 = null ?: when { true -> 42 } -val wxx7 = "" + when { true -> 42 } +val wxx1 = when { true -> 42 } +val wxx2: Unit = when { true -> 42 } +val wxx3 = idAny(when { true -> 42 }) +val wxx4 = id(when { true -> 42 }) +val wxx5 = idUnit(when { true -> 42 }) +val wxx6 = null ?: when { true -> 42 } +val wxx7 = "" + when { true -> 42 } val fn1 = { if (true) 42 } val fn2 = { if (true) mlist.add() } @@ -41,24 +41,24 @@ val ufn4: () -> Unit = { when { true -> 42 } } val ufn5: () -> Unit = { when { true -> mlist.add() } } val ufn6: () -> Unit = { when { true -> work() } } -fun f1() = if (true) work() -fun f2() = if (true) mlist.add() -fun f3() = if (true) 42 -fun f4(): Unit = if (true) work() -fun f5(): Unit = if (true) mlist.add() -fun f6(): Unit = if (true) 42 -fun g1() = when { true -> work() } -fun g2() = when { true -> mlist.add() } -fun g3() = when { true -> 42 } -fun g4(): Unit = when { true -> work() } -fun g5(): Unit = when { true -> mlist.add() } -fun g6(): Unit = when { true -> 42 } +fun f1() = if (true) work() +fun f2() = if (true) mlist.add() +fun f3() = if (true) 42 +fun f4(): Unit = if (true) work() +fun f5(): Unit = if (true) mlist.add() +fun f6(): Unit = if (true) 42 +fun g1() = when { true -> work() } +fun g2() = when { true -> mlist.add() } +fun g3() = when { true -> 42 } +fun g4(): Unit = when { true -> work() } +fun g5(): Unit = when { true -> mlist.add() } +fun g6(): Unit = when { true -> 42 } fun foo1(x: String?) { - "" + if (true) 42 + "" + if (true) 42 w@while (true) { - x ?: if (true) break - x ?: when { true -> break@w } + x ?: if (true) break + x ?: when { true -> break@w } } } diff --git a/compiler/testData/diagnostics/tests/controlStructures/improperElseInExpression.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/improperElseInExpression.fir.kt index c36cb381506..bc9b8f49d94 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/improperElseInExpression.fir.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/improperElseInExpression.fir.kt @@ -4,7 +4,7 @@ fun example() { val a = if (true) true else false val b = if (true) else false - val c = if (true) true + val c = if (true) true val d = if (true) true else; val e = if (true) {} else false val f = if (true) true else {} @@ -27,7 +27,7 @@ fun example() { }() fun t(): Boolean { - return if (true) true + return if (true) true } return if (true) true else {} diff --git a/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.fir.kt index 2588f6cc895..2aa1d500c0d 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.fir.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/kt770.kt351.kt735_StatementType.fir.kt @@ -99,10 +99,10 @@ fun testImplicitCoercion() { else -> z-- } - var iff = if (true) { + var iff = if (true) { z = 34 } - val g = if (true) 4 + val g = if (true) 4 val h = if (false) 4 else {} bar(if (true) { diff --git a/compiler/testData/diagnostics/tests/controlStructures/when.kt234.kt973.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/when.kt234.kt973.fir.kt index fc5d5665024..baa658b8210 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/when.kt234.kt973.fir.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/when.kt234.kt973.fir.kt @@ -25,7 +25,7 @@ fun t1(x: Int) = when(x) { else -> 1 } -fun t5(x: Int) = when (x) { +fun t5(x: Int) = when (x) { is Int -> 1 2 -> 2 } diff --git a/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.fir.kt b/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.fir.kt index 4b3db89acdc..71a28eb64f4 100644 --- a/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.fir.kt +++ b/compiler/testData/diagnostics/tests/dataFlow/EmptyIf.fir.kt @@ -18,7 +18,7 @@ fun f3(s: Number?) { } fun f4(s: Int?) { - var u = if (s!! == 42); - if (u == Unit) u = if (s == 239); + var u = if (s!! == 42); + if (u == Unit) u = if (s == 239); return u -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/enum/AbstractInEnum.fir.kt b/compiler/testData/diagnostics/tests/enum/AbstractInEnum.fir.kt index f26b0922a84..9d6169605a3 100644 --- a/compiler/testData/diagnostics/tests/enum/AbstractInEnum.fir.kt +++ b/compiler/testData/diagnostics/tests/enum/AbstractInEnum.fir.kt @@ -20,7 +20,7 @@ enum class MyEnum() { abstract var c3: Int = 0; set(v: Int) { field = v } val e: Int get() = a - val e1: Int = 0; get() = a + val e1: Int = 0; get() = a abstract val e2: Int get() = a abstract val e3: Int = 0; get() = a diff --git a/compiler/testData/diagnostics/tests/extensions/kt1875.fir.kt b/compiler/testData/diagnostics/tests/extensions/kt1875.fir.kt index 30a0fe540d1..c1b2b66183d 100644 --- a/compiler/testData/diagnostics/tests/extensions/kt1875.fir.kt +++ b/compiler/testData/diagnostics/tests/extensions/kt1875.fir.kt @@ -9,13 +9,13 @@ interface T { } fun test(t: T) { - t.f(1) //unsafe call error + t.f(1) //unsafe call error t.f?.invoke(1) } fun test1(t: T?) { t.f(1) // todo resolve f as value and report UNSAFE_CALL - t?.f(1) + t?.f(1) t.f?.invoke(1) t?.f?.invoke(1) } diff --git a/compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.fir.kt b/compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.fir.kt new file mode 100644 index 00000000000..a8ab368233b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.fir.kt @@ -0,0 +1,4 @@ +inline operator fun Int.invoke() = this + +val a2 = 1() +val a3 = 1.invoke() diff --git a/compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt b/compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt new file mode 100644 index 00000000000..58dd705eb14 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt @@ -0,0 +1,4 @@ +inline operator fun Int.invoke() = this + +val a2 = 1() +val a3 = 1.invoke() diff --git a/compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.txt b/compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.txt new file mode 100644 index 00000000000..716eb401e26 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.txt @@ -0,0 +1,5 @@ +package + +public val a2: kotlin.Int +public val a3: kotlin.Int +public inline operator fun kotlin.Int.invoke(): kotlin.Int diff --git a/compiler/testData/diagnostics/tests/infos/SmartCasts.fir.kt b/compiler/testData/diagnostics/tests/infos/SmartCasts.fir.kt index f1075938464..90242dc54a5 100644 --- a/compiler/testData/diagnostics/tests/infos/SmartCasts.fir.kt +++ b/compiler/testData/diagnostics/tests/infos/SmartCasts.fir.kt @@ -142,7 +142,7 @@ fun getStringLength(obj : Any) : Char? { } fun toInt(i: Int?): Int = if (i != null) i else 0 -fun illegalWhenBody(a: Any): Int = when(a) { +fun illegalWhenBody(a: Any): Int = when(a) { is Int -> a is String -> a } diff --git a/compiler/testData/diagnostics/tests/modifiers/const/types.fir.kt b/compiler/testData/diagnostics/tests/modifiers/const/types.fir.kt index b55bb6d33ee..6912e0322c6 100644 --- a/compiler/testData/diagnostics/tests/modifiers/const/types.fir.kt +++ b/compiler/testData/diagnostics/tests/modifiers/const/types.fir.kt @@ -13,5 +13,5 @@ const val intArrayConst: IntArray = intArrayOf() const val unresolvedConst1 = Unresolved const var unresolvedConst2 = Unresolved -const val unresolvedConst3 = Unresolved +const val unresolvedConst3 = Unresolved get() = 10 diff --git a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.fir.kt b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.fir.kt index 4f3edd28f85..0e415d6bb24 100644 --- a/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.fir.kt +++ b/compiler/testData/diagnostics/tests/nullabilityAndSmartCasts/InfixCallNullability.fir.kt @@ -18,15 +18,15 @@ fun test(x : Int?, a : A?) { a.plus(1) a?.plus(1) - a plus 1 - a + 1 + a plus 1 + a + 1 -a a.unaryMinus() a?.unaryMinus() a.div(1) - a / 1 - a div 1 + a / 1 + a div 1 a?.div(1) a.times(1) @@ -34,8 +34,8 @@ fun test(x : Int?, a : A?) { a times 1 a?.times(1) - 1 in a - a contains 1 + 1 in a + a contains 1 a.contains(1) a?.contains(1) } diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/invoke.fir.kt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/invoke.fir.kt deleted file mode 100644 index 8189379f712..00000000000 --- a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/invoke.fir.kt +++ /dev/null @@ -1,23 +0,0 @@ -// FILE: J.java - -import org.jetbrains.annotations.*; - -public class J { - public interface Invoke { - void invoke(); - } - - @NotNull - public static Invoke staticNN; - @Nullable - public static Invoke staticN; - public static Invoke staticJ; -} - -// FILE: k.kt - -fun test() { - J.staticNN() - J.staticN() - J.staticJ() -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/invoke.kt b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/invoke.kt index a1c251fae35..d8d9347ddf9 100644 --- a/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/invoke.kt +++ b/compiler/testData/diagnostics/tests/platformTypes/nullabilityWarnings/invoke.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FILE: J.java import org.jetbrains.annotations.*; diff --git a/compiler/testData/diagnostics/tests/regressions/kt282.fir.kt b/compiler/testData/diagnostics/tests/regressions/kt282.fir.kt index 69fae482fa7..3819249ce58 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt282.fir.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt282.fir.kt @@ -14,6 +14,6 @@ fun f(): Unit { val i : Int? = null i + 1 set + 1 - 1 in set + 1 in set 1 in 2 } diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/errors/unsafeCallWithInvoke.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/errors/unsafeCallWithInvoke.fir.kt index dddbda1ff30..27539cd2175 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/errors/unsafeCallWithInvoke.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/errors/unsafeCallWithInvoke.fir.kt @@ -4,7 +4,7 @@ operator fun String.invoke(i: Int) {} fun foo(s: String?) { - s(1) + s(1) - (s ?: null)(1) + (s ?: null)(1) } diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/invokeAndSmartCast.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAndSmartCast.fir.kt index a339133b60c..41aeacd7829 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/invokeAndSmartCast.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAndSmartCast.fir.kt @@ -7,8 +7,8 @@ fun test(a: A) { (a.x)("") } "".(a.x)() - a.x("") - (a.x)("") + a.x("") + (a.x)("") with("") { a.x() diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.fir.kt b/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.fir.kt index ee5b1fb0b16..1bdeabc1273 100644 --- a/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.fir.kt +++ b/compiler/testData/diagnostics/tests/resolve/invoke/kt30695_2.fir.kt @@ -14,7 +14,7 @@ class MemberInvokeOwner { class Cls { fun testImplicitReceiver() { - nullableExtensionProperty() + nullableExtensionProperty() } } @@ -30,7 +30,7 @@ fun testNullableReceiver(nullable: Cls?) { } fun testNotNullableReceiver(notNullable: Cls) { - notNullable.nullableExtensionProperty() + notNullable.nullableExtensionProperty() notNullable?.extensionProperty() } @@ -38,6 +38,6 @@ fun testFlexibleReceiver() { val flexible = JavaClass.createFlexible() flexible.extensionProperty() flexible?.extensionProperty() - flexible.nullableExtensionProperty() - flexible?.nullableExtensionProperty() + flexible.nullableExtensionProperty() + flexible?.nullableExtensionProperty() } diff --git a/compiler/testData/diagnostics/tests/safeCall.fir.kt b/compiler/testData/diagnostics/tests/safeCall.fir.kt index 2cdf67aa545..6e02bc3303b 100644 --- a/compiler/testData/diagnostics/tests/safeCall.fir.kt +++ b/compiler/testData/diagnostics/tests/safeCall.fir.kt @@ -1,7 +1,7 @@ // !WITH_NEW_INFERENCE fun f(s: String, action: (String.() -> Unit)?) { - s.foo().bar().action() + s.foo().bar().action() } fun String.foo() = "" @@ -12,4 +12,4 @@ fun String.bar() = "" val functions: Map Any> = TODO() -fun run(name: String) = functions[name]() \ No newline at end of file +fun run(name: String) = functions[name]() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.fir.kt b/compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.fir.kt index f1227579248..7ce78c898ac 100644 --- a/compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/initializerScopeOfExtensionProperty.fir.kt @@ -2,11 +2,11 @@ package i -val List.length = size +val List.length = size val List.length1 : Int get() = size -val String.bd = this + "!" +val String.bd = this + "!" val String.bd1 : String get() = this + "!" @@ -15,7 +15,7 @@ class A { val ii : Int = 1 } -val A.foo = ii +val A.foo = ii val A.foo1 : Int get() = ii @@ -24,8 +24,8 @@ class C { inner class D {} } -val C.foo : C.D = D() +val C.foo : C.D = D() -val C.bar : C.D = C().D() +val C.bar : C.D = C().D() val C.foo1 : C.D get() = D() diff --git a/compiler/testData/diagnostics/tests/sealed/DerivedTopLevel.fir.kt b/compiler/testData/diagnostics/tests/sealed/DerivedTopLevel.fir.kt index 26c557d48cd..4b6d60300f8 100644 --- a/compiler/testData/diagnostics/tests/sealed/DerivedTopLevel.fir.kt +++ b/compiler/testData/diagnostics/tests/sealed/DerivedTopLevel.fir.kt @@ -1,7 +1,7 @@ sealed class Base class Derived: Base() { - class Derived2: Base() + class Derived2: Base() } fun test() { diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt index afef06f3764..04b049c2dc3 100644 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt +++ b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnRoot.fir.kt @@ -13,11 +13,11 @@ fun test(x: Stmt): String = } fun test2(x: Stmt): String = - when (x) { + when (x) { is Expr -> "expr" } fun test3(x: Expr): String = when (x) { is Stmt -> "stmt" - } \ No newline at end of file + } diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTree.fir.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTree.fir.kt deleted file mode 100644 index d19eb6011fc..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTree.fir.kt +++ /dev/null @@ -1,34 +0,0 @@ -sealed class Base { - sealed class A : Base() { - object A1 : A() - sealed class A2 : A() - } - sealed class B : Base() { - sealed class B1 : B() - object B2 : B() - } - - fun foo() = when (this) { - is A -> 1 - is B.B1 -> 2 - B.B2 -> 3 - // No else required - } - - fun bar() = when (this) { - is A -> 1 - is B.B1 -> 2 - } - - fun baz() = when (this) { - is A -> 1 - B.B2 -> 3 - // No else required (no possible B1 instances) - } - - fun negated() = when (this) { - !is A -> 1 - A.A1 -> 2 - is A.A2 -> 3 - } -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTree.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTree.kt index 292767ade22..598ce99c605 100644 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTree.kt +++ b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTree.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL sealed class Base { sealed class A : Base() { object A1 : A() diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTriangleStar.fir.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTriangleStar.fir.kt deleted file mode 100644 index 68a39439d7c..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTriangleStar.fir.kt +++ /dev/null @@ -1,24 +0,0 @@ -sealed class A -sealed class B : A() - -class C : B() -class D : B() - -fun test(a: A): Any { - return when (a) { - is C -> "" - is D -> "" - } -} - -fun test2(a: A): Any { - return when (a) { - is B -> "" - } -} - -fun test3(a: A): Any { - return when (a) { - is D -> "" - } -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTriangleStar.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTriangleStar.kt index 5991129f143..35acddf35c2 100644 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTriangleStar.kt +++ b/compiler/testData/diagnostics/tests/sealed/ExhaustiveOnTriangleStar.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL sealed class A sealed class B : A() diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenMultipleInner.fir.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenMultipleInner.fir.kt deleted file mode 100644 index 5c46abf6f29..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenMultipleInner.fir.kt +++ /dev/null @@ -1,47 +0,0 @@ -sealed class Sealed() { - object First: Sealed() - open class NonFirst: Sealed() { - class NonSecond: NonFirst() { - object Third: Sealed() - class NonThird: Sealed() { - object Fourth: NonFirst() - class Fifth: Sealed() - } - } - object Second: Sealed() - } -} - -fun foo(s: Sealed) = when(s) { - Sealed.First -> 1 - is Sealed.NonFirst -> 2 - Sealed.NonFirst.Second -> 4 - Sealed.NonFirst.NonSecond.Third -> 6 - is Sealed.NonFirst.NonSecond.NonThird -> 8 - is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10 - // no else required -} - -fun fooWithElse(s: Sealed) = when(s) { - Sealed.First -> 1 - Sealed.NonFirst.NonSecond.Third -> 6 - is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10 - else -> 0 -} - -fun fooWithoutElse(s: Sealed) = when(s) { - Sealed.First -> 1 - is Sealed.NonFirst -> 2 - Sealed.NonFirst.NonSecond.Third -> 6 - is Sealed.NonFirst.NonSecond.NonThird -> 8 - is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10 -} - -fun barWithoutElse(s: Sealed) = when(s) { - Sealed.First -> 1 - is Sealed.NonFirst -> 2 - Sealed.NonFirst.Second -> 4 - is Sealed.NonFirst.NonSecond.NonThird -> 8 - is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10 -} - diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenMultipleInner.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenMultipleInner.kt index b7afa1df5ac..58e1f50baf9 100644 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenMultipleInner.kt +++ b/compiler/testData/diagnostics/tests/sealed/ExhaustiveWhenMultipleInner.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL sealed class Sealed() { object First: Sealed() open class NonFirst: Sealed() { diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveWithFreedom.fir.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveWithFreedom.fir.kt deleted file mode 100644 index f90edc7720d..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveWithFreedom.fir.kt +++ /dev/null @@ -1,64 +0,0 @@ -// ISSUE: KT-13495 -// !DIAGNOSTICS: -UNUSED_VARIABLE -// !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage - -// FILE: Base.kt - -sealed class Base { - class A : Base() -} - -// FILE: B.kt - -class B : Base() - -// FILE: Container.kt - -class Containter { - class C : Base() - - inner class D : Base() -} - -// FILE: main.kt - -fun test_OK(base: Base) { - val x = when (base) { - is Base.A -> 1 - is B -> 2 - is Containter.C -> 3 - is Containter.D -> 4 - } -} - -fun test_error_1(base: Base) { - val x = when (base) { - is B -> 2 - is Containter.C -> 3 - is Containter.D -> 4 - } -} - -fun test_error_2(base: Base) { - val x = when (base) { - is Base.A -> 1 - is Containter.C -> 3 - is Containter.D -> 4 - } -} - -fun test_error_3(base: Base) { - val x = when (base) { - is Base.A -> 1 - is B -> 2 - is Containter.D -> 4 - } -} - -fun test_error_4(base: Base) { - val x = when (base) { - is Base.A -> 1 - is B -> 2 - is Containter.C -> 3 - } -} diff --git a/compiler/testData/diagnostics/tests/sealed/ExhaustiveWithFreedom.kt b/compiler/testData/diagnostics/tests/sealed/ExhaustiveWithFreedom.kt index d72d40c9102..50bf4002221 100644 --- a/compiler/testData/diagnostics/tests/sealed/ExhaustiveWithFreedom.kt +++ b/compiler/testData/diagnostics/tests/sealed/ExhaustiveWithFreedom.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // ISSUE: KT-13495 // !DIAGNOSTICS: -UNUSED_VARIABLE // !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage diff --git a/compiler/testData/diagnostics/tests/sealed/MultipleFiles_enabled.fir.kt b/compiler/testData/diagnostics/tests/sealed/MultipleFiles_enabled.fir.kt index 3300a9cb6aa..455e7591dde 100644 --- a/compiler/testData/diagnostics/tests/sealed/MultipleFiles_enabled.fir.kt +++ b/compiler/testData/diagnostics/tests/sealed/MultipleFiles_enabled.fir.kt @@ -13,21 +13,21 @@ sealed class Base { package foo -class B : Base() +class B : Base() // FILE: c.kt package foo class Container { - class C : Base() + class C : Base() - inner class D : Base() + inner class D : Base() - val anon = object : Base() {} // Should be an error + val anon = object : Base() {} // Should be an error fun someFun() { - class LocalClass : Base() {} // Should be an error + class LocalClass : Base() {} // Should be an error } } @@ -37,4 +37,4 @@ package bar import foo.Base -class E : Base() +class E : Base() diff --git a/compiler/testData/diagnostics/tests/sealed/NestedSealedWithoutRestrictions.fir.kt b/compiler/testData/diagnostics/tests/sealed/NestedSealedWithoutRestrictions.fir.kt deleted file mode 100644 index ff3c72191d0..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/NestedSealedWithoutRestrictions.fir.kt +++ /dev/null @@ -1,39 +0,0 @@ -// ISSUE: KT-13495 -// !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage -// !DIAGNOSTICS: -UNUSED_VARIABLE - -// FILE: base.kt - -package foo - -class Container { - sealed class Base -} - -// FILE: a.kt - -package foo - -class A : Container.Base() - -// FILE: b.kt - -package foo - -class BContainer { - class B : Container.Base() - - inner class C : Container.Base() -} - -// FILE: test.kt - -package foo - -fun test(base: Container.Base) { - val x = when (base) { - is A -> 1 - is BContainer.B -> 2 - is BContainer.C -> 3 - } -} diff --git a/compiler/testData/diagnostics/tests/sealed/NestedSealedWithoutRestrictions.kt b/compiler/testData/diagnostics/tests/sealed/NestedSealedWithoutRestrictions.kt index c6da20d58a6..31716bacff5 100644 --- a/compiler/testData/diagnostics/tests/sealed/NestedSealedWithoutRestrictions.kt +++ b/compiler/testData/diagnostics/tests/sealed/NestedSealedWithoutRestrictions.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // ISSUE: KT-13495 // !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage // !DIAGNOSTICS: -UNUSED_VARIABLE diff --git a/compiler/testData/diagnostics/tests/sealed/NeverDerivedFromNested.fir.kt b/compiler/testData/diagnostics/tests/sealed/NeverDerivedFromNested.fir.kt index f455a892688..b59a1dae1f6 100644 --- a/compiler/testData/diagnostics/tests/sealed/NeverDerivedFromNested.fir.kt +++ b/compiler/testData/diagnostics/tests/sealed/NeverDerivedFromNested.fir.kt @@ -2,7 +2,7 @@ class A { sealed class Base } -class Derived : A.Base() +class Derived : A.Base() fun test() { class DerivedLocal : A.Base() diff --git a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhen.fir.kt b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhen.fir.kt deleted file mode 100644 index 9c5be055bd6..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhen.fir.kt +++ /dev/null @@ -1,14 +0,0 @@ -sealed class Sealed(val x: Int) { - object First: Sealed(12) - open class NonFirst(x: Int, val y: Int): Sealed(x) { - object Second: NonFirst(34, 2) - object Third: NonFirst(56, 3) - } -} - -fun foo(s: Sealed): Int { - return when(s) { - is Sealed.NonFirst -> 0 - } -} - diff --git a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhen.kt b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhen.kt index 439de1ee3fe..1aebcb54486 100644 --- a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhen.kt +++ b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhen.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL sealed class Sealed(val x: Int) { object First: Sealed(12) open class NonFirst(x: Int, val y: Int): Sealed(x) { diff --git a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenNegated.fir.kt b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenNegated.fir.kt deleted file mode 100644 index 77cbfbf26c7..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenNegated.fir.kt +++ /dev/null @@ -1,14 +0,0 @@ -sealed class Sealed(val x: Int) { - object First: Sealed(12) - open class NonFirst(x: Int, val y: Int): Sealed(x) { - object Second: NonFirst(34, 2) - object Third: NonFirst(56, 3) - } -} - -fun foo(s: Sealed): Int { - return when(s) { - !is Sealed.NonFirst -> 1 - } -} - diff --git a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenNegated.kt b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenNegated.kt index 0d02f2c6757..6ad07912e17 100644 --- a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenNegated.kt +++ b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenNegated.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL sealed class Sealed(val x: Int) { object First: Sealed(12) open class NonFirst(x: Int, val y: Int): Sealed(x) { diff --git a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAdditionalCase.fir.kt b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAdditionalCase.fir.kt deleted file mode 100644 index e2d3b79c3c0..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAdditionalCase.fir.kt +++ /dev/null @@ -1,22 +0,0 @@ -sealed class Sealed(val x: Int) { - interface ITuple { - val x: Int - val y: Int - } - class Tuple(override val x: Int, override val y: Int): ITuple - object First: Sealed(12) - open class NonFirst(tuple: Tuple): Sealed(tuple.x), ITuple { - override val y: Int = tuple.y - object Second: NonFirst(Tuple(34, 2)) - class Third: NonFirst(Tuple(56, 3)) - } -} - -fun foo(s: Sealed): Int { - return when(s) { - is Sealed.First -> 1 - !is Sealed.ITuple -> 0 - // else required - } -} - diff --git a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAdditionalCase.kt b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAdditionalCase.kt index d8f20b9c3fc..8b78455629e 100644 --- a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAdditionalCase.kt +++ b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAdditionalCase.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL sealed class Sealed(val x: Int) { interface ITuple { val x: Int diff --git a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.fir.kt b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.fir.kt index e9e4eed0755..fc235670129 100644 --- a/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.fir.kt +++ b/compiler/testData/diagnostics/tests/sealed/NonExhaustiveWhenWithAnyCase.fir.kt @@ -7,7 +7,7 @@ sealed class Sealed { } fun foo(s: Sealed): Int { - return when(s) { + return when(s) { is Sealed.First -> 1 !is Any -> 0 } diff --git a/compiler/testData/diagnostics/tests/sealed/TreeWhenFunctionalNoIs.fir.kt b/compiler/testData/diagnostics/tests/sealed/TreeWhenFunctionalNoIs.fir.kt index c2d43bfb3cc..9aabfe0ddb5 100644 --- a/compiler/testData/diagnostics/tests/sealed/TreeWhenFunctionalNoIs.fir.kt +++ b/compiler/testData/diagnostics/tests/sealed/TreeWhenFunctionalNoIs.fir.kt @@ -9,7 +9,7 @@ sealed class Tree { is Node -> this.left.max() } - fun maxIsClass(): Int = when(this) { + fun maxIsClass(): Int = when(this) { Empty -> -1 Leaf -> 0 is Node -> this.left.max() @@ -20,4 +20,4 @@ sealed class Tree { is Node -> this.left.max() else -> -1 } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/sealed/WhenOnEmptySealed.fir.kt b/compiler/testData/diagnostics/tests/sealed/WhenOnEmptySealed.fir.kt deleted file mode 100644 index 9271a1b4474..00000000000 --- a/compiler/testData/diagnostics/tests/sealed/WhenOnEmptySealed.fir.kt +++ /dev/null @@ -1,11 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -sealed class Sealed { - -} - -fun foo(s: Sealed): Int { - return when(s) { - // We do not return anything, so else branch must be here - } -} - diff --git a/compiler/testData/diagnostics/tests/sealed/WhenOnEmptySealed.kt b/compiler/testData/diagnostics/tests/sealed/WhenOnEmptySealed.kt index ea45861d7cd..05304d09f67 100644 --- a/compiler/testData/diagnostics/tests/sealed/WhenOnEmptySealed.kt +++ b/compiler/testData/diagnostics/tests/sealed/WhenOnEmptySealed.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION sealed class Sealed { diff --git a/compiler/testData/diagnostics/tests/sealed/kt44316.kt b/compiler/testData/diagnostics/tests/sealed/kt44316.kt new file mode 100644 index 00000000000..cd55b84deb6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/kt44316.kt @@ -0,0 +1,11 @@ +// FIR_IDENTICAL +// KT-44316 + +sealed class Base +class Derived : Base() + +class Test(val x: Base) { + private val y = when (x) { + is Derived -> null + } +} diff --git a/compiler/testData/diagnostics/tests/sealed/kt44316.txt b/compiler/testData/diagnostics/tests/sealed/kt44316.txt new file mode 100644 index 00000000000..6e077339484 --- /dev/null +++ b/compiler/testData/diagnostics/tests/sealed/kt44316.txt @@ -0,0 +1,24 @@ +package + +public sealed class Base { + internal constructor Base() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Derived : Base { + public constructor Derived() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Test { + public constructor Test(/*0*/ x: Base) + public final val x: Base + private final val y: kotlin.Nothing? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/elvis/basicOn.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/elvis/basicOn.fir.kt index 89029fb6fd7..dacb3b62b03 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/elvis/basicOn.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/elvis/basicOn.fir.kt @@ -11,13 +11,13 @@ interface Order { fun foo(o: Any) { val order = o as? Order if (order?.expired ?: false) { - order.doSomething() + order.doSomething() } else { } if (order?.notExpired() ?: false) { - order.doSomething() + order.doSomething() } } @@ -47,4 +47,4 @@ fun baz(o: Boolean?) { else { o.hashCode() } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/kt27221_irrelevantClasses.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/kt27221_irrelevantClasses.fir.kt index 337c36e7ba1..51270bfde33 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/kt27221_irrelevantClasses.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/kt27221_irrelevantClasses.fir.kt @@ -10,7 +10,7 @@ object CC : C() fun foo(a: A) { if (a is B) { if (a is C) { - val t = when (a) { + val t = when (a) { is CC -> "CC" } } @@ -20,9 +20,9 @@ fun foo(a: A) { fun foo2(a: A) { if (a is C) { if (a is B) { - val t = when (a) { + val t = when (a) { is CC -> "CC" } } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.fir.kt new file mode 100644 index 00000000000..e1d79e1e21d --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.fir.kt @@ -0,0 +1,9 @@ +public fun foo(x: String?, y: String?): Int { + while (true) { + x ?: if (y == null) break + // y is nullable if x != null + y.length + } + // y is null because of the break + return y.length +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.kt b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.kt index ef2399abbe4..520459f73a9 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/loops/elvisIfBreakInsideWhileTrue.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL public fun foo(x: String?, y: String?): Int { while (true) { x ?: if (y == null) break @@ -7,4 +6,4 @@ public fun foo(x: String?, y: String?): Int { } // y is null because of the break return y.length -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/smartCasts/publicVals/open.fir.kt b/compiler/testData/diagnostics/tests/smartCasts/publicVals/open.fir.kt index 1cd64d4f5e7..4c34ecac3aa 100644 --- a/compiler/testData/diagnostics/tests/smartCasts/publicVals/open.fir.kt +++ b/compiler/testData/diagnostics/tests/smartCasts/publicVals/open.fir.kt @@ -7,5 +7,5 @@ infix fun Int.bar(i: Int) = i fun test() { val p = A() // For open value properties, smart casts should not work - if (p.foo is Int) p.foo bar 11 + if (p.foo is Int) p.foo bar 11 } diff --git a/compiler/testData/diagnostics/tests/subtyping/kt3159.fir.kt b/compiler/testData/diagnostics/tests/subtyping/kt3159.fir.kt deleted file mode 100644 index 2d736b76b07..00000000000 --- a/compiler/testData/diagnostics/tests/subtyping/kt3159.fir.kt +++ /dev/null @@ -1,9 +0,0 @@ -interface Super { - var v: CharSequence - val v2: CharSequence -} - -class Sub: Super { - override var v: String = "fail" - override val v2: String = "ok" -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/subtyping/kt3159.kt b/compiler/testData/diagnostics/tests/subtyping/kt3159.kt index 11c335546d3..c4f6d9bca85 100644 --- a/compiler/testData/diagnostics/tests/subtyping/kt3159.kt +++ b/compiler/testData/diagnostics/tests/subtyping/kt3159.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface Super { var v: CharSequence val v2: CharSequence diff --git a/compiler/testData/diagnostics/tests/thisAndSuper/thisInPropertyInitializer.fir.kt b/compiler/testData/diagnostics/tests/thisAndSuper/thisInPropertyInitializer.fir.kt index 32037c0a692..9b5a0218325 100644 --- a/compiler/testData/diagnostics/tests/thisAndSuper/thisInPropertyInitializer.fir.kt +++ b/compiler/testData/diagnostics/tests/thisAndSuper/thisInPropertyInitializer.fir.kt @@ -1,7 +1,7 @@ interface Base { fun foo() } -val String.test: Base = object: Base { +val String.test: Base = object: Base { override fun foo() { this@test } diff --git a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.fir.kt b/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.fir.kt deleted file mode 100644 index 209e68c9f15..00000000000 --- a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.fir.kt +++ /dev/null @@ -1,8 +0,0 @@ -interface IWithToString { - override fun toString(): String -} - -class A : IWithToString { - // Should be Any#toString(), even though IWithToString defines an abstract toString. - override fun toString(): String = super.toString() -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.kt b/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.kt index ba5f4f70298..38c2975daef 100644 --- a/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.kt +++ b/compiler/testData/diagnostics/tests/thisAndSuper/unqualifiedSuper/withMethodOfAnyOverridenInInterface.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL interface IWithToString { override fun toString(): String } diff --git a/compiler/testData/diagnostics/tests/unit/nullableUnit.fir.kt b/compiler/testData/diagnostics/tests/unit/nullableUnit.fir.kt deleted file mode 100644 index 42d2f77036a..00000000000 --- a/compiler/testData/diagnostics/tests/unit/nullableUnit.fir.kt +++ /dev/null @@ -1,5 +0,0 @@ -fun foo() {} - -val x: Unit? = when ("A") { - "B" -> foo() -} diff --git a/compiler/testData/diagnostics/tests/unit/nullableUnit.kt b/compiler/testData/diagnostics/tests/unit/nullableUnit.kt index 03d7ed33876..2c886979558 100644 --- a/compiler/testData/diagnostics/tests/unit/nullableUnit.kt +++ b/compiler/testData/diagnostics/tests/unit/nullableUnit.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL fun foo() {} val x: Unit? = when ("A") { diff --git a/compiler/testData/diagnostics/tests/when/ElseOnNullableEnum.fir.kt b/compiler/testData/diagnostics/tests/when/ElseOnNullableEnum.fir.kt index 31da011183f..830e0ff2104 100644 --- a/compiler/testData/diagnostics/tests/when/ElseOnNullableEnum.fir.kt +++ b/compiler/testData/diagnostics/tests/when/ElseOnNullableEnum.fir.kt @@ -12,7 +12,7 @@ enum class E { A, B } -fun test(e: E?) = when (e) { +fun test(e: E?) = when (e) { E.A -> 1 E.B -> 2 } diff --git a/compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.fir.kt b/compiler/testData/diagnostics/tests/when/ExhaustiveBooleanComplex.fir.kt similarity index 54% rename from compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.fir.kt rename to compiler/testData/diagnostics/tests/when/ExhaustiveBooleanComplex.fir.kt index 0a39652a6fd..298acefd490 100644 --- a/compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.fir.kt +++ b/compiler/testData/diagnostics/tests/when/ExhaustiveBooleanComplex.fir.kt @@ -1,18 +1,18 @@ /* - * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) * - * SPEC VERSION: 0.1-152 + * SPEC VERSION: 0.1-313 * PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1 * expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 3 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 10 + * expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 4 + * expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 5 */ // See also: KT-3743 -fun foo(arg: Boolean?): String { - // Must be NOT exhaustive - return when(arg) { - true -> "truth" - false -> "falsehood" +fun foo(arg: Boolean): String { + // Must be exhaustive + return when(arg) { + 2 == 2 -> "truth" + 2 == 1 -> "falsehood" } } diff --git a/compiler/testData/diagnostics/tests/when/ExhaustiveBooleanComplex.kt b/compiler/testData/diagnostics/tests/when/ExhaustiveBooleanComplex.kt index 3b0933f5354..11e7d5f8d1c 100644 --- a/compiler/testData/diagnostics/tests/when/ExhaustiveBooleanComplex.kt +++ b/compiler/testData/diagnostics/tests/when/ExhaustiveBooleanComplex.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL /* * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) * diff --git a/compiler/testData/diagnostics/tests/when/ExhaustiveEnumIs.fir.kt b/compiler/testData/diagnostics/tests/when/ExhaustiveEnumIs.fir.kt index 278ee04bced..398609150ba 100644 --- a/compiler/testData/diagnostics/tests/when/ExhaustiveEnumIs.fir.kt +++ b/compiler/testData/diagnostics/tests/when/ExhaustiveEnumIs.fir.kt @@ -12,7 +12,7 @@ enum class MyEnum { } fun foo(x: MyEnum): Int { - return when (x) { + return when (x) { is MyEnum.A -> 1 is MyEnum.B -> 2 is MyEnum.C -> 3 diff --git a/compiler/testData/diagnostics/tests/when/ExhaustiveEnumMixed.fir.kt b/compiler/testData/diagnostics/tests/when/ExhaustiveEnumMixed.fir.kt index 481970e4455..aaea91337b6 100644 --- a/compiler/testData/diagnostics/tests/when/ExhaustiveEnumMixed.fir.kt +++ b/compiler/testData/diagnostics/tests/when/ExhaustiveEnumMixed.fir.kt @@ -13,7 +13,7 @@ enum class MyEnum { } fun foo(x: MyEnum): Int { - return when (x) { + return when (x) { MyEnum.A -> 1 is MyEnum.B -> 2 is MyEnum.C -> 3 diff --git a/compiler/testData/diagnostics/tests/when/NoElseExpectedUnit.fir.kt b/compiler/testData/diagnostics/tests/when/NoElseExpectedUnit.fir.kt deleted file mode 100644 index 382c03583e0..00000000000 --- a/compiler/testData/diagnostics/tests/when/NoElseExpectedUnit.fir.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) - * - * SPEC VERSION: 0.1-152 - * PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1 - * expressions, when-expression -> paragraph 9 -> sentence 2 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1 - */ - -fun foo(x: Int) { - val y: Unit = when (x) { - 2 -> {} - 3 -> {} - } - return y -} diff --git a/compiler/testData/diagnostics/tests/when/NoElseExpectedUnit.kt b/compiler/testData/diagnostics/tests/when/NoElseExpectedUnit.kt index d08e040bc97..21b7d43fe64 100644 --- a/compiler/testData/diagnostics/tests/when/NoElseExpectedUnit.kt +++ b/compiler/testData/diagnostics/tests/when/NoElseExpectedUnit.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL /* * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) * diff --git a/compiler/testData/diagnostics/tests/when/NoElseNoExpectedType.fir.kt b/compiler/testData/diagnostics/tests/when/NoElseNoExpectedType.fir.kt deleted file mode 100644 index 81081046fa7..00000000000 --- a/compiler/testData/diagnostics/tests/when/NoElseNoExpectedType.fir.kt +++ /dev/null @@ -1,15 +0,0 @@ -/* - * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) - * - * SPEC VERSION: 0.1-152 - * PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1 - * expressions, when-expression -> paragraph 9 -> sentence 2 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1 - */ - -fun foo(x: Int): Any { - val v = when (x) { - 2 -> 0 - } - return v -} diff --git a/compiler/testData/diagnostics/tests/when/NoElseNoExpectedType.kt b/compiler/testData/diagnostics/tests/when/NoElseNoExpectedType.kt index 5cc1a2be78f..fd65ecfa23b 100644 --- a/compiler/testData/diagnostics/tests/when/NoElseNoExpectedType.kt +++ b/compiler/testData/diagnostics/tests/when/NoElseNoExpectedType.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL /* * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) * diff --git a/compiler/testData/diagnostics/tests/when/NoElseReturnedNonUnit.fir.kt b/compiler/testData/diagnostics/tests/when/NoElseReturnedNonUnit.fir.kt deleted file mode 100644 index 69423511de3..00000000000 --- a/compiler/testData/diagnostics/tests/when/NoElseReturnedNonUnit.fir.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) - * - * SPEC VERSION: 0.1-152 - * PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1 - * expressions, when-expression -> paragraph 9 -> sentence 2 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1 - */ - -fun foo(x: Int): Any { - return when (x) { - 2 -> 0 - } -} diff --git a/compiler/testData/diagnostics/tests/when/NoElseReturnedNonUnit.kt b/compiler/testData/diagnostics/tests/when/NoElseReturnedNonUnit.kt index 6822f03a47a..de869792156 100644 --- a/compiler/testData/diagnostics/tests/when/NoElseReturnedNonUnit.kt +++ b/compiler/testData/diagnostics/tests/when/NoElseReturnedNonUnit.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL /* * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) * diff --git a/compiler/testData/diagnostics/tests/when/NoElseReturnedUnit.fir.kt b/compiler/testData/diagnostics/tests/when/NoElseReturnedUnit.fir.kt deleted file mode 100644 index 94b8f840ec2..00000000000 --- a/compiler/testData/diagnostics/tests/when/NoElseReturnedUnit.fir.kt +++ /dev/null @@ -1,16 +0,0 @@ -/* - * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) - * - * SPEC VERSION: 0.1-152 - * PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1 - * expressions, when-expression -> paragraph 9 -> sentence 2 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1 - */ - - -fun foo(x: Int) { - return when (x) { - 2 -> {} - 3 -> {} - } -} diff --git a/compiler/testData/diagnostics/tests/when/NoElseReturnedUnit.kt b/compiler/testData/diagnostics/tests/when/NoElseReturnedUnit.kt index 4a5dbe3116a..8b60f0b072c 100644 --- a/compiler/testData/diagnostics/tests/when/NoElseReturnedUnit.kt +++ b/compiler/testData/diagnostics/tests/when/NoElseReturnedUnit.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL /* * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) * diff --git a/compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.kt b/compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.kt index 545d5c3cc55..1b798926dff 100644 --- a/compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.kt +++ b/compiler/testData/diagnostics/tests/when/NonExhaustiveBooleanNullable.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL /* * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) * diff --git a/compiler/testData/diagnostics/tests/when/NonExhaustivePlatformEnum.fir.kt b/compiler/testData/diagnostics/tests/when/NonExhaustivePlatformEnum.fir.kt deleted file mode 100644 index c3014d5ef6f..00000000000 --- a/compiler/testData/diagnostics/tests/when/NonExhaustivePlatformEnum.fir.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) - * - * SPEC VERSION: 0.1-152 - * PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 9 - */ - -// See KT-6399: exhaustive whens on platform enums - -// FILE: J.java - -public enum J { - A, B; - - public static J create() { - return J.A; - } -} - -// FILE: K.kt - -fun foo(): Int { - // When is not-exhaustive - return when (J.create()) { - J.A -> 1 - } -} diff --git a/compiler/testData/diagnostics/tests/when/NonExhaustivePlatformEnum.kt b/compiler/testData/diagnostics/tests/when/NonExhaustivePlatformEnum.kt index b9480bf6cc4..bb9451bca98 100644 --- a/compiler/testData/diagnostics/tests/when/NonExhaustivePlatformEnum.kt +++ b/compiler/testData/diagnostics/tests/when/NonExhaustivePlatformEnum.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL /* * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) * diff --git a/compiler/testData/diagnostics/tests/when/NonExhaustiveWithNullabilityCheck.fir.kt b/compiler/testData/diagnostics/tests/when/NonExhaustiveWithNullabilityCheck.fir.kt index e0bcb365303..9e4351e95bc 100644 --- a/compiler/testData/diagnostics/tests/when/NonExhaustiveWithNullabilityCheck.fir.kt +++ b/compiler/testData/diagnostics/tests/when/NonExhaustiveWithNullabilityCheck.fir.kt @@ -13,7 +13,7 @@ enum class X { A, B } fun foo(arg: X?): Int { if (arg != null) { - return when (arg) { + return when (arg) { X.B -> 2 } } diff --git a/compiler/testData/diagnostics/tests/when/TopLevelSealed.fir.kt b/compiler/testData/diagnostics/tests/when/TopLevelSealed.fir.kt deleted file mode 100644 index b7577c720de..00000000000 --- a/compiler/testData/diagnostics/tests/when/TopLevelSealed.fir.kt +++ /dev/null @@ -1,32 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_VARIABLE -/* - * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) - * - * SPEC VERSION: 0.1-152 - * PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1 - * expressions, when-expression -> paragraph 6 -> sentence 1 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 6 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 7 - * expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 8 - */ - -sealed class A { - class B: A() { - class C: A() - } -} - -class D: A() - -fun test(a: A) { - val nonExhaustive = when (a) { - is A.B -> "B" - is A.B.C -> "C" - } - - val exhaustive = when (a) { - is A.B -> "B" - is A.B.C -> "C" - is D -> "D" - } -} diff --git a/compiler/testData/diagnostics/tests/when/TopLevelSealed.kt b/compiler/testData/diagnostics/tests/when/TopLevelSealed.kt index 14d6fd04291..6581b1c9cc1 100644 --- a/compiler/testData/diagnostics/tests/when/TopLevelSealed.kt +++ b/compiler/testData/diagnostics/tests/when/TopLevelSealed.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_VARIABLE /* * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) diff --git a/compiler/testData/diagnostics/tests/when/kt4434.fir.kt b/compiler/testData/diagnostics/tests/when/kt4434.fir.kt index 46abd84179d..8a378378379 100644 --- a/compiler/testData/diagnostics/tests/when/kt4434.fir.kt +++ b/compiler/testData/diagnostics/tests/when/kt4434.fir.kt @@ -27,7 +27,7 @@ fun foo(): Int { fun bar(): Int { val a = "a" if (a.length > 0) { - return when (a) { + return when (a) { "a" -> 1 } } diff --git a/compiler/testData/diagnostics/tests/when/withSubjectVariable/nestedWhenWithSubject.fir.kt b/compiler/testData/diagnostics/tests/when/withSubjectVariable/nestedWhenWithSubject.fir.kt index 1be42fe50ee..bec1af3affc 100644 --- a/compiler/testData/diagnostics/tests/when/withSubjectVariable/nestedWhenWithSubject.fir.kt +++ b/compiler/testData/diagnostics/tests/when/withSubjectVariable/nestedWhenWithSubject.fir.kt @@ -38,4 +38,4 @@ fun test4() { 2 -> bar(x, y) } } -} \ No newline at end of file +} diff --git a/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToEnum.fir.kt b/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToEnum.fir.kt deleted file mode 100644 index 882e2c17b76..00000000000 --- a/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToEnum.fir.kt +++ /dev/null @@ -1,18 +0,0 @@ -// !LANGUAGE: +VariableDeclarationInWhenSubject -// !DIAGNOSTICS: -UNUSED_VARIABLE - -enum class E { FIRST, SECOND } - -fun testSmartcastToEnumInSubjectInitializer1(e: E?) { - val x1 = when (val ne = e!!) { - E.FIRST -> "f" - E.SECOND -> "s" - } -} - -fun testSmartcastToEnumInSubjectInitializer2(e: E?) { - val x2 = when (val ne: Any = e!!) { // NB explicit type annotation - E.FIRST -> "f" - E.SECOND -> "s" - } -} diff --git a/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToEnum.kt b/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToEnum.kt index 1b9f4988ed8..fe94c3c103b 100644 --- a/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToEnum.kt +++ b/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToEnum.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +VariableDeclarationInWhenSubject // !DIAGNOSTICS: -UNUSED_VARIABLE diff --git a/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToSealed.fir.kt b/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToSealed.fir.kt deleted file mode 100644 index 7e66946fe0b..00000000000 --- a/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToSealed.fir.kt +++ /dev/null @@ -1,20 +0,0 @@ -// !LANGUAGE: +VariableDeclarationInWhenSubject -// !DIAGNOSTICS: -UNUSED_VARIABLE - -sealed class Either -class Left : Either() -class Right : Either() - -fun testSmartcastToSealedInSubjectInitializer1(x: Any?) { - val y1 = when (val either = x as Either) { - is Left -> "L" - is Right -> "R" - } -} - -fun testSmartcastToSealedInSubjectInitializer2(x: Any?) { - val y2 = when (val either: Any = x as Either) { // NB explicit type annotation - is Left -> "L" - is Right -> "R" - } -} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToSealed.kt b/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToSealed.kt index bde8ea93959..9fe474c40fc 100644 --- a/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToSealed.kt +++ b/compiler/testData/diagnostics/tests/when/withSubjectVariable/smartcastToSealed.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +VariableDeclarationInWhenSubject // !DIAGNOSTICS: -UNUSED_VARIABLE diff --git a/compiler/testData/diagnostics/testsWithStdLib/buildLazyValueForMap.kt b/compiler/testData/diagnostics/testsWithStdLib/buildLazyValueForMap.kt new file mode 100644 index 00000000000..be566e49c07 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/buildLazyValueForMap.kt @@ -0,0 +1,23 @@ +// FIR_IDENTICAL + +interface ClassId + +interface JavaAnnotation { + val classId: ClassId? +} + +interface JavaAnnotationOwner { + val annotations: Collection +} + +interface MapBasedJavaAnnotationOwner : JavaAnnotationOwner { + val annotationsByFqNameHash: Map +} + +fun JavaAnnotationOwner.buildLazyValueForMap() = lazy { + annotations.associateBy { it.classId?.hashCode() } +} + +abstract class BinaryJavaMethodBase(): MapBasedJavaAnnotationOwner { + override val annotationsByFqNameHash by buildLazyValueForMap() +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/buildLazyValueForMap.txt b/compiler/testData/diagnostics/testsWithStdLib/buildLazyValueForMap.txt new file mode 100644 index 00000000000..1ac5e5e1a86 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/buildLazyValueForMap.txt @@ -0,0 +1,40 @@ +package + +public fun JavaAnnotationOwner.buildLazyValueForMap(): kotlin.Lazy> + +public abstract class BinaryJavaMethodBase : MapBasedJavaAnnotationOwner { + public constructor BinaryJavaMethodBase() + public abstract override /*1*/ /*fake_override*/ val annotations: kotlin.collections.Collection + public open override /*1*/ val annotationsByFqNameHash: kotlin.collections.Map + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface ClassId { + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface JavaAnnotation { + public abstract val classId: ClassId? + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface JavaAnnotationOwner { + public abstract val annotations: kotlin.collections.Collection + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface MapBasedJavaAnnotationOwner : JavaAnnotationOwner { + public abstract override /*1*/ /*fake_override*/ val annotations: kotlin.collections.Collection + public abstract val annotationsByFqNameHash: kotlin.collections.Map + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/contractCallSites.1.3.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/contractCallSites.1.3.fir.kt index 479961a85b4..56dd3270e77 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/contractCallSites.1.3.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/contractCallSites.1.3.fir.kt @@ -56,7 +56,7 @@ val topLevelAnonymousFunction = fun (x: Boolean) { contract { returns() implies (x) } } -var topLevelPropertyAccessors: Int? = 42 +var topLevelPropertyAccessors: Int? = 42 get() { contract { returns() implies (field != null) } return 42 diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/contractCallSites.1.4.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/contractCallSites.1.4.fir.kt index 375929dbd06..8617996f90b 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/contractCallSites.1.4.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/contractCallSites.1.4.fir.kt @@ -71,7 +71,7 @@ val topLevelAnonymousFunction = fun (x: Boolean) { contract { returns() implies (x) } } -var topLevelPropertyAccessors: Int? = 42 +var topLevelPropertyAccessors: Int? = 42 get() { contract { returns() implies (field != null) } return 42 diff --git a/compiler/testData/integration/smoke/reflect/reflect.kt b/compiler/testData/integration/smoke/reflect/reflect.kt index 4fb5c0b80cf..4c402f51d00 100644 --- a/compiler/testData/integration/smoke/reflect/reflect.kt +++ b/compiler/testData/integration/smoke/reflect/reflect.kt @@ -1,5 +1,8 @@ package reflect +import kotlin.reflect.jvm.kotlinFunction + fun main() { String::class.annotations -} \ No newline at end of file + KotlinVersion::class.java.methods.first().kotlinFunction +} diff --git a/compiler/testData/ir/irText/classes/delegatedGenericImplementation.fir.kt.txt b/compiler/testData/ir/irText/classes/delegatedGenericImplementation.fir.kt.txt index 4861e83dbf8..73650a6c7c9 100644 --- a/compiler/testData/ir/irText/classes/delegatedGenericImplementation.fir.kt.txt +++ b/compiler/testData/ir/irText/classes/delegatedGenericImplementation.fir.kt.txt @@ -14,7 +14,6 @@ class Test1 : IBase { super/*Any*/() /* () */ - .#<$$delegate_0> = i } override fun foo(a: E, b: B) { @@ -34,7 +33,7 @@ class Test1 : IBase { (.#<$$delegate_0>, ).( = ) } - local /* final field */ val <$$delegate_0>: IBase + local /* final field */ val <$$delegate_0>: IBase = i } @@ -43,14 +42,8 @@ class Test2 : IBase { super/*Any*/() /* () */ - .#<$$delegate_0> = j } - var j: IBase - field = j - get - set - override fun foo(a: String, b: B) { .#<$$delegate_0>.foo(a = a, b = b) } @@ -68,7 +61,11 @@ class Test2 : IBase { (.#<$$delegate_0>, ).( = ) } - local /* final field */ val <$$delegate_0>: IBase + local /* final field */ val <$$delegate_0>: IBase = j + var j: IBase + field = j + get + set } diff --git a/compiler/testData/ir/irText/classes/delegatedGenericImplementation.fir.txt b/compiler/testData/ir/irText/classes/delegatedGenericImplementation.fir.txt index ccdc5eb4067..0cb00f8c810 100644 --- a/compiler/testData/ir/irText/classes/delegatedGenericImplementation.fir.txt +++ b/compiler/testData/ir/irText/classes/delegatedGenericImplementation.fir.txt @@ -46,9 +46,6 @@ FILE fqName: fileName:/delegatedGenericImplementation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test1 modality:FINAL visibility:public superTypes:[.IBase.Test1>]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IBase.Test1> visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .Test1.Test1> declared in .Test1' type=.Test1.Test1> origin=null - value: GET_VAR 'i: .IBase.Test1> declared in .Test1.' type=.IBase.Test1> origin=null FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN ($this:.Test1.Test1>, a:E of .Test1, b:B of .Test1.foo) returnType:kotlin.Unit overridden: public abstract fun foo (a: A of .IBase, b: B of .IBase.foo): kotlin.Unit declared in .IBase @@ -109,6 +106,8 @@ FILE fqName: fileName:/delegatedGenericImplementation.kt $receiver: GET_VAR ': kotlin.collections.List.Test1.> declared in .Test1.' type=kotlin.collections.List.Test1.> origin=null : GET_VAR ': D of .Test1.? declared in .Test1.' type=D of .Test1.? origin=null FIELD DELEGATE name:<$$delegate_0> type:.IBase.Test1> visibility:local [final] + EXPRESSION_BODY + GET_VAR 'i: .IBase.Test1> declared in .Test1.' type=.IBase.Test1> origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any @@ -129,28 +128,6 @@ FILE fqName: fileName:/delegatedGenericImplementation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test2 modality:FINAL visibility:public superTypes:[.IBase]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IBase visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .Test2 declared in .Test2' type=.Test2 origin=null - value: GET_VAR 'j: .IBase declared in .Test2.' type=.IBase origin=null - PROPERTY name:j visibility:public modality:FINAL [var] - FIELD PROPERTY_BACKING_FIELD name:j type:.IBase visibility:private - EXPRESSION_BODY - GET_VAR 'j: .IBase declared in .Test2.' type=.IBase origin=INITIALIZE_PROPERTY_FROM_PARAMETER - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Test2) returnType:.IBase - correspondingProperty: PROPERTY name:j visibility:public modality:FINAL [var] - $this: VALUE_PARAMETER name: type:.Test2 - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): .IBase declared in .Test2' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j type:.IBase visibility:private' type=.IBase origin=null - receiver: GET_VAR ': .Test2 declared in .Test2.' type=.Test2 origin=null - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Test2, :.IBase) returnType:kotlin.Unit - correspondingProperty: PROPERTY name:j visibility:public modality:FINAL [var] - $this: VALUE_PARAMETER name: type:.Test2 - VALUE_PARAMETER name: index:0 type:.IBase - BLOCK_BODY - SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j type:.IBase visibility:private' type=kotlin.Unit origin=null - receiver: GET_VAR ': .Test2 declared in .Test2.' type=.Test2 origin=null - value: GET_VAR ': .IBase declared in .Test2.' type=.IBase origin=null FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN ($this:.Test2, a:kotlin.String, b:B of .Test2.foo) returnType:kotlin.Unit overridden: public abstract fun foo (a: A of .IBase, b: B of .IBase.foo): kotlin.Unit declared in .IBase @@ -211,6 +188,27 @@ FILE fqName: fileName:/delegatedGenericImplementation.kt $receiver: GET_VAR ': kotlin.collections.List.Test2.> declared in .Test2.' type=kotlin.collections.List.Test2.> origin=null : GET_VAR ': D of .Test2.? declared in .Test2.' type=D of .Test2.? origin=null FIELD DELEGATE name:<$$delegate_0> type:.IBase visibility:local [final] + EXPRESSION_BODY + GET_VAR 'j: .IBase declared in .Test2.' type=.IBase origin=null + PROPERTY name:j visibility:public modality:FINAL [var] + FIELD PROPERTY_BACKING_FIELD name:j type:.IBase visibility:private + EXPRESSION_BODY + GET_VAR 'j: .IBase declared in .Test2.' type=.IBase origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Test2) returnType:.IBase + correspondingProperty: PROPERTY name:j visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.Test2 + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .IBase declared in .Test2' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j type:.IBase visibility:private' type=.IBase origin=null + receiver: GET_VAR ': .Test2 declared in .Test2.' type=.Test2 origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Test2, :.IBase) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:j visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.Test2 + VALUE_PARAMETER name: index:0 type:.IBase + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j type:.IBase visibility:private' type=kotlin.Unit origin=null + receiver: GET_VAR ': .Test2 declared in .Test2.' type=.Test2 origin=null + value: GET_VAR ': .IBase declared in .Test2.' type=.IBase origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/classes/delegatedImplementation.fir.kt.txt b/compiler/testData/ir/irText/classes/delegatedImplementation.fir.kt.txt index 7d3062bf224..32d05a7406b 100644 --- a/compiler/testData/ir/irText/classes/delegatedImplementation.fir.kt.txt +++ b/compiler/testData/ir/irText/classes/delegatedImplementation.fir.kt.txt @@ -82,7 +82,6 @@ class Test1 : IBase { super/*Any*/() /* () */ - .#<$$delegate_0> = BaseImpl } override fun foo(x: Int, s: String) { @@ -97,7 +96,7 @@ class Test1 : IBase { (.#<$$delegate_0>, ).qux() } - local /* final field */ val <$$delegate_0>: IBase + local /* final field */ val <$$delegate_0>: IBase = BaseImpl } @@ -106,8 +105,6 @@ class Test2 : IBase, IOther { super/*Any*/() /* () */ - .#<$$delegate_0> = BaseImpl - .#<$$delegate_1> = otherImpl(x0 = "", y0 = 42) } override fun foo(x: Int, s: String) { @@ -122,7 +119,7 @@ class Test2 : IBase, IOther { (.#<$$delegate_0>, ).qux() } - local /* final field */ val <$$delegate_0>: IBase + local /* final field */ val <$$delegate_0>: IBase = BaseImpl override val x: String override get(): String { return .#<$$delegate_1>.() @@ -149,7 +146,7 @@ class Test2 : IBase, IOther { (.#<$$delegate_1>, ).( = ) } - local /* final field */ val <$$delegate_1>: IOther + local /* final field */ val <$$delegate_1>: IOther = otherImpl(x0 = "", y0 = 42) } diff --git a/compiler/testData/ir/irText/classes/delegatedImplementation.fir.txt b/compiler/testData/ir/irText/classes/delegatedImplementation.fir.txt index cdb02665cd0..747f419f513 100644 --- a/compiler/testData/ir/irText/classes/delegatedImplementation.fir.txt +++ b/compiler/testData/ir/irText/classes/delegatedImplementation.fir.txt @@ -200,9 +200,6 @@ FILE fqName: fileName:/delegatedImplementation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test1 modality:FINAL visibility:public superTypes:[.IBase]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IBase visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .Test1 declared in .Test1' type=.Test1 origin=null - value: GET_OBJECT 'CLASS OBJECT name:BaseImpl modality:FINAL visibility:public superTypes:[.IBase]' type=.BaseImpl FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:.Test1, x:kotlin.Int, s:kotlin.String) returnType:kotlin.Unit overridden: public abstract fun foo (x: kotlin.Int, s: kotlin.String): kotlin.Unit declared in .IBase @@ -235,6 +232,8 @@ FILE fqName: fileName:/delegatedImplementation.kt receiver: GET_VAR ': .Test1 declared in .Test1.qux' type=.Test1 origin=null $receiver: GET_VAR ': kotlin.String declared in .Test1.qux' type=kotlin.String origin=null FIELD DELEGATE name:<$$delegate_0> type:.IBase visibility:local [final] + EXPRESSION_BODY + GET_OBJECT 'CLASS OBJECT name:BaseImpl modality:FINAL visibility:public superTypes:[.IBase]' type=.BaseImpl FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any @@ -254,14 +253,6 @@ FILE fqName: fileName:/delegatedImplementation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test2 modality:FINAL visibility:public superTypes:[.IBase; .IOther]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IBase visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .Test2 declared in .Test2' type=.Test2 origin=null - value: GET_OBJECT 'CLASS OBJECT name:BaseImpl modality:FINAL visibility:public superTypes:[.IBase]' type=.BaseImpl - SET_FIELD 'FIELD DELEGATE name:<$$delegate_1> type:.IOther visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .Test2 declared in .Test2' type=.Test2 origin=null - value: CALL 'public final fun otherImpl (x0: kotlin.String, y0: kotlin.Int): .IOther declared in ' type=.IOther origin=null - x0: CONST String type=kotlin.String value="" - y0: CONST Int type=kotlin.Int value=42 FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:.Test2, x:kotlin.Int, s:kotlin.String) returnType:kotlin.Unit overridden: public abstract fun foo (x: kotlin.Int, s: kotlin.String): kotlin.Unit declared in .IBase @@ -294,6 +285,8 @@ FILE fqName: fileName:/delegatedImplementation.kt receiver: GET_VAR ': .Test2 declared in .Test2.qux' type=.Test2 origin=null $receiver: GET_VAR ': kotlin.String declared in .Test2.qux' type=kotlin.String origin=null FIELD DELEGATE name:<$$delegate_0> type:.IBase visibility:local [final] + EXPRESSION_BODY + GET_OBJECT 'CLASS OBJECT name:BaseImpl modality:FINAL visibility:public superTypes:[.IBase]' type=.BaseImpl PROPERTY DELEGATED_MEMBER name:x visibility:public modality:OPEN [val] FUN DELEGATED_MEMBER name: visibility:public modality:OPEN <> ($this:.Test2) returnType:kotlin.String correspondingProperty: PROPERTY DELEGATED_MEMBER name:x visibility:public modality:OPEN [val] @@ -367,6 +360,10 @@ FILE fqName: fileName:/delegatedImplementation.kt $receiver: GET_VAR ': kotlin.Byte declared in .Test2.' type=kotlin.Byte origin=null : GET_VAR ': kotlin.Int declared in .Test2.' type=kotlin.Int origin=null FIELD DELEGATE name:<$$delegate_1> type:.IOther visibility:local [final] + EXPRESSION_BODY + CALL 'public final fun otherImpl (x0: kotlin.String, y0: kotlin.Int): .IOther declared in ' type=.IOther origin=null + x0: CONST String type=kotlin.String value="" + y0: CONST Int type=kotlin.Int value=42 FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/classes/delegatedImplementationOfJavaInterface.fir.kt.txt b/compiler/testData/ir/irText/classes/delegatedImplementationOfJavaInterface.fir.kt.txt index f8ae385e192..fb36d5785c8 100644 --- a/compiler/testData/ir/irText/classes/delegatedImplementationOfJavaInterface.fir.kt.txt +++ b/compiler/testData/ir/irText/classes/delegatedImplementationOfJavaInterface.fir.kt.txt @@ -3,13 +3,8 @@ class Test : J { super/*Any*/() /* () */ - .#<$$delegate_0> = j } - private val j: J - field = j - private get - override fun takeNotNull(x: @EnhancedNullability String) { .#<$$delegate_0>.takeNotNull(x = x) } @@ -36,7 +31,10 @@ class Test : J { return .#<$$delegate_0>.returnsFlexible() } - local /* final field */ val <$$delegate_0>: J + local /* final field */ val <$$delegate_0>: J = j + private val j: J + field = j + private get } diff --git a/compiler/testData/ir/irText/classes/delegatedImplementationOfJavaInterface.fir.txt b/compiler/testData/ir/irText/classes/delegatedImplementationOfJavaInterface.fir.txt index 49e7a896708..5cd15a79d17 100644 --- a/compiler/testData/ir/irText/classes/delegatedImplementationOfJavaInterface.fir.txt +++ b/compiler/testData/ir/irText/classes/delegatedImplementationOfJavaInterface.fir.txt @@ -6,20 +6,6 @@ FILE fqName: fileName:/delegatedImplementationOfJavaInterface.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test modality:FINAL visibility:public superTypes:[.J]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.J visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .Test declared in .Test' type=.Test origin=null - value: GET_VAR 'j: .J declared in .Test.' type=.J origin=null - PROPERTY name:j visibility:private modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:j type:.J visibility:private [final] - EXPRESSION_BODY - GET_VAR 'j: .J declared in .Test.' type=.J origin=INITIALIZE_PROPERTY_FROM_PARAMETER - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:private modality:FINAL <> ($this:.Test) returnType:.J - correspondingProperty: PROPERTY name:j visibility:private modality:FINAL [val] - $this: VALUE_PARAMETER name: type:.Test - BLOCK_BODY - RETURN type=kotlin.Nothing from='private final fun (): .J declared in .Test' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j type:.J visibility:private [final]' type=.J origin=null - receiver: GET_VAR ': .Test declared in .Test.' type=.Test origin=null FUN DELEGATED_MEMBER name:takeNotNull visibility:public modality:OPEN <> ($this:.Test, x:@[EnhancedNullability] kotlin.String) returnType:kotlin.Unit overridden: public abstract fun takeNotNull (x: @[EnhancedNullability] kotlin.String): kotlin.Unit declared in .J @@ -82,6 +68,19 @@ FILE fqName: fileName:/delegatedImplementationOfJavaInterface.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.J visibility:local [final]' type=.J origin=null receiver: GET_VAR ': .Test declared in .Test.returnsFlexible' type=.Test origin=null FIELD DELEGATE name:<$$delegate_0> type:.J visibility:local [final] + EXPRESSION_BODY + GET_VAR 'j: .J declared in .Test.' type=.J origin=null + PROPERTY name:j visibility:private modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:j type:.J visibility:private [final] + EXPRESSION_BODY + GET_VAR 'j: .J declared in .Test.' type=.J origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:private modality:FINAL <> ($this:.Test) returnType:.J + correspondingProperty: PROPERTY name:j visibility:private modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Test + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun (): .J declared in .Test' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:j type:.J visibility:private [final]' type=.J origin=null + receiver: GET_VAR ': .Test declared in .Test.' type=.Test origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.fir.kt.txt b/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.fir.kt.txt index 103c62d6993..0c91c731dfd 100644 --- a/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.fir.kt.txt +++ b/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.fir.kt.txt @@ -24,17 +24,15 @@ class C : IFooBar { super/*Any*/() /* () */ - .#<$$delegate_0> = FooBarImpl - } - - override fun bar() { } override fun foo() { .#<$$delegate_0>.foo() } - local /* final field */ val <$$delegate_0>: IFooBar + local /* final field */ val <$$delegate_0>: IFooBar = FooBarImpl + override fun bar() { + } } diff --git a/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.fir.txt b/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.fir.txt index a30487d58ad..96935a1c251 100644 --- a/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.fir.txt +++ b/compiler/testData/ir/irText/classes/delegatedImplementationWithExplicitOverride.fir.txt @@ -53,14 +53,6 @@ FILE fqName: fileName:/delegatedImplementationWithExplicitOverride.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[.IFooBar]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFooBar visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .C declared in .C' type=.C origin=null - value: GET_OBJECT 'CLASS OBJECT name:FooBarImpl modality:FINAL visibility:public superTypes:[.IFooBar]' type=.FooBarImpl - FUN name:bar visibility:public modality:FINAL <> ($this:.C) returnType:kotlin.Unit - overridden: - public abstract fun bar (): kotlin.Unit declared in .IFooBar - $this: VALUE_PARAMETER name: type:.C - BLOCK_BODY FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:.C) returnType:kotlin.Unit overridden: public abstract fun foo (): kotlin.Unit declared in .IFooBar @@ -70,6 +62,13 @@ FILE fqName: fileName:/delegatedImplementationWithExplicitOverride.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFooBar visibility:local [final]' type=.IFooBar origin=null receiver: GET_VAR ': .C declared in .C.foo' type=.C origin=null FIELD DELEGATE name:<$$delegate_0> type:.IFooBar visibility:local [final] + EXPRESSION_BODY + GET_OBJECT 'CLASS OBJECT name:FooBarImpl modality:FINAL visibility:public superTypes:[.IFooBar]' type=.FooBarImpl + FUN name:bar visibility:public modality:FINAL <> ($this:.C) returnType:kotlin.Unit + overridden: + public abstract fun bar (): kotlin.Unit declared in .IFooBar + $this: VALUE_PARAMETER name: type:.C + BLOCK_BODY FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.kt.txt b/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.kt.txt index 154bbcaad18..f6da264d0a5 100644 --- a/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.kt.txt +++ b/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.kt.txt @@ -52,14 +52,13 @@ class TestJFoo : IFoo { super/*Any*/() /* () */ - .#<$$delegate_0> = JFoo() } override fun foo(): String { return .#<$$delegate_0>.foo() } - local /* final field */ val <$$delegate_0>: IFoo + local /* final field */ val <$$delegate_0>: IFoo = JFoo() } @@ -68,14 +67,13 @@ class TestK1 : IFoo { super/*Any*/() /* () */ - .#<$$delegate_0> = K1() } override fun foo(): String { return .#<$$delegate_0>.foo() } - local /* final field */ val <$$delegate_0>: IFoo + local /* final field */ val <$$delegate_0>: IFoo = K1() } @@ -84,14 +82,13 @@ class TestK2 : IFoo { super/*Any*/() /* () */ - .#<$$delegate_0> = K2() } override fun foo(): String { return .#<$$delegate_0>.foo() } - local /* final field */ val <$$delegate_0>: IFoo + local /* final field */ val <$$delegate_0>: IFoo = K2() } @@ -100,14 +97,13 @@ class TestK3 : IFoo { super/*Any*/() /* () */ - .#<$$delegate_0> = K3() } override fun foo(): String { return .#<$$delegate_0>.foo() } - local /* final field */ val <$$delegate_0>: IFoo + local /* final field */ val <$$delegate_0>: IFoo = K3() } @@ -116,14 +112,13 @@ class TestK4 : IFoo { super/*Any*/() /* () */ - .#<$$delegate_0> = K4() } override fun foo(): String { return .#<$$delegate_0>.foo() } - local /* final field */ val <$$delegate_0>: IFoo + local /* final field */ val <$$delegate_0>: IFoo = K4() } diff --git a/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.txt b/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.txt index cca274e6190..da87507f689 100644 --- a/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.txt +++ b/compiler/testData/ir/irText/classes/implicitNotNullOnDelegatedImplementation.fir.txt @@ -124,9 +124,6 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:TestJFoo modality:FINAL visibility:public superTypes:[.IFoo]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .TestJFoo declared in .TestJFoo' type=.TestJFoo origin=null - value: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .JFoo' type=.JFoo origin=null FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:.TestJFoo) returnType:kotlin.String overridden: public abstract fun foo (): kotlin.String declared in .IFoo @@ -137,6 +134,8 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=.IFoo origin=null receiver: GET_VAR ': .TestJFoo declared in .TestJFoo.foo' type=.TestJFoo origin=null FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final] + EXPRESSION_BODY + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .JFoo' type=.JFoo origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any @@ -156,9 +155,6 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:TestK1 modality:FINAL visibility:public superTypes:[.IFoo]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .TestK1 declared in .TestK1' type=.TestK1 origin=null - value: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .K1' type=.K1 origin=null FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:.TestK1) returnType:kotlin.String overridden: public abstract fun foo (): kotlin.String declared in .IFoo @@ -169,6 +165,8 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=.IFoo origin=null receiver: GET_VAR ': .TestK1 declared in .TestK1.foo' type=.TestK1 origin=null FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final] + EXPRESSION_BODY + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .K1' type=.K1 origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any @@ -188,9 +186,6 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:TestK2 modality:FINAL visibility:public superTypes:[.IFoo]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .TestK2 declared in .TestK2' type=.TestK2 origin=null - value: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .K2' type=.K2 origin=null FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:.TestK2) returnType:kotlin.String overridden: public abstract fun foo (): kotlin.String declared in .IFoo @@ -201,6 +196,8 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=.IFoo origin=null receiver: GET_VAR ': .TestK2 declared in .TestK2.foo' type=.TestK2 origin=null FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final] + EXPRESSION_BODY + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .K2' type=.K2 origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any @@ -220,9 +217,6 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:TestK3 modality:FINAL visibility:public superTypes:[.IFoo]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .TestK3 declared in .TestK3' type=.TestK3 origin=null - value: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .K3' type=.K3 origin=null FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:.TestK3) returnType:kotlin.String overridden: public abstract fun foo (): kotlin.String declared in .IFoo @@ -233,6 +227,8 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=.IFoo origin=null receiver: GET_VAR ': .TestK3 declared in .TestK3.foo' type=.TestK3 origin=null FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final] + EXPRESSION_BODY + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .K3' type=.K3 origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any @@ -252,9 +248,6 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:TestK4 modality:FINAL visibility:public superTypes:[.IFoo]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .TestK4 declared in .TestK4' type=.TestK4 origin=null - value: CONSTRUCTOR_CALL 'public constructor () [primary] declared in .K4' type=.K4 origin=null FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:.TestK4) returnType:kotlin.String overridden: public abstract fun foo (): kotlin.String declared in .IFoo @@ -265,6 +258,8 @@ FILE fqName: fileName:/implicitNotNullOnDelegatedImplementation.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=.IFoo origin=null receiver: GET_VAR ': .TestK4 declared in .TestK4.foo' type=.TestK4 origin=null FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final] + EXPRESSION_BODY + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .K4' type=.K4 origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/declarations/annotations/annotationsOnDelegatedMembers.fir.kt.txt b/compiler/testData/ir/irText/declarations/annotations/annotationsOnDelegatedMembers.fir.kt.txt index d2fd97a09fd..29030292342 100644 --- a/compiler/testData/ir/irText/declarations/annotations/annotationsOnDelegatedMembers.fir.kt.txt +++ b/compiler/testData/ir/irText/declarations/annotations/annotationsOnDelegatedMembers.fir.kt.txt @@ -24,7 +24,6 @@ class DFoo : IFoo { super/*Any*/() /* () */ - .#<$$delegate_0> = d } @Ann @@ -49,7 +48,7 @@ class DFoo : IFoo { return (.#<$$delegate_0>, ).() } - local /* final field */ val <$$delegate_0>: IFoo + local /* final field */ val <$$delegate_0>: IFoo = d } diff --git a/compiler/testData/ir/irText/declarations/annotations/annotationsOnDelegatedMembers.fir.txt b/compiler/testData/ir/irText/declarations/annotations/annotationsOnDelegatedMembers.fir.txt index 6eae326f169..0fc194a84d1 100644 --- a/compiler/testData/ir/irText/declarations/annotations/annotationsOnDelegatedMembers.fir.txt +++ b/compiler/testData/ir/irText/declarations/annotations/annotationsOnDelegatedMembers.fir.txt @@ -59,9 +59,6 @@ FILE fqName: fileName:/annotationsOnDelegatedMembers.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:DFoo modality:FINAL visibility:public superTypes:[.IFoo]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .DFoo declared in .DFoo' type=.DFoo origin=null - value: GET_VAR 'd: .IFoo declared in .DFoo.' type=.IFoo origin=null FUN DELEGATED_MEMBER name:testFun visibility:public modality:OPEN <> ($this:.DFoo) returnType:kotlin.Unit annotations: Ann @@ -113,6 +110,8 @@ FILE fqName: fileName:/annotationsOnDelegatedMembers.kt receiver: GET_VAR ': .DFoo declared in .DFoo.' type=.DFoo origin=null $receiver: GET_VAR ': kotlin.String declared in .DFoo.' type=kotlin.String origin=null FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final] + EXPRESSION_BODY + GET_VAR 'd: .IFoo declared in .DFoo.' type=.IFoo origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/declarations/annotations/inheritingDeprecation.fir.kt.txt b/compiler/testData/ir/irText/declarations/annotations/inheritingDeprecation.fir.kt.txt index 2c3ee7d7203..9061db9158a 100644 --- a/compiler/testData/ir/irText/declarations/annotations/inheritingDeprecation.fir.kt.txt +++ b/compiler/testData/ir/irText/declarations/annotations/inheritingDeprecation.fir.kt.txt @@ -18,7 +18,6 @@ class Delegated : IFoo { super/*Any*/() /* () */ - .#<$$delegate_0> = foo } @Deprecated(message = "") @@ -33,7 +32,7 @@ class Delegated : IFoo { return (.#<$$delegate_0>, ).() } - local /* final field */ val <$$delegate_0>: IFoo + local /* final field */ val <$$delegate_0>: IFoo = foo } diff --git a/compiler/testData/ir/irText/declarations/annotations/inheritingDeprecation.fir.txt b/compiler/testData/ir/irText/declarations/annotations/inheritingDeprecation.fir.txt index 64901ed4215..ac03ff1228d 100644 --- a/compiler/testData/ir/irText/declarations/annotations/inheritingDeprecation.fir.txt +++ b/compiler/testData/ir/irText/declarations/annotations/inheritingDeprecation.fir.txt @@ -40,9 +40,6 @@ FILE fqName: fileName:/inheritingDeprecation.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Delegated modality:FINAL visibility:public superTypes:[.IFoo]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .Delegated declared in .Delegated' type=.Delegated origin=null - value: GET_VAR 'foo: .IFoo declared in .Delegated.' type=.IFoo origin=null PROPERTY DELEGATED_MEMBER name:prop visibility:public modality:OPEN [val] annotations: Deprecated(message = '', replaceWith = , level = ) @@ -72,6 +69,8 @@ FILE fqName: fileName:/inheritingDeprecation.kt receiver: GET_VAR ': .Delegated declared in .Delegated.' type=.Delegated origin=null $receiver: GET_VAR ': kotlin.String declared in .Delegated.' type=kotlin.String origin=null FIELD DELEGATE name:<$$delegate_0> type:.IFoo visibility:local [final] + EXPRESSION_BODY + GET_VAR 'foo: .IFoo declared in .Delegated.' type=.IFoo origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/declarations/kt35550.fir.kt.txt b/compiler/testData/ir/irText/declarations/kt35550.fir.kt.txt index ec35a44d722..90017fc08b0 100644 --- a/compiler/testData/ir/irText/declarations/kt35550.fir.kt.txt +++ b/compiler/testData/ir/irText/declarations/kt35550.fir.kt.txt @@ -11,7 +11,6 @@ class A : I { super/*Any*/() /* () */ - .#<$$delegate_0> = i } override val T.id: T @@ -19,7 +18,7 @@ class A : I { return (.#<$$delegate_0>, ).() } - local /* final field */ val <$$delegate_0>: I + local /* final field */ val <$$delegate_0>: I = i } diff --git a/compiler/testData/ir/irText/declarations/kt35550.fir.txt b/compiler/testData/ir/irText/declarations/kt35550.fir.txt index fca54190d10..d453e82a9ef 100644 --- a/compiler/testData/ir/irText/declarations/kt35550.fir.txt +++ b/compiler/testData/ir/irText/declarations/kt35550.fir.txt @@ -30,9 +30,6 @@ FILE fqName: fileName:/kt35550.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[.I]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.I visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .A declared in .A' type=.A origin=null - value: GET_VAR 'i: .I declared in .A.' type=.I origin=null PROPERTY DELEGATED_MEMBER name:id visibility:public modality:OPEN [val] FUN DELEGATED_MEMBER name: visibility:public modality:OPEN ($this:.A, $receiver:T of .A.) returnType:T of .A. correspondingProperty: PROPERTY DELEGATED_MEMBER name:id visibility:public modality:OPEN [val] @@ -49,6 +46,8 @@ FILE fqName: fileName:/kt35550.kt receiver: GET_VAR ': .A declared in .A.' type=.A origin=null $receiver: GET_VAR ': T of .A. declared in .A.' type=T of .A. origin=null FIELD DELEGATE name:<$$delegate_0> type:.I visibility:local [final] + EXPRESSION_BODY + GET_VAR 'i: .I declared in .A.' type=.I origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/declarations/parameters/delegatedMembers.fir.kt.txt b/compiler/testData/ir/irText/declarations/parameters/delegatedMembers.fir.kt.txt index 2ea28d408b8..5a876d4c310 100644 --- a/compiler/testData/ir/irText/declarations/parameters/delegatedMembers.fir.kt.txt +++ b/compiler/testData/ir/irText/declarations/parameters/delegatedMembers.fir.kt.txt @@ -12,7 +12,6 @@ class Test : IBase { super/*Any*/() /* () */ - .#<$$delegate_0> = impl } override fun foo(x: Int) { @@ -28,7 +27,7 @@ class Test : IBase { return .#<$$delegate_0>.() } - local /* final field */ val <$$delegate_0>: IBase + local /* final field */ val <$$delegate_0>: IBase = impl } diff --git a/compiler/testData/ir/irText/declarations/parameters/delegatedMembers.fir.txt b/compiler/testData/ir/irText/declarations/parameters/delegatedMembers.fir.txt index 2e25ff1cdb9..a6077d73000 100644 --- a/compiler/testData/ir/irText/declarations/parameters/delegatedMembers.fir.txt +++ b/compiler/testData/ir/irText/declarations/parameters/delegatedMembers.fir.txt @@ -35,9 +35,6 @@ FILE fqName: fileName:/delegatedMembers.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test modality:FINAL visibility:public superTypes:[.IBase.Test>]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IBase.Test> visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .Test.Test> declared in .Test' type=.Test.Test> origin=null - value: GET_VAR 'impl: .IBase.Test> declared in .Test.' type=.IBase.Test> origin=null FUN DELEGATED_MEMBER name:foo visibility:public modality:OPEN <> ($this:.Test.Test>, x:kotlin.Int) returnType:kotlin.Unit overridden: public abstract fun foo (x: kotlin.Int): kotlin.Unit declared in .IBase @@ -74,6 +71,8 @@ FILE fqName: fileName:/delegatedMembers.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.IBase.Test> visibility:local [final]' type=.IBase.Test> origin=null receiver: GET_VAR ': .Test.Test> declared in .Test.' type=.Test.Test> origin=null FIELD DELEGATE name:<$$delegate_0> type:.IBase.Test> visibility:local [final] + EXPRESSION_BODY + GET_VAR 'impl: .IBase.Test> declared in .Test.' type=.IBase.Test> origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/expressions/kt30796.fir.kt.txt b/compiler/testData/ir/irText/expressions/kt30796.fir.kt.txt index 78adb7af6f6..067424caa70 100644 --- a/compiler/testData/ir/irText/expressions/kt30796.fir.kt.txt +++ b/compiler/testData/ir/irText/expressions/kt30796.fir.kt.txt @@ -50,17 +50,17 @@ fun test(value: T, value2: T) { } } val x5: Any = { // BLOCK - val : Any = magic() + val : Any? = magic() when { EQEQ(arg0 = , arg1 = null) -> 42 else -> } } val x6: Any = { // BLOCK - val : Any = { // BLOCK + val : Any? = { // BLOCK val : T = value when { - EQEQ(arg0 = , arg1 = null) -> magic() + EQEQ(arg0 = , arg1 = null) -> magic() else -> } } @@ -70,8 +70,8 @@ fun test(value: T, value2: T) { } } val x7: Any = { // BLOCK - val : Any = { // BLOCK - val : Any = magic() + val : Any? = { // BLOCK + val : Any? = magic() when { EQEQ(arg0 = , arg1 = null) -> value else -> @@ -83,3 +83,4 @@ fun test(value: T, value2: T) { } } } + diff --git a/compiler/testData/ir/irText/expressions/kt30796.fir.txt b/compiler/testData/ir/irText/expressions/kt30796.fir.txt index 3e33c57eb70..e6aab2f4ce2 100644 --- a/compiler/testData/ir/irText/expressions/kt30796.fir.txt +++ b/compiler/testData/ir/irText/expressions/kt30796.fir.txt @@ -97,65 +97,65 @@ FILE fqName: fileName:/kt30796.kt then: GET_VAR 'val tmp_5: T of .test [val] declared in .test' type=T of .test origin=null VAR name:x5 type:kotlin.Any [val] BLOCK type=kotlin.Any origin=ELVIS - VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Any [val] - CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Any origin=null - : kotlin.Any + VAR IR_TEMPORARY_VARIABLE name:tmp_7 type:kotlin.Any? [val] + CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Any? origin=null + : kotlin.Any? WHEN type=kotlin.Any origin=ELVIS BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - arg0: GET_VAR 'val tmp_7: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + arg0: GET_VAR 'val tmp_7: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null arg1: CONST Null type=kotlin.Nothing? value=null then: CONST Int type=kotlin.Int value=42 BRANCH if: CONST Boolean type=kotlin.Boolean value=true - then: GET_VAR 'val tmp_7: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + then: GET_VAR 'val tmp_7: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null VAR name:x6 type:kotlin.Any [val] BLOCK type=kotlin.Any origin=ELVIS - VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.Any [val] - BLOCK type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_8 type:kotlin.Any? [val] + BLOCK type=kotlin.Any? origin=ELVIS VAR IR_TEMPORARY_VARIABLE name:tmp_9 type:T of .test [val] GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null - WHEN type=kotlin.Any origin=ELVIS + WHEN type=kotlin.Any? origin=ELVIS BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ arg0: GET_VAR 'val tmp_9: T of .test [val] declared in .test' type=T of .test origin=null arg1: CONST Null type=kotlin.Nothing? value=null - then: CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Any origin=null - : kotlin.Any + then: CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Any? origin=null + : kotlin.Any? BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: GET_VAR 'val tmp_9: T of .test [val] declared in .test' type=T of .test origin=null WHEN type=kotlin.Any origin=ELVIS BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - arg0: GET_VAR 'val tmp_8: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + arg0: GET_VAR 'val tmp_8: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null arg1: CONST Null type=kotlin.Nothing? value=null then: CONST Int type=kotlin.Int value=42 BRANCH if: CONST Boolean type=kotlin.Boolean value=true - then: GET_VAR 'val tmp_8: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + then: GET_VAR 'val tmp_8: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null VAR name:x7 type:kotlin.Any [val] BLOCK type=kotlin.Any origin=ELVIS - VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlin.Any [val] - BLOCK type=kotlin.Any origin=ELVIS - VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:kotlin.Any [val] - CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Any origin=null - : kotlin.Any - WHEN type=kotlin.Any origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_10 type:kotlin.Any? [val] + BLOCK type=kotlin.Any? origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_11 type:kotlin.Any? [val] + CALL 'public final fun magic (): T of .magic declared in ' type=kotlin.Any? origin=null + : kotlin.Any? + WHEN type=kotlin.Any? origin=ELVIS BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - arg0: GET_VAR 'val tmp_11: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + arg0: GET_VAR 'val tmp_11: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null arg1: CONST Null type=kotlin.Nothing? value=null then: GET_VAR 'value: T of .test declared in .test' type=T of .test origin=null BRANCH if: CONST Boolean type=kotlin.Boolean value=true - then: GET_VAR 'val tmp_11: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + then: GET_VAR 'val tmp_11: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null WHEN type=kotlin.Any origin=ELVIS BRANCH if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ - arg0: GET_VAR 'val tmp_10: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + arg0: GET_VAR 'val tmp_10: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null arg1: CONST Null type=kotlin.Nothing? value=null then: CONST Int type=kotlin.Int value=42 BRANCH if: CONST Boolean type=kotlin.Boolean value=true - then: GET_VAR 'val tmp_10: kotlin.Any [val] declared in .test' type=kotlin.Any origin=null + then: GET_VAR 'val tmp_10: kotlin.Any? [val] declared in .test' type=kotlin.Any? origin=null diff --git a/compiler/testData/ir/irText/firProblems/AnnotationLoader.fir.kt.txt b/compiler/testData/ir/irText/firProblems/AnnotationLoader.fir.kt.txt index d5b69b11743..7e96f4877a7 100644 --- a/compiler/testData/ir/irText/firProblems/AnnotationLoader.fir.kt.txt +++ b/compiler/testData/ir/irText/firProblems/AnnotationLoader.fir.kt.txt @@ -56,10 +56,6 @@ class AnnotationLoader { super/*Any*/() /* () */ - .#<$$delegate_0> = visitor - } - - override fun visit() { } override fun visitArray(): Visitor? { @@ -70,7 +66,9 @@ class AnnotationLoader { return .#<$$delegate_0>.visitAnnotation() } - local /* final field */ val <$$delegate_0>: Visitor + local /* final field */ val <$$delegate_0>: Visitor = visitor + override fun visit() { + } } diff --git a/compiler/testData/ir/irText/firProblems/AnnotationLoader.fir.txt b/compiler/testData/ir/irText/firProblems/AnnotationLoader.fir.txt index 4a4e4fe278c..e450d609bc7 100644 --- a/compiler/testData/ir/irText/firProblems/AnnotationLoader.fir.txt +++ b/compiler/testData/ir/irText/firProblems/AnnotationLoader.fir.txt @@ -108,14 +108,6 @@ FILE fqName: fileName:/AnnotationLoader.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name: modality:FINAL visibility:local superTypes:[.Visitor]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.Visitor visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .AnnotationLoader.loadAnnotation..visitAnnotation. declared in .AnnotationLoader.loadAnnotation..visitAnnotation.' type=.AnnotationLoader.loadAnnotation..visitAnnotation. origin=null - value: GET_VAR 'val visitor: .Visitor [val] declared in .AnnotationLoader.loadAnnotation..visitAnnotation' type=.Visitor origin=null - FUN name:visit visibility:public modality:FINAL <> ($this:.AnnotationLoader.loadAnnotation..visitAnnotation.) returnType:kotlin.Unit - overridden: - public abstract fun visit (): kotlin.Unit declared in .Visitor - $this: VALUE_PARAMETER name: type:.AnnotationLoader.loadAnnotation..visitAnnotation. - BLOCK_BODY FUN DELEGATED_MEMBER name:visitArray visibility:public modality:OPEN <> ($this:.AnnotationLoader.loadAnnotation..visitAnnotation.) returnType:.Visitor? overridden: public open fun visitArray (): .Visitor? declared in .Visitor @@ -135,6 +127,13 @@ FILE fqName: fileName:/AnnotationLoader.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.Visitor visibility:local [final]' type=.Visitor origin=null receiver: GET_VAR ': .AnnotationLoader.loadAnnotation..visitAnnotation. declared in .AnnotationLoader.loadAnnotation..visitAnnotation..visitAnnotation' type=.AnnotationLoader.loadAnnotation..visitAnnotation. origin=null FIELD DELEGATE name:<$$delegate_0> type:.Visitor visibility:local [final] + EXPRESSION_BODY + GET_VAR 'val visitor: .Visitor [val] declared in .AnnotationLoader.loadAnnotation..visitAnnotation' type=.Visitor origin=null + FUN name:visit visibility:public modality:FINAL <> ($this:.AnnotationLoader.loadAnnotation..visitAnnotation.) returnType:kotlin.Unit + overridden: + public abstract fun visit (): kotlin.Unit declared in .Visitor + $this: VALUE_PARAMETER name: type:.AnnotationLoader.loadAnnotation..visitAnnotation. + BLOCK_BODY FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.kt.txt b/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.kt.txt index cf7ebc19190..5ae5a47c206 100644 --- a/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.kt.txt +++ b/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.kt.txt @@ -3,7 +3,6 @@ class Impl : A, B { super/*Any*/() /* () */ - .#<$$delegate_0> = b } override fun add(element: String?): Boolean { @@ -51,7 +50,7 @@ class Impl : A, B { return .#<$$delegate_0>.() } - local /* final field */ val <$$delegate_0>: B + local /* final field */ val <$$delegate_0>: B = b } diff --git a/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.txt b/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.txt index 9c8a43fdf46..6d6bb4ab0cc 100644 --- a/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.txt +++ b/compiler/testData/ir/irText/firProblems/DelegationAndInheritanceFromJava.fir.txt @@ -6,9 +6,6 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Impl modality:FINAL visibility:public superTypes:[.Foo.A; .Foo.B]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.Foo.B visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .Impl declared in .Impl' type=.Impl origin=null - value: GET_VAR 'b: .Foo.B declared in .Impl.' type=.Foo.B origin=null FUN DELEGATED_MEMBER name:add visibility:public modality:OPEN <> ($this:.Impl, element:kotlin.String?) returnType:kotlin.Boolean overridden: public abstract fun add (element: E of kotlin.collections.MutableSet): kotlin.Boolean declared in kotlin.collections.MutableSet @@ -124,6 +121,8 @@ FILE fqName: fileName:/DelegationAndInheritanceFromJava.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.Foo.B visibility:local [final]' type=.Foo.B origin=null receiver: GET_VAR ': .Impl declared in .Impl.' type=.Impl origin=null FIELD DELEGATE name:<$$delegate_0> type:.Foo.B visibility:local [final] + EXPRESSION_BODY + GET_VAR 'b: .Foo.B declared in .Impl.' type=.Foo.B origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.fir.kt.txt b/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.fir.kt.txt new file mode 100644 index 00000000000..f73b371eb74 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.fir.kt.txt @@ -0,0 +1,66 @@ +class FirSession { + constructor(name: String) /* primary */ { + super/*Any*/() + /* () */ + + } + + val name: String + field = name + get + +} + +interface Fir2IrComponents { + abstract val session: FirSession + abstract get + + abstract val classifierStorage: Fir2IrClassifierStorage + abstract get + +} + +class Fir2IrComponentsStorage : Fir2IrComponents { + constructor(session: FirSession) /* primary */ { + super/*Any*/() + /* () */ + + } + + override val session: FirSession + field = session + override get + + override lateinit var classifierStorage: Fir2IrClassifierStorage + override get + set + +} + +class Fir2IrClassifierStorage : Fir2IrComponents { + constructor(components: Fir2IrComponents) /* primary */ { + super/*Any*/() + /* () */ + + } + + override val session: FirSession + override get(): FirSession { + return .#<$$delegate_0>.() + } + + override val classifierStorage: Fir2IrClassifierStorage + override get(): Fir2IrClassifierStorage { + return .#<$$delegate_0>.() + } + + local /* final field */ val <$$delegate_0>: Fir2IrComponents = components + private val components: Fir2IrComponents + field = components + private get + + private val name: String + field = .().() + private get + +} diff --git a/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.fir.txt b/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.fir.txt new file mode 100644 index 00000000000..6ae4fdc9f10 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.fir.txt @@ -0,0 +1,176 @@ +FILE fqName: fileName:/Fir2IrClassifierStorage.kt + CLASS CLASS name:FirSession modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FirSession + CONSTRUCTOR visibility:public <> (name:kotlin.String) returnType:.FirSession [primary] + VALUE_PARAMETER name:name index:0 type:kotlin.String + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:FirSession modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:name visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final] + EXPRESSION_BODY + GET_VAR 'name: kotlin.String declared in .FirSession.' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.FirSession) returnType:kotlin.String + correspondingProperty: PROPERTY name:name visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.FirSession + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .FirSession' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .FirSession declared in .FirSession.' type=.FirSession origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:Fir2IrComponents modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Fir2IrComponents + PROPERTY name:session visibility:public modality:ABSTRACT [val] + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:.Fir2IrComponents) returnType:.FirSession + correspondingProperty: PROPERTY name:session visibility:public modality:ABSTRACT [val] + $this: VALUE_PARAMETER name: type:.Fir2IrComponents + PROPERTY name:classifierStorage visibility:public modality:ABSTRACT [val] + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:.Fir2IrComponents) returnType:.Fir2IrClassifierStorage + correspondingProperty: PROPERTY name:classifierStorage visibility:public modality:ABSTRACT [val] + $this: VALUE_PARAMETER name: type:.Fir2IrComponents + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:Fir2IrComponentsStorage modality:FINAL visibility:public superTypes:[.Fir2IrComponents] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Fir2IrComponentsStorage + CONSTRUCTOR visibility:public <> (session:.FirSession) returnType:.Fir2IrComponentsStorage [primary] + VALUE_PARAMETER name:session index:0 type:.FirSession + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Fir2IrComponentsStorage modality:FINAL visibility:public superTypes:[.Fir2IrComponents]' + PROPERTY name:session visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:session type:.FirSession visibility:private [final] + EXPRESSION_BODY + GET_VAR 'session: .FirSession declared in .Fir2IrComponentsStorage.' type=.FirSession origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Fir2IrComponentsStorage) returnType:.FirSession + correspondingProperty: PROPERTY name:session visibility:public modality:FINAL [val] + overridden: + public abstract fun (): .FirSession declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:.Fir2IrComponentsStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .FirSession declared in .Fir2IrComponentsStorage' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:session type:.FirSession visibility:private [final]' type=.FirSession origin=null + receiver: GET_VAR ': .Fir2IrComponentsStorage declared in .Fir2IrComponentsStorage.' type=.Fir2IrComponentsStorage origin=null + PROPERTY name:classifierStorage visibility:public modality:FINAL [lateinit,var] + FIELD PROPERTY_BACKING_FIELD name:classifierStorage type:.Fir2IrClassifierStorage visibility:public + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Fir2IrComponentsStorage) returnType:.Fir2IrClassifierStorage + correspondingProperty: PROPERTY name:classifierStorage visibility:public modality:FINAL [lateinit,var] + overridden: + public abstract fun (): .Fir2IrClassifierStorage declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:.Fir2IrComponentsStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): .Fir2IrClassifierStorage declared in .Fir2IrComponentsStorage' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:classifierStorage type:.Fir2IrClassifierStorage visibility:public' type=.Fir2IrClassifierStorage origin=null + receiver: GET_VAR ': .Fir2IrComponentsStorage declared in .Fir2IrComponentsStorage.' type=.Fir2IrComponentsStorage origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Fir2IrComponentsStorage, :.Fir2IrClassifierStorage) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:classifierStorage visibility:public modality:FINAL [lateinit,var] + $this: VALUE_PARAMETER name: type:.Fir2IrComponentsStorage + VALUE_PARAMETER name: index:0 type:.Fir2IrClassifierStorage + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:classifierStorage type:.Fir2IrClassifierStorage visibility:public' type=kotlin.Unit origin=null + receiver: GET_VAR ': .Fir2IrComponentsStorage declared in .Fir2IrComponentsStorage.' type=.Fir2IrComponentsStorage origin=null + value: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrComponentsStorage.' type=.Fir2IrClassifierStorage origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:Fir2IrClassifierStorage modality:FINAL visibility:public superTypes:[.Fir2IrComponents] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Fir2IrClassifierStorage + CONSTRUCTOR visibility:public <> (components:.Fir2IrComponents) returnType:.Fir2IrClassifierStorage [primary] + VALUE_PARAMETER name:components index:0 type:.Fir2IrComponents + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Fir2IrClassifierStorage modality:FINAL visibility:public superTypes:[.Fir2IrComponents]' + PROPERTY DELEGATED_MEMBER name:session visibility:public modality:OPEN [val] + FUN DELEGATED_MEMBER name: visibility:public modality:OPEN <> ($this:.Fir2IrClassifierStorage) returnType:.FirSession + correspondingProperty: PROPERTY DELEGATED_MEMBER name:session visibility:public modality:OPEN [val] + overridden: + public abstract fun (): .FirSession declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:.Fir2IrClassifierStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun (): .FirSession declared in .Fir2IrClassifierStorage' + CALL 'public abstract fun (): .FirSession declared in .Fir2IrComponents' type=.FirSession origin=null + $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.Fir2IrComponents visibility:local [final]' type=.Fir2IrComponents origin=null + receiver: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage.' type=.Fir2IrClassifierStorage origin=null + PROPERTY DELEGATED_MEMBER name:classifierStorage visibility:public modality:OPEN [val] + FUN DELEGATED_MEMBER name: visibility:public modality:OPEN <> ($this:.Fir2IrClassifierStorage) returnType:.Fir2IrClassifierStorage + correspondingProperty: PROPERTY DELEGATED_MEMBER name:classifierStorage visibility:public modality:OPEN [val] + overridden: + public abstract fun (): .Fir2IrClassifierStorage declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:.Fir2IrClassifierStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun (): .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage' + CALL 'public abstract fun (): .Fir2IrClassifierStorage declared in .Fir2IrComponents' type=.Fir2IrClassifierStorage origin=null + $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.Fir2IrComponents visibility:local [final]' type=.Fir2IrComponents origin=null + receiver: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage.' type=.Fir2IrClassifierStorage origin=null + FIELD DELEGATE name:<$$delegate_0> type:.Fir2IrComponents visibility:local [final] + EXPRESSION_BODY + GET_VAR 'components: .Fir2IrComponents declared in .Fir2IrClassifierStorage.' type=.Fir2IrComponents origin=null + PROPERTY name:components visibility:private modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:components type:.Fir2IrComponents visibility:private [final] + EXPRESSION_BODY + GET_VAR 'components: .Fir2IrComponents declared in .Fir2IrClassifierStorage.' type=.Fir2IrComponents origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:private modality:FINAL <> ($this:.Fir2IrClassifierStorage) returnType:.Fir2IrComponents + correspondingProperty: PROPERTY name:components visibility:private modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Fir2IrClassifierStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun (): .Fir2IrComponents declared in .Fir2IrClassifierStorage' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:components type:.Fir2IrComponents visibility:private [final]' type=.Fir2IrComponents origin=null + receiver: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage.' type=.Fir2IrClassifierStorage origin=null + PROPERTY name:name visibility:private modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final] + EXPRESSION_BODY + CALL 'public final fun (): kotlin.String declared in .FirSession' type=kotlin.String origin=GET_PROPERTY + $this: CALL 'public open fun (): .FirSession declared in .Fir2IrClassifierStorage' type=.FirSession origin=GET_PROPERTY + $this: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage' type=.Fir2IrClassifierStorage origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:private modality:FINAL <> ($this:.Fir2IrClassifierStorage) returnType:kotlin.String + correspondingProperty: PROPERTY name:name visibility:private modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Fir2IrClassifierStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun (): kotlin.String declared in .Fir2IrClassifierStorage' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage.' type=.Fir2IrClassifierStorage origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.kt b/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.kt new file mode 100644 index 00000000000..3fb5b303fdd --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.kt @@ -0,0 +1,18 @@ +class FirSession(val name: String) + +interface Fir2IrComponents { + val session: FirSession + val classifierStorage: Fir2IrClassifierStorage +} + +class Fir2IrComponentsStorage( + override val session: FirSession +) : Fir2IrComponents { + override lateinit var classifierStorage: Fir2IrClassifierStorage +} + +class Fir2IrClassifierStorage( + private val components: Fir2IrComponents +) : Fir2IrComponents by components { + private val name = session.name +} diff --git a/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.kt.txt b/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.kt.txt new file mode 100644 index 00000000000..e52d537d945 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.kt.txt @@ -0,0 +1,65 @@ +class FirSession { + constructor(name: String) /* primary */ { + super/*Any*/() + /* () */ + + } + + val name: String + field = name + get + +} + +interface Fir2IrComponents { + abstract val session: FirSession + abstract get + + abstract val classifierStorage: Fir2IrClassifierStorage + abstract get + +} + +class Fir2IrComponentsStorage : Fir2IrComponents { + constructor(session: FirSession) /* primary */ { + super/*Any*/() + /* () */ + + } + + override val session: FirSession + field = session + override get + + override lateinit var classifierStorage: Fir2IrClassifierStorage + override get + open set + +} + +class Fir2IrClassifierStorage : Fir2IrComponents { + constructor(components: Fir2IrComponents) /* primary */ { + super/*Any*/() + /* () */ + + } + + private val components: Fir2IrComponents + field = components + private get + + override val classifierStorage: Fir2IrClassifierStorage + override get(): Fir2IrClassifierStorage { + return .#components.() + } + + override val session: FirSession + override get(): FirSession { + return .#components.() + } + + private val name: String + field = .().() + private get + +} diff --git a/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.txt b/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.txt new file mode 100644 index 00000000000..f33e0eb64c7 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.txt @@ -0,0 +1,173 @@ +FILE fqName: fileName:/Fir2IrClassifierStorage.kt + CLASS CLASS name:FirSession modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FirSession + CONSTRUCTOR visibility:public <> (name:kotlin.String) returnType:.FirSession [primary] + VALUE_PARAMETER name:name index:0 type:kotlin.String + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:FirSession modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:name visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final] + EXPRESSION_BODY + GET_VAR 'name: kotlin.String declared in .FirSession.' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.FirSession) returnType:kotlin.String + correspondingProperty: PROPERTY name:name visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.FirSession + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .FirSession' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .FirSession declared in .FirSession.' type=.FirSession origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:Fir2IrComponents modality:ABSTRACT visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Fir2IrComponents + PROPERTY name:session visibility:public modality:ABSTRACT [val] + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:.Fir2IrComponents) returnType:.FirSession + correspondingProperty: PROPERTY name:session visibility:public modality:ABSTRACT [val] + $this: VALUE_PARAMETER name: type:.Fir2IrComponents + PROPERTY name:classifierStorage visibility:public modality:ABSTRACT [val] + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:.Fir2IrComponents) returnType:.Fir2IrClassifierStorage + correspondingProperty: PROPERTY name:classifierStorage visibility:public modality:ABSTRACT [val] + $this: VALUE_PARAMETER name: type:.Fir2IrComponents + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:Fir2IrComponentsStorage modality:FINAL visibility:public superTypes:[.Fir2IrComponents] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Fir2IrComponentsStorage + CONSTRUCTOR visibility:public <> (session:.FirSession) returnType:.Fir2IrComponentsStorage [primary] + VALUE_PARAMETER name:session index:0 type:.FirSession + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Fir2IrComponentsStorage modality:FINAL visibility:public superTypes:[.Fir2IrComponents]' + PROPERTY name:session visibility:public modality:OPEN [val] + FIELD PROPERTY_BACKING_FIELD name:session type:.FirSession visibility:private [final] + EXPRESSION_BODY + GET_VAR 'session: .FirSession declared in .Fir2IrComponentsStorage.' type=.FirSession origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:OPEN <> ($this:.Fir2IrComponentsStorage) returnType:.FirSession + correspondingProperty: PROPERTY name:session visibility:public modality:OPEN [val] + overridden: + public abstract fun (): .FirSession declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:.Fir2IrComponentsStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun (): .FirSession declared in .Fir2IrComponentsStorage' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:session type:.FirSession visibility:private [final]' type=.FirSession origin=null + receiver: GET_VAR ': .Fir2IrComponentsStorage declared in .Fir2IrComponentsStorage.' type=.Fir2IrComponentsStorage origin=null + PROPERTY name:classifierStorage visibility:public modality:OPEN [lateinit,var] + FIELD PROPERTY_BACKING_FIELD name:classifierStorage type:.Fir2IrClassifierStorage visibility:public + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:OPEN <> ($this:.Fir2IrComponentsStorage) returnType:.Fir2IrClassifierStorage + correspondingProperty: PROPERTY name:classifierStorage visibility:public modality:OPEN [lateinit,var] + overridden: + public abstract fun (): .Fir2IrClassifierStorage declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:.Fir2IrComponentsStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun (): .Fir2IrClassifierStorage declared in .Fir2IrComponentsStorage' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:classifierStorage type:.Fir2IrClassifierStorage visibility:public' type=.Fir2IrClassifierStorage origin=null + receiver: GET_VAR ': .Fir2IrComponentsStorage declared in .Fir2IrComponentsStorage.' type=.Fir2IrComponentsStorage origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:OPEN <> ($this:.Fir2IrComponentsStorage, :.Fir2IrClassifierStorage) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:classifierStorage visibility:public modality:OPEN [lateinit,var] + $this: VALUE_PARAMETER name: type:.Fir2IrComponentsStorage + VALUE_PARAMETER name: index:0 type:.Fir2IrClassifierStorage + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:classifierStorage type:.Fir2IrClassifierStorage visibility:public' type=kotlin.Unit origin=null + receiver: GET_VAR ': .Fir2IrComponentsStorage declared in .Fir2IrComponentsStorage.' type=.Fir2IrComponentsStorage origin=null + value: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrComponentsStorage.' type=.Fir2IrClassifierStorage origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:Fir2IrClassifierStorage modality:FINAL visibility:public superTypes:[.Fir2IrComponents] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Fir2IrClassifierStorage + CONSTRUCTOR visibility:public <> (components:.Fir2IrComponents) returnType:.Fir2IrClassifierStorage [primary] + VALUE_PARAMETER name:components index:0 type:.Fir2IrComponents + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Fir2IrClassifierStorage modality:FINAL visibility:public superTypes:[.Fir2IrComponents]' + PROPERTY name:components visibility:private modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:components type:.Fir2IrComponents visibility:private [final] + EXPRESSION_BODY + GET_VAR 'components: .Fir2IrComponents declared in .Fir2IrClassifierStorage.' type=.Fir2IrComponents origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:private modality:FINAL <> ($this:.Fir2IrClassifierStorage) returnType:.Fir2IrComponents + correspondingProperty: PROPERTY name:components visibility:private modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Fir2IrClassifierStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun (): .Fir2IrComponents declared in .Fir2IrClassifierStorage' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:components type:.Fir2IrComponents visibility:private [final]' type=.Fir2IrComponents origin=null + receiver: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage.' type=.Fir2IrClassifierStorage origin=null + PROPERTY DELEGATED_MEMBER name:classifierStorage visibility:public modality:OPEN [val] + FUN DELEGATED_MEMBER name: visibility:public modality:OPEN <> ($this:.Fir2IrClassifierStorage) returnType:.Fir2IrClassifierStorage + correspondingProperty: PROPERTY DELEGATED_MEMBER name:classifierStorage visibility:public modality:OPEN [val] + overridden: + public abstract fun (): .Fir2IrClassifierStorage declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:.Fir2IrClassifierStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun (): .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage' + CALL 'public abstract fun (): .Fir2IrClassifierStorage declared in .Fir2IrComponents' type=.Fir2IrClassifierStorage origin=null + $this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:components type:.Fir2IrComponents visibility:private [final]' type=.Fir2IrComponents origin=null + receiver: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage.' type=.Fir2IrClassifierStorage origin=null + PROPERTY DELEGATED_MEMBER name:session visibility:public modality:OPEN [val] + FUN DELEGATED_MEMBER name: visibility:public modality:OPEN <> ($this:.Fir2IrClassifierStorage) returnType:.FirSession + correspondingProperty: PROPERTY DELEGATED_MEMBER name:session visibility:public modality:OPEN [val] + overridden: + public abstract fun (): .FirSession declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:.Fir2IrClassifierStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='public open fun (): .FirSession declared in .Fir2IrClassifierStorage' + CALL 'public abstract fun (): .FirSession declared in .Fir2IrComponents' type=.FirSession origin=null + $this: GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:components type:.Fir2IrComponents visibility:private [final]' type=.Fir2IrComponents origin=null + receiver: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage.' type=.Fir2IrClassifierStorage origin=null + PROPERTY name:name visibility:private modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final] + EXPRESSION_BODY + CALL 'public final fun (): kotlin.String declared in .FirSession' type=kotlin.String origin=GET_PROPERTY + $this: CALL 'public open fun (): .FirSession declared in .Fir2IrClassifierStorage' type=.FirSession origin=GET_PROPERTY + $this: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage' type=.Fir2IrClassifierStorage origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:private modality:FINAL <> ($this:.Fir2IrClassifierStorage) returnType:kotlin.String + correspondingProperty: PROPERTY name:name visibility:private modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Fir2IrClassifierStorage + BLOCK_BODY + RETURN type=kotlin.Nothing from='private final fun (): kotlin.String declared in .Fir2IrClassifierStorage' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .Fir2IrClassifierStorage declared in .Fir2IrClassifierStorage.' type=.Fir2IrClassifierStorage origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in .Fir2IrComponents + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.kt.txt b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.kt.txt new file mode 100644 index 00000000000..3bf28334e98 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.kt.txt @@ -0,0 +1,52 @@ +fun foo(s: String?): String { + { // BLOCK + val tmp0_safe_receiver: String? = s + when { + EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null + else -> tmp0_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } /*~> Unit */ + return "" +} + +fun bar(s: String?, t: String?): String { + { // BLOCK + val tmp1_safe_receiver: String? = s + when { + EQEQ(arg0 = tmp1_safe_receiver, arg1 = null) -> null + else -> tmp1_safe_receiver.let(block = local fun (it: String): Nothing? { + return { // BLOCK + val tmp2_safe_receiver: String? = t + when { + EQEQ(arg0 = tmp2_safe_receiver, arg1 = null) -> null + else -> tmp2_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } + } +) + } + } /*~> Unit */ + return "" +} + +val String?.baz: String + get(): String { + { // BLOCK + val tmp3_safe_receiver: String? = + when { + EQEQ(arg0 = tmp3_safe_receiver, arg1 = null) -> null + else -> tmp3_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } /*~> Unit */ + return "" + } + diff --git a/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.txt b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.txt new file mode 100644 index 00000000000..4a50937c199 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.fir.txt @@ -0,0 +1,105 @@ +FILE fqName: fileName:/SafeLetWithReturn.kt + FUN name:foo visibility:public modality:FINAL <> (s:kotlin.String?) returnType:kotlin.String + VALUE_PARAMETER name:s index:0 type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.String? [val] + GET_VAR 's: kotlin.String? declared in .foo' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .foo' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .foo' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun foo (s: kotlin.String?): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in .foo.' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun foo (s: kotlin.String?): kotlin.String declared in ' + CONST String type=kotlin.String value="" + FUN name:bar visibility:public modality:FINAL <> (s:kotlin.String?, t:kotlin.String?) returnType:kotlin.String + VALUE_PARAMETER name:s index:0 type:kotlin.String? + VALUE_PARAMETER name:t index:1 type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.String? [val] + GET_VAR 's: kotlin.String? declared in .bar' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .bar' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing? origin=null + : kotlin.String + : kotlin.Nothing? + $receiver: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .bar' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing? + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.String): kotlin.Nothing? declared in .bar' + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.String? [val] + GET_VAR 't: kotlin.String? declared in .bar' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .bar.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .bar.' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun bar (s: kotlin.String?, t: kotlin.String?): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in .bar..' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun bar (s: kotlin.String?, t: kotlin.String?): kotlin.String declared in ' + CONST String type=kotlin.String value="" + PROPERTY name:baz visibility:public modality:FINAL [val] + FUN name: visibility:public modality:FINAL <> ($receiver:kotlin.String?) returnType:kotlin.String + correspondingProperty: PROPERTY name:baz visibility:public modality:FINAL [val] + $receiver: VALUE_PARAMETER name: type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.String? [val] + GET_VAR ': kotlin.String? declared in .' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_3: kotlin.String? [val] declared in .' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_3: kotlin.String? [val] declared in .' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in ..' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' + CONST String type=kotlin.String value="" diff --git a/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt new file mode 100644 index 00000000000..a1944d97ff4 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt @@ -0,0 +1,25 @@ +// WITH_RUNTIME + +fun foo(s: String?): String { + s?.let { it -> + return it + } + return "" +} + +fun bar(s: String?, t: String?): String { + s?.let { + t?.let { + return it + } + } + return "" +} + +val String?.baz: String + get() { + this?.let { + return it + } + return "" + } \ No newline at end of file diff --git a/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt.txt b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt.txt new file mode 100644 index 00000000000..aca6153a0e8 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt.txt @@ -0,0 +1,52 @@ +fun foo(s: String?): String { + { // BLOCK + val tmp0_safe_receiver: String? = s + when { + EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null + else -> tmp0_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } /*~> Unit */ + return "" +} + +fun bar(s: String?, t: String?): String { + { // BLOCK + val tmp0_safe_receiver: String? = s + when { + EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null + else -> tmp0_safe_receiver.let(block = local fun (it: String): Nothing? { + { // BLOCK + val tmp0_safe_receiver: String? = t + when { + EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null + else -> tmp0_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } /*~> Unit */ + } +) + } + } /*~> Unit */ + return "" +} + +val String?.baz: String + get(): String { + { // BLOCK + val tmp0_safe_receiver: String? = + when { + EQEQ(arg0 = tmp0_safe_receiver, arg1 = null) -> null + else -> tmp0_safe_receiver.let(block = local fun (it: String): Nothing { + return it + } +) + } + } /*~> Unit */ + return "" + } + diff --git a/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.txt b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.txt new file mode 100644 index 00000000000..78487630cb9 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SafeLetWithReturn.txt @@ -0,0 +1,105 @@ +FILE fqName: fileName:/SafeLetWithReturn.kt + FUN name:foo visibility:public modality:FINAL <> (s:kotlin.String?) returnType:kotlin.String + VALUE_PARAMETER name:s index:0 type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.String? [val] + GET_VAR 's: kotlin.String? declared in .foo' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .foo' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .foo' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun foo (s: kotlin.String?): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in .foo.' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun foo (s: kotlin.String?): kotlin.String declared in ' + CONST String type=kotlin.String value="" + FUN name:bar visibility:public modality:FINAL <> (s:kotlin.String?, t:kotlin.String?) returnType:kotlin.String + VALUE_PARAMETER name:s index:0 type:kotlin.String? + VALUE_PARAMETER name:t index:1 type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.String? [val] + GET_VAR 's: kotlin.String? declared in .bar' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .bar' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing? origin=null + : kotlin.String + : kotlin.Nothing? + $receiver: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .bar' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing? + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.String? [val] + GET_VAR 't: kotlin.String? declared in .bar' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .bar.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .bar.' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun bar (s: kotlin.String?, t: kotlin.String?): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in .bar..' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun bar (s: kotlin.String?, t: kotlin.String?): kotlin.String declared in ' + CONST String type=kotlin.String value="" + PROPERTY name:baz visibility:public modality:FINAL [val] + FUN name: visibility:public modality:FINAL <> ($receiver:kotlin.String?) returnType:kotlin.String + correspondingProperty: PROPERTY name:baz visibility:public modality:FINAL [val] + $receiver: VALUE_PARAMETER name: type:kotlin.String? + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + BLOCK type=kotlin.Nothing? origin=SAFE_CALL + VAR IR_TEMPORARY_VARIABLE name:tmp_3 type:kotlin.String? [val] + GET_VAR ': kotlin.String? declared in .' type=kotlin.String? origin=null + WHEN type=kotlin.Nothing? origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_3: kotlin.String? [val] declared in .' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CALL 'public final fun let (block: kotlin.Function1): R of kotlin.StandardKt.let [inline] declared in kotlin.StandardKt' type=kotlin.Nothing origin=null + : kotlin.String + : kotlin.Nothing + $receiver: GET_VAR 'val tmp_3: kotlin.String? [val] declared in .' type=kotlin.String? origin=null + block: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.String) returnType:kotlin.Nothing + VALUE_PARAMETER name:it index:0 type:kotlin.String + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' + GET_VAR 'it: kotlin.String declared in ..' type=kotlin.String origin=null + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in ' + CONST String type=kotlin.String value="" diff --git a/compiler/testData/ir/irText/firProblems/SignatureClash.fir.kt.txt b/compiler/testData/ir/irText/firProblems/SignatureClash.fir.kt.txt index 885315add8f..c526daa3155 100644 --- a/compiler/testData/ir/irText/firProblems/SignatureClash.fir.kt.txt +++ b/compiler/testData/ir/irText/firProblems/SignatureClash.fir.kt.txt @@ -34,9 +34,13 @@ data class DataClass : Derived, Delegate { super/*Any*/() /* () */ - .#<$$delegate_0> = delegate } + override fun bar() { + .#<$$delegate_0>.bar() + } + + local /* final field */ val <$$delegate_0>: Delegate = delegate val delegate: Delegate field = delegate get @@ -49,11 +53,6 @@ data class DataClass : Derived, Delegate { return DataClass(delegate = delegate) } - override fun bar() { - .#<$$delegate_0>.bar() - } - - local /* final field */ val <$$delegate_0>: Delegate override fun equals(other: Any?): Boolean { when { EQEQEQ(arg0 = , arg1 = other) -> return true diff --git a/compiler/testData/ir/irText/firProblems/SignatureClash.fir.txt b/compiler/testData/ir/irText/firProblems/SignatureClash.fir.txt index eee7eb43a0e..cb1dbac87ff 100644 --- a/compiler/testData/ir/irText/firProblems/SignatureClash.fir.txt +++ b/compiler/testData/ir/irText/firProblems/SignatureClash.fir.txt @@ -90,9 +90,17 @@ FILE fqName: fileName:/SignatureClash.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:DataClass modality:FINAL visibility:public [data] superTypes:[.Derived; .Delegate]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.Delegate visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .DataClass declared in .DataClass' type=.DataClass origin=null - value: GET_VAR 'delegate: .Delegate declared in .DataClass.' type=.Delegate origin=null + FUN DELEGATED_MEMBER name:bar visibility:public modality:OPEN <> ($this:.DataClass) returnType:kotlin.Unit + overridden: + public abstract fun bar (): kotlin.Unit declared in .Delegate + $this: VALUE_PARAMETER name: type:.DataClass + BLOCK_BODY + CALL 'public abstract fun bar (): kotlin.Unit declared in .Delegate' type=kotlin.Unit origin=null + $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.Delegate visibility:local [final]' type=.Delegate origin=null + receiver: GET_VAR ': .DataClass declared in .DataClass.bar' type=.DataClass origin=null + FIELD DELEGATE name:<$$delegate_0> type:.Delegate visibility:local [final] + EXPRESSION_BODY + GET_VAR 'delegate: .Delegate declared in .DataClass.' type=.Delegate origin=null PROPERTY name:delegate visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:delegate type:.Delegate visibility:private [final] EXPRESSION_BODY @@ -120,15 +128,6 @@ FILE fqName: fileName:/SignatureClash.kt RETURN type=kotlin.Nothing from='public final fun copy (delegate: .Delegate): .DataClass declared in .DataClass' CONSTRUCTOR_CALL 'public constructor (delegate: .Delegate) [primary] declared in .DataClass' type=.DataClass origin=null delegate: GET_VAR 'delegate: .Delegate declared in .DataClass.copy' type=.Delegate origin=null - FUN DELEGATED_MEMBER name:bar visibility:public modality:OPEN <> ($this:.DataClass) returnType:kotlin.Unit - overridden: - public abstract fun bar (): kotlin.Unit declared in .Delegate - $this: VALUE_PARAMETER name: type:.DataClass - BLOCK_BODY - CALL 'public abstract fun bar (): kotlin.Unit declared in .Delegate' type=kotlin.Unit origin=null - $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.Delegate visibility:local [final]' type=.Delegate origin=null - receiver: GET_VAR ': .DataClass declared in .DataClass.bar' type=.DataClass origin=null - FIELD DELEGATE name:<$$delegate_0> type:.Delegate visibility:local [final] FUN GENERATED_DATA_CLASS_MEMBER name:equals visibility:public modality:OPEN <> ($this:.DataClass, other:kotlin.Any?) returnType:kotlin.Boolean overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/firProblems/kt43342.fir.kt.txt b/compiler/testData/ir/irText/firProblems/kt43342.fir.kt.txt index c8ff8f1c5f3..c11a33034fd 100644 --- a/compiler/testData/ir/irText/firProblems/kt43342.fir.kt.txt +++ b/compiler/testData/ir/irText/firProblems/kt43342.fir.kt.txt @@ -3,13 +3,8 @@ open class ControlFlowInfo : Map { super/*Any*/() /* () */ - .#<$$delegate_0> = map } - val map: Map - field = map - get - override fun containsKey(key: K): Boolean { return .#<$$delegate_0>.containsKey(key = key) } @@ -52,7 +47,10 @@ open class ControlFlowInfo : Map { return .#<$$delegate_0>.() } - local /* final field */ val <$$delegate_0>: Map + local /* final field */ val <$$delegate_0>: Map = map + val map: Map + field = map + get } diff --git a/compiler/testData/ir/irText/firProblems/kt43342.fir.txt b/compiler/testData/ir/irText/firProblems/kt43342.fir.txt index cdd198c1fb4..a5076e5d6e0 100644 --- a/compiler/testData/ir/irText/firProblems/kt43342.fir.txt +++ b/compiler/testData/ir/irText/firProblems/kt43342.fir.txt @@ -8,20 +8,6 @@ FILE fqName: fileName:/kt43342.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:ControlFlowInfo modality:OPEN visibility:public superTypes:[kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo>]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo> declared in .ControlFlowInfo' type=.ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo> origin=null - value: GET_VAR 'map: kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> declared in .ControlFlowInfo.' type=kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> origin=null - PROPERTY name:map visibility:public modality:FINAL [val] - FIELD PROPERTY_BACKING_FIELD name:map type:kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> visibility:private [final] - EXPRESSION_BODY - GET_VAR 'map: kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> declared in .ControlFlowInfo.' type=kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> origin=INITIALIZE_PROPERTY_FROM_PARAMETER - FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo>) returnType:kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> - correspondingProperty: PROPERTY name:map visibility:public modality:FINAL [val] - $this: VALUE_PARAMETER name: type:.ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> declared in .ControlFlowInfo' - GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:map type:kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> visibility:private [final]' type=kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> origin=null - receiver: GET_VAR ': .ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo> declared in .ControlFlowInfo.' type=.ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo> origin=null FUN DELEGATED_MEMBER name:containsKey visibility:public modality:OPEN <> ($this:.ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo>, key:K of .ControlFlowInfo) returnType:kotlin.Boolean overridden: public abstract fun containsKey (key: K of kotlin.collections.Map): kotlin.Boolean declared in kotlin.collections.Map @@ -125,6 +111,19 @@ FILE fqName: fileName:/kt43342.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> visibility:local [final]' type=kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> origin=null receiver: GET_VAR ': .ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo> declared in .ControlFlowInfo.' type=.ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo> origin=null FIELD DELEGATE name:<$$delegate_0> type:kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> visibility:local [final] + EXPRESSION_BODY + GET_VAR 'map: kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> declared in .ControlFlowInfo.' type=kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> origin=null + PROPERTY name:map visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:map type:kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> visibility:private [final] + EXPRESSION_BODY + GET_VAR 'map: kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> declared in .ControlFlowInfo.' type=kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo>) returnType:kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> + correspondingProperty: PROPERTY name:map visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo> + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> declared in .ControlFlowInfo' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:map type:kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> visibility:private [final]' type=kotlin.collections.Map.ControlFlowInfo, V of .ControlFlowInfo> origin=null + receiver: GET_VAR ': .ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo> declared in .ControlFlowInfo.' type=.ControlFlowInfo.ControlFlowInfo, V of .ControlFlowInfo> origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/types/javaWildcardType.fir.kt.txt b/compiler/testData/ir/irText/types/javaWildcardType.fir.kt.txt index f497b74edb0..19c032519a3 100644 --- a/compiler/testData/ir/irText/types/javaWildcardType.fir.kt.txt +++ b/compiler/testData/ir/irText/types/javaWildcardType.fir.kt.txt @@ -11,8 +11,6 @@ class C : J, K { super/*Any*/() /* () */ - .#<$$delegate_0> = j - .#<$$delegate_1> = k } override fun jf1(): Collection? { @@ -31,7 +29,7 @@ class C : J, K { .#<$$delegate_0>.jg2(c = c) } - local /* final field */ val <$$delegate_0>: J + local /* final field */ val <$$delegate_0>: J = j override fun kf1(): Collection { return .#<$$delegate_1>.kf1() } @@ -48,7 +46,7 @@ class C : J, K { .#<$$delegate_1>.kg2(c = c) } - local /* final field */ val <$$delegate_1>: K + local /* final field */ val <$$delegate_1>: K = k } diff --git a/compiler/testData/ir/irText/types/javaWildcardType.fir.txt b/compiler/testData/ir/irText/types/javaWildcardType.fir.txt index 256454833dd..eb3ee656b68 100644 --- a/compiler/testData/ir/irText/types/javaWildcardType.fir.txt +++ b/compiler/testData/ir/irText/types/javaWildcardType.fir.txt @@ -32,12 +32,6 @@ FILE fqName: fileName:/javaWildcardType.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[.J; .K]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.J visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .C declared in .C' type=.C origin=null - value: GET_VAR 'j: .J declared in .C.' type=.J origin=null - SET_FIELD 'FIELD DELEGATE name:<$$delegate_1> type:.K visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .C declared in .C' type=.C origin=null - value: GET_VAR 'k: .K declared in .C.' type=.K origin=null FUN DELEGATED_MEMBER name:jf1 visibility:public modality:OPEN <> ($this:.C) returnType:kotlin.collections.Collection? overridden: public abstract fun jf1 (): kotlin.collections.Collection? declared in .J @@ -77,6 +71,8 @@ FILE fqName: fileName:/javaWildcardType.kt receiver: GET_VAR ': .C declared in .C.jg2' type=.C origin=null c: GET_VAR 'c: kotlin.collections.Collection? declared in .C.jg2' type=kotlin.collections.Collection? origin=null FIELD DELEGATE name:<$$delegate_0> type:.J visibility:local [final] + EXPRESSION_BODY + GET_VAR 'j: .J declared in .C.' type=.J origin=null FUN DELEGATED_MEMBER name:kf1 visibility:public modality:OPEN <> ($this:.C) returnType:kotlin.collections.Collection overridden: public abstract fun kf1 (): kotlin.collections.Collection declared in .K @@ -116,6 +112,8 @@ FILE fqName: fileName:/javaWildcardType.kt receiver: GET_VAR ': .C declared in .C.kg2' type=.C origin=null c: GET_VAR 'c: kotlin.collections.Collection declared in .C.kg2' type=kotlin.collections.Collection origin=null FIELD DELEGATE name:<$$delegate_1> type:.K visibility:local [final] + EXPRESSION_BODY + GET_VAR 'k: .K declared in .C.' type=.K origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/testData/ir/irText/types/rawTypeInSignature.fir.kt.txt b/compiler/testData/ir/irText/types/rawTypeInSignature.fir.kt.txt index 0c810163b36..0954b249933 100644 --- a/compiler/testData/ir/irText/types/rawTypeInSignature.fir.kt.txt +++ b/compiler/testData/ir/irText/types/rawTypeInSignature.fir.kt.txt @@ -42,7 +42,6 @@ class KRaw : JRaw { super/*Any*/() /* () */ - .#<$$delegate_0> = j } override fun takesRawList(list: List<*>?) { @@ -77,7 +76,7 @@ class KRaw : JRaw { return .#<$$delegate_0>.returnsRawGenericOut() } - local /* final field */ val <$$delegate_0>: JRaw + local /* final field */ val <$$delegate_0>: JRaw = j } diff --git a/compiler/testData/ir/irText/types/rawTypeInSignature.fir.txt b/compiler/testData/ir/irText/types/rawTypeInSignature.fir.txt index 30b0c189dc0..276e36ae09e 100644 --- a/compiler/testData/ir/irText/types/rawTypeInSignature.fir.txt +++ b/compiler/testData/ir/irText/types/rawTypeInSignature.fir.txt @@ -84,9 +84,6 @@ FILE fqName: fileName:/rawTypeInSignature.kt BLOCK_BODY DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:KRaw modality:FINAL visibility:public superTypes:[.JRaw]' - SET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.JRaw visibility:local [final]' type=kotlin.Unit origin=EQ - receiver: GET_VAR ': .KRaw declared in .KRaw' type=.KRaw origin=null - value: GET_VAR 'j: .JRaw declared in .KRaw.' type=.JRaw origin=null FUN DELEGATED_MEMBER name:takesRawList visibility:public modality:OPEN <> ($this:.KRaw, list:kotlin.collections.List<*>?) returnType:kotlin.Unit overridden: public abstract fun takesRawList (list: kotlin.collections.List<*>?): kotlin.Unit declared in .JRaw @@ -164,6 +161,8 @@ FILE fqName: fileName:/rawTypeInSignature.kt $this: GET_FIELD 'FIELD DELEGATE name:<$$delegate_0> type:.JRaw visibility:local [final]' type=.JRaw origin=null receiver: GET_VAR ': .KRaw declared in .KRaw.returnsRawGenericOut' type=.KRaw origin=null FIELD DELEGATE name:<$$delegate_0> type:.JRaw visibility:local [final] + EXPRESSION_BODY + GET_VAR 'j: .JRaw declared in .KRaw.' type=.JRaw origin=null FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] overridden: public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 32e1253c1d5..9ab80c8a85b 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -11841,6 +11841,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/inference/equalitySubstitutionInsideNonInvariantType.kt"); } + @Test + @TestMetadata("errorsOnImplicitInvokeInSimpleCall.kt") + public void testErrorsOnImplicitInvokeInSimpleCall() throws Exception { + runTest("compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt"); + } + @Test @TestMetadata("expectedTypeAdditionalTest.kt") public void testExpectedTypeAdditionalTest() throws Exception { @@ -24475,6 +24481,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/sealed/inheritorInDifferentModule.kt"); } + @Test + @TestMetadata("kt44316.kt") + public void testKt44316() throws Exception { + runTest("compiler/testData/diagnostics/tests/sealed/kt44316.kt"); + } + @Test @TestMetadata("Local.kt") public void testLocal() throws Exception { @@ -30734,6 +30746,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/testsWithStdLib/assignedInSynchronized.kt"); } + @Test + @TestMetadata("buildLazyValueForMap.kt") + public void testBuildLazyValueForMap() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/buildLazyValueForMap.kt"); + } + @Test @TestMetadata("CallCompanionProtectedNonStatic.kt") public void testCallCompanionProtectedNonStatic() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 0d276b1f143..881b0294160 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -13644,6 +13644,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/elvis/nullNullOk.kt"); } + @Test + @TestMetadata("ofNonNullableResultType.kt") + public void testOfNonNullableResultType() throws Exception { + runTest("compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt"); + } + @Test @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { @@ -14623,6 +14629,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testPropertySetter() throws Exception { runTest("compiler/testData/codegen/box/fakeOverride/propertySetter.kt"); } + + @Test + @TestMetadata("varianceOverload.kt") + public void testVarianceOverload() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/varianceOverload.kt"); + } } @Nested @@ -14834,12 +14846,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/fir/FakeOverrideBuilder.kt"); } + @Test + @TestMetadata("Fir2IrClassifierStorage.kt") + public void testFir2IrClassifierStorage() throws Exception { + runTest("compiler/testData/codegen/box/fir/Fir2IrClassifierStorage.kt"); + } + @Test @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { runTest("compiler/testData/codegen/box/fir/IrBuiltIns.kt"); } + @Test + @TestMetadata("LookupTags.kt") + public void testLookupTags() throws Exception { + runTest("compiler/testData/codegen/box/fir/LookupTags.kt"); + } + @Test @TestMetadata("NameHighlighter.kt") public void testNameHighlighter() throws Exception { @@ -16936,6 +16960,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineClasses/conformToComparableAndCallInterfaceMethod.kt"); } + @Test + @TestMetadata("constructorCallableReference.kt") + public void testConstructorCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt"); + } + @Test @TestMetadata("constructorImplVisibility.kt") public void testConstructorImplVisibility() throws Exception { @@ -38966,6 +38996,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); } + @Test + @TestMetadata("extensionFunction.kt") + public void testExtensionFunction() throws Exception { + runTest("compiler/testData/codegen/box/typealias/extensionFunction.kt"); + } + @Test @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java index f080a1b5d6e..72138fbfd89 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -1020,6 +1020,46 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo runTest("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); } + @Nested + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/adaptedReferences") + @TestDataPath("$PROJECT_ROOT") + public class AdaptedReferences { + @Test + public void testAllFilesPresentInAdaptedReferences() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @Test + @TestMetadata("inlineBound.kt") + public void testInlineBound() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt"); + } + + @Test + @TestMetadata("inlineDefault.kt") + public void testInlineDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt"); + } + + @Test + @TestMetadata("inlineVararg.kt") + public void testInlineVararg() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt"); + } + + @Test + @TestMetadata("inlineVarargAndDefault.kt") + public void testInlineVarargAndDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt"); + } + + @Test + @TestMetadata("inlineVarargInts.kt") + public void testInlineVarargInts() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index b5a34bce5e4..d0f0178aca3 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1020,6 +1020,46 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi runTest("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); } + @Nested + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/adaptedReferences") + @TestDataPath("$PROJECT_ROOT") + public class AdaptedReferences { + @Test + public void testAllFilesPresentInAdaptedReferences() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @Test + @TestMetadata("inlineBound.kt") + public void testInlineBound() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt"); + } + + @Test + @TestMetadata("inlineDefault.kt") + public void testInlineDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt"); + } + + @Test + @TestMetadata("inlineVararg.kt") + public void testInlineVararg() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt"); + } + + @Test + @TestMetadata("inlineVarargAndDefault.kt") + public void testInlineVarargAndDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt"); + } + + @Test + @TestMetadata("inlineVarargInts.kt") + public void testInlineVarargInts() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index a5b60776c46..fe98e42f7e8 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -13644,6 +13644,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/elvis/nullNullOk.kt"); } + @Test + @TestMetadata("ofNonNullableResultType.kt") + public void testOfNonNullableResultType() throws Exception { + runTest("compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt"); + } + @Test @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { @@ -14623,6 +14629,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testPropertySetter() throws Exception { runTest("compiler/testData/codegen/box/fakeOverride/propertySetter.kt"); } + + @Test + @TestMetadata("varianceOverload.kt") + public void testVarianceOverload() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/varianceOverload.kt"); + } } @Nested @@ -14834,12 +14846,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/fir/FakeOverrideBuilder.kt"); } + @Test + @TestMetadata("Fir2IrClassifierStorage.kt") + public void testFir2IrClassifierStorage() throws Exception { + runTest("compiler/testData/codegen/box/fir/Fir2IrClassifierStorage.kt"); + } + @Test @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { runTest("compiler/testData/codegen/box/fir/IrBuiltIns.kt"); } + @Test + @TestMetadata("LookupTags.kt") + public void testLookupTags() throws Exception { + runTest("compiler/testData/codegen/box/fir/LookupTags.kt"); + } + @Test @TestMetadata("NameHighlighter.kt") public void testNameHighlighter() throws Exception { @@ -16936,6 +16960,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/conformToComparableAndCallInterfaceMethod.kt"); } + @Test + @TestMetadata("constructorCallableReference.kt") + public void testConstructorCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt"); + } + @Test @TestMetadata("constructorImplVisibility.kt") public void testConstructorImplVisibility() throws Exception { @@ -38760,6 +38790,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); } + @Test + @TestMetadata("extensionFunction.kt") + public void testExtensionFunction() throws Exception { + runTest("compiler/testData/codegen/box/typealias/extensionFunction.kt"); + } + @Test @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenTestGenerated.java index b27943edb45..58f7c16bd5b 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxInlineCodegenTestGenerated.java @@ -1020,6 +1020,46 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli runTest("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); } + @Nested + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/adaptedReferences") + @TestDataPath("$PROJECT_ROOT") + public class AdaptedReferences { + @Test + public void testAllFilesPresentInAdaptedReferences() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("inlineBound.kt") + public void testInlineBound() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt"); + } + + @Test + @TestMetadata("inlineDefault.kt") + public void testInlineDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt"); + } + + @Test + @TestMetadata("inlineVararg.kt") + public void testInlineVararg() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt"); + } + + @Test + @TestMetadata("inlineVarargAndDefault.kt") + public void testInlineVarargAndDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt"); + } + + @Test + @TestMetadata("inlineVarargInts.kt") + public void testInlineVarargInts() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index 82a9a8ed03d..656b29eb9e4 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -1020,6 +1020,46 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC runTest("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); } + @Nested + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/adaptedReferences") + @TestDataPath("$PROJECT_ROOT") + public class AdaptedReferences { + @Test + public void testAllFilesPresentInAdaptedReferences() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @Test + @TestMetadata("inlineBound.kt") + public void testInlineBound() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt"); + } + + @Test + @TestMetadata("inlineDefault.kt") + public void testInlineDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt"); + } + + @Test + @TestMetadata("inlineVararg.kt") + public void testInlineVararg() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt"); + } + + @Test + @TestMetadata("inlineVarargAndDefault.kt") + public void testInlineVarargAndDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt"); + } + + @Test + @TestMetadata("inlineVarargInts.kt") + public void testInlineVarargInts() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java index b33d5bef291..d50581746ff 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmIrAgainstOldBoxInlineTestGenerated.java @@ -1020,6 +1020,46 @@ public class JvmIrAgainstOldBoxInlineTestGenerated extends AbstractJvmIrAgainstO runTest("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); } + @Nested + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/adaptedReferences") + @TestDataPath("$PROJECT_ROOT") + public class AdaptedReferences { + @Test + public void testAllFilesPresentInAdaptedReferences() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_MULTI_MODULE_IR_AGAINST_OLD, true); + } + + @Test + @TestMetadata("inlineBound.kt") + public void testInlineBound() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt"); + } + + @Test + @TestMetadata("inlineDefault.kt") + public void testInlineDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt"); + } + + @Test + @TestMetadata("inlineVararg.kt") + public void testInlineVararg() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt"); + } + + @Test + @TestMetadata("inlineVarargAndDefault.kt") + public void testInlineVarargAndDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt"); + } + + @Test + @TestMetadata("inlineVarargInts.kt") + public void testInlineVarargInts() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java index d97680edabe..cb3218d01f0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/JvmOldAgainstIrBoxInlineTestGenerated.java @@ -1020,6 +1020,46 @@ public class JvmOldAgainstIrBoxInlineTestGenerated extends AbstractJvmOldAgainst runTest("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); } + @Nested + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/adaptedReferences") + @TestDataPath("$PROJECT_ROOT") + public class AdaptedReferences { + @Test + public void testAllFilesPresentInAdaptedReferences() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_MULTI_MODULE_OLD_AGAINST_IR, true); + } + + @Test + @TestMetadata("inlineBound.kt") + public void testInlineBound() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt"); + } + + @Test + @TestMetadata("inlineDefault.kt") + public void testInlineDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt"); + } + + @Test + @TestMetadata("inlineVararg.kt") + public void testInlineVararg() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt"); + } + + @Test + @TestMetadata("inlineVarargAndDefault.kt") + public void testInlineVarargAndDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt"); + } + + @Test + @TestMetadata("inlineVarargInts.kt") + public void testInlineVarargInts() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); + } + } + @Nested @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") @TestDataPath("$PROJECT_ROOT") diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java index 9f6dbe9f456..b7324e8531e 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/ir/IrTextTestGenerated.java @@ -2116,6 +2116,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest { runTest("compiler/testData/ir/irText/firProblems/deprecated.kt"); } + @Test + @TestMetadata("Fir2IrClassifierStorage.kt") + public void testFir2IrClassifierStorage() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/Fir2IrClassifierStorage.kt"); + } + @Test @TestMetadata("FirBuilder.kt") public void testFirBuilder() throws Exception { @@ -2182,6 +2188,12 @@ public class IrTextTestGenerated extends AbstractIrTextTest { runTest("compiler/testData/ir/irText/firProblems/recursiveCapturedTypeInPropertyReference.kt"); } + @Test + @TestMetadata("SafeLetWithReturn.kt") + public void testSafeLetWithReturn() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/SafeLetWithReturn.kt"); + } + @Test @TestMetadata("SameJavaFieldReferences.kt") public void testSameJavaFieldReferences() throws Exception { diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrResultsConverter.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrResultsConverter.kt index 2c82f999c12..d6c5b69a5ae 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrResultsConverter.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/fir/Fir2IrResultsConverter.kt @@ -91,7 +91,8 @@ class Fir2IrResultsConverter( phaseConfig, irProviders, extensions, - FirJvmBackendExtension(inputArtifact.session, components) + FirJvmBackendExtension(inputArtifact.session, components), + {}, ) ) } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt index 48fcd38274a..89e790458bb 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/CompilerConfigurationProvider.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.test.services -import com.intellij.mock.MockProject import com.intellij.openapi.Disposable import com.intellij.openapi.project.Project import com.intellij.psi.search.GlobalSearchScope @@ -26,6 +25,7 @@ import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.platform.konan.isNative import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.test.ApplicationEnvironmentDisposer +import org.jetbrains.kotlin.test.TestInfrastructureInternals import org.jetbrains.kotlin.test.model.TestFile import org.jetbrains.kotlin.test.model.TestModule import java.io.File @@ -68,6 +68,7 @@ open class CompilerConfigurationProviderImpl( } } + @OptIn(TestInfrastructureInternals::class) protected open fun createKotlinCoreEnvironment(module: TestModule): KotlinCoreEnvironment { val platform = module.targetPlatform val configFiles = when { @@ -85,12 +86,13 @@ open class CompilerConfigurationProviderImpl( val projectEnv = KotlinCoreEnvironment.ProjectEnvironment(testRootDisposable, applicationEnvironment) return KotlinCoreEnvironment.createForTests( projectEnv, - createCompilerConfiguration(module, projectEnv.project), + createCompilerConfiguration(module), configFiles ) } - private fun createCompilerConfiguration(module: TestModule, project: MockProject): CompilerConfiguration { + @TestInfrastructureInternals + fun createCompilerConfiguration(module: TestModule): CompilerConfiguration { val configuration = CompilerConfiguration() configuration[CommonConfigurationKeys.MODULE_NAME] = module.name @@ -108,7 +110,7 @@ open class CompilerConfigurationProviderImpl( } configuration.languageVersionSettings = module.languageVersionSettings - configurators.forEach { it.configureCompileConfigurationWithAdditionalConfigurationKeys(configuration, module, project) } + configurators.forEach { it.configureCompileConfigurationWithAdditionalConfigurationKeys(configuration, module) } return configuration } diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/CommonEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/CommonEnvironmentConfigurator.kt index 5799d2fcffe..1d9d69563e5 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/CommonEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/CommonEnvironmentConfigurator.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.test.services.configuration -import com.intellij.mock.MockProject import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfigurationKey import org.jetbrains.kotlin.test.directives.ConfigurationDirectives @@ -19,7 +18,7 @@ class CommonEnvironmentConfigurator(testServices: TestServices) : EnvironmentCon override val directivesContainers: List get() = listOf(ConfigurationDirectives) - override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule, project: MockProject) { + override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) { val rawFlags = module.directives[ConfigurationDirectives.KOTLIN_CONFIGURATION_FLAGS] parseAnalysisFlags(rawFlags).forEach { (key, value) -> @Suppress("UNCHECKED_CAST") diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JsEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JsEnvironmentConfigurator.kt index b7f0929e65f..2c7c1e7355a 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JsEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JsEnvironmentConfigurator.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.test.services.configuration -import com.intellij.mock.MockProject import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.js.config.JSConfigurationKeys import org.jetbrains.kotlin.js.config.JsConfig @@ -21,7 +20,7 @@ class JsEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigu override val directivesContainers: List get() = listOf(JsEnvironmentConfigurationDirectives) - override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule, project: MockProject) { + override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) { val moduleKinds = module.directives[JsEnvironmentConfigurationDirectives.MODULE_KIND] val moduleKind = when (moduleKinds.size) { 0 -> ModuleKind.PLAIN diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt index 1ee91629bec..b175d6c327f 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmEnvironmentConfigurator.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.test.services.configuration -import com.intellij.mock.MockProject import com.intellij.openapi.util.SystemInfo import org.jetbrains.kotlin.cli.jvm.config.addJavaSourceRoot import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot @@ -22,11 +21,18 @@ import org.jetbrains.kotlin.test.TestJdkKind import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.ASSERTIONS_MODE import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.CONSTRUCTOR_CALL_NORMALIZATION_MODE +import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.JVM_TARGET import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.LAMBDAS import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.SAM_CONVERSIONS import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.STRING_CONCAT import org.jetbrains.kotlin.test.directives.JvmEnvironmentConfigurationDirectives.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME -import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.DISABLE_CALL_ASSERTIONS +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.DISABLE_PARAM_ASSERTIONS +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.EMIT_JVM_TYPE_ANNOTATIONS +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.ENABLE_JVM_PREVIEW +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.NO_OPTIMIZED_CALLABLE_REFERENCES +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.NO_UNIFIED_NULL_CHECKS +import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.PARAMETERS_METADATA import org.jetbrains.kotlin.test.directives.model.DirectivesContainer import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives import org.jetbrains.kotlin.test.model.DependencyDescription @@ -60,18 +66,20 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig register(SAM_CONVERSIONS, JVMConfigurationKeys.SAM_CONVERSIONS) register(LAMBDAS, JVMConfigurationKeys.LAMBDAS) register(USE_OLD_INLINE_CLASSES_MANGLING_SCHEME, JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME) + register(ENABLE_JVM_PREVIEW, JVMConfigurationKeys.ENABLE_JVM_PREVIEW) + register(EMIT_JVM_TYPE_ANNOTATIONS, JVMConfigurationKeys.EMIT_JVM_TYPE_ANNOTATIONS) + register(NO_OPTIMIZED_CALLABLE_REFERENCES, JVMConfigurationKeys.NO_OPTIMIZED_CALLABLE_REFERENCES) + register(DISABLE_PARAM_ASSERTIONS, JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS) + register(DISABLE_CALL_ASSERTIONS, JVMConfigurationKeys.DISABLE_CALL_ASSERTIONS) + register(NO_UNIFIED_NULL_CHECKS, JVMConfigurationKeys.NO_UNIFIED_NULL_CHECKS) + register(PARAMETERS_METADATA, JVMConfigurationKeys.PARAMETERS_METADATA) + register(JVM_TARGET, JVMConfigurationKeys.JVM_TARGET) } - override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule, project: MockProject) { + override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) { if (module.targetPlatform !in JvmPlatforms.allJvmPlatforms) return - val registeredDirectives = module.directives - val targets = registeredDirectives[JvmEnvironmentConfigurationDirectives.JVM_TARGET] - when (targets.size) { - 0 -> {} - 1 -> configuration.put(JVMConfigurationKeys.JVM_TARGET, targets.single()) - else -> error("Too many jvm targets passed: ${targets.joinToArrayString()}") - } configureDefaultJvmTarget(configuration) + val registeredDirectives = module.directives when (extractJdkKind(registeredDirectives)) { TestJdkKind.MOCK_JDK -> { @@ -128,10 +136,6 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig configuration.addJvmClasspathRoot(ForTestCompileRuntime.androidAnnotationsForTests()) } - if (LanguageSettingsDirectives.ENABLE_JVM_PREVIEW in module.directives) { - configuration.put(JVMConfigurationKeys.ENABLE_JVM_PREVIEW, true) - } - val isIr = module.targetBackend?.isIR == true configuration.put(JVMConfigurationKeys.IR, isIr) @@ -169,7 +173,7 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig } } - private fun extractJdkKind(registeredDirectives: RegisteredDirectives): TestJdkKind { + fun extractJdkKind(registeredDirectives: RegisteredDirectives): TestJdkKind { val fullJdkEnabled = JvmEnvironmentConfigurationDirectives.FULL_JDK in registeredDirectives val jdkKinds = registeredDirectives[JvmEnvironmentConfigurationDirectives.JDK_KIND] @@ -187,7 +191,7 @@ class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfig } } - private fun extractConfigurationKind(registeredDirectives: RegisteredDirectives): ConfigurationKind { + fun extractConfigurationKind(registeredDirectives: RegisteredDirectives): ConfigurationKind { val withRuntime = JvmEnvironmentConfigurationDirectives.WITH_RUNTIME in registeredDirectives || JvmEnvironmentConfigurationDirectives.WITH_STDLIB in registeredDirectives val withReflect = JvmEnvironmentConfigurationDirectives.WITH_REFLECT in registeredDirectives diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmForeignAnnotationsConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmForeignAnnotationsConfigurator.kt index e6b7ddd7ca6..6fa455331ff 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmForeignAnnotationsConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/JvmForeignAnnotationsConfigurator.kt @@ -5,8 +5,6 @@ package org.jetbrains.kotlin.test.services.configuration -import com.intellij.mock.MockProject -import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots import org.jetbrains.kotlin.codegen.CodegenTestUtil import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime @@ -24,7 +22,6 @@ import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives import org.jetbrains.kotlin.test.directives.model.singleOrZeroValue import org.jetbrains.kotlin.test.model.TestModule import org.jetbrains.kotlin.test.services.* -import org.jetbrains.kotlin.test.util.KtTestUtil import org.jetbrains.kotlin.utils.JavaTypeEnhancementState import org.jetbrains.kotlin.utils.ReportLevel import java.io.File @@ -48,7 +45,7 @@ open class JvmForeignAnnotationsConfigurator(testServices: TestServices) : Envir get() = listOf(ForeignAnnotationsDirectives) @OptIn(ExperimentalStdlibApi::class) - override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule, project: MockProject) { + override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) { val extraClassPath = buildList { val foreignAnnotations = createJarWithForeignAnnotations(module) addAll(foreignAnnotations) @@ -102,7 +99,7 @@ open class JvmForeignAnnotationsConfigurator(testServices: TestServices) : Envir class JvmForeignAnnotationsAgainstCompiledJavaConfigurator(testServices: TestServices) : JvmForeignAnnotationsConfigurator(testServices) { @OptIn(ExperimentalStdlibApi::class) - override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule, project: MockProject) { + override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) { val compiledJavaPath = testServices.createTempDirectory("java-compiled-files") val foreignAnnotations = createJarWithForeignAnnotations(module) diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/ScriptingEnvironmentConfigurator.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/ScriptingEnvironmentConfigurator.kt index 89aa9fee42f..eca34894dfe 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/ScriptingEnvironmentConfigurator.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/services/configuration/ScriptingEnvironmentConfigurator.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.test.services.configuration -import com.intellij.mock.MockProject import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.script.loadScriptingPlugin import org.jetbrains.kotlin.test.model.TestModule @@ -14,7 +13,7 @@ import org.jetbrains.kotlin.test.services.TestServices import org.jetbrains.kotlin.test.services.isKtsFile class ScriptingEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) { - override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule, project: MockProject) { + override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) { if (module.files.any { it.isKtsFile }) { loadScriptingPlugin(configuration) } diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/FirResolveBench.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/FirResolveBench.kt index 790eb388187..8aa8f282457 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/fir/FirResolveBench.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/fir/FirResolveBench.kt @@ -159,7 +159,7 @@ class FirResolveBench(val withProgress: Boolean) { private fun runStage(processor: FirResolveProcessor, firFileSequence: Sequence) { when (processor) { is FirTransformerBasedResolveProcessor -> runStage(processor, firFileSequence) - is FirGlobalResolveProcessor -> runStage(processor) + is FirGlobalResolveProcessor -> runStage(processor, firFileSequence.toList()) } } @@ -182,10 +182,10 @@ class FirResolveBench(val withProgress: Boolean) { } } - private fun runStage(processor: FirGlobalResolveProcessor) { + private fun runStage(processor: FirGlobalResolveProcessor, firFiles: List) { processWithTimeMeasure( processor::class, - { processor.process() } + { processor.process(firFiles) } ) { e -> val message = "Fail on stage ${processor::class}" println(message) diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/D8Checker.java b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/D8Checker.java index 4849709db52..569b6e74a49 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/D8Checker.java +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/D8Checker.java @@ -20,12 +20,14 @@ import java.util.function.Consumer; public class D8Checker { - public static final boolean RUN_D8_CHECKER = true; + public static final boolean RUN_D8_CHECKER = !Boolean.valueOf(System.getProperty("kotlin.test.box.d8.disable")); private D8Checker() { } public static void check(ClassFileFactory outputFiles) { + if (!RUN_D8_CHECKER) return; + runD8(builder -> { for (OutputFile file : ClassFileUtilsKt.getClassFiles(outputFiles)) { byte[] bytes = file.asByteArray(); @@ -35,6 +37,7 @@ public class D8Checker { } public static void checkFilesWithD8(Collection> classFiles) { + if (!RUN_D8_CHECKER) return; runD8(builder -> { classFiles.forEach(pair -> { builder.addClassProgramData(pair.getFirst(), new PathOrigin(Paths.get(pair.getSecond()))); diff --git a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt index 23e10301bca..26c8fc7a309 100644 --- a/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt +++ b/compiler/tests-compiler-utils/tests/org/jetbrains/kotlin/codegen/GenerationUtils.kt @@ -131,7 +131,7 @@ object GenerationUtils { generationState.beforeCompile() codegenFactory.generateModuleInFrontendIRMode( - generationState, moduleFragment, symbolTable, sourceManager, extensions, FirJvmBackendExtension(session, components), + generationState, moduleFragment, symbolTable, sourceManager, extensions, FirJvmBackendExtension(session, components), {}, ) generationState.factory.done() diff --git a/compiler/tests-different-jdk/build.gradle.kts b/compiler/tests-different-jdk/build.gradle.kts index 54a5604d756..7d2665648d2 100644 --- a/compiler/tests-different-jdk/build.gradle.kts +++ b/compiler/tests-different-jdk/build.gradle.kts @@ -69,38 +69,48 @@ codegenTest(target = 6, jvm = 6, jdk = "JDK_18") { } } +//JDK 8 +codegenTest(target = 6, jvm = 8) {} + +// This is default one and is executed in default build configuration codegenTest(target = 8, jvm = 8) {} -// Switch TC builds to... +//JDK 11 codegenTest(target = 6, jvm = 11) {} codegenTest(target = 8, jvm = 11) {} codegenTest(target = 11, jvm = 11) {} -//...and delete old tasks.. -codegenTest(target = 6, jvm = 9) {} +//JDK 15 +codegenTest(target = 6, jvm = 15) { + jvmArgs( "-XX:-FailOverToOldVerifier") +} -codegenTest(target = 8, jvm = 9) {} +codegenTest(target = 8, jvm = 15) { + jvmArgs( "-XX:-FailOverToOldVerifier") +} -codegenTest(target = 9, jvm = 9) {} +codegenTest(target = 15, jvm = 15) { + jvmArgs( "-XX:-FailOverToOldVerifier") + systemProperty("kotlin.test.box.d8.disable", true) +} //..also add this two tasks to build after adding fresh jdks to build agents val mostRecentJdk = JdkMajorVersion.values().last().name -codegenTest(target = 6, jvm = "Last", jdk = mostRecentJdk) { - jvmArgs!!.add( "-XX:-FailOverToOldVerifier") -} +//LAST JDK from JdkMajorVersion available on machine +codegenTest(target = 6, jvm = "Last", jdk = mostRecentJdk) {} -codegenTest(target = 8, jvm = "Last", jdk = mostRecentJdk) { - jvmArgs!!.add( "-XX:-FailOverToOldVerifier") -} +codegenTest(target = 8, jvm = "Last", jdk = mostRecentJdk) {} codegenTest( mostRecentJdk.substringAfter('_').toInt(), targetInTestClass = "Last", jvm = "Last", jdk = mostRecentJdk -) {} +) { + systemProperty("kotlin.test.box.d8.disable", true) +} testsJar() diff --git a/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/CustomJvmTargetOnJvmBaseTest.kt b/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/CustomJvmTargetOnJvmBaseTest.kt index 3cde663b783..6c7c072ba39 100644 --- a/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/CustomJvmTargetOnJvmBaseTest.kt +++ b/compiler/tests-different-jdk/tests/org/jetbrains/kotlin/codegen/jdk/CustomJvmTargetOnJvmBaseTest.kt @@ -31,14 +31,20 @@ import org.junit.runner.RunWith @UseTechnicalNames abstract class CustomJvmTargetOnJvmBaseTest +// JDK 6 @RunOnlyJdk6Test @Execution(ExecutionMode.SAME_THREAD) @RunWith(JUnitPlatformRunnerForJdk6::class) class JvmTarget6OnJvm6 : CustomJvmTargetOnJvmBaseTest() +// JDK 8 +@RunWith(JUnitPlatform::class) +class JvmTarget6OnJvm8 : CustomJvmTargetOnJvmBaseTest() + @RunWith(JUnitPlatform::class) class JvmTarget8OnJvm8 : CustomJvmTargetOnJvmBaseTest() +// JDK 11 @RunWith(JUnitPlatform::class) class JvmTarget6OnJvm11 : CustomJvmTargetOnJvmBaseTest() @@ -48,6 +54,17 @@ class JvmTarget8OnJvm11 : CustomJvmTargetOnJvmBaseTest() @RunWith(JUnitPlatform::class) class JvmTarget11OnJvm11 : CustomJvmTargetOnJvmBaseTest() +// JDK 15 +@RunWith(JUnitPlatform::class) +class JvmTarget6OnJvm15 : CustomJvmTargetOnJvmBaseTest() + +@RunWith(JUnitPlatform::class) +class JvmTarget8OnJvm15 : CustomJvmTargetOnJvmBaseTest() + +@RunWith(JUnitPlatform::class) +class JvmTarget15OnJvm15 : CustomJvmTargetOnJvmBaseTest() + +// LAST JDK from JdkMajorVersion available on machine @RunWith(JUnitPlatform::class) class JvmTarget6OnJvmLast : CustomJvmTargetOnJvmBaseTest() @@ -56,14 +73,3 @@ class JvmTarget8OnJvmLast : CustomJvmTargetOnJvmBaseTest() @RunWith(JUnitPlatform::class) class JvmTargetLastOnJvmLast : CustomJvmTargetOnJvmBaseTest() - -//TODO: delete old tasks -@RunWith(JUnitPlatform::class) -class JvmTarget6OnJvm9 : CustomJvmTargetOnJvmBaseTest() - -@RunWith(JUnitPlatform::class) -class JvmTarget8OnJvm9 : CustomJvmTargetOnJvmBaseTest() - -@RunWith(JUnitPlatform::class) -class JvmTarget9OnJvm9 : CustomJvmTargetOnJvmBaseTest() - diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index a1e5951d85e..40454e58f67 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -440,6 +440,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.kt"); } + @TestMetadata("ListAndSet.kt") + public void testListAndSet() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet.kt"); + } + @TestMetadata("mapOfPrimitivesFullJdk.kt") public void testMapOfPrimitivesFullJdk() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/mapOfPrimitivesFullJdk.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 037244e41a9..e970f3d16d1 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -11220,6 +11220,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/elvis/nullNullOk.kt"); } + @TestMetadata("ofNonNullableResultType.kt") + public void testOfNonNullableResultType() throws Exception { + runTest("compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt"); + } + @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { runTest("compiler/testData/codegen/box/elvis/primitive.kt"); @@ -12073,6 +12078,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testPropertySetter() throws Exception { runTest("compiler/testData/codegen/box/fakeOverride/propertySetter.kt"); } + + @TestMetadata("varianceOverload.kt") + public void testVarianceOverload() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/varianceOverload.kt"); + } } @TestMetadata("compiler/testData/codegen/box/fieldRename") @@ -12268,11 +12278,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/fir/FakeOverrideBuilder.kt"); } + @TestMetadata("Fir2IrClassifierStorage.kt") + public void testFir2IrClassifierStorage() throws Exception { + runTest("compiler/testData/codegen/box/fir/Fir2IrClassifierStorage.kt"); + } + @TestMetadata("IrBuiltIns.kt") public void testIrBuiltIns() throws Exception { runTest("compiler/testData/codegen/box/fir/IrBuiltIns.kt"); } + @TestMetadata("LookupTags.kt") + public void testLookupTags() throws Exception { + runTest("compiler/testData/codegen/box/fir/LookupTags.kt"); + } + @TestMetadata("NameHighlighter.kt") public void testNameHighlighter() throws Exception { runTest("compiler/testData/codegen/box/fir/NameHighlighter.kt"); @@ -14114,6 +14134,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineClasses/conformToComparableAndCallInterfaceMethod.kt"); } + @TestMetadata("constructorCallableReference.kt") + public void testConstructorCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt"); + } + @TestMetadata("constructorImplVisibility.kt") public void testConstructorImplVisibility() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/constructorImplVisibility.kt"); @@ -31323,6 +31348,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); } + @TestMetadata("extensionFunction.kt") + public void testExtensionFunction() throws Exception { + runTest("compiler/testData/codegen/box/typealias/extensionFunction.kt"); + } + @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { runTest("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor.kt"); diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index 3538229668d..8e298304579 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -440,6 +440,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/kt44233.kt"); } + @TestMetadata("ListAndSet.kt") + public void testListAndSet() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/ListAndSet.kt"); + } + @TestMetadata("mapOfPrimitivesFullJdk.kt") public void testMapOfPrimitivesFullJdk() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/collectionStubs/mapOfPrimitivesFullJdk.kt"); diff --git a/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.1.fir.kt deleted file mode 100644 index 7ddc8f0f5a1..00000000000 --- a/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.1.fir.kt +++ /dev/null @@ -1,19 +0,0 @@ -// !LANGUAGE: +NewInference -// !DIAGNOSTICS: -IMPLICIT_CAST_TO_ANY -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION -// SKIP_TXT - -// TESTCASE NUMBER: 1 - -fun case1() { - val b = true - val a = if (b) { - "true" - } -} - -// TESTCASE NUMBER: 2 - -fun case2() { - val b = true - val a = if (b) "true" -} diff --git a/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.1.kt b/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.1.kt index d44f58871e0..6f05ffc27e6 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.1.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !LANGUAGE: +NewInference // !DIAGNOSTICS: -IMPLICIT_CAST_TO_ANY -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION // SKIP_TXT diff --git a/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.2.fir.kt index 775c449d4a2..e29d0112510 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.2.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.2.fir.kt @@ -2,6 +2,15 @@ // !DIAGNOSTICS: -IMPLICIT_CAST_TO_ANY -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION // SKIP_TXT +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-296 + * MAIN LINK: control--and-data-flow-analysis, control-flow-graph, expressions-1, conditional-expressions -> paragraph 1 -> sentence 1 + * NUMBER: 2 + * DESCRIPTION: check if-expressions must have both branches. + */ + // TESTCASE NUMBER: 1 fun case1() { @@ -9,7 +18,7 @@ fun case1() { val c = true val a = if (b) { "first true" - } else if (c) { + } else if (c) { "else if true" } } diff --git a/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.3.fir.kt index 1767cf6d9e7..5f9a0c36a00 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.3.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/1.3.fir.kt @@ -2,6 +2,15 @@ // !DIAGNOSTICS: -UNREACHABLE_CODE -IMPLICIT_CAST_TO_ANY -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION // SKIP_TXT +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-296 + * MAIN LINK: control--and-data-flow-analysis, control-flow-graph, expressions-1, conditional-expressions -> paragraph 1 -> sentence 1 + * NUMBER: 3 + * DESCRIPTION: check if-expressions must have both branches. (attempt to pass Nothing to if-condition without 'else' key word) + */ + fun throwExc(b: Boolean): Boolean { if (b) throw Exception() else return false @@ -9,13 +18,13 @@ fun throwExc(b: Boolean): Boolean { // TESTCASE NUMBER: 1 fun case1() { - val x1 = if (throwExc(false)) true + val x1 = if (throwExc(false)) true } // TESTCASE NUMBER: 3 fun case3() { - val x1 = if (throwExc(true)) true + val x1 = if (throwExc(true)) true } /* @@ -24,18 +33,18 @@ fun case3() { * ISSUES: KT-35510 */ fun case4() { - val x1 = if (throw Exception()) true + val x1 = if (throw Exception()) true - val x2 = if (TODO()) true + val x2 = if (TODO()) true - val x0 = if (false) true else if (throw Exception()) ; + val x0 = if (false) true else if (throw Exception()) ; } // TESTCASE NUMBER: 5 fun case5() { var flag: Boolean? = null - val x1 = if (flag ?: throw Exception()) true + val x1 = if (flag ?: throw Exception()) true } /* @@ -44,7 +53,7 @@ fun case5() { * ISSUES: KT-35510 */ fun case6() { - val k1 = if(throw Exception()); + val k1 = if(throw Exception()); } /* @@ -62,7 +71,7 @@ fun case7(nothing: Nothing) { * ISSUES: KT-35510 */ fun case8(nothing: Nothing) { - val x1 = if (nothing) true + val x1 = if (nothing) true } /* diff --git a/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/2.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/2.1.fir.kt index fd3905ad21e..86ea234ab6c 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/2.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/control--and-data-flow-analysis/control-flow-graph/expressions-1/conditional-expressions/p-1/neg/2.1.fir.kt @@ -2,6 +2,16 @@ // !DIAGNOSTICS: -UNUSED_VARIABLE -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_PARAMETER -UNUSED_EXPRESSION // SKIP_TXT +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-296 + * MAIN LINK: control--and-data-flow-analysis, control-flow-graph, expressions-1, conditional-expressions -> paragraph 1 -> sentence 2 + * NUMBER: 1 + * DESCRIPTION: check any if-statement in kotlin may be trivially turned into such an expression by replacing the missing branch with a kotlin.Unit object expression. + * HELPERS: checkType + */ + // TESTCASE NUMBER: 1 fun case1() { @@ -9,7 +19,7 @@ fun case1() { if (!b) { println("this is statement") } - val statement = if (!b) { println("statement could not be assigned") } + val statement = if (!b) { println("statement could not be assigned") } } // TESTCASE NUMBER: 2 diff --git a/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/abstract-classes/p-2/neg/1.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/abstract-classes/p-2/neg/1.3.fir.kt index 57af86eaa66..3f25c0fadc5 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/abstract-classes/p-2/neg/1.3.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/declarations/classifier-declaration/class-declaration/abstract-classes/p-2/neg/1.3.fir.kt @@ -18,7 +18,7 @@ class Case1 : Base() { override val a: Any? get() = TODO() - override var b: String + override var b: String get() = TODO() set(value) {} @@ -29,7 +29,7 @@ class Case1 : Base() { * TESTCASE NUMBER: 2 */ -class Case2(override val a: String, override var b: String) : Base() { +class Case2(override val a: String, override var b: String) : Base() { override fun foo(): CharSequence? { return "" } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.fir.kt deleted file mode 100644 index 54f48e8883c..00000000000 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.fir.kt +++ /dev/null @@ -1,16 +0,0 @@ -// SKIP_TXT - -// TESTCASE NUMBER: 1 -fun case_1(value_1: Int): String = when { - value_1 == 1 -> "" - value_1 == 2 -> "" - value_1 == 3 -> "" -} - -// TESTCASE NUMBER: 2 -fun case_2(value_1: Int): String = when { - value_1 == 1 -> "" -} - -// TESTCASE NUMBER: 3 -fun case_3(): Int = when {} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.kt index ca615536179..62f00d0c2c2 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.1.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // SKIP_TXT /* diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.fir.kt deleted file mode 100644 index bd125a9d679..00000000000 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.fir.kt +++ /dev/null @@ -1,17 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -// SKIP_TXT - -// TESTCASE NUMBER: 1 -fun case_1(value_1: Int): String = when (value_1) { - 1 -> "" - 2 -> "" - 3 -> "" -} - -// TESTCASE NUMBER: 2 -fun case_2(value_1: Int): String = when (value_1) { - 1 -> "" -} - -// TESTCASE NUMBER: 3 -fun case_3(value_1: Int): Int = when (value_1) {} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.kt index 6df980a3982..2621f903616 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/1.2.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION // SKIP_TXT diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.1.fir.kt deleted file mode 100644 index eb07a21078b..00000000000 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.1.fir.kt +++ /dev/null @@ -1,19 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -// SKIP_TXT - - - -// TESTCASE NUMBER: 1 -fun case_1(value_1: Boolean?): String = when(value_1) { - true -> "" - false -> "" -} - -// TESTCASE NUMBER: 2 -fun case_2(value_1: Boolean?): String = when(value_1) { - true -> "" - null -> "" -} - -// TESTCASE NUMBER: 3 -fun case_3(value_1: Boolean?): Int = when(value_1) { } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.1.kt index 9e3a53b5d06..836b4f37b7d 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.1.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION // SKIP_TXT diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.2.fir.kt deleted file mode 100644 index 5f3ce02603a..00000000000 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.2.fir.kt +++ /dev/null @@ -1,72 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -// SKIP_TXT - - -// TESTCASE NUMBER: 1 -fun case_1(value_1: SealedClass?): String = when(value_1) { - is SealedChild1 -> "" - is SealedChild2 -> "" - is SealedChild3 -> "" -} - -// TESTCASE NUMBER: 2 -fun case_2(value_1: SealedClassMixed?): String = when(value_1) { - is SealedMixedChild1 -> "" - is SealedMixedChild2 -> "" - SealedMixedChildObject1 -> "" - null -> "" -} - -// TESTCASE NUMBER: 3 -fun case_3(value_1: SealedClassMixed?): String = when(value_1) { - null, is SealedMixedChild1, is SealedMixedChild2, SealedMixedChildObject1 -> "" -} - -// TESTCASE NUMBER: 4 -fun case_4(value_1: SealedClassMixed?): String = when(value_1) { - is SealedMixedChild1 -> "" - is SealedMixedChild2 -> "" - is SealedMixedChild3 -> "" - SealedMixedChildObject1 -> "" - SealedMixedChildObject2 -> "" - SealedMixedChildObject3 -> "" -} - -// TESTCASE NUMBER: 5 -fun case_5(value_1: SealedClassMixed?): String = when(value_1) { - is SealedMixedChild1 -> "" - is SealedMixedChild2 -> "" - is SealedMixedChild3 -> "" -} - -// TESTCASE NUMBER: 6 -fun case_6(value_1: SealedClassMixed?): Int = when(value_1) {} - -// TESTCASE NUMBER: 7 -fun case_7(value_1: SealedClassMixed?): String = when(value_1) { - is SealedMixedChild1 -> "" - is SealedMixedChild2-> "" - is SealedMixedChild3 -> "" - null -> "" -} - -// TESTCASE NUMBER: 8 -fun case_8(value_1: SealedClassMixed?): String = when(value_1) { - SealedMixedChildObject1 -> "" -} - -/* - * TESTCASE NUMBER: 9 - * DISCUSSION: maybe make exhaustive without else? - */ -fun case_9(value_1: Any?): String = when (value_1) { - is Any -> "" - null -> "" -} - -/* - * TESTCASE NUMBER: 10 - * DISCUSSION - * ISSUES: KT-26044 - */ -fun case_10(value: SealedClassEmpty): String = when (value) {} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.2.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.2.kt index 014eec0ea2a..270201e6b75 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.2.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.2.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION // SKIP_TXT diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.3.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.3.fir.kt deleted file mode 100644 index e91e58f4ee1..00000000000 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.3.fir.kt +++ /dev/null @@ -1,37 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -// SKIP_TXT - - -// TESTCASE NUMBER: 1 -fun case_1(value_1: EnumClass?): String = when(value_1) { - EnumClass.EAST -> "" - EnumClass.SOUTH -> "" - EnumClass.NORTH -> "" - EnumClass.WEST -> "" -} - -// TESTCASE NUMBER: 2 -fun case_2(value_1: EnumClass?): String = when(value_1) { - EnumClass.EAST -> "" - EnumClass.SOUTH -> "" - EnumClass.NORTH -> "" - null -> "" -} - -// TESTCASE NUMBER: 3 -fun case_3(value_1: EnumClass?): String = when(value_1) { - EnumClass.EAST, null, EnumClass.SOUTH, EnumClass.NORTH -> "" -} - -// TESTCASE NUMBER: 4 -fun case_4(value_1: EnumClassSingle): Int = when(value_1) {} - -// TESTCASE NUMBER: 5 -fun case_5(value_1: EnumClassSingle?): String = when(value_1) { - EnumClassSingle.EVERYTHING -> "" -} - -// TESTCASE NUMBER: 6 -fun case_6(value_1: EnumClassSingle?): String = when(value_1) { - null -> "" -} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.3.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.3.kt index 1a7f76a7371..69b5d521070 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.3.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/11.3.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION // SKIP_TXT diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.fir.kt deleted file mode 100644 index b2120411a79..00000000000 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.fir.kt +++ /dev/null @@ -1,36 +0,0 @@ -// !DIAGNOSTICS: -UNUSED_EXPRESSION -// SKIP_TXT - -// TESTCASE NUMBER: 1 -fun case_1(value_1: Boolean): String = when(value_1) { - true -> "" -} - -// TESTCASE NUMBER: 2 -fun case_2(value_1: Boolean): String = when(value_1) { - false -> "" -} - -// TESTCASE NUMBER: 3 -fun case_3(value_1: Boolean): Int = when(value_1) { } - -// TESTCASE NUMBER: 4 -fun case_4(value_1: Boolean): String = when { - value_1 == true -> "" - value_1 == false -> "" -} - -/* - * TESTCASE NUMBER: 5 - * DISCUSSION: maybe use const propagation here? - * ISSUES: KT-25265 - */ -fun case_5(value_1: Boolean): String { - val trueValue = true - val falseValue = false - - return when (value_1) { - trueValue -> "" - falseValue -> "" - } -} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.kt index 31e7ae51243..ab7cdda9b7b 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/3.1.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !DIAGNOSTICS: -UNUSED_EXPRESSION // SKIP_TXT diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.fir.kt index 64a2e11d768..03a0b7bb732 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/neg/9.1.fir.kt @@ -1,48 +1,57 @@ // !DIAGNOSTICS: -UNUSED_EXPRESSION // SKIP_TXT +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-435 + * MAIN LINK: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 9 + * NUMBER: 1 + * DESCRIPTION: Non-exhaustive when using subclasses of the sealed class. + * HELPERS: sealedClasses + */ // TESTCASE NUMBER: 1 -fun case_1(value_1: SealedClass): String = when(value_1) { +fun case_1(value_1: SealedClass): String = when(value_1) { is SealedChild1 -> "" is SealedChild2 -> "" } // TESTCASE NUMBER: 2 -fun case_2(value_1: SealedClass): String = when(value_1) { +fun case_2(value_1: SealedClass): String = when(value_1) { is SealedChild1, is SealedChild2 -> "" } // TESTCASE NUMBER: 3 -fun case_3(value_1: SealedClassMixed): String = when(value_1) { +fun case_3(value_1: SealedClassMixed): String = when(value_1) { is SealedMixedChild1 -> "" is SealedMixedChild2 -> "" SealedMixedChildObject1 -> "" } // TESTCASE NUMBER: 4 -fun case_4(value_1: SealedClassMixed): String = when(value_1) { +fun case_4(value_1: SealedClassMixed): String = when(value_1) { SealedMixedChildObject1, is SealedMixedChild2, is SealedMixedChild1 -> "" } // TESTCASE NUMBER: 5 -fun case_5(value_1: SealedClassMixed): String = when(value_1) { +fun case_5(value_1: SealedClassMixed): String = when(value_1) { is SealedMixedChild1 -> "" is SealedMixedChild2 -> "" is SealedMixedChild3 -> "" } // TESTCASE NUMBER: 6 -fun case_6(value_1: SealedClassMixed): Int = when(value_1) { } +fun case_6(value_1: SealedClassMixed): Int = when(value_1) { } // TESTCASE NUMBER: 7 -fun case_7(value_1: SealedClassSingleWithObject): Int = when(value_1) { } +fun case_7(value_1: SealedClassSingleWithObject): Int = when(value_1) { } // TESTCASE NUMBER: 8 -fun case_8(value_1: SealedClassEmpty): String = when (value_1) { } +fun case_8(value_1: SealedClassEmpty): String = when (value_1) { } // TESTCASE NUMBER: 9 -fun case_9(value_1: Number): String = when (value_1) { +fun case_9(value_1: Number): String = when (value_1) { is Byte -> "" is Double -> "" is Float -> "" @@ -55,19 +64,19 @@ fun case_9(value_1: Number): String = when (value_1) { * TESTCASE NUMBER: 10 * DISCUSSION: maybe make exhaustive without else? */ -fun case_10(value_1: Any): String = when (value_1) { +fun case_10(value_1: Any): String = when (value_1) { is Any -> "" } // TESTCASE NUMBER: 11 -fun case_11(value_1: SealedClass): String = when { +fun case_11(value_1: SealedClass): String = when { value_1 is SealedChild1 -> "" value_1 is SealedChild2 -> "" value_1 is SealedChild3 -> "" } // TESTCASE NUMBER: 12 -fun case_12(value_1: SealedClassMixed): String = when(value_1) { +fun case_12(value_1: SealedClassMixed): String = when(value_1) { is SealedMixedChild1 -> "" is SealedMixedChild2 -> "" is SealedMixedChild3 -> "" diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.1.fir.kt new file mode 100644 index 00000000000..a6bbd1d1652 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.1.fir.kt @@ -0,0 +1,24 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-435 + * MAIN LINK: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 11 + * NUMBER: 1 + * DESCRIPTION: Exhaustive when using nullable boolean values. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Boolean?): String = when (value_1) { + true -> "" + false -> "" + null -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Boolean?): String = when (value_1) { + true && false && ((true || false)) || true && !!!false && !!!true -> "" + true && false && ((true || false)) || true && !!!false -> "" + null -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.1.kt index c27fb8f45f7..073abe3ea85 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.1.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // SKIP_TXT /* diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.2.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.2.fir.kt index a57e44c723c..5802adafd71 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.2.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/11.2.fir.kt @@ -1,5 +1,14 @@ // SKIP_TXT +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-435 + * MAIN LINK: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 11 + * NUMBER: 2 + * DESCRIPTION: Exhaustive when using nullable enum values. + * HELPERS: enumClasses + */ // TESTCASE NUMBER: 1 fun case_1(value_1: EnumClass?): String = when (value_1) { diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/3.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/3.1.fir.kt new file mode 100644 index 00000000000..3c414d2fff5 --- /dev/null +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/3.1.fir.kt @@ -0,0 +1,22 @@ +// SKIP_TXT + +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-100 + * MAIN LINK: expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 3 + * NUMBER: 1 + * DESCRIPTION: Exhaustive when using boolean values. + */ + +// TESTCASE NUMBER: 1 +fun case_1(value_1: Boolean): String = when (value_1) { + true -> "" + false -> "" +} + +// TESTCASE NUMBER: 2 +fun case_2(value_1: Boolean): String = when (value_1) { + true && false && ((true || false)) || true && !!!false && !!!true -> "" + true && false && ((true || false)) || true && !!!false -> "" +} diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/3.1.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/3.1.kt index 33c447aaad3..41f07c616de 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/3.1.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/exhaustive-when-expressions/p-2/pos/3.1.kt @@ -1,4 +1,3 @@ -// FIR_IDENTICAL // SKIP_TXT /* diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/neg/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/neg/1.1.fir.kt index df48db627e0..7b0a61a6302 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/neg/1.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/neg/1.1.fir.kt @@ -3,6 +3,15 @@ // SKIP_TXT // FULL_JDK +/* + * KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE) + * + * SPEC VERSION: 0.1-313 + * MAIN LINK: expressions, when-expression -> paragraph 4 -> sentence 1 + * NUMBER: 1 + * DESCRIPTION: it is possible to replace the else condition with an always-true condition + */ + // FILE: JavaEnum.java enum JavaEnum { @@ -15,7 +24,7 @@ enum JavaEnum { // TESTCASE NUMBER: 1 fun case1() { val z = JavaEnum.Val_1 - val when2 = when (z) { + val when2 = when (z) { JavaEnum.Val_1 -> { } JavaEnum.Val_1 -> { } } @@ -26,7 +35,7 @@ fun case1() { fun case2() { val b = false - val when2: Any = when (b) { + val when2: Any = when (b) { false -> { } false -> { } } @@ -36,7 +45,7 @@ fun case2() { fun case3() { val a = false - val when2: Any = when (a) { + val when2: Any = when (a) { true -> { } true -> { } } @@ -46,7 +55,7 @@ fun case3() { fun case4() { val x: SClass = SClass.B() - val when2 = when (x){ + val when2 = when (x){ is SClass.A ->{ } is SClass.B ->{ } is SClass.B ->{ } diff --git a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/pos/1.1.fir.kt b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/pos/1.1.fir.kt index 814b0720ea6..db667a1f77b 100644 --- a/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/pos/1.1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/linked/expressions/when-expression/p-4/pos/1.1.fir.kt @@ -3,6 +3,15 @@ // SKIP_TXT // FULL_JDK +/* + * KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE) + * + * SPEC VERSION: 0.1-313 + * MAIN LINK: expressions, when-expression -> paragraph 4 -> sentence 1 + * NUMBER: 1 + * DESCRIPTION: it is possible to replace the else condition with an always-true condition + */ + // FILE: JavaEnum.java enum JavaEnum { @@ -42,11 +51,11 @@ fun case2() { else -> { } } - val when2: Any = when (b) { + val when2: Any = when (b) { false -> { } !false -> { } } - val when3: Any = when (b) { + val when3: Any = when (b) { false -> { } false -> { } !false -> { } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/coercion-to-unit/neg/1.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/coercion-to-unit/neg/1.fir.kt index 1cbb749a12e..e6c61bbe2e1 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/coercion-to-unit/neg/1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/coercion-to-unit/neg/1.fir.kt @@ -1,11 +1,20 @@ +/* + * KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (NEGATIVE) + * + * SECTIONS: coercion-to-unit + * NUMBER: 1 + * DESCRIPTION: Coercion to Unit error diagnostics absence + * ISSUES: KT-38490 + */ + // TESTCASE NUMBER: 1 val y0 = when (2) { - else -> if (true) {""} + else -> if (true) {""} } val w:Any = TODO() val y1 = when (2) { - else -> if (true) {""} // false ok with coercion to Unit + else -> if (true) {""} // false ok with coercion to Unit } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt index 280bc9152a5..51c1b9ece1b 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/neg/1.fir.kt @@ -361,23 +361,23 @@ fun case_21() { // TESTCASE NUMBER: 22 fun case_22(a: (() -> Unit)?) { if (a != null !is Boolean) { - a() - a().equals(null) - a().propT - a().propAny - a().propNullableT - a().propNullableAny - a().funT() - a().funAny() - a().funNullableT() - a().funNullableAny() + a() + a().equals(null) + a().propT + a().propAny + a().propNullableT + a().propNullableAny + a().funT() + a().funAny() + a().funNullableT() + a().funNullableAny() } } // TESTCASE NUMBER: 23 fun case_23(a: ((Float) -> Int?)?, b: Float?) { if (a != null !is Boolean && b !== null is Boolean) { - val x = a(b) + val x = a(b) if (x != null) { x x.equals(null) @@ -396,8 +396,8 @@ fun case_23(a: ((Float) -> Int?)?, b: Float?) { // TESTCASE NUMBER: 24 fun case_24(a: ((() -> Unit) -> Unit)?, b: (() -> Unit)?) = if (a !== null is Boolean && b !== null !is Boolean) { - a(?")!>b) - a(b) + a(?")!>b) + a(b) ?")!>b.equals(null) ?")!>b.propT ?")!>b.propAny @@ -440,7 +440,7 @@ fun case_25(b: Boolean) { // TESTCASE NUMBER: 26 fun case_26(a: ((Float) -> Int?)?, b: Float?) { if (a != null == true == false && b != null == true == false) { - val x = a(b) + val x = a(b) if (x != null == true === false) { x x.equals(null) diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/2.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/2.fir.kt index fc921ac860d..5dd3f3ab3e1 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/2.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/2.fir.kt @@ -67,7 +67,7 @@ fun case_3(b: Boolean) { val y = if (b) x else null if (false || false || false || false || y !== null) { - val z = ?")!>y() + val z = ?")!>y() ?>?")!>y.equals(null) ?>?")!>y.propT ?>?")!>y.propAny @@ -87,7 +87,7 @@ fun case_3(b: Boolean) { // TESTCASE NUMBER: 4 fun case_4(a: ((Float) -> Int?)?, b: Float?) { if (a != null == true && b != null == true || false || false || false || false || false || false || false || false || false) { - val x = a(b) + val x = a(b) ?")!>a.equals(null) ?")!>a.propT ?")!>a.propAny @@ -274,7 +274,7 @@ fun case_11(b: Boolean) { val y = if (b) x else null if (y === null && true) else { - val z = ?")!>y() + val z = ?")!>y() ?>?")!>y.equals(null) ?>?")!>y.propT ?>?")!>y.propAny @@ -298,7 +298,7 @@ fun case_12(a: ((Float) -> Int?)?, b: Float?, c: Boolean?) { if (true && a == null == true || b == null == true) { } else { - val x = a(b) + val x = a(b) ?")!>a.equals(null) ?")!>a.propT ?")!>a.propAny diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt index 7a2c794098a..df90a41a8e8 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/6.fir.kt @@ -422,7 +422,7 @@ fun case_21() { // TESTCASE NUMBER: 22 fun case_22(a: (() -> Unit)?) { if (a != implicitNullableNothingProperty) { - a() + a() ?")!>a.equals(null) ?")!>a.propT ?")!>a.propAny @@ -438,7 +438,7 @@ fun case_22(a: (() -> Unit)?) { // TESTCASE NUMBER: 23 fun case_23(a: ((Float) -> Int?)?, b: Float?, z: Nothing?) { if (a != z && b !== z && b !== z) { - val x = a(b) + val x = a(b) if (x != z || x !== implicitNullableNothingProperty) { x x.equals(null) @@ -457,7 +457,7 @@ fun case_23(a: ((Float) -> Int?)?, b: Float?, z: Nothing?) { // TESTCASE NUMBER: 24 fun case_24(a: ((() -> Unit) -> Unit)?, b: (() -> Unit)?, z: Nothing?) = if (a !== z && b !== z) { - a(?")!>b) + a(?")!>b) , kotlin.Unit>?")!>a.equals(null) , kotlin.Unit>?")!>a.propT , kotlin.Unit>?")!>a.propAny @@ -489,7 +489,7 @@ fun case_25(b: Boolean, z: Nothing?) { val y = if (b) x else z if (y !== z || y != implicitNullableNothingProperty) { - val z1 = ?")!>y() + val z1 = ?")!>y() if (z1 != z && implicitNullableNothingProperty !== z1) { ?")!>z1.a @@ -511,7 +511,7 @@ fun case_26(a: ((Float) -> Int?)?, b: Float?) { var z = null if (a != z == true && b != implicitNullableNothingProperty == true) { - val x = a(b) + val x = a(b) if (x != implicitNullableNothingProperty == true || z !== x) { x x.equals(null) @@ -575,7 +575,7 @@ fun case_29(x: Boolean) { val y = if (x) z else null if (false || false || false || false || y !== v) { - val t = ?")!>y() + val t = ?")!>y() if (z !== t || false) { ?")!>t.a @@ -595,7 +595,7 @@ fun case_29(x: Boolean) { // TESTCASE NUMBER: 30 fun case_30(a: ((Float) -> Int?)?, b: Float?) { if (implicitNullableNothingProperty != a == true && b != implicitNullableNothingProperty == true || false || false || false || false || false || false || false || false || false) { - val x = a(b) + val x = a(b) if (false || implicitNullableNothingProperty != x == true) { x x.equals(null) @@ -651,7 +651,7 @@ fun case_33(a: ((Float) -> Int?)?, b: Float?, c: Boolean?) { if (true && a == z == true || b == null == true) { } else { - val x = a(b) + val x = a(b) if (x == z == true && x === z || (c != z && !c)) { } else { @@ -1054,7 +1054,7 @@ fun case_60(b: Boolean) { val y = if (b) x else nullableNothingProperty if (y != nullableNothingProperty) { - val z = ?")!>y() + val z = ?")!>y() if (z == nullableNothingProperty) { ?")!>z diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/62.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/62.fir.kt index 52460da9fda..aa7e83aa357 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/62.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/62.fir.kt @@ -2,6 +2,15 @@ // !DIAGNOSTICS: -UNUSED_EXPRESSION -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_PARAMETER -UNUSED_VARIABLE -UNUSED_VALUE -VARIABLE_WITH_REDUNDANT_INITIALIZER // SKIP_TXT +/* + * KOTLIN DIAGNOSTICS NOT LINKED SPEC TEST (POSITIVE) + * + * SECTIONS: dfa + * NUMBER: 62 + * DESCRIPTION: Raw data flow analysis test + * HELPERS: classes, objects, typealiases, functions, enumClasses, interfaces, sealedClasses + */ + /* * TESTCASE NUMBER: 1 * UNEXPECTED BEHAVIOUR @@ -145,7 +154,7 @@ fun case_10(x: Any): String { */ fun case_11(x: Any?): String? { if (x is Nothing?) { - return when(x) { + return when(x) { null -> null } } @@ -159,7 +168,7 @@ fun case_11(x: Any?): String? { */ fun case_12(x: Any?): String? { if (x == null) { - return when(x) { + return when(x) { null -> null } } @@ -173,7 +182,7 @@ fun case_12(x: Any?): String? { */ fun case_13(x: Any?): String? { if (x === null) { - return when(x) { + return when(x) { null -> null } } @@ -187,7 +196,7 @@ fun case_13(x: Any?): String? { */ fun case_14(x: Any?): String? { x as Nothing? - return when(x) { + return when(x) { null -> null } } diff --git a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/7.fir.kt b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/7.fir.kt index 7b7ff033335..076f229c9ff 100644 --- a/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/7.fir.kt +++ b/compiler/tests-spec/testData/diagnostics/notLinked/dfa/pos/7.fir.kt @@ -406,7 +406,7 @@ fun case_21() { fun case_22(a: (() -> Unit)?) { var y = null if (a != null || y != a) { - a() + a() ?")!>a.equals(null) ?")!>a.propT ?")!>a.propAny @@ -422,7 +422,7 @@ fun case_22(a: (() -> Unit)?) { // TESTCASE NUMBER: 23 fun case_23(a: ((Float) -> Int?)?, b: Float?, c: Nothing?) { if (a != null && b !== null || a != c && b !== c) { - val x = a(b) + val x = a(b) if (x != null || c !== x) { x x.equals(null) @@ -441,7 +441,7 @@ fun case_23(a: ((Float) -> Int?)?, b: Float?, c: Nothing?) { // TESTCASE NUMBER: 24 fun case_24(a: ((() -> Unit) -> Unit)?, b: (() -> Unit)?) = if (a !== null && b !== null || implicitNullableNothingProperty != a && nullableNothingProperty !== b) { - a(?")!>b) + a(?")!>b) , kotlin.Unit>?")!>a.equals(null) , kotlin.Unit>?")!>a.propT , kotlin.Unit>?")!>a.propAny @@ -475,7 +475,7 @@ fun case_25(b: Boolean) { if (y !== null || x()!!.b != y) { if (x()!!.b != y) { - val z = ?")!>y() + val z = ?")!>y() if (z != null) { & ?")!>z.a @@ -498,7 +498,7 @@ fun case_26(a: ((Float) -> Int?)?, b: Float?) { var c: Nothing? = null if (a != null == true && b != null == true || c != a == true && b != c == true) { - val x = a(b) + val x = a(b) if (x != null == true) { x x.equals(null) diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt index c36330550c9..8b4940a5851 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt @@ -229,6 +229,14 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration doTestBrokenLibrary("library", "test/Super.class") } + fun testIncompleteHierarchyWithExtendedCompilerChecks() { + doTestBrokenLibrary( + "library", + "test/Super.class", + additionalOptions = listOf("-Xextended-compiler-checks"), + ) + } + fun testIncompleteHierarchyErrorPositions() { doTestBrokenLibrary("library", "test/Super.class") } diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 1fd27a05cc3..3d6720c65bd 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -382,6 +382,9 @@ class LanguageVersionSettingsImpl @JvmOverloads constructor( } append(" $char$feature") } + analysisFlags.forEach { (flag, value) -> + append(" $flag:$value") + } } override fun isPreRelease(): Boolean = languageVersion.isPreRelease() || diff --git a/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt b/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt index fd066bea142..afbeefee386 100644 --- a/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt +++ b/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.resolve.directExpansionType -import org.jetbrains.kotlin.fir.resolve.firSymbolProvider +import org.jetbrains.kotlin.fir.resolve.symbolProvider import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol @@ -278,7 +278,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { inner class FirRenderer : FirVisitor() { private val session = firFile.session private val filePackage = firFile.packageFqName.toString().replace(".", "/") - private val symbolProvider = firFile.session.firSymbolProvider + private val symbolProvider = firFile.session.symbolProvider private fun removeCurrentFilePackage(fqName: String): String { return if (fqName.startsWith(filePackage) && !fqName.substring(filePackage.length + 1).contains("/")) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt index bd8224e80ed..3bc4e41cb33 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt @@ -138,6 +138,24 @@ class DescriptorKindFilter( } } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as DescriptorKindFilter + + if (excludes != other.excludes) return false + if (kindMask != other.kindMask) return false + + return true + } + + override fun hashCode(): Int { + var result = excludes.hashCode() + result = 31 * result + kindMask + return result + } + companion object { private var nextMaskValue: Int = 0x01 private fun nextMask() = nextMaskValue.apply { nextMaskValue = nextMaskValue shl 1 } diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/Printer.java b/core/util.runtime/src/org/jetbrains/kotlin/utils/Printer.java index ccfb3ed5f57..2ac97fc6f35 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/utils/Printer.java +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/Printer.java @@ -177,4 +177,12 @@ public class Printer { public String toString() { return out.toString(); } + + public int getCurrentIndentLengthInUnits() { + return indent.length() / indentUnit.length(); + } + + public int getIndentUnitLength() { + return indentUnit.length(); + } } diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 2cfbf41962c..a6c56fe8408 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -100,12 +100,10 @@ import org.jetbrains.kotlin.idea.highlighter.* import org.jetbrains.kotlin.idea.imports.AbstractJsOptimizeImportsTest import org.jetbrains.kotlin.idea.imports.AbstractJvmOptimizeImportsTest import org.jetbrains.kotlin.idea.index.AbstractKotlinTypeAliasByExpansionShortNameIndexTest +import org.jetbrains.kotlin.idea.inspections.AbstractHLInspectionTest import org.jetbrains.kotlin.idea.inspections.AbstractLocalInspectionTest import org.jetbrains.kotlin.idea.inspections.AbstractMultiFileLocalInspectionTest -import org.jetbrains.kotlin.idea.intentions.AbstractConcatenatedStringGeneratorTest -import org.jetbrains.kotlin.idea.intentions.AbstractIntentionTest -import org.jetbrains.kotlin.idea.intentions.AbstractIntentionTest2 -import org.jetbrains.kotlin.idea.intentions.AbstractMultiFileIntentionTest +import org.jetbrains.kotlin.idea.intentions.* import org.jetbrains.kotlin.idea.intentions.declarations.AbstractJoinLinesTest import org.jetbrains.kotlin.idea.internal.AbstractBytecodeToolWindowTest import org.jetbrains.kotlin.idea.kdoc.AbstractKDocHighlightingTest @@ -116,6 +114,7 @@ import org.jetbrains.kotlin.idea.navigation.* import org.jetbrains.kotlin.idea.navigationToolbar.AbstractKotlinNavBarTest import org.jetbrains.kotlin.idea.parameterInfo.AbstractParameterInfoTest import org.jetbrains.kotlin.idea.perf.* +import org.jetbrains.kotlin.idea.quickfix.AbstractHighLevelQuickFixTest import org.jetbrains.kotlin.idea.quickfix.AbstractQuickFixMultiFileTest import org.jetbrains.kotlin.idea.quickfix.AbstractQuickFixMultiModuleTest import org.jetbrains.kotlin.idea.quickfix.AbstractQuickFixTest @@ -1100,6 +1099,23 @@ fun main(args: Array) { model("checker/infos") model("checker/diagnosticsMessage") } + + + testClass { + val pattern = "^([\\w\\-_]+)\\.kt$" + model("quickfix/modifiers", pattern = pattern, filenameStartsLowerCase = true, recursive = false) + model("quickfix/override/typeMismatchOnOverride", pattern = pattern, filenameStartsLowerCase = true, recursive = false) + } + + testClass { + val pattern = "^(inspections\\.test)$" + model("inspections/redundantUnitReturnType", pattern = pattern, singleClass = true) + } + + testClass { + val pattern = "^([\\w\\-_]+)\\.(kt|kts)$" + model("intentions/specifyTypeExplicitly", pattern = pattern) + } } testGroup("idea/idea-fir/tests", "idea/idea-completion/testData") { diff --git a/gradle/jps.gradle.kts b/gradle/jps.gradle.kts index 07494f9c62e..463b2afb0eb 100644 --- a/gradle/jps.gradle.kts +++ b/gradle/jps.gradle.kts @@ -76,7 +76,7 @@ fun setupFirRunConfiguration() { | |

Write your description here. + Start the description with a verb in 3rd person singular, like reports, detects, highlights. + In the first sentence, briefly explain what exactly the inspection helps you detect. + Make sure the sentence is not very long and complicated. + The first sentence must be in a dedicated paragraph separated from the rest of the text. This will make the description easier to read. + Make sure the description doesn’t just repeat the inspection title. +

+ +

Text after this comment will only be shown in the settings of the inspection.

+ + \ No newline at end of file diff --git a/idea/resources-en/intentionDescriptions/HLSpecifyExplicitTypeForCallableDeclarationIntention/description.html b/idea/resources-en/intentionDescriptions/HLSpecifyExplicitTypeForCallableDeclarationIntention/description.html new file mode 100644 index 00000000000..5ae4fcbb90b --- /dev/null +++ b/idea/resources-en/intentionDescriptions/HLSpecifyExplicitTypeForCallableDeclarationIntention/description.html @@ -0,0 +1,7 @@ + + +

+ Specify declaration return type explicitly +

+ + \ No newline at end of file diff --git a/idea/resources-fir/META-INF/extensions.xml b/idea/resources-fir/META-INF/extensions.xml new file mode 100644 index 00000000000..59037fc488e --- /dev/null +++ b/idea/resources-fir/META-INF/extensions.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/idea/resources-fir/META-INF/firInspections.xml b/idea/resources-fir/META-INF/firInspections.xml new file mode 100644 index 00000000000..003fc65c660 --- /dev/null +++ b/idea/resources-fir/META-INF/firInspections.xml @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/idea/resources-fir/META-INF/firIntentions.xml b/idea/resources-fir/META-INF/firIntentions.xml new file mode 100644 index 00000000000..bf2c30a3cc0 --- /dev/null +++ b/idea/resources-fir/META-INF/firIntentions.xml @@ -0,0 +1,8 @@ + + + + org.jetbrains.kotlin.idea.fir.intentions.declarations.HLSpecifyExplicitTypeForCallableDeclarationIntention + Kotlin + + + \ No newline at end of file diff --git a/idea/resources-fir/META-INF/plugin.xml b/idea/resources-fir/META-INF/plugin.xml index ad428ee635d..69c6efe8e26 100644 --- a/idea/resources-fir/META-INF/plugin.xml +++ b/idea/resources-fir/META-INF/plugin.xml @@ -37,9 +37,13 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu + + + + @@ -267,7 +271,7 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu - + @@ -287,10 +291,7 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu fieldName="INSTANCE" extensions="kotlin_module"/> - + diff --git a/idea/resources-fir/inspectionDescriptions/AddFunctionReturnTypeIntention.html b/idea/resources-fir/inspectionDescriptions/AddFunctionReturnTypeIntention.html deleted file mode 100644 index f29f4353573..00000000000 --- a/idea/resources-fir/inspectionDescriptions/AddFunctionReturnTypeIntention.html +++ /dev/null @@ -1,5 +0,0 @@ - - -This intention adds an explicit type specification for functions. - - \ No newline at end of file diff --git a/idea/resources/META-INF/extensions/ide.xml b/idea/resources/META-INF/extensions/ide.xml index ef26c494b9a..2c665b65c8a 100644 --- a/idea/resources/META-INF/extensions/ide.xml +++ b/idea/resources/META-INF/extensions/ide.xml @@ -38,6 +38,10 @@ interface="kotlin.script.experimental.intellij.ScriptDefinitionsProvider" area="IDEA_PROJECT" dynamic="true"/> + + @@ -98,6 +102,8 @@ + + diff --git a/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt b/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt index 20183edfdbd..e86544c2581 100644 --- a/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt +++ b/idea/src/org/jetbrains/kotlin/idea/j2k/J2KPostProcessingRegistrarImpl.kt @@ -104,7 +104,9 @@ object J2KPostProcessingRegistrarImpl : J2KPostProcessingRegistrar { } registerDiagnosticBasedProcessing(Errors.REDUNDANT_PROJECTION) { _, diagnostic -> - val fix = RemoveModifierFix.createRemoveProjectionFactory(true).createActions(diagnostic).single() as RemoveModifierFix + val fix = RemoveModifierFix.createRemoveProjectionFactory(true) + .asKotlinIntentionActionsFactory() + .createActions(diagnostic).single() as RemoveModifierFix fix.invoke() } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt index 053596ae436..13f9422221e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/AddModifierFix.kt @@ -43,7 +43,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.TypeUtils -open class AddModifierFix( + open class AddModifierFix( element: KtModifierListOwner, protected val modifier: KtModifierKeywordToken ) : KotlinCrossLanguageQuickFixAction(element), KotlinUniversalQuickFix { diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCallableReturnTypeFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCallableReturnTypeFix.kt index bf871505b96..ab2061bc3c2 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCallableReturnTypeFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeCallableReturnTypeFix.kt @@ -34,6 +34,7 @@ import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil import org.jetbrains.kotlin.idea.project.builtIns import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext import org.jetbrains.kotlin.resolve.BindingContext @@ -71,19 +72,10 @@ abstract class ChangeCallableReturnTypeFix( open fun functionPresentation(): String? { val element = element!! - val name = element.name - if (name != null) { - val container = element.unsafeResolveToDescriptor().containingDeclaration as? ClassDescriptor - val containerName = container?.name?.takeUnless { it.isSpecial }?.asString() - val fullName = if (containerName != null) "'$containerName.$name'" else "'$name'" - if (element is KtParameter) { - return KotlinBundle.message("fix.change.return.type.presentation.property", fullName) - } else { - return KotlinBundle.message("fix.change.return.type.presentation.function", fullName) - } - } else { - return null - } + if (element.name == null) return null + val container = element.unsafeResolveToDescriptor().containingDeclaration as? ClassDescriptor + val containerName = container?.name?.takeUnless { it.isSpecial } + return StringPresentation.functionOrConstructorParameterPresentation(element, containerName) } class OnType(element: KtFunction, type: KotlinType) : ChangeCallableReturnTypeFix(element, type), HighPriorityAction { @@ -112,7 +104,7 @@ abstract class ChangeCallableReturnTypeFix( class ForOverridden(element: KtFunction, type: KotlinType) : ChangeCallableReturnTypeFix(element, type) { override fun functionPresentation(): String? { val presentation = super.functionPresentation() ?: return null - return KotlinBundle.message("fix.change.return.type.presentation.base", presentation) + return StringPresentation.baseFunctionOrConstructorParameterPresentation(presentation) } } @@ -123,32 +115,10 @@ abstract class ChangeCallableReturnTypeFix( return changeFunctionLiteralReturnTypeFix.text } - val functionPresentation = functionPresentation() - - if (isUnitType && element is KtFunction && element.hasBlockBody()) { - return if (functionPresentation == null) - KotlinBundle.message("fix.change.return.type.remove.explicit.return.type") - else - KotlinBundle.message("fix.change.return.type.remove.explicit.return.type.of", functionPresentation) - } - - return when (element) { - is KtFunction -> { - if (functionPresentation != null) - KotlinBundle.message("fix.change.return.type.return.type.text.of", functionPresentation, typePresentation) - else - KotlinBundle.message("fix.change.return.type.return.type.text", typePresentation) - } - else -> { - if (functionPresentation != null) - KotlinBundle.message("fix.change.return.type.type.text.of", functionPresentation, typePresentation) - else - KotlinBundle.message("fix.change.return.type.type.text", typePresentation) - } - } + return StringPresentation.getTextForQuickFix(element, functionPresentation(), isUnitType, typePresentation) } - override fun getFamilyName() = KotlinBundle.message("fix.change.return.type.family") + override fun getFamilyName(): String = StringPresentation.familyName() override fun isAvailable(project: Project, editor: Editor?, file: KtFile): Boolean { return !typeContainsError && @@ -264,4 +234,59 @@ abstract class ChangeCallableReturnTypeFix( return multiDeclaration.entries[componentIndex - 1] } } + + object StringPresentation { + fun familyName(): String = KotlinBundle.message("fix.change.return.type.family") + + fun functionOrConstructorParameterPresentation(element: KtCallableDeclaration, containerName: Name?): String? { + val name = element.name + return if (name != null) { + val fullName = if (containerName != null) "'${containerName.asString()}.$name'" else "'$name'" + when (element) { + is KtParameter -> KotlinBundle.message("fix.change.return.type.presentation.property", fullName) + is KtProperty -> KotlinBundle.message("fix.change.return.type.presentation.property", fullName) + else -> KotlinBundle.message("fix.change.return.type.presentation.function", fullName) + } + } else null + } + + + fun baseFunctionOrConstructorParameterPresentation(presentation: String): String = + KotlinBundle.message("fix.change.return.type.presentation.base", presentation) + + fun baseFunctionOrConstructorParameterPresentation(element: KtCallableDeclaration, containerName: Name?): String? { + val presentation = functionOrConstructorParameterPresentation(element, containerName) ?: return null + return baseFunctionOrConstructorParameterPresentation(presentation) + } + + fun getTextForQuickFix( + element: KtCallableDeclaration, + presentation: String?, + isUnitType: Boolean, + typePresentation: String + ): String { + if (isUnitType && element is KtFunction && element.hasBlockBody()) { + return if (presentation == null) + KotlinBundle.message("fix.change.return.type.remove.explicit.return.type") + else + KotlinBundle.message("fix.change.return.type.remove.explicit.return.type.of", presentation) + } + + return when (element) { + is KtFunction -> { + if (presentation != null) + KotlinBundle.message("fix.change.return.type.return.type.text.of", presentation, typePresentation) + else + KotlinBundle.message("fix.change.return.type.return.type.text", typePresentation) + } + else -> { + if (presentation != null) + KotlinBundle.message("fix.change.return.type.type.text.of", presentation, typePresentation) + else + KotlinBundle.message("fix.change.return.type.type.text", typePresentation) + } + } + } + } } + diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinSingleIntentionActionFactory.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinSingleIntentionActionFactory.kt index aaddf121d8e..706baf8857c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinSingleIntentionActionFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/KotlinSingleIntentionActionFactory.kt @@ -17,10 +17,26 @@ package org.jetbrains.kotlin.idea.quickfix import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.psi.PsiElement import org.jetbrains.kotlin.diagnostics.Diagnostic abstract class KotlinSingleIntentionActionFactory : KotlinIntentionActionsFactory() { protected abstract fun createAction(diagnostic: Diagnostic): IntentionAction? final override fun doCreateActions(diagnostic: Diagnostic): List = listOfNotNull(createAction(diagnostic)) + + companion object { + inline fun createFromQuickFixesPsiBasedFactory( + psiBasedFactory: QuickFixesPsiBasedFactory + ): KotlinSingleIntentionActionFactory = object : KotlinSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + val factories = psiBasedFactory.createQuickFix(diagnostic.psiElement as PSI) + return when (factories.size) { + 0 -> null + 1 -> factories.single() + else -> error("To convert QuickFixesPsiBasedFactory to KotlinSingleIntentionActionFactory, it should always return one or zero quickfixes") + } + } + } + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 99488a1231a..184884ceaa7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.inspections.InfixCallFixActionFactory import org.jetbrains.kotlin.idea.inspections.PlatformUnresolvedProvider import org.jetbrains.kotlin.idea.inspections.RemoveAnnotationFix import org.jetbrains.kotlin.idea.intentions.* +import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix.Companion.createRemoveModifierFromListOwnerPsiBasedFactory import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.* import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromCallWithConstructorCalleeActionFactory import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.CreateClassFromConstructorCallActionFactory @@ -56,7 +57,7 @@ import org.jetbrains.kotlin.resolve.konan.diagnostics.ErrorsNative.THROWS_LIST_E class QuickFixRegistrar : QuickFixContributor { override fun registerQuickFixes(quickFixes: QuickFixes) { - fun DiagnosticFactory<*>.registerFactory(vararg factory: KotlinIntentionActionsFactory) { + fun DiagnosticFactory<*>.registerFactory(vararg factory: QuickFixFactory) { quickFixes.register(this, *factory) } @@ -64,7 +65,7 @@ class QuickFixRegistrar : QuickFixContributor { quickFixes.register(this, *action) } - val removeAbstractModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(ABSTRACT_KEYWORD) + val removeAbstractModifierFactory = createRemoveModifierFromListOwnerPsiBasedFactory(ABSTRACT_KEYWORD ) val addAbstractModifierFactory = AddModifierFix.createFactory(ABSTRACT_KEYWORD) ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS.registerFactory(removeAbstractModifierFactory) @@ -98,7 +99,7 @@ class QuickFixRegistrar : QuickFixContributor { NON_MEMBER_FUNCTION_NO_BODY.registerFactory(AddFunctionBodyFix) NOTHING_TO_OVERRIDE.registerFactory( - RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OVERRIDE_KEYWORD), + RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(OVERRIDE_KEYWORD), ChangeMemberFunctionSignatureFix, AddFunctionToSupertypeFix, AddPropertyToSupertypeFix @@ -117,15 +118,15 @@ class QuickFixRegistrar : QuickFixContributor { val removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFactory(true) REDUNDANT_MODIFIER.registerFactory(removeRedundantModifierFactory) - REDUNDANT_OPEN_IN_INTERFACE.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OPEN_KEYWORD, true)) + REDUNDANT_OPEN_IN_INTERFACE.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(OPEN_KEYWORD, true)) REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE.registerFactory(RemoveModifierFix.createRemoveSuspendFactory()) - UNNECESSARY_LATEINIT.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerFactory(LATEINIT_KEYWORD)) + UNNECESSARY_LATEINIT.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(LATEINIT_KEYWORD)) REDUNDANT_PROJECTION.registerFactory(RemoveModifierFix.createRemoveProjectionFactory(true)) INCOMPATIBLE_MODIFIERS.registerFactory(RemoveModifierFix.createRemoveModifierFactory(false)) VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED.registerFactory(RemoveModifierFix.createRemoveVarianceFactory()) - val removeOpenModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OPEN_KEYWORD) + val removeOpenModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(OPEN_KEYWORD) NON_FINAL_MEMBER_IN_FINAL_CLASS.registerFactory( AddModifierFix.createFactory(OPEN_KEYWORD, KtClass::class.java), removeOpenModifierFactory @@ -539,7 +540,7 @@ class QuickFixRegistrar : QuickFixContributor { OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR.registerFactory(RemoveAnnotationFix.JvmOverloads) OVERLOADS_ANNOTATION_CLASS_CONSTRUCTOR_WARNING.registerFactory(RemoveAnnotationFix.JvmOverloads) - ACTUAL_WITHOUT_EXPECT.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerFactory(ACTUAL_KEYWORD)) + ACTUAL_WITHOUT_EXPECT.registerFactory(RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(ACTUAL_KEYWORD)) ACTUAL_WITHOUT_EXPECT.registerFactory(CreateExpectedFix) NO_ACTUAL_FOR_EXPECT.registerFactory(CreateActualFix) NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS.registerFactory(AddActualFix) diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveModifierFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveModifierFix.kt index 926e6989d59..20bae155702 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveModifierFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/RemoveModifierFix.kt @@ -7,10 +7,10 @@ package org.jetbrains.kotlin.idea.quickfix import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile -import org.jetbrains.kotlin.diagnostics.Diagnostic +import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.idea.KotlinBundle -import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* @@ -50,87 +50,91 @@ class RemoveModifierFix( } companion object { + @Deprecated( + "For binary compatibility", + replaceWith = ReplaceWith("createRemoveModifierFromListOwnerPsiBasedFactory(modifier, isRedundant)") + ) fun createRemoveModifierFromListOwnerFactory( modifier: KtModifierKeywordToken, isRedundant: Boolean = false - ): KotlinSingleIntentionActionFactory { - return object : KotlinSingleIntentionActionFactory() { - override fun createAction(diagnostic: Diagnostic): RemoveModifierFix? { - val modifierListOwner = QuickFixUtil.getParentElementOfType(diagnostic, KtModifierListOwner::class.java) ?: return null - return RemoveModifierFix(modifierListOwner, modifier, isRedundant) - } + ): KotlinSingleIntentionActionFactory = + KotlinSingleIntentionActionFactory.createFromQuickFixesPsiBasedFactory( + createRemoveModifierFromListOwnerPsiBasedFactory(modifier, isRedundant) + ) + + fun createRemoveModifierFromListOwnerPsiBasedFactory( + modifier: KtModifierKeywordToken, + isRedundant: Boolean = false + ): QuickFixesPsiBasedFactory = + createRemoveModifierFromListOwnerFactoryByModifierListOwner( + modifier, + isRedundant + ).coMap { PsiTreeUtil.getParentOfType(it, KtModifierListOwner::class.java, false) } + + fun createRemoveModifierFromListOwnerFactoryByModifierListOwner( + modifier: KtModifierKeywordToken, + isRedundant: Boolean = false + ) = quickFixesPsiBasedFactory { + listOf(RemoveModifierFix(it, modifier, isRedundant)) + } + + fun createRemoveModifierFactory(isRedundant: Boolean = false): QuickFixesPsiBasedFactory { + return quickFixesPsiBasedFactory { psiElement: PsiElement -> + val elementType = psiElement.node.elementType as? KtModifierKeywordToken ?: return@quickFixesPsiBasedFactory emptyList() + val modifierListOwner = psiElement.getStrictParentOfType() + ?: return@quickFixesPsiBasedFactory emptyList() + listOf(RemoveModifierFix(modifierListOwner, elementType, isRedundant)) } } - fun createRemoveModifierFactory(isRedundant: Boolean = false): KotlinSingleIntentionActionFactory { - return object : KotlinSingleIntentionActionFactory() { - override fun createAction(diagnostic: Diagnostic): RemoveModifierFix? { - val psiElement = diagnostic.psiElement - val elementType = psiElement.node.elementType as? KtModifierKeywordToken ?: return null - val modifierListOwner = psiElement.getStrictParentOfType() ?: return null - return RemoveModifierFix(modifierListOwner, elementType, isRedundant) - } + + fun createRemoveProjectionFactory(isRedundant: Boolean): QuickFixesPsiBasedFactory { + return quickFixesPsiBasedFactory { psiElement: PsiElement -> + val projection = psiElement as KtTypeProjection + val elementType = projection.projectionToken?.node?.elementType as? KtModifierKeywordToken + ?: return@quickFixesPsiBasedFactory listOf() + listOf(RemoveModifierFix(projection, elementType, isRedundant)) } } - fun createRemoveProjectionFactory(isRedundant: Boolean): KotlinSingleIntentionActionFactory { - return object : KotlinSingleIntentionActionFactory() { - override fun createAction(diagnostic: Diagnostic): RemoveModifierFix? { - val projection = diagnostic.psiElement as KtTypeProjection - val elementType = projection.projectionToken?.node?.elementType as? KtModifierKeywordToken ?: return null - return RemoveModifierFix(projection, elementType, isRedundant) + fun createRemoveVarianceFactory(): QuickFixesPsiBasedFactory { + return quickFixesPsiBasedFactory { psiElement: PsiElement -> + require(psiElement is KtTypeParameter) + val modifier = when (psiElement.variance) { + Variance.IN_VARIANCE -> KtTokens.IN_KEYWORD + Variance.OUT_VARIANCE -> KtTokens.OUT_KEYWORD + else -> return@quickFixesPsiBasedFactory emptyList() } + listOf(RemoveModifierFix(psiElement, modifier, isRedundant = false)) } } - fun createRemoveVarianceFactory(): KotlinSingleIntentionActionFactory { - return object : KotlinSingleIntentionActionFactory() { - override fun createAction(diagnostic: Diagnostic): RemoveModifierFix? { - val psiElement = diagnostic.psiElement as KtTypeParameter - val modifier = when (psiElement.variance) { - Variance.IN_VARIANCE -> KtTokens.IN_KEYWORD - Variance.OUT_VARIANCE -> KtTokens.OUT_KEYWORD - else -> return null - } - return RemoveModifierFix(psiElement, modifier, isRedundant = false) - } + fun createRemoveSuspendFactory(): QuickFixesPsiBasedFactory { + return quickFixesPsiBasedFactory { psiElement: PsiElement -> + val modifierList = psiElement.parent as KtDeclarationModifierList + val type = modifierList.parent as KtTypeReference + if (!type.hasModifier(KtTokens.SUSPEND_KEYWORD)) return@quickFixesPsiBasedFactory emptyList() + listOf(RemoveModifierFix(type, KtTokens.SUSPEND_KEYWORD, isRedundant = false)) } } - fun createRemoveSuspendFactory(): KotlinSingleIntentionActionFactory { - return object : KotlinSingleIntentionActionFactory() { - override fun createAction(diagnostic: Diagnostic): RemoveModifierFix? { - val suspendKeyword = diagnostic.psiElement - val modifierList = suspendKeyword.parent as KtDeclarationModifierList - val type = modifierList.parent as KtTypeReference - if (!type.hasModifier(KtTokens.SUSPEND_KEYWORD)) return null - return RemoveModifierFix(type, KtTokens.SUSPEND_KEYWORD, isRedundant = false) - } + fun createRemoveLateinitFactory(): QuickFixesPsiBasedFactory { + return quickFixesPsiBasedFactory { psiElement: PsiElement -> + val modifierList = psiElement.parent as? KtDeclarationModifierList ?: return@quickFixesPsiBasedFactory emptyList() + val property = modifierList.parent as? KtProperty ?: return@quickFixesPsiBasedFactory emptyList() + if (!property.hasModifier(KtTokens.LATEINIT_KEYWORD)) return@quickFixesPsiBasedFactory emptyList() + listOf(RemoveModifierFix(property, KtTokens.LATEINIT_KEYWORD, isRedundant = false)) } } - fun createRemoveLateinitFactory(): KotlinSingleIntentionActionFactory { - return object : KotlinSingleIntentionActionFactory() { - override fun createAction(diagnostic: Diagnostic): RemoveModifierFix? { - val keyword = diagnostic.psiElement - val modifierList = keyword.parent as? KtDeclarationModifierList ?: return null - val property = modifierList.parent as? KtProperty ?: return null - if (!property.hasModifier(KtTokens.LATEINIT_KEYWORD)) return null - return RemoveModifierFix(property, KtTokens.LATEINIT_KEYWORD, isRedundant = false) - } - } - } - - fun createRemoveFunFromInterfaceFactory(): KotlinSingleIntentionActionFactory { - return object : KotlinSingleIntentionActionFactory() { - override fun createAction(diagnostic: Diagnostic): RemoveModifierFix? { - val keyword = diagnostic.psiElement - val modifierList = keyword.parent as? KtDeclarationModifierList ?: return null - val funInterface = (modifierList.parent as? KtClass)?.takeIf { - it.isInterface() && it.hasModifier(KtTokens.FUN_KEYWORD) - } ?: return null - return RemoveModifierFix(funInterface, KtTokens.FUN_KEYWORD, isRedundant = false) - } + fun createRemoveFunFromInterfaceFactory(): QuickFixesPsiBasedFactory { + return quickFixesPsiBasedFactory { psiElement: PsiElement -> + val modifierList = psiElement.parent as? KtDeclarationModifierList + ?: return@quickFixesPsiBasedFactory emptyList() + val funInterface = (modifierList.parent as? KtClass)?.takeIf { + it.isInterface() && it.hasModifier(KtTokens.FUN_KEYWORD) + } ?: return@quickFixesPsiBasedFactory emptyList() + listOf(RemoveModifierFix(funInterface, KtTokens.FUN_KEYWORD, isRedundant = false)) } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/script/DefaultIdeScriptingConfigurationFacade.kt b/idea/src/org/jetbrains/kotlin/idea/script/DefaultIdeScriptingConfigurationFacade.kt new file mode 100644 index 00000000000..e5663f02870 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/script/DefaultIdeScriptingConfigurationFacade.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.script + +import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.idea.core.script.configuration.DefaultScriptingSupport +import org.jetbrains.kotlin.psi.KtFile +import kotlin.script.experimental.intellij.IdeScriptConfigurationControlFacade + +class DefaultIdeScriptingConfigurationFacade : IdeScriptConfigurationControlFacade { + override fun reloadScriptConfiguration(scriptFile: PsiFile, updateEditorWithoutNotification: Boolean) { + + (scriptFile as? KtFile) ?: error("Should be called with script KtFile, but called with $scriptFile") + DefaultScriptingSupport.getInstance(scriptFile.project) + .ensureUpToDatedConfigurationSuggested( + scriptFile, + skipNotification = updateEditorWithoutNotification, + forceSync = true + ) + } +} \ No newline at end of file diff --git a/idea/testData/checker/MultipleModality.kt b/idea/testData/checker/MultipleModality.kt index 405a3c4ea73..8094a2f109b 100644 --- a/idea/testData/checker/MultipleModality.kt +++ b/idea/testData/checker/MultipleModality.kt @@ -1,5 +1,3 @@ -// FIR_COMPARISON - sealed abstract class First abstract sealed class Second diff --git a/idea/testData/checker/regression/BadParseForClass.kt b/idea/testData/checker/regression/BadParseForClass.kt index 044ba45a627..c8b0812f13d 100644 --- a/idea/testData/checker/regression/BadParseForClass.kt +++ b/idea/testData/checker/regression/BadParseForClass.kt @@ -1,5 +1,3 @@ -// FIR_COMPARISON - fun main(args: Array) { String.class } diff --git a/idea/testData/checker/regression/ClassDeclarationAfterDot.kt b/idea/testData/checker/regression/ClassDeclarationAfterDot.kt index 16b94e3c8db..e3d955ecb65 100644 --- a/idea/testData/checker/regression/ClassDeclarationAfterDot.kt +++ b/idea/testData/checker/regression/ClassDeclarationAfterDot.kt @@ -1,5 +1,3 @@ -// FIR_COMPARISON - class A fun f() { diff --git a/idea/testData/inspections/redundantUnitReturnType/inspectionData/inspections.test b/idea/testData/inspections/redundantUnitReturnType/inspectionData/inspections.test index 770eda29a61..e8c779128fb 100644 --- a/idea/testData/inspections/redundantUnitReturnType/inspectionData/inspections.test +++ b/idea/testData/inspections/redundantUnitReturnType/inspectionData/inspections.test @@ -1 +1,2 @@ -// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.RedundantUnitReturnTypeInspection \ No newline at end of file +// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.RedundantUnitReturnTypeInspection +// FIR_INSPECTION_CLASS: org.jetbrains.kotlin.idea.fir.inspections.declarations.HLRedundantUnitReturnTypeInspection \ No newline at end of file diff --git a/idea/testData/intentions/specifyTypeExplicitly/.firIntention b/idea/testData/intentions/specifyTypeExplicitly/.firIntention new file mode 100644 index 00000000000..c91c7bd63fe --- /dev/null +++ b/idea/testData/intentions/specifyTypeExplicitly/.firIntention @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.fir.intentions.declarations.HLSpecifyExplicitTypeForCallableDeclarationIntention \ No newline at end of file diff --git a/idea/testData/intentions/specifyTypeExplicitly/anonymousObject.kt b/idea/testData/intentions/specifyTypeExplicitly/anonymousObject.kt index a033868e63b..642344a8efe 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/anonymousObject.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/anonymousObject.kt @@ -1,3 +1,4 @@ +// IGNORE_FIR class A { private fun foo() = { object {} } } \ No newline at end of file diff --git a/idea/testData/intentions/specifyTypeExplicitly/anonymousObject.kt.after b/idea/testData/intentions/specifyTypeExplicitly/anonymousObject.kt.after index 374168dfb5a..74139f27e15 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/anonymousObject.kt.after +++ b/idea/testData/intentions/specifyTypeExplicitly/anonymousObject.kt.after @@ -1,3 +1,4 @@ +// IGNORE_FIR class A { private fun foo(): () -> Any = { object {} } } \ No newline at end of file diff --git a/idea/testData/intentions/specifyTypeExplicitly/backticked.kt b/idea/testData/intentions/specifyTypeExplicitly/backticked.kt index 66be7b9ab5f..e5ca237bf27 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/backticked.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/backticked.kt @@ -1,2 +1,3 @@ +// IGNORE_FIR class `1` val x = `1`() \ No newline at end of file diff --git a/idea/testData/intentions/specifyTypeExplicitly/backticked.kt.after b/idea/testData/intentions/specifyTypeExplicitly/backticked.kt.after index 158fdd3c91c..f817cb01821 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/backticked.kt.after +++ b/idea/testData/intentions/specifyTypeExplicitly/backticked.kt.after @@ -1,2 +1,3 @@ +// IGNORE_FIR class `1` val x: `1` = `1`() \ No newline at end of file diff --git a/idea/testData/intentions/specifyTypeExplicitly/badCaretPosition.kt b/idea/testData/intentions/specifyTypeExplicitly/badCaretPosition.kt index 00c028d20be..fa07eac68b6 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/badCaretPosition.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/badCaretPosition.kt @@ -1,3 +1,4 @@ +// IGNORE_FIR // IS_APPLICABLE: false val x = "" \ No newline at end of file diff --git a/idea/testData/intentions/specifyTypeExplicitly/classNameClashing.kt b/idea/testData/intentions/specifyTypeExplicitly/classNameClashing.kt index 3c1116959ed..2372086559a 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/classNameClashing.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/classNameClashing.kt @@ -1,3 +1,4 @@ +// IGNORE_FIR // WITH_RUNTIME object Holder { diff --git a/idea/testData/intentions/specifyTypeExplicitly/classNameClashing.kt.after b/idea/testData/intentions/specifyTypeExplicitly/classNameClashing.kt.after index f7a67a94bac..cbff2fb6bf4 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/classNameClashing.kt.after +++ b/idea/testData/intentions/specifyTypeExplicitly/classNameClashing.kt.after @@ -1,3 +1,4 @@ +// IGNORE_FIR // WITH_RUNTIME object Holder { diff --git a/idea/testData/intentions/specifyTypeExplicitly/localClass.kt b/idea/testData/intentions/specifyTypeExplicitly/localClass.kt index a9d9ab11fef..fa6766cc5cc 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/localClass.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/localClass.kt @@ -1,3 +1,4 @@ +// IGNORE_FIR class A { private fun bar() = { class Local() diff --git a/idea/testData/intentions/specifyTypeExplicitly/localClass.kt.after b/idea/testData/intentions/specifyTypeExplicitly/localClass.kt.after index 7bde653b217..7ffd9643ad2 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/localClass.kt.after +++ b/idea/testData/intentions/specifyTypeExplicitly/localClass.kt.after @@ -1,5 +1,6 @@ +// IGNORE_FIR class A { - private fun bar(): () -> Any = { + private fun bar(): () -> Any = { class Local() Local() } diff --git a/idea/testData/intentions/specifyTypeExplicitly/localClassInSecondTypeParameter3.kt b/idea/testData/intentions/specifyTypeExplicitly/localClassInSecondTypeParameter3.kt index b3464b8aa46..8389c588e67 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/localClassInSecondTypeParameter3.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/localClassInSecondTypeParameter3.kt @@ -1,3 +1,4 @@ +// IGNORE_FIR open class F class TestClass diff --git a/idea/testData/intentions/specifyTypeExplicitly/localClassInSecondTypeParameter3.kt.after b/idea/testData/intentions/specifyTypeExplicitly/localClassInSecondTypeParameter3.kt.after index 40da2097f01..1481c2242e2 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/localClassInSecondTypeParameter3.kt.after +++ b/idea/testData/intentions/specifyTypeExplicitly/localClassInSecondTypeParameter3.kt.after @@ -1,3 +1,4 @@ +// IGNORE_FIR open class F class TestClass diff --git a/idea/testData/intentions/specifyTypeExplicitly/loopParameter.kt b/idea/testData/intentions/specifyTypeExplicitly/loopParameter.kt index 3186d98f203..670ab2396c9 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/loopParameter.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/loopParameter.kt @@ -1,3 +1,4 @@ +// IGNORE_FIR // WITH_RUNTIME import java.util.HashMap diff --git a/idea/testData/intentions/specifyTypeExplicitly/loopParameter.kt.after b/idea/testData/intentions/specifyTypeExplicitly/loopParameter.kt.after index afda0d44a70..9715c773509 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/loopParameter.kt.after +++ b/idea/testData/intentions/specifyTypeExplicitly/loopParameter.kt.after @@ -1,3 +1,4 @@ +// IGNORE_FIR // WITH_RUNTIME import java.util.HashMap diff --git a/idea/testData/intentions/specifyTypeExplicitly/overriddenAsNull.kt b/idea/testData/intentions/specifyTypeExplicitly/overriddenAsNull.kt index 49facbbf905..158e6ad6566 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/overriddenAsNull.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/overriddenAsNull.kt @@ -7,3 +7,5 @@ interface I { class Test : I { override fun foo() = null } + +// IGNORE_FIR diff --git a/idea/testData/intentions/specifyTypeExplicitly/overriddenAsNull.kt.after b/idea/testData/intentions/specifyTypeExplicitly/overriddenAsNull.kt.after index f8e1cbcf895..bdfe227e05f 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/overriddenAsNull.kt.after +++ b/idea/testData/intentions/specifyTypeExplicitly/overriddenAsNull.kt.after @@ -7,3 +7,5 @@ interface I { class Test : I { override fun foo(): String? = null } + +// IGNORE_FIR diff --git a/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullFunction.kt b/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullFunction.kt index aca4df68dd0..697e228feac 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullFunction.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullFunction.kt @@ -1,3 +1,4 @@ +// IGNORE_FIR // CHOOSE_NULLABLE_TYPE_IF_EXISTS // WITH_RUNTIME interface Base { diff --git a/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullFunction.kt.after b/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullFunction.kt.after index 0cafd272634..f475e2a12c4 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullFunction.kt.after +++ b/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullFunction.kt.after @@ -1,3 +1,4 @@ +// IGNORE_FIR // CHOOSE_NULLABLE_TYPE_IF_EXISTS // WITH_RUNTIME interface Base { diff --git a/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullProperty.kt b/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullProperty.kt index 1eeb24880ce..300d629a26d 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullProperty.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullProperty.kt @@ -1,3 +1,4 @@ +// IGNORE_FIR // CHOOSE_NULLABLE_TYPE_IF_EXISTS // WITH_RUNTIME interface Base { diff --git a/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullProperty.kt.after b/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullProperty.kt.after index 37db9e8a0e2..a14967bdce6 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullProperty.kt.after +++ b/idea/testData/intentions/specifyTypeExplicitly/overrideNotNullProperty.kt.after @@ -1,3 +1,4 @@ +// IGNORE_FIR // CHOOSE_NULLABLE_TYPE_IF_EXISTS // WITH_RUNTIME interface Base { diff --git a/idea/testData/intentions/specifyTypeExplicitly/stringRedefined.kt b/idea/testData/intentions/specifyTypeExplicitly/stringRedefined.kt index 3fbcf12974c..8f053174c34 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/stringRedefined.kt +++ b/idea/testData/intentions/specifyTypeExplicitly/stringRedefined.kt @@ -1,3 +1,4 @@ +// IGNORE_FIR class String {} val x = "" \ No newline at end of file diff --git a/idea/testData/intentions/specifyTypeExplicitly/stringRedefined.kt.after b/idea/testData/intentions/specifyTypeExplicitly/stringRedefined.kt.after index 3299d9b467e..69ca13d5690 100644 --- a/idea/testData/intentions/specifyTypeExplicitly/stringRedefined.kt.after +++ b/idea/testData/intentions/specifyTypeExplicitly/stringRedefined.kt.after @@ -1,5 +1,6 @@ import kotlin.String +// IGNORE_FIR class String {} val x: String = "" \ No newline at end of file diff --git a/idea/testData/multiplatform/whenExhaustivenessForSealed/common/common.kt b/idea/testData/multiplatform/whenExhaustivenessForSealed/common/common.kt new file mode 100644 index 00000000000..9914c58c433 --- /dev/null +++ b/idea/testData/multiplatform/whenExhaustivenessForSealed/common/common.kt @@ -0,0 +1,7 @@ +expect sealed class TestClass() +class CommonImplTestClass: TestClass() + + +fun checkCommon(t: TestClass): Int = when (t) { + is CommonImplTestClass -> 0 +} diff --git a/idea/testData/multiplatform/whenExhaustivenessForSealed/commonA/commonA.kt b/idea/testData/multiplatform/whenExhaustivenessForSealed/commonA/commonA.kt new file mode 100644 index 00000000000..932279efdc9 --- /dev/null +++ b/idea/testData/multiplatform/whenExhaustivenessForSealed/commonA/commonA.kt @@ -0,0 +1 @@ +class CommonAImplTestClass: TestClass() \ No newline at end of file diff --git a/idea/testData/multiplatform/whenExhaustivenessForSealed/dependencies.txt b/idea/testData/multiplatform/whenExhaustivenessForSealed/dependencies.txt new file mode 100644 index 00000000000..fead550b979 --- /dev/null +++ b/idea/testData/multiplatform/whenExhaustivenessForSealed/dependencies.txt @@ -0,0 +1,8 @@ +MODULE common { platform=[JVM, JS, Native]; additionalCompilerArgs=: -XXLanguage:+SealedInterfaces -XXLanguage:+AllowSealedInheritorsInDifferentFilesOfSamePackage } +MODULE commonA { platform=[JVM]; additionalCompilerArgs=: -XXLanguage:+SealedInterfaces -XXLanguage:+AllowSealedInheritorsInDifferentFilesOfSamePackage } +MODULE platformAX { platform=[JVM]; additionalCompilerArgs=: -XXLanguage:+SealedInterfaces -XXLanguage:+AllowSealedInheritorsInDifferentFilesOfSamePackage } +MODULE platformAY { platform=[JVM]; additionalCompilerArgs=: -XXLanguage:+SealedInterfaces -XXLanguage:+AllowSealedInheritorsInDifferentFilesOfSamePackage } + +commonA -> common { kind=DEPENDS_ON } +platformAX -> commonA { kind=DEPENDS_ON } +platformAY -> commonA { kind=DEPENDS_ON } \ No newline at end of file diff --git a/idea/testData/multiplatform/whenExhaustivenessForSealed/platformAX/platformAX.kt b/idea/testData/multiplatform/whenExhaustivenessForSealed/platformAX/platformAX.kt new file mode 100644 index 00000000000..5d8a8717ce1 --- /dev/null +++ b/idea/testData/multiplatform/whenExhaustivenessForSealed/platformAX/platformAX.kt @@ -0,0 +1,8 @@ +actual sealed class TestClass actual constructor() {} +class PlatformAXImplTestClass: TestClass() + +fun checkCommonAX(t: TestClass): Int = when (t) { + is CommonImplTestClass -> 0 + is CommonAImplTestClass -> 1 + is PlatformAXImplTestClass -> 2 +} diff --git a/idea/testData/multiplatform/whenExhaustivenessForSealed/platformAY/platformAY.kt b/idea/testData/multiplatform/whenExhaustivenessForSealed/platformAY/platformAY.kt new file mode 100644 index 00000000000..6654412c806 --- /dev/null +++ b/idea/testData/multiplatform/whenExhaustivenessForSealed/platformAY/platformAY.kt @@ -0,0 +1,8 @@ +actual sealed class TestClass actual constructor() {} +class PlatformAYImplTestClass: TestClass() + +fun checkCommonAY(t: TestClass): Int = when (t) { + is CommonImplTestClass -> 0 + is CommonAImplTestClass -> 1 + is PlatformAYImplTestClass -> 2 +} diff --git a/idea/testData/quickfix/modifiers/cannotMakeClassAnnotation.kt b/idea/testData/quickfix/modifiers/cannotMakeClassAnnotation.kt index 26fb9805cd8..6daad2408fb 100644 --- a/idea/testData/quickfix/modifiers/cannotMakeClassAnnotation.kt +++ b/idea/testData/quickfix/modifiers/cannotMakeClassAnnotation.kt @@ -1,3 +1,4 @@ // "class org.jetbrains.kotlin.idea.quickfix.MakeClassAnAnnotationClassFix" "false" // ERROR: 'String' is not an annotation class @String class foo {} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/nestedAnnotationClass.kt b/idea/testData/quickfix/modifiers/nestedAnnotationClass.kt index 32d1c1e4ca9..d472a3314db 100644 --- a/idea/testData/quickfix/modifiers/nestedAnnotationClass.kt +++ b/idea/testData/quickfix/modifiers/nestedAnnotationClass.kt @@ -5,3 +5,4 @@ class A() { annotation class C } } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/nestedDataClass.kt b/idea/testData/quickfix/modifiers/nestedDataClass.kt index eb8b2b4fe0b..d846cbb7456 100644 --- a/idea/testData/quickfix/modifiers/nestedDataClass.kt +++ b/idea/testData/quickfix/modifiers/nestedDataClass.kt @@ -7,3 +7,4 @@ class A() { data class C } } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/nestedEnumClass.kt b/idea/testData/quickfix/modifiers/nestedEnumClass.kt index a4994f62fbe..457c74fa7f5 100644 --- a/idea/testData/quickfix/modifiers/nestedEnumClass.kt +++ b/idea/testData/quickfix/modifiers/nestedEnumClass.kt @@ -7,3 +7,4 @@ class A() { enum class C } } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/nestedInterface.kt b/idea/testData/quickfix/modifiers/nestedInterface.kt index 869025b6950..faa04f00d96 100644 --- a/idea/testData/quickfix/modifiers/nestedInterface.kt +++ b/idea/testData/quickfix/modifiers/nestedInterface.kt @@ -6,3 +6,4 @@ class A() { interface C } } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/nestedObject.kt b/idea/testData/quickfix/modifiers/nestedObject.kt index 5472f4809ba..78db500cf1d 100644 --- a/idea/testData/quickfix/modifiers/nestedObject.kt +++ b/idea/testData/quickfix/modifiers/nestedObject.kt @@ -6,3 +6,4 @@ class A() { object C } } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/nestedSealedClass.kt b/idea/testData/quickfix/modifiers/nestedSealedClass.kt index e3fe905d0b8..edeed352147 100644 --- a/idea/testData/quickfix/modifiers/nestedSealedClass.kt +++ b/idea/testData/quickfix/modifiers/nestedSealedClass.kt @@ -8,3 +8,4 @@ class A() { sealed class C } } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/noAbstractForAnonymousObject.kt b/idea/testData/quickfix/modifiers/noAbstractForAnonymousObject.kt index bd36c6b8c39..8ec491989d1 100644 --- a/idea/testData/quickfix/modifiers/noAbstractForAnonymousObject.kt +++ b/idea/testData/quickfix/modifiers/noAbstractForAnonymousObject.kt @@ -9,4 +9,5 @@ interface T { fun test() { val o = object : T {} -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/noAbstractForObject.kt b/idea/testData/quickfix/modifiers/noAbstractForObject.kt index 9887ea6cca1..8d475c736c4 100644 --- a/idea/testData/quickfix/modifiers/noAbstractForObject.kt +++ b/idea/testData/quickfix/modifiers/noAbstractForObject.kt @@ -9,3 +9,4 @@ interface T { } object Some : T +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/noLateinitOnNullable.kt b/idea/testData/quickfix/modifiers/noLateinitOnNullable.kt index 7d036855be9..ff7e8f730a5 100644 --- a/idea/testData/quickfix/modifiers/noLateinitOnNullable.kt +++ b/idea/testData/quickfix/modifiers/noLateinitOnNullable.kt @@ -10,4 +10,5 @@ class A { private var a: String? -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/noLateinitOnPrimitive.kt b/idea/testData/quickfix/modifiers/noLateinitOnPrimitive.kt index a27adf5ab72..a0d531e14d8 100644 --- a/idea/testData/quickfix/modifiers/noLateinitOnPrimitive.kt +++ b/idea/testData/quickfix/modifiers/noLateinitOnPrimitive.kt @@ -11,4 +11,5 @@ class A { private var a: Int -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/redundantOpenInInterface.kt b/idea/testData/quickfix/modifiers/redundantOpenInInterface.kt index 86656df35d3..e0a5cbfd311 100644 --- a/idea/testData/quickfix/modifiers/redundantOpenInInterface.kt +++ b/idea/testData/quickfix/modifiers/redundantOpenInInterface.kt @@ -2,4 +2,5 @@ interface My { open fun foo() -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/redundantOpenInInterface.kt.after b/idea/testData/quickfix/modifiers/redundantOpenInInterface.kt.after index 378d19a8e62..fdb5c1bb643 100644 --- a/idea/testData/quickfix/modifiers/redundantOpenInInterface.kt.after +++ b/idea/testData/quickfix/modifiers/redundantOpenInInterface.kt.after @@ -2,4 +2,5 @@ interface My { fun foo() -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/removeProtectedModifier.kt b/idea/testData/quickfix/modifiers/removeProtectedModifier.kt index 633f449798e..809fb1920fa 100644 --- a/idea/testData/quickfix/modifiers/removeProtectedModifier.kt +++ b/idea/testData/quickfix/modifiers/removeProtectedModifier.kt @@ -3,3 +3,4 @@ class A private protected constructor() { } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/modifiers/removeProtectedModifier.kt.after b/idea/testData/quickfix/modifiers/removeProtectedModifier.kt.after index cb41cc26b7d..0c4d4b357c1 100644 --- a/idea/testData/quickfix/modifiers/removeProtectedModifier.kt.after +++ b/idea/testData/quickfix/modifiers/removeProtectedModifier.kt.after @@ -3,3 +3,4 @@ class A private constructor() { } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeMultipleOverriddenPropertiesTypes.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeMultipleOverriddenPropertiesTypes.kt index a586e7fbf63..10cb1883c83 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeMultipleOverriddenPropertiesTypes.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeMultipleOverriddenPropertiesTypes.kt @@ -12,4 +12,5 @@ interface B { interface C : A, B { override val x: (Int) -> Int -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeOverriddenPropertyTypeToMatchOverridingProperty.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeOverriddenPropertyTypeToMatchOverridingProperty.kt index 113219068dc..6d3570592f0 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeOverriddenPropertyTypeToMatchOverridingProperty.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeOverriddenPropertyTypeToMatchOverridingProperty.kt @@ -11,3 +11,4 @@ interface B { interface C : A, B { override var x: String } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangePropertyTypeToMatchOverridenProperties.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangePropertyTypeToMatchOverridenProperties.kt index e816c04d94e..075269abaf5 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangePropertyTypeToMatchOverridenProperties.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangePropertyTypeToMatchOverridenProperties.kt @@ -11,3 +11,4 @@ interface B { interface C : A, B { override var x: Int } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeReturnTypeOfOverriddenFunction.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeReturnTypeOfOverriddenFunction.kt index c556a11f027..e67faff7e96 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeReturnTypeOfOverriddenFunction.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/cantChangeReturnTypeOfOverriddenFunction.kt @@ -11,3 +11,5 @@ interface B { interface C : A, B { override fun foo(): Long } + +/* FIR_COMPARISON */ diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType1.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType1.kt index 398415db622..1e187fe1e1b 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType1.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType1.kt @@ -9,4 +9,5 @@ interface B { interface C : A, B { override val x: (Int) -> Int -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType1.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType1.kt.after index e659b0670a8..83da809265b 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType1.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType1.kt.after @@ -9,4 +9,5 @@ interface B { interface C : A, B { override val x: (Int) -> Int -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType2.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType2.kt index 26dfcefc0b5..c082b2f3fed 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType2.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType2.kt @@ -9,4 +9,5 @@ interface B { interface C : A, B { override var x: String -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType2.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType2.kt.after index 070a6ab2a7a..bf18edd4403 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType2.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyType2.kt.after @@ -9,4 +9,5 @@ interface B { interface C : A, B { override var x: String -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyTypeFromCtorParameter.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyTypeFromCtorParameter.kt index 9daa097c738..1cef1779410 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyTypeFromCtorParameter.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyTypeFromCtorParameter.kt @@ -3,4 +3,5 @@ interface A { val x: CharSequence } -class B(override val x: Any) : A \ No newline at end of file +class B(override val x: Any) : A +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyTypeFromCtorParameter.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyTypeFromCtorParameter.kt.after index 970fa13870e..514c75a7212 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyTypeFromCtorParameter.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverriddenPropertyTypeFromCtorParameter.kt.after @@ -3,4 +3,5 @@ interface A { val x: Any } -class B(override val x: Any) : A \ No newline at end of file +class B(override val x: Any) : A +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingCtorParameterType.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingCtorParameterType.kt index 280487ae400..6526345d0cb 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingCtorParameterType.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingCtorParameterType.kt @@ -3,4 +3,5 @@ interface A { val x: CharSequence } -class B(override val x: Any) : A \ No newline at end of file +class B(override val x: Any) : A +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingCtorParameterType.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingCtorParameterType.kt.after index 2c475dd6e1a..a3e545ea382 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingCtorParameterType.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingCtorParameterType.kt.after @@ -3,4 +3,5 @@ interface A { val x: CharSequence } -class B(override val x: CharSequence) : A \ No newline at end of file +class B(override val x: CharSequence) : A +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingPropertyTypeToFunctionType.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingPropertyTypeToFunctionType.kt index 3ecabb8a48b..17e1f5f0eb7 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingPropertyTypeToFunctionType.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingPropertyTypeToFunctionType.kt @@ -4,4 +4,5 @@ interface A { } interface B : A { override var x: (Int) -> String -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingPropertyTypeToFunctionType.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingPropertyTypeToFunctionType.kt.after index 2e719f97f4a..0e3256ca2c4 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingPropertyTypeToFunctionType.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeOverridingPropertyTypeToFunctionType.kt.after @@ -4,4 +4,5 @@ interface A { } interface B : A { override var x: (String) -> Int -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeReturnTypeOfOverriddenFunction.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/changeReturnTypeOfOverriddenFunction.kt index 0637470776c..a0fd8f8fb31 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeReturnTypeOfOverriddenFunction.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeReturnTypeOfOverriddenFunction.kt @@ -9,4 +9,5 @@ interface B { interface C : A, B { override fun foo(): Long -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/changeReturnTypeOfOverriddenFunction.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/changeReturnTypeOfOverriddenFunction.kt.after index f298475a37c..a0138984cc7 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/changeReturnTypeOfOverriddenFunction.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/changeReturnTypeOfOverriddenFunction.kt.after @@ -9,4 +9,5 @@ interface B { interface C : A, B { override fun foo(): Long -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/propertyReturnTypeMismatchOnOverride.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/propertyReturnTypeMismatchOnOverride.kt index 7e4ded6883c..b3e9e11804d 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/propertyReturnTypeMismatchOnOverride.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/propertyReturnTypeMismatchOnOverride.kt @@ -5,4 +5,5 @@ interface X { class A : X { override val x: Number = 42 -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/propertyReturnTypeMismatchOnOverride.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/propertyReturnTypeMismatchOnOverride.kt.after index d5b8f1e3773..0f0a2a821c8 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/propertyReturnTypeMismatchOnOverride.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/propertyReturnTypeMismatchOnOverride.kt.after @@ -5,4 +5,5 @@ interface X { class A : X { override val x: Int = 42 -} \ No newline at end of file +} +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/propertyTypeMismatchOnOverrideIntLong.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/propertyTypeMismatchOnOverrideIntLong.kt index 3a434bca3bb..dbb82a6de7f 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/propertyTypeMismatchOnOverrideIntLong.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/propertyTypeMismatchOnOverrideIntLong.kt @@ -6,3 +6,5 @@ abstract class A { abstract class B : A() { override abstract var x: Long } + +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/propertyTypeMismatchOnOverrideIntLong.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/propertyTypeMismatchOnOverrideIntLong.kt.after index e75ee15370c..05e3ca665b8 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/propertyTypeMismatchOnOverrideIntLong.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/propertyTypeMismatchOnOverrideIntLong.kt.after @@ -6,3 +6,5 @@ abstract class A { abstract class B : A() { override abstract var x: Int } + +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverride.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverride.kt index 7a54f43ac80..1b021c9663c 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverride.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverride.kt @@ -13,3 +13,5 @@ interface X { abstract class B : A(), X { override abstract fun foo(): Int } + +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverride.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverride.kt.after index 61fe7a054fe..9aff6772d70 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverride.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverride.kt.after @@ -13,3 +13,5 @@ interface X { abstract class B : A(), X { override abstract fun foo(): T } + +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverrideAmbiguity.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverrideAmbiguity.kt index 4a6b63a6f6b..782b7f687cb 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverrideAmbiguity.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnMultipleOverrideAmbiguity.kt @@ -14,3 +14,4 @@ interface X { abstract class B : A(), X { abstract override fun foo() : String } +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntLong.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntLong.kt index fb7d4e8964e..7c6be0bd4eb 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntLong.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntLong.kt @@ -6,3 +6,5 @@ abstract class A { abstract class B : A() { abstract override fun foo(): Long } + +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntLong.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntLong.kt.after index 2abf8dbbd4a..f41241f90a3 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntLong.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntLong.kt.after @@ -6,3 +6,5 @@ abstract class A { abstract class B : A() { abstract override fun foo(): Int } + +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntUnit.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntUnit.kt index de628e696b0..730fd6cc17d 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntUnit.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntUnit.kt @@ -6,3 +6,5 @@ abstract class A { abstract class B : A() { abstract override fun foo() } + +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntUnit.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntUnit.kt.after index 3c636fe0b08..01953ef3c79 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntUnit.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideIntUnit.kt.after @@ -6,3 +6,5 @@ abstract class A { abstract class B : A() { abstract override fun foo(): Int } + +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideUnitInt.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideUnitInt.kt index 9c038ebaa52..1b570f38605 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideUnitInt.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideUnitInt.kt @@ -2,3 +2,5 @@ abstract class A : java.util.Iterator { public abstract override fun remove() : Int; } + +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideUnitInt.kt.after b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideUnitInt.kt.after index ffd4cf48bca..98807e59771 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideUnitInt.kt.after +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/returnTypeMismatchOnOverrideUnitInt.kt.after @@ -2,3 +2,5 @@ abstract class A : java.util.Iterator { public abstract override fun remove(); } + +/* FIR_COMPARISON */ \ No newline at end of file diff --git a/idea/testData/resolve/references/WrongNumberOfTypeArguments3.kt b/idea/testData/resolve/references/WrongNumberOfTypeArguments3.kt new file mode 100644 index 00000000000..040d61195d8 --- /dev/null +++ b/idea/testData/resolve/references/WrongNumberOfTypeArguments3.kt @@ -0,0 +1,9 @@ +package foo + +class CC +class DD + +val v1 = DDC> + +// REF1: (foo).DD +// REF2: (foo).CC diff --git a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiplatformAnalysisTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiplatformAnalysisTestGenerated.java index a0d86c053ff..dfc1a59e90e 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiplatformAnalysisTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/caches/resolve/MultiplatformAnalysisTestGenerated.java @@ -268,4 +268,9 @@ public class MultiplatformAnalysisTestGenerated extends AbstractMultiplatformAna public void testWeaklyIncompatibleActualInIntermediateModule() throws Exception { runTest("idea/testData/multiplatform/weaklyIncompatibleActualInIntermediateModule/"); } + + @TestMetadata("whenExhaustivenessForSealed") + public void testWhenExhaustivenessForSealed() throws Exception { + runTest("idea/testData/multiplatform/whenExhaustivenessForSealed/"); + } } diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt index d3768c15995..d146f9d1fd2 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/AbstractInspectionTest.kt @@ -37,13 +37,17 @@ abstract class AbstractInspectionTest : KotlinLightCodeInsightFixtureTestCase() try { super.setUp() EntryPointsManagerBase.getInstance(project).ADDITIONAL_ANNOTATIONS.add(ENTRY_POINT_ANNOTATION) - runWriteAction { FileTypeManager.getInstance().associateExtension(GroovyFileType.GROOVY_FILE_TYPE, "gradle") } + registerGradlPlugin() } catch (e: Throwable) { TestLoggerFactory.onTestFinished(false) throw e } } + protected open fun registerGradlPlugin() { + runWriteAction { FileTypeManager.getInstance().associateExtension(GroovyFileType.GROOVY_FILE_TYPE, "gradle") } + } + override fun tearDown() { EntryPointsManagerBase.getInstance(project).ADDITIONAL_ANNOTATIONS.remove(ENTRY_POINT_ANNOTATION) super.tearDown() @@ -55,11 +59,13 @@ abstract class AbstractInspectionTest : KotlinLightCodeInsightFixtureTestCase() protected open val forceUsePackageFolder: Boolean = false //workaround for IDEA-176033 - protected fun doTest(path: String) { + protected open fun inspectionClassDirective(): String = "// INSPECTION_CLASS: " + + protected open fun doTest(path: String) { val optionsFile = File(path) val options = FileUtil.loadFile(optionsFile, true) - val inspectionClass = Class.forName(InTextDirectivesUtils.findStringWithPrefixes(options, "// INSPECTION_CLASS: ")!!) + val inspectionClass = Class.forName(InTextDirectivesUtils.findStringWithPrefixes(options, inspectionClassDirective())!!) val fixtureClasses = InTextDirectivesUtils.findListWithPrefixes(options, "// FIXTURE_CLASS: ") diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/AbstractIntentionTest.kt b/idea/tests/org/jetbrains/kotlin/idea/intentions/AbstractIntentionTest.kt index 6f400aa139a..553e89c28cf 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/AbstractIntentionTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/AbstractIntentionTest.kt @@ -22,6 +22,7 @@ import com.intellij.refactoring.util.CommonRefactoringUtil import com.intellij.testFramework.PlatformTestUtil import junit.framework.ComparisonFailure import junit.framework.TestCase +import org.jetbrains.annotations.NotNull import org.jetbrains.kotlin.formatter.FormatSettingsUtil import org.jetbrains.kotlin.idea.test.* import org.jetbrains.kotlin.idea.util.application.executeCommand @@ -109,15 +110,11 @@ abstract class AbstractIntentionTest : KotlinLightCodeInsightFixtureTestCase() { val minJavaVersion = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// MIN_JAVA_VERSION: ") if (minJavaVersion != null && !SystemInfo.isJavaVersionAtLeast(minJavaVersion)) return@configureRegistryAndRun - if (file is KtFile && !InTextDirectivesUtils.isDirectiveDefined(fileText, "// SKIP_ERRORS_BEFORE")) { - DirectiveBasedActionUtils.checkForUnexpectedErrors(file as KtFile) - } + checkForErrorsBefore(fileText) - doTestFor(mainFile.name, pathToFiles, intentionAction, fileText) + doTestFor(mainFile, pathToFiles, intentionAction, fileText) - if (file is KtFile && !InTextDirectivesUtils.isDirectiveDefined(fileText, "// SKIP_ERRORS_AFTER")) { - DirectiveBasedActionUtils.checkForUnexpectedErrors(file as KtFile) - } + checkForErrorsAfter(fileText) } finally { ConfigLibraryUtil.unconfigureLibrariesByDirective(module, fileText) } @@ -126,6 +123,18 @@ abstract class AbstractIntentionTest : KotlinLightCodeInsightFixtureTestCase() { } } + protected open fun checkForErrorsAfter(fileText: String) { + if (file is KtFile && !InTextDirectivesUtils.isDirectiveDefined(fileText, "// SKIP_ERRORS_AFTER")) { + DirectiveBasedActionUtils.checkForUnexpectedErrors(file as KtFile) + } + } + + protected open fun checkForErrorsBefore(fileText: String) { + if (file is KtFile && !InTextDirectivesUtils.isDirectiveDefined(fileText, "// SKIP_ERRORS_BEFORE")) { + DirectiveBasedActionUtils.checkForUnexpectedErrors(file as KtFile) + } + } + private fun computeUnderProgressIndicatorAndWait(compute: () -> T): T { val result = CompletableFuture() val progressIndicator = ProgressIndicatorBase() @@ -143,7 +152,8 @@ abstract class AbstractIntentionTest : KotlinLightCodeInsightFixtureTestCase() { } @Throws(Exception::class) - private fun doTestFor(mainFilePath: String, pathToFiles: Map, intentionAction: IntentionAction, fileText: String) { + protected open fun doTestFor(mainFile: File, pathToFiles: Map, intentionAction: IntentionAction, fileText: String) { + val mainFilePath = mainFile.name val isApplicableString = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// ${isApplicableDirectiveName()}: ") val isApplicableExpected = isApplicableString == null || isApplicableString == "true" diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/AbstractQuickFixTest.kt b/idea/tests/org/jetbrains/kotlin/idea/quickfix/AbstractQuickFixTest.kt index 5f8662d3d05..60c0c406b6a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/AbstractQuickFixTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/AbstractQuickFixTest.kt @@ -20,6 +20,7 @@ import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.UsefulTestCase import com.intellij.util.ui.UIUtil import junit.framework.TestCase +import org.jetbrains.annotations.NotNull import org.jetbrains.kotlin.idea.caches.resolve.ResolveInDispatchThreadException import org.jetbrains.kotlin.idea.caches.resolve.forceCheckForResolveInDispatchThreadInTests import org.jetbrains.kotlin.idea.facet.KotlinFacet @@ -50,7 +51,7 @@ abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase(), Q } @Throws(Exception::class) - protected fun doTest(beforeFileName: String) { + protected open fun doTest(beforeFileName: String) { val beforeFileText = FileUtil.loadFile(File(beforeFileName)) withCustomCompilerOptions(beforeFileText, project, module) { val inspections = parseInspectionsToEnable(beforeFileName, beforeFileText).toTypedArray() @@ -231,7 +232,7 @@ abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase(), Q } } else { // Action shouldn't be found. Check that other actions are expected and thus tested action isn't there under another name. - DirectiveBasedActionUtils.checkAvailableActionsAreExpected(myFixture.file, actions) + checkAvailableActionsAreExpected(actions) } } } @@ -259,7 +260,11 @@ abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase(), Q return null } - private fun checkForUnexpectedErrors() = DirectiveBasedActionUtils.checkForUnexpectedErrors(myFixture.file as KtFile) + protected open fun checkAvailableActionsAreExpected(actions: List) { + DirectiveBasedActionUtils.checkAvailableActionsAreExpected(myFixture.file, actions) + } + + protected open fun checkForUnexpectedErrors() = DirectiveBasedActionUtils.checkForUnexpectedErrors(myFixture.file as KtFile) override fun getTestDataPath(): String { // Ensure full path is returned. Otherwise FileComparisonFailureException does not provide link to file diff diff --git a/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java index 0ad7563c22b..b5fcd41ad55 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/resolve/ReferenceResolveTestGenerated.java @@ -429,6 +429,11 @@ public class ReferenceResolveTestGenerated extends AbstractReferenceResolveTest runTest("idea/testData/resolve/references/WrongNumberOfTypeArguments2.kt"); } + @TestMetadata("WrongNumberOfTypeArguments3.kt") + public void testWrongNumberOfTypeArguments3() throws Exception { + runTest("idea/testData/resolve/references/WrongNumberOfTypeArguments3.kt"); + } + @TestMetadata("WrongNumberOfTypeArgumentsInSupertype.kt") public void testWrongNumberOfTypeArgumentsInSupertype() throws Exception { runTest("idea/testData/resolve/references/WrongNumberOfTypeArgumentsInSupertype.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrBoxJsES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrBoxJsES6TestGenerated.java index a2520f7fae2..2431469a3cd 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrBoxJsES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrBoxJsES6TestGenerated.java @@ -1632,6 +1632,21 @@ public class IrBoxJsES6TestGenerated extends AbstractIrBoxJsES6Test { runTest("js/js.translator/testData/box/export/nonIndetifierModuleName.kt"); } + @TestMetadata("overriddenChainNonExportIntermediate.kt") + public void testOverriddenChainNonExportIntermediate() throws Exception { + runTest("js/js.translator/testData/box/export/overriddenChainNonExportIntermediate.kt"); + } + + @TestMetadata("overriddenExternalMethodWithSameNameMethod.kt") + public void testOverriddenExternalMethodWithSameNameMethod() throws Exception { + runTest("js/js.translator/testData/box/export/overriddenExternalMethodWithSameNameMethod.kt"); + } + + @TestMetadata("overriddenExternalMethodWithSameStableNameMethod.kt") + public void testOverriddenExternalMethodWithSameStableNameMethod() throws Exception { + runTest("js/js.translator/testData/box/export/overriddenExternalMethodWithSameStableNameMethod.kt"); + } + @TestMetadata("overridenMethod.kt") public void testOverridenMethod() throws Exception { runTest("js/js.translator/testData/box/export/overridenMethod.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 616a670a869..576fd3cbf45 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -10015,6 +10015,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/elvis/nullNullOk.kt"); } + @TestMetadata("ofNonNullableResultType.kt") + public void testOfNonNullableResultType() throws Exception { + runTest("compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt"); + } + @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { runTest("compiler/testData/codegen/box/elvis/primitive.kt"); @@ -10708,6 +10713,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes public void testPropertySetter() throws Exception { runTest("compiler/testData/codegen/box/fakeOverride/propertySetter.kt"); } + + @TestMetadata("varianceOverload.kt") + public void testVarianceOverload() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/varianceOverload.kt"); + } } @TestMetadata("compiler/testData/codegen/box/fieldRename") @@ -12379,6 +12389,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/inlineClasses/conformToComparableAndCallInterfaceMethod.kt"); } + @TestMetadata("constructorCallableReference.kt") + public void testConstructorCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt"); + } + @TestMetadata("correctBoxingForBranchExpressions.kt") public void testCorrectBoxingForBranchExpressions() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/correctBoxingForBranchExpressions.kt"); @@ -26729,6 +26744,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); } + @TestMetadata("extensionFunction.kt") + public void testExtensionFunction() throws Exception { + runTest("compiler/testData/codegen/box/typealias/extensionFunction.kt"); + } + @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { runTest("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenInlineES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenInlineES6TestGenerated.java index 656a28746bd..7873282c37d 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenInlineES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenInlineES6TestGenerated.java @@ -770,6 +770,44 @@ public class IrJsCodegenInlineES6TestGenerated extends AbstractIrJsCodegenInline runTest("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); } + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/adaptedReferences") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class AdaptedReferences extends AbstractIrJsCodegenInlineES6Test { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath); + } + + public void testAllFilesPresentInAdaptedReferences() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); + } + + @TestMetadata("inlineBound.kt") + public void testInlineBound() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt"); + } + + @TestMetadata("inlineDefault.kt") + public void testInlineDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt"); + } + + @TestMetadata("inlineVararg.kt") + public void testInlineVararg() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt"); + } + + @TestMetadata("inlineVarargAndDefault.kt") + public void testInlineVarargAndDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt"); + } + + @TestMetadata("inlineVarargInts.kt") + public void testInlineVarargInts() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); + } + } + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java index 6a722ac2d4b..902c771bee4 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrBoxJsTestGenerated.java @@ -1632,6 +1632,21 @@ public class IrBoxJsTestGenerated extends AbstractIrBoxJsTest { runTest("js/js.translator/testData/box/export/nonIndetifierModuleName.kt"); } + @TestMetadata("overriddenChainNonExportIntermediate.kt") + public void testOverriddenChainNonExportIntermediate() throws Exception { + runTest("js/js.translator/testData/box/export/overriddenChainNonExportIntermediate.kt"); + } + + @TestMetadata("overriddenExternalMethodWithSameNameMethod.kt") + public void testOverriddenExternalMethodWithSameNameMethod() throws Exception { + runTest("js/js.translator/testData/box/export/overriddenExternalMethodWithSameNameMethod.kt"); + } + + @TestMetadata("overriddenExternalMethodWithSameStableNameMethod.kt") + public void testOverriddenExternalMethodWithSameStableNameMethod() throws Exception { + runTest("js/js.translator/testData/box/export/overriddenExternalMethodWithSameStableNameMethod.kt"); + } + @TestMetadata("overridenMethod.kt") public void testOverridenMethod() throws Exception { runTest("js/js.translator/testData/box/export/overridenMethod.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 037a75ef67b..b57b4501bcc 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -9500,6 +9500,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/elvis/nullNullOk.kt"); } + @TestMetadata("ofNonNullableResultType.kt") + public void testOfNonNullableResultType() throws Exception { + runTest("compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt"); + } + @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { runTest("compiler/testData/codegen/box/elvis/primitive.kt"); @@ -10193,6 +10198,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { public void testPropertySetter() throws Exception { runTest("compiler/testData/codegen/box/fakeOverride/propertySetter.kt"); } + + @TestMetadata("varianceOverload.kt") + public void testVarianceOverload() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/varianceOverload.kt"); + } } @TestMetadata("compiler/testData/codegen/box/fieldRename") @@ -11864,6 +11874,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/conformToComparableAndCallInterfaceMethod.kt"); } + @TestMetadata("constructorCallableReference.kt") + public void testConstructorCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt"); + } + @TestMetadata("correctBoxingForBranchExpressions.kt") public void testCorrectBoxingForBranchExpressions() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/correctBoxingForBranchExpressions.kt"); @@ -26214,6 +26229,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); } + @TestMetadata("extensionFunction.kt") + public void testExtensionFunction() throws Exception { + runTest("compiler/testData/codegen/box/typealias/extensionFunction.kt"); + } + @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { runTest("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java index ad8ae8af225..c2eb3216cec 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenInlineTestGenerated.java @@ -770,6 +770,44 @@ public class IrJsCodegenInlineTestGenerated extends AbstractIrJsCodegenInlineTes runTest("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); } + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/adaptedReferences") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class AdaptedReferences extends AbstractIrJsCodegenInlineTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInAdaptedReferences() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + + @TestMetadata("inlineBound.kt") + public void testInlineBound() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt"); + } + + @TestMetadata("inlineDefault.kt") + public void testInlineDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt"); + } + + @TestMetadata("inlineVararg.kt") + public void testInlineVararg() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt"); + } + + @TestMetadata("inlineVarargAndDefault.kt") + public void testInlineVarargAndDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt"); + } + + @TestMetadata("inlineVarargInts.kt") + public void testInlineVarargInts() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); + } + } + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index 4bffcc65168..74d0097f158 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -1637,6 +1637,21 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { runTest("js/js.translator/testData/box/export/nonIndetifierModuleName.kt"); } + @TestMetadata("overriddenChainNonExportIntermediate.kt") + public void testOverriddenChainNonExportIntermediate() throws Exception { + runTest("js/js.translator/testData/box/export/overriddenChainNonExportIntermediate.kt"); + } + + @TestMetadata("overriddenExternalMethodWithSameNameMethod.kt") + public void testOverriddenExternalMethodWithSameNameMethod() throws Exception { + runTest("js/js.translator/testData/box/export/overriddenExternalMethodWithSameNameMethod.kt"); + } + + @TestMetadata("overriddenExternalMethodWithSameStableNameMethod.kt") + public void testOverriddenExternalMethodWithSameStableNameMethod() throws Exception { + runTest("js/js.translator/testData/box/export/overriddenExternalMethodWithSameStableNameMethod.kt"); + } + @TestMetadata("overridenMethod.kt") public void testOverridenMethod() throws Exception { runTest("js/js.translator/testData/box/export/overridenMethod.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 1051675f628..42e581345c0 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -9500,6 +9500,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/elvis/nullNullOk.kt"); } + @TestMetadata("ofNonNullableResultType.kt") + public void testOfNonNullableResultType() throws Exception { + runTest("compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt"); + } + @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { runTest("compiler/testData/codegen/box/elvis/primitive.kt"); @@ -10193,6 +10198,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { public void testPropertySetter() throws Exception { runTest("compiler/testData/codegen/box/fakeOverride/propertySetter.kt"); } + + @TestMetadata("varianceOverload.kt") + public void testVarianceOverload() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/varianceOverload.kt"); + } } @TestMetadata("compiler/testData/codegen/box/fieldRename") @@ -11929,6 +11939,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/conformToComparableAndCallInterfaceMethod.kt"); } + @TestMetadata("constructorCallableReference.kt") + public void testConstructorCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt"); + } + @TestMetadata("correctBoxingForBranchExpressions.kt") public void testCorrectBoxingForBranchExpressions() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/correctBoxingForBranchExpressions.kt"); @@ -26179,6 +26194,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); } + @TestMetadata("extensionFunction.kt") + public void testExtensionFunction() throws Exception { + runTest("compiler/testData/codegen/box/typealias/extensionFunction.kt"); + } + @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { runTest("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java index 52adc97aede..16d7521b1f4 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenInlineTestGenerated.java @@ -770,6 +770,44 @@ public class JsCodegenInlineTestGenerated extends AbstractJsCodegenInlineTest { runTest("compiler/testData/codegen/boxInline/callableReference/topLevelProperty.kt"); } + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/adaptedReferences") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class AdaptedReferences extends AbstractJsCodegenInlineTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInAdaptedReferences() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/boxInline/callableReference/adaptedReferences"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + + @TestMetadata("inlineBound.kt") + public void testInlineBound() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineBound.kt"); + } + + @TestMetadata("inlineDefault.kt") + public void testInlineDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineDefault.kt"); + } + + @TestMetadata("inlineVararg.kt") + public void testInlineVararg() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVararg.kt"); + } + + @TestMetadata("inlineVarargAndDefault.kt") + public void testInlineVarargAndDefault() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargAndDefault.kt"); + } + + @TestMetadata("inlineVarargInts.kt") + public void testInlineVarargInts() throws Exception { + runTest("compiler/testData/codegen/boxInline/callableReference/adaptedReferences/inlineVarargInts.kt"); + } + } + @TestMetadata("compiler/testData/codegen/boxInline/callableReference/bound") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index d39ca056001..d0369ce3b16 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -4549,6 +4549,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/elvis/nullNullOk.kt"); } + @TestMetadata("ofNonNullableResultType.kt") + public void testOfNonNullableResultType() throws Exception { + runTest("compiler/testData/codegen/box/elvis/ofNonNullableResultType.kt"); + } + @TestMetadata("primitive.kt") public void testPrimitive() throws Exception { runTest("compiler/testData/codegen/box/elvis/primitive.kt"); @@ -5167,6 +5172,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest public void testPropertySetter() throws Exception { runTest("compiler/testData/codegen/box/fakeOverride/propertySetter.kt"); } + + @TestMetadata("varianceOverload.kt") + public void testVarianceOverload() throws Exception { + runTest("compiler/testData/codegen/box/fakeOverride/varianceOverload.kt"); + } } @TestMetadata("compiler/testData/codegen/box/fieldRename") @@ -6360,6 +6370,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/inlineClasses/conformToComparableAndCallInterfaceMethod.kt"); } + @TestMetadata("constructorCallableReference.kt") + public void testConstructorCallableReference() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/constructorCallableReference.kt"); + } + @TestMetadata("correctBoxingForBranchExpressions.kt") public void testCorrectBoxingForBranchExpressions() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/correctBoxingForBranchExpressions.kt"); @@ -14485,6 +14500,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/typealias/enumEntryQualifier.kt"); } + @TestMetadata("extensionFunction.kt") + public void testExtensionFunction() throws Exception { + runTest("compiler/testData/codegen/box/typealias/extensionFunction.kt"); + } + @TestMetadata("genericTypeAliasConstructor.kt") public void testGenericTypeAliasConstructor() throws Exception { runTest("compiler/testData/codegen/box/typealias/genericTypeAliasConstructor.kt"); diff --git a/js/js.translator/testData/box/export/exportNestedClass.kt b/js/js.translator/testData/box/export/exportNestedClass.kt index ac724223f75..5bb3a61cecc 100644 --- a/js/js.translator/testData/box/export/exportNestedClass.kt +++ b/js/js.translator/testData/box/export/exportNestedClass.kt @@ -16,10 +16,14 @@ class B { override fun foo(k: String): String { return "O" + k } + + fun bar(k: String): String { + return foo(k) + } } } // FILE: test.js function box() { - return new this["export-nested-class"].B.Foo().foo("K"); + return new this["export-nested-class"].B.Foo().bar("K"); } \ No newline at end of file diff --git a/js/js.translator/testData/box/export/overriddenChainNonExportIntermediate.kt b/js/js.translator/testData/box/export/overriddenChainNonExportIntermediate.kt new file mode 100644 index 00000000000..b04e9fc2b5e --- /dev/null +++ b/js/js.translator/testData/box/export/overriddenChainNonExportIntermediate.kt @@ -0,0 +1,38 @@ +// IGNORE_BACKEND: JS +// RUN_PLAIN_BOX_FUNCTION +// INFER_MAIN_MODULE + +// MODULE: overriden-chain-non-export-intermediate +// FILE: lib.kt +@JsExport +abstract class A { + abstract fun foo(): String + + abstract fun bar(): String +} + +abstract class B : A() { + abstract fun baz(): String + + override fun foo(): String = "foo" +} + +@JsExport +class C : B() { + override fun bar(): String = "bar" + override fun baz(): String = "baz" + + fun bay(): String = "bay" +} + +// FILE: test.js + +function box() { + return test(new this["overriden-chain-non-export-intermediate"].C()); +} + +function test(c) { + if (c.foo() === "foo" && c.bar() === "bar" && c.bay() == "bay") return "OK" + + return "fail" +} \ No newline at end of file diff --git a/js/js.translator/testData/box/export/overriddenExternalMethodWithSameNameMethod.kt b/js/js.translator/testData/box/export/overriddenExternalMethodWithSameNameMethod.kt new file mode 100644 index 00000000000..bc9a6222260 --- /dev/null +++ b/js/js.translator/testData/box/export/overriddenExternalMethodWithSameNameMethod.kt @@ -0,0 +1,38 @@ +// IGNORE_BACKEND: JS +// RUN_PLAIN_BOX_FUNCTION +// INFER_MAIN_MODULE + +// MODULE: overriden-external-method-with-same-name-method +// FILE: lib.kt +external abstract class Foo { + abstract fun o(): String +} + +abstract class Bar : Foo() { + abstract fun String.o(): String + + override fun o(): String { + return "O".o() + } +} + +@JsExport +class Baz : Bar() { + override fun String.o(): String { + return this + } +} + +// FILE: test.js +function Foo() {} +Foo.prototype.k = function() { + return "K" +} + +function box() { + return test(new this["overriden-external-method-with-same-name-method"].Baz()); +} + +function test(foo) { + return foo.o() + foo.k() +} \ No newline at end of file diff --git a/js/js.translator/testData/box/export/overriddenExternalMethodWithSameStableNameMethod.kt b/js/js.translator/testData/box/export/overriddenExternalMethodWithSameStableNameMethod.kt new file mode 100644 index 00000000000..3bc6dcae649 --- /dev/null +++ b/js/js.translator/testData/box/export/overriddenExternalMethodWithSameStableNameMethod.kt @@ -0,0 +1,41 @@ +// IGNORE_BACKEND: JS +// RUN_PLAIN_BOX_FUNCTION +// INFER_MAIN_MODULE + +// MODULE: overriden-external-method-with-same-stable-name-method +// FILE: lib.kt +external abstract class Foo { + abstract fun o(): String +} + +abstract class Bar : Foo() { + @JsName("oStable") + abstract fun String.o(): String + + override fun o(): String { + return "O".o() + } +} + +@JsExport +class Baz : Bar() { + override fun String.o(): String { + return this + } +} + +// FILE: test.js +function Foo() {} +Foo.prototype.k = function() { + return "K" +} + +function box() { + return test(new this["overriden-external-method-with-same-stable-name-method"].Baz()); +} + +function test(foo) { + const oStable = foo.oStable("OK") + if (oStable !== "OK") return "false: " + oStable + return foo.o() + foo.k() +} \ No newline at end of file diff --git a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt index e7d58b300f1..8f4987ee357 100644 --- a/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt +++ b/kotlin-native/Interop/StubGenerator/src/main/kotlin/org/jetbrains/kotlin/native/interop/gen/jvm/main.kt @@ -35,6 +35,7 @@ import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.util.KonanHomeProvider import org.jetbrains.kotlin.library.KotlinLibrary import org.jetbrains.kotlin.library.packageFqName +import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder import org.jetbrains.kotlin.library.resolver.impl.KotlinLibraryResolverImpl import org.jetbrains.kotlin.library.resolver.impl.libraryResolver import org.jetbrains.kotlin.library.toUnresolvedLibraries @@ -430,7 +431,7 @@ private fun resolveDependencies( noStdLib = false, noDefaultLibs = noDefaultLibs, noEndorsedLibs = noEndorsedLibs - ).getFullList() + ).getFullList(TopologicalLibraryOrder) } internal fun prepareTool(target: String?, flavor: KotlinPlatform): ToolConfig { diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt index 98a55efed06..5becbc2f988 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CAdapterGenerator.kt @@ -233,7 +233,12 @@ private class ExportedElement(val kind: ElementKind, val irClass = irSymbol.owner as IrClass cname = "_konan_function_${owner.nextFunctionIndex()}" // Produce type getter. - val getTypeFunction = LLVMAddFunction(context.llvmModule, "${cname}_type", owner.kGetTypeFuncType)!! + val getTypeFunction = addLlvmFunctionWithDefaultAttributes( + context, + context.llvmModule!!, + "${cname}_type", + owner.kGetTypeFuncType + ) val builder = LLVMCreateBuilderInContext(llvmContext)!! val bb = LLVMAppendBasicBlockInContext(llvmContext, getTypeFunction, "")!! LLVMPositionBuilderAtEnd(builder, bb) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt index 894b25a18b0..6e8ac6cecdb 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator import org.jetbrains.kotlin.resolve.BindingContext @@ -67,6 +68,9 @@ internal fun Context.psiToIr( object : IrDeserializer { override fun getDeclaration(symbol: IrSymbol) = stubGenerator.getDeclaration(symbol) + override fun resolveBySignatureInModule(signature: IdSignature, kind: IrDeserializer.TopLevelSymbolKind, moduleName: Name): IrSymbol { + error("Should not be called") + } } } else { val irProviderForCEnumsAndCStructs = diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 3f610a1ea0f..48ca2a89b60 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -140,7 +140,12 @@ internal inline fun generateFunction( name: String, block: FunctionGenerationContext.(FunctionGenerationContext) -> Unit ): LLVMValueRef { - val function = LLVMAddFunction(codegen.context.llvmModule, name, functionType)!! + val function = addLlvmFunctionWithDefaultAttributes( + codegen.context, + codegen.context.llvmModule!!, + name, + functionType + ) generateFunction(codegen, function, startLocation = null, endLocation = null, code = block) return function } @@ -345,6 +350,13 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, // for example. var needsRuntimeInit = false + // Marks that function is not allowed to call into Kotlin runtime. For this function no safepoints, no enter/leave + // frames are generated. + // TODO: Should forbid all calls into runtime except for explicitly allowed. Also should impose the same restriction + // on function being called from this one. + // TODO: Consider using a different abstraction than `FunctionGenerationContext`. + var forbidRuntime = false + init { irFunction?.let { if (!irFunction.isExported()) { @@ -1041,9 +1053,13 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, ObjectStorageKind.THREAD_LOCAL -> { val valueGetterName = irClass.threadLocalObjectStorageGetterSymbolName val valueGetterFunction = LLVMGetNamedFunction(context.llvmModule, valueGetterName) - ?: LLVMAddFunction(context.llvmModule, valueGetterName, - functionType(kObjHeaderPtrPtr, false)) - call(valueGetterFunction!!, + ?: addLlvmFunctionWithDefaultAttributes( + context, + context.llvmModule!!, + valueGetterName, + functionType(kObjHeaderPtrPtr, false) + ) + call(valueGetterFunction, listOf(), resultLifetime = Lifetime.GLOBAL, exceptionHandler = exceptionHandler) @@ -1212,6 +1228,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, internal fun epilogue() { appendingTo(prologueBb) { if (needsRuntimeInit) { + check(!forbidRuntime) { "Attempt to init runtime where runtime usage is forbidden" } call(context.llvm.initRuntimeIfNeeded, emptyList()) } val slots = if (needSlotsPhi) @@ -1219,6 +1236,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, else kNullObjHeaderPtrPtr if (needSlots) { + check(!forbidRuntime) { "Attempt to start a frame where runtime usage is forbidden" } // Zero-init slots. val slotsMem = bitcast(kInt8Ptr, slots) call(context.llvm.memsetFunction, @@ -1258,7 +1276,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, returnType == voidType -> { releaseVars() assert(returnSlot == null) - if (context.memoryModel == MemoryModel.EXPERIMENTAL) + if (!forbidRuntime && context.memoryModel == MemoryModel.EXPERIMENTAL) call(context.llvm.Kotlin_mm_safePointFunctionEpilogue, emptyList()) LLVMBuildRetVoid(builder) } @@ -1269,7 +1287,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, updateReturnRef(returnPhi, returnSlot!!) } releaseVars() - if (context.memoryModel == MemoryModel.EXPERIMENTAL) + if (!forbidRuntime && context.memoryModel == MemoryModel.EXPERIMENTAL) call(context.llvm.Kotlin_mm_safePointFunctionEpilogue, emptyList()) LLVMBuildRet(builder, returnPhi) } @@ -1311,7 +1329,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, } releaseVars() - if (context.memoryModel == MemoryModel.EXPERIMENTAL) + if (!forbidRuntime && context.memoryModel == MemoryModel.EXPERIMENTAL) call(context.llvm.Kotlin_mm_safePointExceptionUnwind, emptyList()) LLVMBuildResume(builder, landingpad) } @@ -1443,6 +1461,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, private fun releaseVars() { if (needSlots) { + check(!forbidRuntime) { "Attempt to leave a frame where runtime usage is forbidden" } call(context.llvm.leaveFrameFunction, listOf(slotsPhi!!, Int32(vars.skipSlots).llvm, Int32(slotCount).llvm)) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index 680ba5e927b..b6c840a2133 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -314,12 +314,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { private fun importMemset(): LLVMValueRef { val functionType = functionType(voidType, false, int8TypePtr, int8Type, int32Type, int1Type) - return LLVMAddFunction(llvmModule, "llvm.memset.p0i8.i32", functionType)!! - } - - private fun importMemcpy(): LLVMValueRef { - val functionType = functionType(voidType, false, int8TypePtr, int8TypePtr, int32Type, int1Type) - return LLVMAddFunction(llvmModule, "llvm.memcpy.p0i8.p0i8.i32", functionType)!! + return llvmIntrinsic("llvm.memset.p0i8.i32", functionType) } private fun llvmIntrinsic(name: String, type: LLVMTypeRef, vararg attributes: String): LLVMValueRef { @@ -350,7 +345,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) { } else { // As exported functions are written in C++ they assume sign extension for promoted types - // mention that in attributes. - val function = LLVMAddFunction(llvmModule, name, type)!! + val function = addLlvmFunctionWithDefaultAttributes(context, llvmModule, name, type) return memScoped { val paramCount = LLVMCountParamTypes(type) val paramTypes = allocArray(paramCount) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 5c032c67613..d2796f57542 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -389,7 +389,12 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) { generateFunction(codegen, ctorFunction) { + forbidRuntime = true val initGuardName = ctorFunction.name.orEmpty() + "_guard" val initGuard = LLVMAddGlobal(context.llvmModule, int32Type, initGuardName) LLVMSetInitializer(initGuard, kImmZero) @@ -2535,9 +2553,15 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map) { if (context.config.produce.isFinalBinary) { // Generate function calling all [ctorFunctions]. - val globalCtorFunction = LLVMAddFunction(context.llvmModule, "_Konan_constructors", kVoidFuncType)!! + val globalCtorFunction = addLlvmFunctionWithDefaultAttributes( + context, + context.llvmModule!!, + "_Konan_constructors", + kVoidFuncType + ) LLVMSetLinkage(globalCtorFunction, LLVMLinkage.LLVMPrivateLinkage) generateFunction(codegen, globalCtorFunction) { + forbidRuntime = true ctorFunctions.forEach { call(it, emptyList(), Lifetime.IRRELEVANT, exceptionHandler = ExceptionHandler.Caller, verbatim = true) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmAttributes.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmAttributes.kt index e1d35a12afd..ab8b1b50a2f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmAttributes.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmAttributes.kt @@ -5,8 +5,7 @@ package org.jetbrains.kotlin.backend.konan.llvm -import llvm.LLVMAddTargetDependentFunctionAttr -import llvm.LLVMValueRef +import llvm.* import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrFunction @@ -14,15 +13,30 @@ import org.jetbrains.kotlin.ir.types.isNothing import org.jetbrains.kotlin.ir.util.isThrowable import org.jetbrains.kotlin.konan.target.Family -internal fun addLlvmAttributes(context: Context, irFunction: IrFunction, llvmFunction: LLVMValueRef) { - if (irFunction.returnType.isNothing()) { - setFunctionNoReturn(llvmFunction) - } +internal fun addLlvmFunctionWithDefaultAttributes( + context: Context, + module: LLVMModuleRef, + name: String, + type: LLVMTypeRef +): LLVMValueRef = LLVMAddFunction(module, name, type)!!.also { + addDefaultLlvmFunctionAttributes(context, it) +} +/** + * Mimics parts of clang's `CodeGenModule::getDefaultFunctionAttributes` + * that are required for Kotlin/Native compiler. + */ +private fun addDefaultLlvmFunctionAttributes(context: Context, llvmFunction: LLVMValueRef) { if (shouldEnforceFramePointer(context)) { // Note: this is default for clang on at least on iOS and macOS. enforceFramePointer(llvmFunction) } +} + +internal fun addLlvmAttributesForKotlinFunction(context: Context, irFunction: IrFunction, llvmFunction: LLVMValueRef) { + if (irFunction.returnType.isNothing()) { + setFunctionNoReturn(llvmFunction) + } if (mustNotInline(context, irFunction)) { setFunctionNoInline(llvmFunction) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt index 59fe67afec9..d0307816f08 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt @@ -366,11 +366,15 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : } else { "kfun:" + qualifyInternalName(declaration) } - val function = LLVMAddFunction(context.llvmModule, symbolName, llvmFunctionType)!! - addLlvmAttributes(context, declaration, function) - - function + addLlvmFunctionWithDefaultAttributes( + context, + context.llvmModule!!, + symbolName, + llvmFunctionType + ).also { + addLlvmAttributesForKotlinFunction(context, declaration, it) + } } declaration.metadata = CodegenFunctionMetadata( diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt index 092f87dbbc1..88434f9e2c4 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt @@ -354,6 +354,7 @@ internal class ObjCExportCodeGenerator( if (externalGlobalInitializers.isEmpty()) return val initializer = generateFunction(codegen, functionType(voidType, false), "initObjCExportGlobals") { + forbidRuntime = true externalGlobalInitializers.forEach { (global, value) -> store(value.llvm, global) } @@ -742,7 +743,12 @@ private inline fun ObjCExportCodeGenerator.generateObjCImpBy( debugInfo: Boolean = false, genBody: FunctionGenerationContext.() -> Unit ): LLVMValueRef { - val result = LLVMAddFunction(context.llvmModule, "objc2kotlin", objCFunctionType(context, methodBridge))!! + val result = addLlvmFunctionWithDefaultAttributes( + context, + context.llvmModule!!, + "objc2kotlin", + objCFunctionType(context, methodBridge) + ) val location = if (debugInfo) { setupBridgeDebugInfo(context, result) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt index 2b15d33cdcf..bf9893cc4c5 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionReferenceLowering.kt @@ -263,65 +263,51 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass private val kSuspendFunctionImplConstructorSymbol = kSuspendFunctionImplSymbol.constructors.single() fun build(): BuiltFunctionReference { - val numberOfParameters = unboundFunctionParameters.size - val functionParameterTypes = unboundFunctionParameters.map { it.type } - val superTypes = mutableListOf() - val functionClass: IrClass - val suspendFunctionClass: IrClass? - if (isKSuspendFunction) { - superTypes += kSuspendFunctionImplSymbol.typeWith(referencedFunction.returnType) - functionClass = symbols.functionN(numberOfParameters + 1).owner - val continuationType = continuationClassSymbol.typeWith(referencedFunction.returnType) - superTypes += functionClass.typeWith(functionParameterTypes + continuationType + irBuiltIns.anyNType) - suspendFunctionClass = symbols.kSuspendFunctionN(numberOfParameters).owner - superTypes += suspendFunctionClass.typeWith(functionParameterTypes + referencedFunction.returnType) - } - else { - superTypes += if (isLambda) - irBuiltIns.anyType - else - kFunctionImplSymbol.typeWith(referencedFunction.returnType) - functionClass = (if (isKFunction) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner - superTypes += functionClass.typeWith(functionParameterTypes + referencedFunction.returnType) - val lastParameterType = unboundFunctionParameters.lastOrNull()?.type - if (lastParameterType?.classifierOrNull != continuationClassSymbol) - suspendFunctionClass = null - else { - lastParameterType as IrSimpleType - // If the last parameter is Continuation<> inherit from SuspendFunction. - suspendFunctionClass = symbols.suspendFunctionN(numberOfParameters - 1).owner - val suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) + - (lastParameterType.arguments.single().typeOrNull ?: irBuiltIns.anyNType) - superTypes += suspendFunctionClass.symbol.typeWith(suspendFunctionClassTypeParameters) - } + val superClass = when { + isKSuspendFunction -> kSuspendFunctionImplSymbol.typeWith(referencedFunction.returnType) + isLambda -> irBuiltIns.anyType + else -> kFunctionImplSymbol.typeWith(referencedFunction.returnType) } + val superTypes = mutableListOf(superClass) + if (samSuperType != null) { + superTypes += samSuperType - val constructor = buildConstructor() - val functionInvoke = if (isKSuspendFunction) - null - else - buildInvokeMethod(functionClass.getInvokeFunction()) - val suspendFunctionInvoke = if (suspendFunctionClass == null) - null - else { - buildInvokeMethod(suspendFunctionClass.getInvokeFunction()).also { - if (isKSuspendFunction) - it.overriddenSymbols += functionClass.getInvokeFunction().symbol + val sam = samSuperClass!!.functions.single { it.owner.modality == Modality.ABSTRACT } + buildInvokeMethod(sam.owner) + } else { + val numberOfParameters = unboundFunctionParameters.size + val functionParameterTypes = unboundFunctionParameters.map { it.type } + val functionClass: IrClass + val suspendFunctionClass: IrClass? + if (isKSuspendFunction) { + functionClass = symbols.functionN(numberOfParameters + 1).owner + val continuationType = continuationClassSymbol.typeWith(referencedFunction.returnType) + superTypes += functionClass.typeWith(functionParameterTypes + continuationType + irBuiltIns.anyNType) + suspendFunctionClass = symbols.kSuspendFunctionN(numberOfParameters).owner + superTypes += suspendFunctionClass.typeWith(functionParameterTypes + referencedFunction.returnType) + } else { + functionClass = (if (isKFunction) symbols.kFunctionN(numberOfParameters) else symbols.functionN(numberOfParameters)).owner + superTypes += functionClass.typeWith(functionParameterTypes + referencedFunction.returnType) + val lastParameterType = unboundFunctionParameters.lastOrNull()?.type + if (lastParameterType?.classifierOrNull != continuationClassSymbol) + suspendFunctionClass = null + else { + lastParameterType as IrSimpleType + // If the last parameter is Continuation<> inherit from SuspendFunction. + suspendFunctionClass = symbols.suspendFunctionN(numberOfParameters - 1).owner + val suspendFunctionClassTypeParameters = functionParameterTypes.dropLast(1) + + (lastParameterType.arguments.single().typeOrNull ?: irBuiltIns.anyNType) + superTypes += suspendFunctionClass.symbol.typeWith(suspendFunctionClassTypeParameters) + } } - } - samSuperType?.let { superTypes += it } - val sam = samSuperClass?.functions?.single { it.owner.modality == Modality.ABSTRACT } - if (sam != null) { - if (sam.owner.extensionReceiverParameter != null) - buildInvokeMethod(sam.owner) - else { - // The signatures of SAM and [invoke] coincide - no need to build additional function. - val properInvoke = if (sam.isSuspend) - suspendFunctionInvoke - else - functionInvoke - if (properInvoke != null) - properInvoke.overriddenSymbols += sam + + if (!isKSuspendFunction) + buildInvokeMethod(functionClass.getInvokeFunction()) + if (suspendFunctionClass != null) { + buildInvokeMethod(suspendFunctionClass.getInvokeFunction()).also { + if (isKSuspendFunction) + it.overriddenSymbols += functionClass.getInvokeFunction().symbol + } } } @@ -329,7 +315,7 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass functionReferenceClass.addFakeOverrides(context.irBuiltIns) - return BuiltFunctionReference(functionReferenceClass, constructor) + return BuiltFunctionReference(functionReferenceClass, buildConstructor()) } private fun buildConstructor(): IrConstructor = diff --git a/kotlin-native/backend.native/tests/build.gradle b/kotlin-native/backend.native/tests/build.gradle index d58c8fcc5e4..f2d6430e992 100644 --- a/kotlin-native/backend.native/tests/build.gradle +++ b/kotlin-native/backend.native/tests/build.gradle @@ -2396,6 +2396,11 @@ task hash_map0(type: KonanLocalTest) { source = "runtime/collections/hash_map0.kt" } +task hash_map1(type: KonanLocalTest) { + goldValue = "OK\n" + source = "runtime/collections/hash_map1.kt" +} + task hash_set0(type: KonanLocalTest) { goldValue = "OK\n" source = "runtime/collections/hash_set0.kt" @@ -2864,6 +2869,10 @@ standaloneTest("lambda14") { flags = ['-tr'] } +task funInterface_implIsNotFunction(type: KonanLocalTest) { + source = "codegen/funInterface/implIsNotFunction.kt" +} + task objectExpression1(type: KonanLocalTest) { goldValue = "aabb\n" source = "codegen/objectExpression/expr1.kt" @@ -4222,7 +4231,7 @@ interopTest("interop_kt43265") { } dynamicTest("interop_kt43502") { - disabled = (project.testTarget == 'wasm32') // No interop for wasm yet. + disabled = (project.target.name != project.hostName) interop = "kt43502" source = "interop/kt43502/main.kt" cSource = "$projectDir/interop/kt43502/main.c" diff --git a/kotlin-native/backend.native/tests/codegen/funInterface/implIsNotFunction.kt b/kotlin-native/backend.native/tests/codegen/funInterface/implIsNotFunction.kt new file mode 100644 index 00000000000..64a41058e31 --- /dev/null +++ b/kotlin-native/backend.native/tests/codegen/funInterface/implIsNotFunction.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.funInterface.implIsNotFunction + +import kotlin.test.* + +fun interface Foo { + fun invoke(): String +} + +fun foo(f: Foo) = f is Function<*> + +@Test +fun test() { + assertFalse(foo { "zzz" }) +} \ No newline at end of file diff --git a/kotlin-native/backend.native/tests/interop/incomplete_types/library.cpp b/kotlin-native/backend.native/tests/interop/incomplete_types/library.cpp index 60d1bc8750f..32ff138ba85 100644 --- a/kotlin-native/backend.native/tests/interop/incomplete_types/library.cpp +++ b/kotlin-native/backend.native/tests/interop/incomplete_types/library.cpp @@ -1,21 +1,24 @@ +#include #include "library.h" extern "C" { struct S { - const char* name; + std::string name; }; -struct S s = { +S s = { .name = "initial" }; void setContent(struct S* s, const char* name) { + // Note that copy here is intentional: we use it as a workaround + // for short lifetime of copy of the passed Kotlin string. s->name = name; } const char* getContent(struct S* s) { - return s->name; + return s->name.c_str(); } union U { diff --git a/kotlin-native/backend.native/tests/interop/incomplete_types/main.kt b/kotlin-native/backend.native/tests/interop/incomplete_types/main.kt index 8118c449c29..11ac83e16d1 100644 --- a/kotlin-native/backend.native/tests/interop/incomplete_types/main.kt +++ b/kotlin-native/backend.native/tests/interop/incomplete_types/main.kt @@ -9,7 +9,8 @@ fun main() { assertEquals("initial", getContent(s.ptr)?.toKString()) setContent(s.ptr, "yo") - assertEquals("yo", getContent(s.ptr)?.toKString()) + val ptr = getContent(s.ptr) + assertEquals("yo", ptr?.toKString()) assertEquals(0.0, getDouble(u.ptr)) setDouble(u.ptr, Double.MIN_VALUE) diff --git a/kotlin-native/backend.native/tests/objcexport/expectedLazy.h b/kotlin-native/backend.native/tests/objcexport/expectedLazy.h index e146fda0a52..d01dc46ecb9 100644 --- a/kotlin-native/backend.native/tests/objcexport/expectedLazy.h +++ b/kotlin-native/backend.native/tests/objcexport/expectedLazy.h @@ -377,6 +377,19 @@ __attribute__((swift_name("EmptyEnum"))) + (KtKotlinArray *)values __attribute__((swift_name("values()"))); @end; +__attribute__((swift_name("FunInterface"))) +@protocol KtFunInterface +@required +- (int32_t)run __attribute__((swift_name("run()"))); +@end; + +__attribute__((objc_subclassing_restricted)) +__attribute__((swift_name("FunInterfacesKt"))) +@interface KtFunInterfacesKt : KtBase ++ (id)getObject __attribute__((swift_name("getObject()"))); ++ (id)getLambda __attribute__((swift_name("getLambda()"))); +@end; + __attribute__((swift_name("FHolder"))) @interface KtFHolder : KtBase - (instancetype)init __attribute__((swift_name("init()"))) __attribute__((objc_designated_initializer)); diff --git a/kotlin-native/backend.native/tests/objcexport/funInterfaces.kt b/kotlin-native/backend.native/tests/objcexport/funInterfaces.kt new file mode 100644 index 00000000000..945133f0963 --- /dev/null +++ b/kotlin-native/backend.native/tests/objcexport/funInterfaces.kt @@ -0,0 +1,15 @@ +package funinterfaces + +fun interface FunInterface { + fun run(): Int +} + +fun getObject(): FunInterface { + return object : FunInterface { + override fun run() = 1 + } +} + +fun getLambda(): FunInterface { + return FunInterface { 2 } +} diff --git a/kotlin-native/backend.native/tests/objcexport/funInterfaces.swift b/kotlin-native/backend.native/tests/objcexport/funInterfaces.swift new file mode 100644 index 00000000000..97a057bbd35 --- /dev/null +++ b/kotlin-native/backend.native/tests/objcexport/funInterfaces.swift @@ -0,0 +1,15 @@ +import Kt + +// Based on https://youtrack.jetbrains.com/issue/KT-44799. +private func testSAMConversion() throws { + try assertEquals(actual: FunInterfacesKt.getObject().run(), expected: 1) + try assertEquals(actual: FunInterfacesKt.getLambda().run(), expected: 2) +} + +class FunInterfacesTests : SimpleTestProvider { + override init() { + super.init() + + test("TestSAMConversion", testSAMConversion) + } +} diff --git a/kotlin-native/backend.native/tests/runtime/collections/hash_map0.kt b/kotlin-native/backend.native/tests/runtime/collections/hash_map0.kt index d147ecd9485..b0f85d55630 100644 --- a/kotlin-native/backend.native/tests/runtime/collections/hash_map0.kt +++ b/kotlin-native/backend.native/tests/runtime/collections/hash_map0.kt @@ -94,58 +94,6 @@ fun testBasic() { assertEquals(0, m.size) } -fun testRehashAndCompact() { - val m = HashMap() - for (repeat in 1..10) { - val n = when (repeat) { - 1 -> 1000 - 2 -> 10000 - 3 -> 10 - else -> 100000 - } - for (i in 1..n) { - assertFalse(m.containsKey(i.toString())) - assertEquals(null, m.put(i.toString(), "val$i")) - assertTrue(m.containsKey(i.toString())) - assertEquals(i, m.size) - } - for (i in 1..n) { - assertTrue(m.containsKey(i.toString())) - } - for (i in 1..n) { - assertEquals("val$i", m.remove(i.toString())) - assertFalse(m.containsKey(i.toString())) - assertEquals(n - i, m.size) - } - assertTrue(m.isEmpty()) - } -} - -fun testClear() { - val m = HashMap() - for (repeat in 1..10) { - val n = when (repeat) { - 1 -> 1000 - 2 -> 10000 - 3 -> 10 - else -> 100000 - } - for (i in 1..n) { - assertFalse(m.containsKey(i.toString())) - assertEquals(null, m.put(i.toString(), "val$i")) - assertTrue(m.containsKey(i.toString())) - assertEquals(i, m.size) - } - for (i in 1..n) { - assertTrue(m.containsKey(i.toString())) - } - m.clear() - assertEquals(0, m.size) - for (i in 1..n) { - assertFalse(m.containsKey(i.toString())) - } - } -} fun testEquals() { val expected = mapOf("a" to "1", "b" to "2", "c" to "3") val m = HashMap(expected) @@ -257,8 +205,6 @@ fun testEntriesIteratorSet() { @Test fun runTest() { testBasic() - testRehashAndCompact() - testClear() testEquals() testHashCode() testToString() @@ -272,4 +218,4 @@ fun testEntriesIteratorSet() { testEntriesIteratorSet() //testDegenerateKeys() println("OK") -} \ No newline at end of file +} diff --git a/kotlin-native/backend.native/tests/runtime/collections/hash_map1.kt b/kotlin-native/backend.native/tests/runtime/collections/hash_map1.kt new file mode 100644 index 00000000000..b9475ebed8d --- /dev/null +++ b/kotlin-native/backend.native/tests/runtime/collections/hash_map1.kt @@ -0,0 +1,100 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package runtime.collections.hash_map1 + +import kotlin.native.MemoryModel +import kotlin.native.Platform +import kotlin.native.internal.GC +import kotlin.test.* + +fun assertTrue(cond: Boolean) { + if (!cond) + println("FAIL") +} + +fun assertFalse(cond: Boolean) { + if (cond) + println("FAIL") +} + +fun assertEquals(value1: Any?, value2: Any?) { + if (value1 != value2) + println("FAIL") +} + +fun assertNotEquals(value1: Any?, value2: Any?) { + if (value1 == value2) + println("FAIL") +} + +fun assertEquals(value1: Int, value2: Int) { + if (value1 != value2) + println("FAIL") +} + +fun testRehashAndCompact() { + val m = HashMap() + for (repeat in 1..10) { + val n = when (repeat) { + 1 -> 1000 + 2 -> 10000 + 3 -> 10 + else -> 100000 + } + for (i in 1..n) { + assertFalse(m.containsKey(i.toString())) + assertEquals(null, m.put(i.toString(), "val$i")) + assertTrue(m.containsKey(i.toString())) + assertEquals(i, m.size) + } + for (i in 1..n) { + assertTrue(m.containsKey(i.toString())) + } + for (i in 1..n) { + assertEquals("val$i", m.remove(i.toString())) + assertFalse(m.containsKey(i.toString())) + assertEquals(n - i, m.size) + } + assertTrue(m.isEmpty()) + } +} + +fun testClear() { + val m = HashMap() + for (repeat in 1..10) { + val n = when (repeat) { + 1 -> 1000 + 2 -> 10000 + 3 -> 10 + else -> 100000 + } + for (i in 1..n) { + assertFalse(m.containsKey(i.toString())) + assertEquals(null, m.put(i.toString(), "val$i")) + assertTrue(m.containsKey(i.toString())) + assertEquals(i, m.size) + } + for (i in 1..n) { + assertTrue(m.containsKey(i.toString())) + } + m.clear() + assertEquals(0, m.size) + for (i in 1..n) { + assertFalse(m.containsKey(i.toString())) + } + } +} + +@Test fun runTest() { + // TODO: Do not manually control this. + if (Platform.memoryModel == MemoryModel.EXPERIMENTAL) { + GC.threshold = 1000000 + GC.thresholdAllocations = 1000000 + } + testRehashAndCompact() + testClear() + println("OK") +} diff --git a/kotlin-native/build-tools/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy b/kotlin-native/build-tools/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy index 44c275bfe3f..b8ccd2bd27e 100644 --- a/kotlin-native/build-tools/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy +++ b/kotlin-native/build-tools/src/main/groovy/org/jetbrains/kotlin/KonanTest.groovy @@ -419,7 +419,6 @@ fun runTest() { "external/compiler/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt", // KT-33091 "external/compiler/codegen/box/multiplatform/multiModule/expectActualLink.kt", // KT-41901 "external/compiler/codegen/box/coroutines/multiModule/", // KT-40121 - "external/compiler/codegen/box/callableReference/genericConstructorReference.kt", // KT-42631 "external/compiler/codegen/box/defaultArguments/recursiveDefaultArguments.kt" // KT-42684 ] diff --git a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CompareDistributionSignatures.kt b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CompareDistributionSignatures.kt index 381cc7c551d..6a5320f04c8 100644 --- a/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CompareDistributionSignatures.kt +++ b/kotlin-native/build-tools/src/main/kotlin/org/jetbrains/kotlin/CompareDistributionSignatures.kt @@ -5,6 +5,10 @@ import org.gradle.api.tasks.Input import org.gradle.api.tasks.TaskAction import org.jetbrains.kotlin.konan.target.HostManager import java.io.File +import java.nio.file.Files +import java.nio.file.LinkOption +import java.nio.file.Path +import java.nio.file.Paths /** * Compares SignatureIds of the current distribution and the given older one. @@ -60,6 +64,12 @@ open class CompareDistributionSignatures : DefaultTask() { @TaskAction fun run() { + check(looksLikeKotlinNativeDistribution(Paths.get(oldDistribution))) { + """ + `$oldDistribution` doesn't look like Kotlin/Native distribution. + Make sure to provide an absolute path to it. + """.trimIndent() + } val platformLibsDiff = computeDiff() if (platformLibsDiff.missingLibs.isNotEmpty()) { messageBuilder.apply { @@ -114,10 +124,24 @@ open class CompareDistributionSignatures : DefaultTask() { ) private fun String.stdlib(): File = - File("$this/klib/common/stdlib") + File("$this/klib/common/stdlib").also { + check(it.exists()) { + """ + `${it.absolutePath}` doesn't exists. + If $oldDistribution has a different directory layout then it is time to update this comparator. + """.trimIndent() + } + } private fun String.platformLibs(target: String): File = - File("$this/klib/platform/$target") + File("$this/klib/platform/$target").also { + check(it.exists()) { + """ + `${it.absolutePath}` doesn't exists. + Make sure that given distribution actually supports $target. + """.trimIndent() + } + } private fun getKlibSignatures(klib: File): List { @@ -137,4 +161,12 @@ open class CompareDistributionSignatures : DefaultTask() { oldKlibSignatures - newKlibSignatures, ) } + + private fun looksLikeKotlinNativeDistribution(directory: Path): Boolean { + val distributionComponents = directory.run { + val konanDir = resolve("konan") + setOf(resolve("bin"), resolve("klib"), konanDir, konanDir.resolve("konan.properties")) + } + return distributionComponents.all { Files.exists(it, LinkOption.NOFOLLOW_LINKS) } + } } \ No newline at end of file diff --git a/kotlin-native/build.gradle b/kotlin-native/build.gradle index bbb6a03c0ed..af88a956fbc 100644 --- a/kotlin-native/build.gradle +++ b/kotlin-native/build.gradle @@ -790,22 +790,24 @@ task compdb(type: Copy) { into "$projectDir" } -if (project.hasProperty("anotherDistro")) { - targetList.each { targetName -> - task "${targetName}CheckPlatformAbiCompatibility"(type: CompareDistributionSignatures) { - dependsOn "${targetName}PlatformLibs" +targetList.each { targetName -> + task "${targetName}CheckPlatformAbiCompatibility"(type: CompareDistributionSignatures) { + dependsOn "${targetName}PlatformLibs" - libraries = new CompareDistributionSignatures.Libraries.Platform(targetName) + libraries = new CompareDistributionSignatures.Libraries.Platform(targetName) + if (project.hasProperty("anotherDistro")) { oldDistribution = project.findProperty("anotherDistro") - onMismatchMode = CompareDistributionSignatures.OnMismatchMode.FAIL } - } - - task "checkStdlibAbiCompatibility"(type: CompareDistributionSignatures) { - dependsOn "distRuntime" - - libraries = CompareDistributionSignatures.Libraries.Standard.INSTANCE - oldDistribution = project.findProperty("anotherDistro") onMismatchMode = CompareDistributionSignatures.OnMismatchMode.FAIL } } + +task "checkStdlibAbiCompatibility"(type: CompareDistributionSignatures) { + dependsOn "distRuntime" + + libraries = CompareDistributionSignatures.Libraries.Standard.INSTANCE + if (project.hasProperty("anotherDistro")) { + oldDistribution = project.findProperty("anotherDistro") + } + onMismatchMode = CompareDistributionSignatures.OnMismatchMode.FAIL +} diff --git a/kotlin-native/gradle.properties b/kotlin-native/gradle.properties index 73c19670fa6..c3df1ce19b0 100644 --- a/kotlin-native/gradle.properties +++ b/kotlin-native/gradle.properties @@ -18,12 +18,12 @@ buildKotlinVersion=1.5.20-dev-372 buildKotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:1.5.20-dev-372,branch:default:any,pinned:true/artifacts/content/maven remoteRoot=konan_tests -kotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:1.5.20-dev-372,branch:default:any,pinned:true/artifacts/content/maven -kotlinVersion=1.5.20-dev-372 -kotlinStdlibRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:1.5.20-dev-372,branch:default:any,pinned:true/artifacts/content/maven -kotlinStdlibVersion=1.5.20-dev-372 -kotlinStdlibTestsVersion=1.5.20-dev-372 -testKotlinCompilerVersion=1.5.20-dev-372 +kotlinCompilerRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:1.5.20-dev-576,branch:default:any,pinned:true/artifacts/content/maven +kotlinVersion=1.5.20-dev-576 +kotlinStdlibRepo=https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_KotlinPublic_Compiler),number:1.5.20-dev-576,branch:default:any,pinned:true/artifacts/content/maven +kotlinStdlibVersion=1.5.20-dev-576 +kotlinStdlibTestsVersion=1.5.20-dev-576 +testKotlinCompilerVersion=1.5.20-dev-576 konanVersion=1.5.20 # A version of Xcode required to build the Kotlin/Native compiler. diff --git a/kotlin-native/konan/konan.properties b/kotlin-native/konan/konan.properties index 152be800d67..2404950378e 100644 --- a/kotlin-native/konan/konan.properties +++ b/kotlin-native/konan/konan.properties @@ -574,7 +574,9 @@ linkerKonanFlags.linux_mips32 = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread \ # targetSysroot-relative. libGcc.linux_mips32 = ../../lib/gcc/mips-unknown-linux-gnu/8.3.0 targetCpu.linux_mips32 = mips32r2 -clangFlags.linux_mips32 = -cc1 -emit-obj -disable-llvm-optzns -x ir -target-cpu $targetCpu.linux_mips32 +# We generate a single binary with a big GOT. It causes problems for MIPS. +# See https://gcc.gnu.org/onlinedocs/gcc/MIPS-Options.html about mxgot. +clangFlags.linux_mips32 = -cc1 -emit-obj -disable-llvm-optzns -x ir -target-cpu $targetCpu.linux_mips32 -mllvm -mxgot clangNooptFlags.linux_mips32 = -O1 clangOptFlags.linux_mips32 = -O3 -ffunction-sections clangDebugFlags.linux_mips32 = -O0 @@ -614,7 +616,7 @@ linkerKonanFlags.linux_mipsel32 = -Bstatic -lstdc++ -Bdynamic -ldl -lm -lpthread # targetSysroot-relative. libGcc.linux_mipsel32 = ../../lib/gcc/mipsel-unknown-linux-gnu/8.3.0 targetCpu.linux_mipsel32 = mips32r2 -clangFlags.linux_mipsel32 = -cc1 -emit-obj -disable-llvm-optzns -x ir -target-cpu $targetCpu.linux_mipsel32 +clangFlags.linux_mipsel32 = -cc1 -emit-obj -disable-llvm-optzns -x ir -target-cpu $targetCpu.linux_mipsel32 -mllvm -mxgot clangNooptFlags.linux_mipsel32 = -O1 clangOptFlags.linux_mipsel32 = -O3 -ffunction-sections clangDebugFlags.linux_mipsel32 = -O0 diff --git a/kotlin-native/platformLibs/src/platform/android/builtin.def b/kotlin-native/platformLibs/src/platform/android/builtin.def index d7d93621827..b106a84964e 100644 --- a/kotlin-native/platformLibs/src/platform/android/builtin.def +++ b/kotlin-native/platformLibs/src/platform/android/builtin.def @@ -1,3 +1,4 @@ +depends = posix package = platform.builtin headerFilter = language = C diff --git a/kotlin-native/platformLibs/src/platform/linux/builtin.def b/kotlin-native/platformLibs/src/platform/linux/builtin.def index d7d93621827..b106a84964e 100644 --- a/kotlin-native/platformLibs/src/platform/linux/builtin.def +++ b/kotlin-native/platformLibs/src/platform/linux/builtin.def @@ -1,3 +1,4 @@ +depends = posix package = platform.builtin headerFilter = language = C diff --git a/kotlin-native/platformLibs/src/platform/mingw/builtin.def b/kotlin-native/platformLibs/src/platform/mingw/builtin.def index d7d93621827..b106a84964e 100644 --- a/kotlin-native/platformLibs/src/platform/mingw/builtin.def +++ b/kotlin-native/platformLibs/src/platform/mingw/builtin.def @@ -1,3 +1,4 @@ +depends = posix package = platform.builtin headerFilter = language = C diff --git a/kotlin-native/runtime/src/main/cpp/MultiSourceQueue.hpp b/kotlin-native/runtime/src/main/cpp/MultiSourceQueue.hpp index 31aecaf7e71..30166c31b0d 100644 --- a/kotlin-native/runtime/src/main/cpp/MultiSourceQueue.hpp +++ b/kotlin-native/runtime/src/main/cpp/MultiSourceQueue.hpp @@ -71,6 +71,11 @@ public: owner_.deletionQueue_.splice(owner_.deletionQueue_.end(), deletionQueue_); } + void ClearForTests() noexcept { + queue_.clear(); + deletionQueue_.clear(); + } + private: MultiSourceQueue& owner_; // weak KStdList queue_; diff --git a/kotlin-native/runtime/src/mm/cpp/GlobalData.cpp b/kotlin-native/runtime/src/mm/cpp/GlobalData.cpp index 73347e58e6f..e8f47f427b5 100644 --- a/kotlin-native/runtime/src/mm/cpp/GlobalData.cpp +++ b/kotlin-native/runtime/src/mm/cpp/GlobalData.cpp @@ -8,7 +8,6 @@ using namespace kotlin; mm::GlobalData::GlobalData() = default; -mm::GlobalData::~GlobalData() = default; // static -mm::GlobalData mm::GlobalData::instance_; +mm::GlobalData mm::GlobalData::instance_ [[clang::no_destroy]]; diff --git a/kotlin-native/runtime/src/mm/cpp/GlobalData.hpp b/kotlin-native/runtime/src/mm/cpp/GlobalData.hpp index 6cc47c09c69..2b084e45cb8 100644 --- a/kotlin-native/runtime/src/mm/cpp/GlobalData.hpp +++ b/kotlin-native/runtime/src/mm/cpp/GlobalData.hpp @@ -29,8 +29,9 @@ public: private: GlobalData(); - ~GlobalData(); + ~GlobalData() = delete; + // This `GlobalData` is never destroyed. static GlobalData instance_; ThreadRegistry threadRegistry_; diff --git a/kotlin-native/runtime/src/mm/cpp/InitializationSchemeTest.cpp b/kotlin-native/runtime/src/mm/cpp/InitializationSchemeTest.cpp index a46c01debf3..f63e08f4bf9 100644 --- a/kotlin-native/runtime/src/mm/cpp/InitializationSchemeTest.cpp +++ b/kotlin-native/runtime/src/mm/cpp/InitializationSchemeTest.cpp @@ -39,6 +39,7 @@ public: // Make sure to clean everything allocated by the tests. for (auto& threadData : threadDatas_) { threadData->objectFactoryThreadQueue().ClearForTests(); + threadData->globalsThreadQueue().ClearForTests(); } } diff --git a/kotlin-native/runtime/src/mm/cpp/Memory.cpp b/kotlin-native/runtime/src/mm/cpp/Memory.cpp index ddab007b465..67e8ce2f928 100644 --- a/kotlin-native/runtime/src/mm/cpp/Memory.cpp +++ b/kotlin-native/runtime/src/mm/cpp/Memory.cpp @@ -263,6 +263,48 @@ extern "C" void Kotlin_native_internal_GC_collectCyclic(ObjHeader*) { ThrowIllegalArgumentException(); } +extern "C" void Kotlin_native_internal_GC_setThreshold(ObjHeader*, int32_t value) { + if (value < 0) { + ThrowIllegalArgumentException(); + } + mm::GlobalData::Instance().gc().SetThreshold(static_cast(value)); +} + +extern "C" int32_t Kotlin_native_internal_GC_getThreshold(ObjHeader*) { + auto threshold = mm::GlobalData::Instance().gc().GetThreshold(); + auto maxValue = std::numeric_limits::max(); + if (threshold > static_cast(maxValue)) { + return maxValue; + } + return static_cast(maxValue); +} + +extern "C" void Kotlin_native_internal_GC_setCollectCyclesThreshold(ObjHeader*, int64_t value) { + // TODO: Remove when legacy MM is gone. + ThrowIllegalArgumentException(); +} + +extern "C" int64_t Kotlin_native_internal_GC_getCollectCyclesThreshold(ObjHeader*) { + // TODO: Remove when legacy MM is gone. + ThrowIllegalArgumentException(); +} + +extern "C" void Kotlin_native_internal_GC_setThresholdAllocations(ObjHeader*, int64_t value) { + if (value < 0) { + ThrowIllegalArgumentException(); + } + mm::GlobalData::Instance().gc().SetAllocationThresholdBytes(static_cast(value)); +} + +extern "C" int64_t Kotlin_native_internal_GC_getThresholdAllocations(ObjHeader*) { + auto threshold = mm::GlobalData::Instance().gc().GetAllocationThresholdBytes(); + auto maxValue = std::numeric_limits::max(); + if (threshold > static_cast(maxValue)) { + return maxValue; + } + return static_cast(maxValue); +} + extern "C" OBJ_GETTER(Kotlin_native_internal_GC_detectCycles, ObjHeader*) { // TODO: Remove when legacy MM is gone. RETURN_OBJ(nullptr); diff --git a/kotlin-native/runtime/src/mm/cpp/Stubs.cpp b/kotlin-native/runtime/src/mm/cpp/Stubs.cpp index 9bd72a6b2a3..056020841d5 100644 --- a/kotlin-native/runtime/src/mm/cpp/Stubs.cpp +++ b/kotlin-native/runtime/src/mm/cpp/Stubs.cpp @@ -42,30 +42,6 @@ void Kotlin_native_internal_GC_start(ObjHeader*) { TODO(); } -void Kotlin_native_internal_GC_setThreshold(ObjHeader*, int32_t value) { - TODO(); -} - -int32_t Kotlin_native_internal_GC_getThreshold(ObjHeader*) { - TODO(); -} - -void Kotlin_native_internal_GC_setCollectCyclesThreshold(ObjHeader*, int64_t value) { - TODO(); -} - -int64_t Kotlin_native_internal_GC_getCollectCyclesThreshold(ObjHeader*) { - TODO(); -} - -void Kotlin_native_internal_GC_setThresholdAllocations(ObjHeader*, int64_t value) { - TODO(); -} - -int64_t Kotlin_native_internal_GC_getThresholdAllocations(ObjHeader*) { - TODO(); -} - void Kotlin_native_internal_GC_setTuneThreshold(ObjHeader*, int32_t value) { TODO(); } diff --git a/kotlin-native/runtime/src/mm/cpp/gc/NoOpGC.hpp b/kotlin-native/runtime/src/mm/cpp/gc/NoOpGC.hpp index aa7cce129a5..3adf33f7d4a 100644 --- a/kotlin-native/runtime/src/mm/cpp/gc/NoOpGC.hpp +++ b/kotlin-native/runtime/src/mm/cpp/gc/NoOpGC.hpp @@ -38,10 +38,18 @@ public: private: }; - NoOpGC() noexcept = default; + NoOpGC() noexcept {} ~NoOpGC() = default; + void SetThreshold(size_t value) noexcept { threshold_ = value; } + size_t GetThreshold() noexcept { return threshold_; } + + void SetAllocationThresholdBytes(size_t value) noexcept { allocationThresholdBytes_ = value; } + size_t GetAllocationThresholdBytes() noexcept { return allocationThresholdBytes_; } + private: + size_t threshold_ = 0; + size_t allocationThresholdBytes_ = 0; }; } // namespace mm diff --git a/kotlin-native/tools/scripts/repack_bundles.py b/kotlin-native/tools/scripts/repack_bundles.py new file mode 100755 index 00000000000..849dcbf9f0f --- /dev/null +++ b/kotlin-native/tools/scripts/repack_bundles.py @@ -0,0 +1,40 @@ +#!/usr/bin/python + +import sys +import os +import os.path +import shutil + +if len(sys.argv) != 2: + print('Usage: ' + sys.argv[0] + ' ') + sys.exit(0) + +kotlinVersion = sys.argv[1] +print('Repacking bundles for Kotlin/Native version ' + kotlinVersion) + +bundles = [f for f in os.listdir('.') if f.startswith('kotlin-native-prebuilt-') and (f.endswith('.tar.gz') or f.endswith('.zip')) and os.path.isfile(f)] +print('Found ' + str(len(bundles)) + ' bundle files to repack: ' + ', '.join(bundles)) + +for bundle in bundles: + print('') + print('Unpacking ' + bundle) + unpackCommand = 'unzip -qq' if bundle.endswith('.zip') else 'tar -xzf' + os.system(unpackCommand + ' ' + bundle) + + extractedDir = bundle.rstrip('.tar.gz').rstrip('.zip') + renamedDir = extractedDir.replace('-prebuilt-', '-') + print('Renaming ' + extractedDir + ' to ' + renamedDir) + os.rename(extractedDir, renamedDir) + + repackedBundle = renamedDir + ('.zip' if bundle.endswith('.zip') else '.tar.gz') + print('Packing ' + repackedBundle) + packCommand = 'zip -qq -r' if bundle.endswith('.zip') else 'COPYFILE_DISABLE=true tar -czf' + os.system(packCommand + ' ' + repackedBundle + ' ' + renamedDir) + shutil.rmtree(renamedDir) + + print('Calculating SHA256') + shaCommand = 'shasum -a 256' + os.system(shaCommand + ' ' + repackedBundle + ' > ' + repackedBundle + '.sha256') + +print('') +print('Done.') diff --git a/libraries/scripting/intellij/src/kotlin/script/experimental/intellij/scriptConfigurationTools.kt b/libraries/scripting/intellij/src/kotlin/script/experimental/intellij/scriptConfigurationTools.kt new file mode 100644 index 00000000000..3b68b924539 --- /dev/null +++ b/libraries/scripting/intellij/src/kotlin/script/experimental/intellij/scriptConfigurationTools.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package kotlin.script.experimental.intellij + +import com.intellij.openapi.extensions.ExtensionPointName +import com.intellij.openapi.extensions.Extensions +import com.intellij.psi.PsiFile + +/** + * Force reloading the script definition associated with the passed [scriptFile] in the Kotlin plugin + * + * [updateEditorWithoutNotification] controls whether the update of the indexes and highlighting of the script files + * based on the reloaded definition should be reloaded automatically or using notification and explicit reload action + */ +fun reloadScriptConfiguration(scriptFile: PsiFile, updateEditorWithoutNotification: Boolean = false) { + val extensions = Extensions.getArea(scriptFile.project).getExtensionPoint(IdeScriptConfigurationControlFacade.EP_NAME).extensions + for (extension in extensions) { + extension.reloadScriptConfiguration(scriptFile, updateEditorWithoutNotification) + } +} + +/** + * The IntelliJ extension point needed for the [reloadScriptConfiguration] function. Should not be used directly. + */ +interface IdeScriptConfigurationControlFacade { + + fun reloadScriptConfiguration(scriptFile: PsiFile, updateEditorWithoutNotification: Boolean = false) + + companion object { + val EP_NAME: ExtensionPointName = + ExtensionPointName.create("org.jetbrains.kotlin.ideScriptConfigurationControlFacade") + } +} diff --git a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt index 90d5bab0b97..5df15802764 100644 --- a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt +++ b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt @@ -14,6 +14,8 @@ import kotlin.script.experimental.api.* import kotlin.script.experimental.host.toScriptSource import kotlin.script.experimental.jvm.BasicJvmReplEvaluator import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration +import kotlin.script.experimental.jvm.updateClasspath +import kotlin.script.experimental.jvm.util.classpathFromClass class ReplTest : TestCase() { @@ -191,6 +193,44 @@ class ReplTest : TestCase() { ) } + @Test + fun testAddNewAnnotationHandler() { + val replCompiler = KJvmReplCompilerBase.create(defaultJvmScriptingHostConfiguration) + val replEvaluator = BasicJvmReplEvaluator() + val compilationConfiguration = ScriptCompilationConfiguration().with { + updateClasspath(classpathFromClass()) + } + val evaluationConfiguration = ScriptEvaluationConfiguration() + + val res0 = runBlocking { + replCompiler.compile("1".toScriptSource("Line_0.kts"), compilationConfiguration).onSuccess { + replEvaluator.eval(it, evaluationConfiguration) + } + } + assertTrue("Expecting 1 got $res0", res0 is ResultWithDiagnostics.Success && (res0.value.get().result as ResultValue.Value).value == 1) + + var handlerInvoked = false + + val compilationConfiguration2 = compilationConfiguration.with { + refineConfiguration { +// defaultImports(NewAnn::class) // TODO: fix support for default imports + onAnnotations { + handlerInvoked = true + it.compilationConfiguration.asSuccess() + } + } + } + + val res1 = runBlocking { + replCompiler.compile("@file:kotlin.script.experimental.jvmhost.test.NewAnn()\n2".toScriptSource("Line_1.kts"), compilationConfiguration2).onSuccess { + replEvaluator.eval(it, evaluationConfiguration) + } + } + assertTrue("Expecting 2 got $res1", res1 is ResultWithDiagnostics.Success && (res1.value.get().result as ResultValue.Value).value == 2) + + assertTrue("Refinement handler on annotation is not invoked", handlerInvoked) + } + companion object { private fun evaluateInRepl( snippets: Sequence, @@ -300,3 +340,6 @@ class ReplTest : TestCase() { ) } } + +@Target(AnnotationTarget.FILE) +annotation class NewAnn diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts index 48ba118ee31..7530f173133 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/build.gradle.kts @@ -45,7 +45,7 @@ dependencies { // Workaround for missing transitive import of the common(project `kotlin-test-common` // for `kotlin-test-jvm` into the IDE: testCompileOnly(project(":kotlin-test:kotlin-test-common")) { isTransitive = false } - testCompileOnly("org.jetbrains.intellij.deps:asm-all:9.0") + compileOnly(intellijDep()) { includeJars("asm-all") } } // Aapt2 from Android Gradle Plugin 3.2 and below does not handle long paths on Windows. diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt index a7c111b0b05..a92ebadc3c7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinDependenciesManagement.kt @@ -41,7 +41,6 @@ import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName internal fun customizeKotlinDependencies(project: Project) { configureStdlibDefaultDependency(project) - configureKotlinTestDependencies(project) configureKotlinTestDependency(project) configureDefaultVersionsResolutionStrategy(project) } @@ -287,113 +286,6 @@ private fun kotlinTestCapabilityForJvmSourceSet(project: Project, kotlinSourceSe internal const val KOTLIN_TEST_ROOT_MODULE_NAME = "kotlin-test" - -internal fun configureKotlinTestDependencies(project: Project) { - fun isKotlinTestMultiplatformDependency(dependency: Dependency) = - dependency.group == KOTLIN_MODULE_GROUP && dependency.name == KOTLIN_TEST_MULTIPLATFORM_MODULE_NAME - - KotlinDependencyScope.values().forEach { scope -> - val versionOrNullBySourceSet = mutableMapOf() - - project.kotlinExtension.sourceSets.all { kotlinSourceSet -> - val configuration = project.sourceSetDependencyConfigurationByScope(kotlinSourceSet, scope) - var finalizingDependencies = false - - configuration.dependencies.matching(::isKotlinTestMultiplatformDependency).apply { - firstOrNull()?.let { versionOrNullBySourceSet[kotlinSourceSet] = it.version } - whenObjectRemoved { - if (!finalizingDependencies && !any()) - versionOrNullBySourceSet.remove(kotlinSourceSet) - } - whenObjectAdded { item -> - versionOrNullBySourceSet[kotlinSourceSet] = item.version - } - } - - project.tryWithDependenciesIfUnresolved(configuration) { dependencies -> - val parentOrOwnVersions: List = - kotlinSourceSet.getSourceSetHierarchy().filter(versionOrNullBySourceSet::contains).map(versionOrNullBySourceSet::get) - - finalizingDependencies = true - - parentOrOwnVersions.distinct().forEach { version -> // add dependencies with each version and let Gradle disambiguate them - val dependenciesToAdd = kotlinTestDependenciesForSourceSet(project, kotlinSourceSet, version) - dependenciesToAdd.filterIsInstance().forEach { - if (it.version == null) { - it.version { constraint -> constraint.require(project.kotlinExtension.coreLibrariesVersion) } - } - } - dependencies.addAll(dependenciesToAdd) - dependencies.removeIf(::isKotlinTestMultiplatformDependency) - } - } - } - } -} - -private fun kotlinTestDependenciesForSourceSet(project: Project, kotlinSourceSet: KotlinSourceSet, version: String?): List { - val compilations = CompilationSourceSetUtil.compilationsBySourceSets(project).getValue(kotlinSourceSet) - .filter { it.target !is KotlinMetadataTarget } - - val platformTypes = compilations.mapTo(mutableSetOf()) { it.platformType } - - return when { - platformTypes.isEmpty() -> emptyList() - setOf(KotlinPlatformType.jvm, KotlinPlatformType.androidJvm).containsAll(platformTypes) -> listOf( - kotlinTestDependenciesForJvm(project, compilations, version) - ) - platformTypes.singleOrNull() == KotlinPlatformType.js -> listOf( - project.kotlinDependency("kotlin-test-js", version) - ) - platformTypes.singleOrNull() == KotlinPlatformType.native -> emptyList() - else -> listOf( - project.kotlinDependency("kotlin-test-common", version), - project.kotlinDependency("kotlin-test-annotations-common", version) - ) - } -} - -internal const val KOTLIN_TEST_MULTIPLATFORM_MODULE_NAME = "kotlin-test-multiplatform" - -private fun Project.kotlinDependency(moduleName: String, versionOrNull: String?) = - project.dependencies.create("$KOTLIN_MODULE_GROUP:$moduleName${versionOrNull?.prependIndent(":").orEmpty()}") - -private fun kotlinTestDependenciesForJvm(project: Project, compilations: Iterable>, version: String?): Dependency { - val testTaskLists: List?> = compilations.map { compilation -> - val target = compilation.target - when { - target is KotlinTargetWithTests<*, *> -> - target.findTestRunsByCompilation(compilation)?.filterIsInstance>()?.map { it.executionTask.get() } - target is KotlinWithJavaTarget<*> -> - if (compilation.name == KotlinCompilation.TEST_COMPILATION_NAME) - project.locateTask(target.testTaskName)?.get()?.let(::listOf) - else null - compilation is KotlinJvmAndroidCompilation -> when (compilation.androidVariant) { - is UnitTestVariant -> - project.locateTask(lowerCamelCaseName("test", compilation.androidVariant.name))?.get()?.let(::listOf) - is TestVariant -> (compilation.androidVariant as TestVariant).connectedInstrumentTest?.let(::listOf) - else -> null - } - else -> null - } - } - if (null in testTaskLists) { - return project.kotlinDependency("kotlin-test", version) - } - val testTasks = testTaskLists.flatMap { checkNotNull(it) } - val frameworks = testTasks.mapTo(mutableSetOf()) { testTask -> - when (testTask) { - is Test -> testFrameworkOf(testTask) - else -> // Android connected test tasks don't inherit from Test, but we use JUnit for them - KotlinTestJvmFramework.junit - } - } - return when { - frameworks.size > 1 -> project.kotlinDependency("kotlin-test", version) - else -> project.kotlinDependency("kotlin-test-${frameworks.single().name}", version) - } -} - private enum class KotlinTestJvmFramework { junit, testng, junit5 } @@ -417,6 +309,9 @@ private fun KotlinTargetWithTests<*, *>.findTestRunsByCompilation(byCompilation: } //endregion +private fun Project.kotlinDependency(moduleName: String, versionOrNull: String?) = + project.dependencies.create("$KOTLIN_MODULE_GROUP:$moduleName${versionOrNull?.prependIndent(":").orEmpty()}") + private fun Project.tryWithDependenciesIfUnresolved(configuration: Configuration, action: (DependencySet) -> Unit) { fun reportAlreadyResolved() { logger.info("Could not setup Kotlin-specific dependencies for $configuration as it is already resolved") diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt index e6c23f37ad8..c10b141ae11 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kapt/KaptWithoutKotlincTask.kt @@ -140,7 +140,7 @@ abstract class KaptWithoutKotlincTask @Inject constructor(private val workerExec internal fun getValue(propertyName: String): String? = if (isGradleVersionAtLeast(6, 5)) { - providers.systemProperty(propertyName).forUseAtConfigurationTime().orNull + providers.gradleProperty(propertyName).forUseAtConfigurationTime().orNull } else { project.findProperty(propertyName) as String? } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/CommonizerParameters.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/CommonizerParameters.kt index 95b4fc4d980..32c6f2746b7 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/CommonizerParameters.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/CommonizerParameters.kt @@ -38,14 +38,17 @@ class CommonizerParameters( _resultsConsumer = value } - fun hasAnythingToCommonize(): Boolean { - if (_targetProviders.size < 2) return false // too few targets + fun getCommonModuleNames(): Set { + if (_targetProviders.size < 2) return emptySet() // too few targets val allModuleNames: List> = _targetProviders.values.map { targetProvider -> targetProvider.modulesProvider.loadModuleInfos().mapTo(HashSet()) { it.name } } - val commonModuleNames: Set = allModuleNames.reduce { a, b -> a intersect b } - return commonModuleNames.isNotEmpty() // there are modules that are present in every target + return allModuleNames.reduce { a, b -> a intersect b } // there are modules that are present in every target + } + + fun hasAnythingToCommonize(): Boolean { + return getCommonModuleNames().isNotEmpty() } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirAnnotation.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirAnnotation.kt index e8a042ff233..f7711863c73 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirAnnotation.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirAnnotation.kt @@ -5,11 +5,8 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.constants.ConstantValue - interface CirAnnotation { val type: CirClassType - val constantValueArguments: Map> - val annotationValueArguments: Map + val constantValueArguments: Map> + val annotationValueArguments: Map } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirClass.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirClass.kt index e9be4f7c01d..b7078dfcb64 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirClass.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirClass.kt @@ -5,14 +5,9 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.name.Name - -interface CirClass : CirClassifier, CirHasModality { - val kind: ClassKind - var companion: Name? // null means no companion object +interface CirClass : CirClassifier, CirContainingClass { + var companion: CirName? // null means no companion object val isCompanion: Boolean - val isData: Boolean val isInline: Boolean val isInner: Boolean val isExternal: Boolean diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirClassConstructor.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirClassConstructor.kt index b241f85e641..4f7b62bff74 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirClassConstructor.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirClassConstructor.kt @@ -14,5 +14,5 @@ interface CirClassConstructor : CirCallableMemberWithParameters { val isPrimary: Boolean - override val containingClassDetails: CirContainingClassDetails // non-nullable + override val containingClass: CirContainingClass // non-nullable } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirConstantValue.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirConstantValue.kt new file mode 100644 index 00000000000..959687906e0 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirConstantValue.kt @@ -0,0 +1,38 @@ +/* + * 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.descriptors.commonizer.cir + +sealed class CirConstantValue { + abstract val value: T + + data class StringValue(override val value: String) : CirConstantValue() + data class CharValue(override val value: Char) : CirConstantValue() + + data class ByteValue(override val value: Byte) : CirConstantValue() + data class ShortValue(override val value: Short) : CirConstantValue() + data class IntValue(override val value: Int) : CirConstantValue() + data class LongValue(override val value: Long) : CirConstantValue() + + data class UByteValue(override val value: Byte) : CirConstantValue() + data class UShortValue(override val value: Short) : CirConstantValue() + data class UIntValue(override val value: Int) : CirConstantValue() + data class ULongValue(override val value: Long) : CirConstantValue() + + data class FloatValue(override val value: Float) : CirConstantValue() + data class DoubleValue(override val value: Double) : CirConstantValue() + data class BooleanValue(override val value: Boolean) : CirConstantValue() + + data class EnumValue(val enumClassId: CirEntityId, val enumEntryName: CirName) : CirConstantValue() { + override val value: String = "${enumClassId}.${enumEntryName}" + } + + data class ArrayValue(override val value: List>) : CirConstantValue>>() + + object NullValue : CirConstantValue() { + override val value: Void? get() = null + override fun toString() = "NullValue(value=null)" + } +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirContainingClassDetails.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirContainingClassDetails.kt deleted file mode 100644 index 1df89347124..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirContainingClassDetails.kt +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.descriptors.commonizer.cir - -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.descriptors.Modality - -data class CirContainingClassDetails( - val kind: ClassKind, - override val modality: Modality, - val isData: Boolean -) : CirHasModality diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirDeclaration.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirDeclaration.kt index b8eef7eb2b6..18ab45d73bd 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirDeclaration.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirDeclaration.kt @@ -6,8 +6,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name /** * An intermediate representation of [DeclarationDescriptor]s for commonization purposes. @@ -17,7 +15,7 @@ import org.jetbrains.kotlin.name.Name * - [CirTypeAlias] - [TypeAliasDescriptor] * - [CirFunction] - [SimpleFunctionDescriptor] * - [CirProperty] - [PropertyDescriptor] - * - [CirPackage] - union of multiple [PackageFragmentDescriptor]s with the same [FqName] contributed by commonized [ModuleDescriptor]s + * - [CirPackage] - union of multiple [PackageFragmentDescriptor]s with the same FQ name contributed by commonized [ModuleDescriptor]s * - [CirModule] - [ModuleDescriptor] * - [CirRoot] - the root of the whole Commonizer IR tree */ @@ -28,11 +26,7 @@ interface CirHasAnnotations { } interface CirHasName { - val name: Name -} - -interface CirHasFqName { - val fqName: FqName + val name: CirName } interface CirHasVisibility { @@ -44,7 +38,15 @@ interface CirHasModality { } interface CirMaybeCallableMemberOfClass { - val containingClassDetails: CirContainingClassDetails? // null assumes no containing class + val containingClass: CirContainingClass? // null assumes no containing class +} + +/** + * A subset of containing [CirClass] visible to such class members as [CirFunction], [CirProperty] and [CirClassConstructor]. + */ +interface CirContainingClass : CirHasModality { + val kind: ClassKind + val isData: Boolean } interface CirHasTypeParameters { diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirFunctionOrProperty.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirFunctionOrProperty.kt index e407bf3129e..02b9f3907d4 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirFunctionOrProperty.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirFunctionOrProperty.kt @@ -26,5 +26,5 @@ interface CirFunctionOrProperty : fun isVirtual(): Boolean = visibility != DescriptorVisibilities.PRIVATE && modality != Modality.FINAL - && !(containingClassDetails?.modality == Modality.FINAL && containingClassDetails?.kind != ClassKind.ENUM_CLASS) + && !(containingClass?.modality == Modality.FINAL && containingClass?.kind != ClassKind.ENUM_CLASS) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirName.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirName.kt new file mode 100644 index 00000000000..02a2bb15d54 --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirName.kt @@ -0,0 +1,152 @@ +/* + * 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.descriptors.commonizer.cir + +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName.Companion.create +import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode +import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner +import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name + +/** + * A representation of a simple name. Examples: + * 1) name of class without package and outer class name (if this is nested class). + * 2) name of class member such as property or function. + * 3) name of type parameter, name of value parameter. + * + * New instances are created via [create] method which encapsulates interning to avoid duplicated instances. + */ +class CirName private constructor(val name: String) { + override fun equals(other: Any?): Boolean = other is CirName && (other === this || other.name == name) + override fun hashCode(): Int = hashCode(name) + override fun toString(): String = name + + fun toStrippedString(): String = name.removeSurrounding("<", ">") + + companion object { + fun create(name: String): CirName = interner.intern(CirName(name)) + fun create(name: Name): CirName = create(name.asString()) + + private val interner = Interner() + } +} + +/** + * A representation of a fully-qualified package name. + * + * New instances are created via [create] method which encapsulates interning to avoid duplicated instances. + */ +class CirPackageName private constructor(val segments: Array) { + override fun equals(other: Any?): Boolean = other is CirPackageName && (other === this || other.segments.contentEquals(segments)) + override fun hashCode(): Int = hashCode(segments) + override fun toString(): String = segments.joinToString(".") + + fun toMetadataString(): String = segments.joinToString("/") + + fun isRoot(): Boolean = segments.isEmpty() + + fun startsWith(other: CirPackageName): Boolean { + return when { + other.isRoot() -> true + other.segments.size > segments.size -> false + else -> { + for (i in other.segments.indices) { + if (segments[i] != other.segments[i]) return false + } + true + } + } + } + + companion object { + val ROOT: CirPackageName = CirPackageName(emptyArray()) + + fun create(packageFqName: String): CirPackageName = create(splitComplexNameToArray(packageFqName, ".") { it }) + fun create(packageFqName: FqName): CirPackageName = if (packageFqName.isRoot) ROOT else create(packageFqName.asString()) + fun create(segments: Array): CirPackageName = if (segments.isEmpty()) ROOT else interner.intern(CirPackageName(segments)) + + private val interner = Interner() + + init { + interner.intern(ROOT) + } + } +} + +/** + * A representation of a fully-qualified classifier ID which includes [CirPackageName] and few [CirName] elements + * to uniquely address any class or type alias. Outer classes and type aliases always have single element + * in [relativeNameSegments]. While nested classes have more than one element in [relativeNameSegments] (the amount + * of elements depends on the nesting depth). + * + * New instances are created via [create] method which encapsulates interning to avoid duplicated instances. + */ +class CirEntityId private constructor(val packageName: CirPackageName, val relativeNameSegments: Array) { + override fun equals(other: Any?): Boolean = when { + other === this -> true + other is CirEntityId -> other.packageName == packageName && other.relativeNameSegments.contentEquals(relativeNameSegments) + else -> false + } + + override fun hashCode(): Int = hashCode(packageName).appendHashCode(relativeNameSegments) + + override fun toString(): String = buildString { + packageName.segments.joinTo(this, "/") + append('/') + relativeNameSegments.joinTo(this, ".") + } + + val isNestedEntity: Boolean get() = relativeNameSegments.size > 1 + + fun createNestedEntityId(entityName: CirName): CirEntityId = create(packageName, relativeNameSegments + entityName) + + fun getParentEntityId(): CirEntityId? = + if (isNestedEntity) create(packageName, relativeNameSegments.copyOfRange(0, relativeNameSegments.size - 1)) else null + + companion object { + fun create(entityId: String): CirEntityId { + val rawPackageName: String + val rawRelativeName: String + when (val index = entityId.lastIndexOf('/')) { + -1 -> { + rawPackageName = "" + rawRelativeName = entityId + } + else -> { + rawPackageName = entityId.substring(0, index) + rawRelativeName = entityId.substring(index + 1) + } + } + + val packageName = CirPackageName.create(splitComplexNameToArray(rawPackageName, "/") { it }) + val relativeNameSegments = splitComplexNameToArray(rawRelativeName, ".", CirName::create) + + return create(packageName, relativeNameSegments) + } + + fun create(classifierId: ClassId): CirEntityId { + val packageName = CirPackageName.create(classifierId.packageFqName) + val relativeNameSegments = splitComplexNameToArray(classifierId.relativeClassName.asString(), ".", CirName::create) + + return create(packageName, relativeNameSegments) + } + + fun create(packageName: CirPackageName, relativeName: CirName): CirEntityId = create(packageName, arrayOf(relativeName)) + + fun create(packageName: CirPackageName, relativeNameSegments: Array): CirEntityId = + interner.intern(CirEntityId(packageName, relativeNameSegments)) + + private val interner = Interner() + } +} + +private inline fun splitComplexNameToArray(complexName: String, delimiter: String, transform: (String) -> T): Array { + if (complexName.isEmpty()) return emptyArray() + val segments = complexName.split(delimiter) + return Array(segments.size) { index -> transform(segments[index]) } +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirPackage.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirPackage.kt index 54586c10a27..7ab72b86677 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirPackage.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirPackage.kt @@ -5,4 +5,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir -interface CirPackage : CirDeclaration, CirHasFqName +interface CirPackage : CirDeclaration { + val packageName: CirPackageName +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirProperty.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirProperty.kt index 9ffd3065b12..81099e96b84 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirProperty.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirProperty.kt @@ -5,8 +5,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir -import org.jetbrains.kotlin.resolve.constants.ConstantValue - interface CirProperty : CirFunctionOrProperty, CirLiftedUpDeclaration { val isExternal: Boolean val isVar: Boolean @@ -17,5 +15,5 @@ interface CirProperty : CirFunctionOrProperty, CirLiftedUpDeclaration { val setter: CirPropertySetter? val backingFieldAnnotations: List? // null assumes no backing field val delegateFieldAnnotations: List? // null assumes no backing field - val compileTimeInitializer: ConstantValue<*>? + val compileTimeInitializer: CirConstantValue<*>? } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirType.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirType.kt index 043ee6dd38b..e3644dee6a8 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirType.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/CirType.kt @@ -5,7 +5,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.types.AbbreviatedType import org.jetbrains.kotlin.types.Variance @@ -58,13 +57,13 @@ data class CirTypeParameterType( } sealed class CirClassOrTypeAliasType : CirSimpleType() { - abstract val classifierId: ClassId + abstract val classifierId: CirEntityId abstract val arguments: List override fun appendDescriptionTo(builder: StringBuilder) = appendDescriptionTo(builder, shortNameOnly = false) protected open fun appendDescriptionTo(builder: StringBuilder, shortNameOnly: Boolean) { - builder.append(if (shortNameOnly) classifierId.relativeClassName.shortName().asString() else classifierId.asString()) + builder.append(if (shortNameOnly) classifierId.relativeNameSegments.last() else classifierId) if (arguments.isNotEmpty()) arguments.joinTo(builder, prefix = "<", postfix = ">") super.appendDescriptionTo(builder) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirAnnotationFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirAnnotationFactory.kt index 4bf9a745fb9..250fe79d212 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirAnnotationFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirAnnotationFactory.kt @@ -9,11 +9,11 @@ import gnu.trove.THashMap import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirAnnotationImpl import org.jetbrains.kotlin.descriptors.commonizer.utils.* -import org.jetbrains.kotlin.descriptors.commonizer.utils.checkConstantSupportedInCommonization import org.jetbrains.kotlin.descriptors.commonizer.utils.compact -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.constants.AnnotationValue import org.jetbrains.kotlin.resolve.constants.ConstantValue @@ -28,21 +28,19 @@ object CirAnnotationFactory { if (allValueArguments.isEmpty()) return create(type = type, constantValueArguments = emptyMap(), annotationValueArguments = emptyMap()) - val constantValueArguments: MutableMap> = THashMap(allValueArguments.size) - val annotationValueArguments: MutableMap = THashMap(allValueArguments.size) + val constantValueArguments: MutableMap> = THashMap(allValueArguments.size) + val annotationValueArguments: MutableMap = THashMap(allValueArguments.size) allValueArguments.forEach { (name, constantValue) -> - checkConstantSupportedInCommonization( - constantValue = constantValue, - constantName = name, - owner = source, - allowAnnotationValues = true - ) - + val cirName = CirName.create(name) if (constantValue is AnnotationValue) - annotationValueArguments[name.intern()] = create(source = constantValue.value) + annotationValueArguments[cirName] = create(source = constantValue.value) else - constantValueArguments[name.intern()] = constantValue + constantValueArguments[cirName] = CirConstantValueFactory.createSafely( + constantValue = constantValue, + constantName = cirName, + owner = source, + ) } return create( @@ -54,8 +52,8 @@ object CirAnnotationFactory { fun create( type: CirClassType, - constantValueArguments: Map>, - annotationValueArguments: Map + constantValueArguments: Map>, + annotationValueArguments: Map ): CirAnnotation { return interner.intern( CirAnnotationImpl( diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirClassConstructorFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirClassConstructorFactory.kt index b9445dc44ad..d25de09ffdc 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirClassConstructorFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirClassConstructorFactory.kt @@ -14,7 +14,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMapNotNull object CirClassConstructorFactory { - fun create(source: ClassConstructorDescriptor): CirClassConstructor { + fun create(source: ClassConstructorDescriptor, containingClass: CirContainingClass): CirClassConstructor { check(source.kind == CallableMemberDescriptor.Kind.DECLARATION) { "Unexpected ${CallableMemberDescriptor.Kind::class.java} for class constructor $source, ${source::class.java}: ${source.kind}" } @@ -26,7 +26,7 @@ object CirClassConstructorFactory { typeParameter.takeIf { it.containingDeclaration == source }?.let(CirTypeParameterFactory::create) }, visibility = source.visibility, - containingClassDetails = CirContainingClassDetailsFactory.create(source), + containingClass = containingClass, valueParameters = source.valueParameters.compactMap(CirValueParameterFactory::create), hasStableParameterNames = source.hasStableParameterNames(), isPrimary = source.isPrimary @@ -38,7 +38,7 @@ object CirClassConstructorFactory { annotations: List, typeParameters: List, visibility: DescriptorVisibility, - containingClassDetails: CirContainingClassDetails, + containingClass: CirContainingClass, valueParameters: List, hasStableParameterNames: Boolean, isPrimary: Boolean @@ -47,7 +47,7 @@ object CirClassConstructorFactory { annotations = annotations, typeParameters = typeParameters, visibility = visibility, - containingClassDetails = containingClassDetails, + containingClass = containingClass, valueParameters = valueParameters, hasStableParameterNames = hasStableParameterNames, isPrimary = isPrimary diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirClassFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirClassFactory.kt index 29fb91d6889..642311b7fac 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirClassFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirClassFactory.kt @@ -11,22 +11,21 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeParameter import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassImpl import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.isInlineClass object CirClassFactory { fun create(source: ClassDescriptor): CirClass = create( annotations = source.annotations.compactMap(CirAnnotationFactory::create), - name = source.name.intern(), + name = CirName.create(source.name), typeParameters = source.declaredTypeParameters.compactMap(CirTypeParameterFactory::create), visibility = source.visibility, modality = source.modality, kind = source.kind, - companion = source.companionObjectDescriptor?.name?.intern(), + companion = source.companionObjectDescriptor?.name?.let(CirName::create), isCompanion = source.isCompanionObject, isData = source.isData, isInline = source.isInlineClass(), @@ -39,12 +38,12 @@ object CirClassFactory { @Suppress("NOTHING_TO_INLINE") inline fun create( annotations: List, - name: Name, + name: CirName, typeParameters: List, visibility: DescriptorVisibility, modality: Modality, kind: ClassKind, - companion: Name?, + companion: CirName?, isCompanion: Boolean, isData: Boolean, isInline: Boolean, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirConstantValueFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirConstantValueFactory.kt new file mode 100644 index 00000000000..250ffa871af --- /dev/null +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirConstantValueFactory.kt @@ -0,0 +1,61 @@ +/* + * 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.descriptors.commonizer.cir.factory + +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName +import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMapIndexed +import org.jetbrains.kotlin.resolve.constants.* + +object CirConstantValueFactory { + fun createSafely( + constantValue: ConstantValue<*>, + constantName: CirName? = null, + owner: Any, + ): CirConstantValue<*> = createSafely( + constantValue = constantValue, + location = { "${owner::class.java}, $owner" + constantName?.toString()?.let { "[$it]" } } + ) + + private fun createSafely( + constantValue: ConstantValue<*>, + location: () -> String + ): CirConstantValue<*> = when (constantValue) { + is StringValue -> CirConstantValue.StringValue(constantValue.value) + is CharValue -> CirConstantValue.CharValue(constantValue.value) + + is ByteValue -> CirConstantValue.ByteValue(constantValue.value) + is ShortValue -> CirConstantValue.ShortValue(constantValue.value) + is IntValue -> CirConstantValue.IntValue(constantValue.value) + is LongValue -> CirConstantValue.LongValue(constantValue.value) + + is UByteValue -> CirConstantValue.UByteValue(constantValue.value) + is UShortValue -> CirConstantValue.UShortValue(constantValue.value) + is UIntValue -> CirConstantValue.UIntValue(constantValue.value) + is ULongValue -> CirConstantValue.ULongValue(constantValue.value) + + is FloatValue -> CirConstantValue.FloatValue(constantValue.value) + is DoubleValue -> CirConstantValue.DoubleValue(constantValue.value) + is BooleanValue -> CirConstantValue.BooleanValue(constantValue.value) + + is EnumValue -> CirConstantValue.EnumValue( + CirEntityId.create(constantValue.enumClassId), + CirName.create(constantValue.enumEntryName) + ) + is NullValue -> CirConstantValue.NullValue + + is ArrayValue -> CirConstantValue.ArrayValue( + constantValue.value.compactMapIndexed { index, innerConstantValue -> + createSafely( + constantValue = innerConstantValue, + location = { "${location()}[$index]" } + ) + }) + + else -> error("Unsupported const value type: ${constantValue::class.java}, $constantValue at ${location()}") + } +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirContainingClassDetailsFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirContainingClassDetailsFactory.kt deleted file mode 100644 index b493a70c9ec..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirContainingClassDetailsFactory.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.descriptors.commonizer.cir.factory - -import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirContainingClassDetails -import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner - -object CirContainingClassDetailsFactory { - private val interner = Interner() - - // speed optimization - val DOES_NOT_MATTER: CirContainingClassDetails = create( - kind = ClassKind.CLASS, - modality = Modality.FINAL, - isData = false - ) - - fun create(source: ClassConstructorDescriptor): CirContainingClassDetails = doCreate(source.containingDeclaration) - - fun create(source: CallableMemberDescriptor): CirContainingClassDetails? { - val containingClass: ClassDescriptor = source.containingDeclaration as? ClassDescriptor ?: return null - return doCreate(containingClass) - } - - @Suppress("NOTHING_TO_INLINE") - private inline fun doCreate(containingClass: ClassDescriptor): CirContainingClassDetails = create( - kind = containingClass.kind, - modality = containingClass.modality, - isData = containingClass.isData - ) - - fun create( - kind: ClassKind, - modality: Modality, - isData: Boolean - ): CirContainingClassDetails { - return interner.intern( - CirContainingClassDetails( - kind = kind, - modality = modality, - isData = isData - ) - ) - } -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirFunctionFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirFunctionFactory.kt index ff0f5331d16..1b22cc3e3b9 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirFunctionFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirFunctionFactory.kt @@ -9,17 +9,15 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.commonizer.cir.* import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirFunctionImpl import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern -import org.jetbrains.kotlin.name.Name object CirFunctionFactory { - fun create(source: SimpleFunctionDescriptor): CirFunction = create( + fun create(source: SimpleFunctionDescriptor, containingClass: CirContainingClass?): CirFunction = create( annotations = source.annotations.compactMap(CirAnnotationFactory::create), - name = source.name.intern(), + name = CirName.create(source.name), typeParameters = source.typeParameters.compactMap(CirTypeParameterFactory::create), visibility = source.visibility, modality = source.modality, - containingClassDetails = CirContainingClassDetailsFactory.create(source), + containingClass = containingClass, valueParameters = source.valueParameters.compactMap(CirValueParameterFactory::create), hasStableParameterNames = source.hasStableParameterNames(), extensionReceiver = source.extensionReceiverParameter?.let(CirExtensionReceiverFactory::create), @@ -31,11 +29,11 @@ object CirFunctionFactory { @Suppress("NOTHING_TO_INLINE") inline fun create( annotations: List, - name: Name, + name: CirName, typeParameters: List, visibility: DescriptorVisibility, modality: Modality, - containingClassDetails: CirContainingClassDetails?, + containingClass: CirContainingClass?, valueParameters: List, hasStableParameterNames: Boolean, extensionReceiver: CirExtensionReceiver?, @@ -49,7 +47,7 @@ object CirFunctionFactory { typeParameters = typeParameters, visibility = visibility, modality = modality, - containingClassDetails = containingClassDetails, + containingClass = containingClass, valueParameters = valueParameters, hasStableParameterNames = hasStableParameterNames, extensionReceiver = extensionReceiver, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirModuleFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirModuleFactory.kt index da0e8d6ca31..9f1071b08d3 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirModuleFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirModuleFactory.kt @@ -5,14 +5,9 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.factory -import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirModule +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirModuleImpl -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern -import org.jetbrains.kotlin.name.Name object CirModuleFactory { - fun create(source: ModuleDescriptor): CirModule = create(source.name.intern()) - - fun create(name: Name) = CirModuleImpl(name) + fun create(name: CirName) = CirModuleImpl(name) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirPackageFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirPackageFactory.kt index b7b2d1898ef..cdfcf857baa 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirPackageFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirPackageFactory.kt @@ -6,9 +6,9 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.factory import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackage +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirPackageImpl -import org.jetbrains.kotlin.name.FqName object CirPackageFactory { - fun create(fqName: FqName): CirPackage = CirPackageImpl(fqName) + fun create(packageName: CirPackageName): CirPackage = CirPackageImpl(packageName) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirPropertyFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirPropertyFactory.kt index c806528394e..86808b55fd7 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirPropertyFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirPropertyFactory.kt @@ -11,30 +11,24 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.commonizer.cir.* import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirPropertyImpl -import org.jetbrains.kotlin.descriptors.commonizer.utils.checkConstantSupportedInCommonization import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.constants.ConstantValue object CirPropertyFactory { - fun create(source: PropertyDescriptor): CirProperty { - val compileTimeInitializer: ConstantValue<*>? = source.compileTimeInitializer - if (compileTimeInitializer != null) { - checkConstantSupportedInCommonization( - constantValue = compileTimeInitializer, + fun create(source: PropertyDescriptor, containingClass: CirContainingClass?): CirProperty { + val compileTimeInitializer = source.compileTimeInitializer?.let { constantValue -> + CirConstantValueFactory.createSafely( + constantValue = constantValue, owner = source, - allowAnnotationValues = false ) } return create( annotations = source.annotations.compactMap(CirAnnotationFactory::create), - name = source.name.intern(), + name = CirName.create(source.name), typeParameters = source.typeParameters.compactMap(CirTypeParameterFactory::create), visibility = source.visibility, modality = source.modality, - containingClassDetails = CirContainingClassDetailsFactory.create(source), + containingClass = containingClass, isExternal = source.isExternal, extensionReceiver = source.extensionReceiverParameter?.let(CirExtensionReceiverFactory::create), returnType = CirTypeFactory.create(source.returnType!!), @@ -47,18 +41,18 @@ object CirPropertyFactory { setter = source.setter?.let(CirPropertySetterFactory::create), backingFieldAnnotations = source.backingField?.annotations?.compactMap(CirAnnotationFactory::create), delegateFieldAnnotations = source.delegateField?.annotations?.compactMap(CirAnnotationFactory::create), - compileTimeInitializer = source.compileTimeInitializer + compileTimeInitializer = compileTimeInitializer ) } @Suppress("NOTHING_TO_INLINE") inline fun create( annotations: List, - name: Name, + name: CirName, typeParameters: List, visibility: DescriptorVisibility, modality: Modality, - containingClassDetails: CirContainingClassDetails?, + containingClass: CirContainingClass?, isExternal: Boolean, extensionReceiver: CirExtensionReceiver?, returnType: CirType, @@ -71,7 +65,7 @@ object CirPropertyFactory { setter: CirPropertySetter?, backingFieldAnnotations: List?, delegateFieldAnnotations: List?, - compileTimeInitializer: ConstantValue<*>? + compileTimeInitializer: CirConstantValue<*>? ): CirProperty { return CirPropertyImpl( annotations = annotations, @@ -79,7 +73,7 @@ object CirPropertyFactory { typeParameters = typeParameters, visibility = visibility, modality = modality, - containingClassDetails = containingClassDetails, + containingClass = containingClass, isExternal = isExternal, extensionReceiver = extensionReceiver, returnType = returnType, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeAliasFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeAliasFactory.kt index bb4c3716fdb..7923348e8ec 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeAliasFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeAliasFactory.kt @@ -10,13 +10,11 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.commonizer.cir.* import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasImpl import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern -import org.jetbrains.kotlin.name.Name object CirTypeAliasFactory { fun create(source: TypeAliasDescriptor): CirTypeAlias = create( annotations = source.annotations.compactMap(CirAnnotationFactory::create), - name = source.name.intern(), + name = CirName.create(source.name), typeParameters = source.declaredTypeParameters.compactMap(CirTypeParameterFactory::create), visibility = source.visibility, underlyingType = CirTypeFactory.create(source.underlyingType, useAbbreviation = true) as CirClassOrTypeAliasType, @@ -26,7 +24,7 @@ object CirTypeAliasFactory { @Suppress("NOTHING_TO_INLINE") inline fun create( annotations: List, - name: Name, + name: CirName, typeParameters: List, visibility: DescriptorVisibility, underlyingType: CirClassOrTypeAliasType, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeFactory.kt index 688baeef93a..cda5e6b83db 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeFactory.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.descriptors.commonizer.cir.* import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassTypeImpl import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeAliasTypeImpl import org.jetbrains.kotlin.descriptors.commonizer.utils.* -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.types.* object CirTypeFactory { @@ -42,7 +41,7 @@ object CirTypeFactory { when (val classifierDescriptor = abbreviation.declarationDescriptor) { is TypeAliasDescriptor -> { return createTypeAliasType( - typeAliasId = classifierDescriptor.internedClassId, + typeAliasId = classifierDescriptor.classifierId, underlyingType = create(extractExpandedType(source), useAbbreviation = true) as CirClassOrTypeAliasType, arguments = createArguments(abbreviation.arguments, useAbbreviation = true), isMarkedNullable = abbreviation.isMarkedNullable @@ -70,7 +69,7 @@ object CirTypeFactory { val cirExpandedTypeWithProperNullability = if (source.isMarkedNullable) makeNullable(cirExpandedType) else cirExpandedType createTypeAliasType( - typeAliasId = classifierDescriptor.internedClassId, + typeAliasId = classifierDescriptor.classifierId, underlyingType = cirExpandedTypeWithProperNullability, arguments = createArguments(source.arguments, useAbbreviation = true), isMarkedNullable = source.isMarkedNullable @@ -82,7 +81,7 @@ object CirTypeFactory { } fun createClassType( - classId: ClassId, + classId: CirEntityId, outerType: CirClassType?, visibility: DescriptorVisibility, arguments: List, @@ -100,7 +99,7 @@ object CirTypeFactory { } fun createTypeAliasType( - typeAliasId: ClassId, + typeAliasId: CirEntityId, underlyingType: CirClassOrTypeAliasType, arguments: List, isMarkedNullable: Boolean @@ -170,7 +169,7 @@ object CirTypeFactory { } return createClassType( - classId = classDescriptor.internedClassId, + classId = classDescriptor.classifierId, outerType = outerType, visibility = classDescriptor.visibility, arguments = remainingArguments, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeParameterFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeParameterFactory.kt index ad6c008945e..aede18423eb 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeParameterFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirTypeParameterFactory.kt @@ -7,12 +7,11 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.factory import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeParameter import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirTypeParameterImpl import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.typeUtil.isNullableAny @@ -23,7 +22,7 @@ object CirTypeParameterFactory { return create( annotations = source.annotations.compactMap(CirAnnotationFactory::create), - name = source.name.intern(), + name = CirName.create(source.name), isReified = source.isReified, variance = source.variance, upperBounds = filteredUpperBounds.compactMap(CirTypeFactory::create) @@ -33,7 +32,7 @@ object CirTypeParameterFactory { @Suppress("NOTHING_TO_INLINE") inline fun create( annotations: List, - name: Name, + name: CirName, isReified: Boolean, variance: Variance, upperBounds: List diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirValueParameterFactory.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirValueParameterFactory.kt index 165e7df9e20..1525a481e81 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirValueParameterFactory.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/factory/CirValueParameterFactory.kt @@ -7,20 +7,19 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.factory import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType import org.jetbrains.kotlin.descriptors.commonizer.cir.CirValueParameter import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirValueParameterImpl import org.jetbrains.kotlin.descriptors.commonizer.utils.Interner import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern -import org.jetbrains.kotlin.name.Name object CirValueParameterFactory { private val interner = Interner() fun create(source: ValueParameterDescriptor): CirValueParameter = create( annotations = source.annotations.compactMap(CirAnnotationFactory::create), - name = source.name.intern(), + name = CirName.create(source.name), returnType = CirTypeFactory.create(source.returnType!!), varargElementType = source.varargElementType?.let(CirTypeFactory::create), declaresDefaultValue = source.declaresDefaultValue(), @@ -30,7 +29,7 @@ object CirValueParameterFactory { fun create( annotations: List, - name: Name, + name: CirName, returnType: CirType, varargElementType: CirType?, declaresDefaultValue: Boolean, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirAnnotationImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirAnnotationImpl.kt index 01c4ea35f9d..39f028635d8 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirAnnotationImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirAnnotationImpl.kt @@ -7,15 +7,15 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.constants.ConstantValue data class CirAnnotationImpl( override val type: CirClassType, - override val constantValueArguments: Map>, - override val annotationValueArguments: Map + override val constantValueArguments: Map>, + override val annotationValueArguments: Map ) : CirAnnotation { // See also org.jetbrains.kotlin.types.KotlinType.cachedHashCode private var cachedHashCode = 0 diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassConstructorImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassConstructorImpl.kt index a2406026584..90de9de82e1 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassConstructorImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassConstructorImpl.kt @@ -12,7 +12,7 @@ data class CirClassConstructorImpl( override val annotations: List, override val typeParameters: List, override val visibility: DescriptorVisibility, - override val containingClassDetails: CirContainingClassDetails, + override val containingClass: CirContainingClass, override var valueParameters: List, override var hasStableParameterNames: Boolean, override val isPrimary: Boolean diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassImpl.kt index 49dd69552ad..84827c18075 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassImpl.kt @@ -8,20 +8,16 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibility -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeParameter -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.descriptors.commonizer.cir.* data class CirClassImpl( override val annotations: List, - override val name: Name, + override val name: CirName, override val typeParameters: List, override val visibility: DescriptorVisibility, override val modality: Modality, override val kind: ClassKind, - override var companion: Name?, + override var companion: CirName?, override val isCompanion: Boolean, override val isData: Boolean, override val isInline: Boolean, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassTypeImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassTypeImpl.kt index 7d91040dd2a..fd3c8d97671 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassTypeImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirClassTypeImpl.kt @@ -7,13 +7,13 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeProjection import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode -import org.jetbrains.kotlin.name.ClassId data class CirClassTypeImpl( - override val classifierId: ClassId, + override val classifierId: CirEntityId, override val outerType: CirClassType?, override val visibility: DescriptorVisibility, // visibility of the class descriptor override val arguments: List, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirFunctionImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirFunctionImpl.kt index 80c3dc4d8bd..8dd9113ebfc 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirFunctionImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirFunctionImpl.kt @@ -9,15 +9,14 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.commonizer.cir.* -import org.jetbrains.kotlin.name.Name data class CirFunctionImpl( override val annotations: List, - override val name: Name, + override val name: CirName, override val typeParameters: List, override val visibility: DescriptorVisibility, override val modality: Modality, - override val containingClassDetails: CirContainingClassDetails?, + override val containingClass: CirContainingClass?, override var valueParameters: List, override var hasStableParameterNames: Boolean, override val extensionReceiver: CirExtensionReceiver?, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirModuleImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirModuleImpl.kt index b9a2655f571..7ee8706f4b3 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirModuleImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirModuleImpl.kt @@ -6,8 +6,8 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl import org.jetbrains.kotlin.descriptors.commonizer.cir.CirModule -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName data class CirModuleImpl( - override val name: Name + override val name: CirName ) : CirModule diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirPackageImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirPackageImpl.kt index d3c285ca65b..9f4e0f8b000 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirPackageImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirPackageImpl.kt @@ -6,8 +6,8 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackage -import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName data class CirPackageImpl( - override val fqName: FqName + override val packageName: CirPackageName ) : CirPackage diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirPropertyImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirPropertyImpl.kt index f7b5654ce2a..b5549c18c04 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirPropertyImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirPropertyImpl.kt @@ -9,16 +9,14 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.commonizer.cir.* -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.constants.ConstantValue data class CirPropertyImpl( override val annotations: List, - override val name: Name, + override val name: CirName, override val typeParameters: List, override val visibility: DescriptorVisibility, override val modality: Modality, - override val containingClassDetails: CirContainingClassDetails?, + override val containingClass: CirContainingClass?, override val isExternal: Boolean, override val extensionReceiver: CirExtensionReceiver?, override val returnType: CirType, @@ -31,7 +29,7 @@ data class CirPropertyImpl( override val setter: CirPropertySetter?, override val backingFieldAnnotations: List?, override val delegateFieldAnnotations: List?, - override val compileTimeInitializer: ConstantValue<*>? + override val compileTimeInitializer: CirConstantValue<*>? ) : CirProperty { // const property in "common" fragment is already lifted up override val isLiftedUp get() = isConst diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeAliasImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeAliasImpl.kt index 6cb409db0a3..6da6b47e091 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeAliasImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeAliasImpl.kt @@ -7,11 +7,10 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.commonizer.cir.* -import org.jetbrains.kotlin.name.Name data class CirTypeAliasImpl( override val annotations: List, - override val name: Name, + override val name: CirName, override val typeParameters: List, override val visibility: DescriptorVisibility, override val underlyingType: CirClassOrTypeAliasType, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeAliasTypeImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeAliasTypeImpl.kt index 9631f7a0ae0..65726178a9a 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeAliasTypeImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeAliasTypeImpl.kt @@ -6,14 +6,14 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassOrTypeAliasType +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAliasType import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeProjection import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode -import org.jetbrains.kotlin.name.ClassId data class CirTypeAliasTypeImpl( - override val classifierId: ClassId, + override val classifierId: CirEntityId, override val underlyingType: CirClassOrTypeAliasType, override val arguments: List, override val isMarkedNullable: Boolean diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeParameterImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeParameterImpl.kt index 28f6d9669f9..4d2ba1dd79f 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeParameterImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirTypeParameterImpl.kt @@ -6,14 +6,14 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeParameter -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance data class CirTypeParameterImpl( override val annotations: List, - override val name: Name, + override val name: CirName, override val isReified: Boolean, override val variance: Variance, override val upperBounds: List diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirValueParameterImpl.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirValueParameterImpl.kt index 16ce4761aa1..9acc38366f9 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirValueParameterImpl.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/CirValueParameterImpl.kt @@ -6,15 +6,15 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType import org.jetbrains.kotlin.descriptors.commonizer.cir.CirValueParameter import org.jetbrains.kotlin.descriptors.commonizer.utils.appendHashCode import org.jetbrains.kotlin.descriptors.commonizer.utils.hashCode -import org.jetbrains.kotlin.name.Name data class CirValueParameterImpl( override val annotations: List, - override val name: Name, + override val name: CirName, override val returnType: CirType, override val varargElementType: CirType?, override val declaresDefaultValue: Boolean, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/RecursionMarkers.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/RecursionMarkers.kt index 20648badf71..7e90e3ffd1f 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/RecursionMarkers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/cir/impl/RecursionMarkers.kt @@ -5,11 +5,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.cir.impl -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifier -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirRecursionMarker -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.descriptors.commonizer.cir.* object CirClassRecursionMarker : CirClass, CirRecursionMarker { override val annotations get() = unsupported() @@ -18,7 +14,7 @@ object CirClassRecursionMarker : CirClass, CirRecursionMarker { override val visibility get() = unsupported() override val modality get() = unsupported() override val kind get() = unsupported() - override var companion: Name? + override var companion: CirName? get() = unsupported() set(_) = unsupported() override val isCompanion get() = unsupported() diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt index 659ddb0d7f6..44498dc546c 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractFunctionOrPropertyCommonizer.kt @@ -9,13 +9,13 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DELEGATION import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED import org.jetbrains.kotlin.descriptors.commonizer.cir.CirFunctionOrProperty +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers -import org.jetbrains.kotlin.name.Name abstract class AbstractFunctionOrPropertyCommonizer( classifiers: CirKnownClassifiers ) : AbstractStandardCommonizer() { - protected lateinit var name: Name + protected lateinit var name: CirName protected val modality = ModalityCommonizer() protected val visibility = VisibilityCommonizer.lowering() protected val extensionReceiver = ExtensionReceiverCommonizer(classifiers) @@ -30,7 +30,7 @@ abstract class AbstractFunctionOrPropertyCommonizer( override fun doCommonizeWith(next: T): Boolean = next.kind != DELEGATION // delegated members should not be commonized - && (next.kind != SYNTHESIZED || next.containingClassDetails?.isData != true) // synthesized members of data classes should not be commonized + && (next.kind != SYNTHESIZED || next.containingClass?.isData != true) // synthesized members of data classes should not be commonized && kind == next.kind && modality.commonizeWith(next.modality) && visibility.commonizeWith(next) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AnnotationsCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AnnotationsCommonizer.kt index 9d2be91f9d1..4ef561e1601 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AnnotationsCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AnnotationsCommonizer.kt @@ -7,21 +7,14 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue.* +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirAnnotationFactory import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory import org.jetbrains.kotlin.descriptors.commonizer.core.AnnotationsCommonizer.Companion.FALLBACK_MESSAGE -import org.jetbrains.kotlin.descriptors.commonizer.utils.DEPRECATED_ANNOTATION_CLASS_ID -import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap -import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMapOf -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern -import org.jetbrains.kotlin.descriptors.commonizer.utils.internedClassId -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.constants.ArrayValue -import org.jetbrains.kotlin.resolve.constants.ConstantValue -import org.jetbrains.kotlin.resolve.constants.EnumValue -import org.jetbrains.kotlin.resolve.constants.StringValue +import org.jetbrains.kotlin.descriptors.commonizer.utils.* import kotlin.DeprecationLevel.WARNING /** @@ -62,20 +55,22 @@ private class DeprecatedAnnotationCommonizer : Commonizer> = if (level == WARNING) { - // don't populate with the default level value - compactMapOf(PROPERTY_NAME_MESSAGE, messageValue) - } else - compactMapOf( - PROPERTY_NAME_MESSAGE, messageValue, - PROPERTY_NAME_LEVEL, level.toDeprecationLevelValue() - ) + val constantValueArguments: Map> = + if (level == WARNING) { + // don't populate with the default level value + compactMapOf(PROPERTY_NAME_MESSAGE, messageValue) + } else + compactMapOf( + PROPERTY_NAME_MESSAGE, messageValue, + PROPERTY_NAME_LEVEL, level.toDeprecationLevelValue() + ) - val annotationValueArguments: Map = if (replaceWithExpression.isEmpty() && replaceWithImports.isEmpty()) { - // don't populate with empty (default) ReplaceWith - emptyMap() - } else - compactMapOf(PROPERTY_NAME_REPLACE_WITH, replaceWithExpression.toReplaceWithValue(replaceWithImports)) + val annotationValueArguments: Map = + if (replaceWithExpression.isEmpty() && replaceWithImports.isEmpty()) { + // don't populate with empty (default) ReplaceWith + emptyMap() + } else + compactMapOf(PROPERTY_NAME_REPLACE_WITH, replaceWithExpression.toReplaceWithValue(replaceWithImports)) return CirAnnotationFactory.create( type = DEPRECATED_ANNOTATION_TYPE, @@ -134,12 +129,12 @@ private class DeprecatedAnnotationCommonizer : Commonizer = listOf( @@ -149,16 +144,16 @@ private class DeprecatedAnnotationCommonizer : Commonizer = DeprecationLevel.values().associate { - it.name to EnumValue(DEPRECATION_LEVEL_CLASS_ID, Name.identifier(it.name).intern()) + it.name to EnumValue(DEPRECATION_LEVEL_CLASS_ID, CirName.create(it.name)) } - private fun buildAnnotationType(classId: ClassId) = CirTypeFactory.createClassType( + private fun buildAnnotationType(classId: CirEntityId) = CirTypeFactory.createClassType( classId = classId, outerType = null, visibility = DescriptorVisibilities.PUBLIC, @@ -194,17 +189,17 @@ private class DeprecatedAnnotationCommonizer : Commonizer): CirAnnotation = createReplaceWithAnnotation(this, imports) - private inline fun Map>.getString(name: Name): String? = + private inline fun Map>.getString(name: CirName): String? = (this[name] as? StringValue)?.value - private inline fun Map>.getEnumEntryName(name: Name): String? = - (this[name] as? EnumValue)?.enumEntryName?.asString() + private inline fun Map>.getEnumEntryName(name: CirName): String? = + (this[name] as? EnumValue)?.enumEntryName?.name - private inline fun Map.getAnnotation(name: Name): CirAnnotation? = + private inline fun Map.getAnnotation(name: CirName): CirAnnotation? = this[name] - private inline fun Map>.getStringArray(name: Name): List? { - val elements: List> = (this[name] as? ArrayValue)?.value ?: return null + private inline fun Map>.getStringArray(name: CirName): List? { + val elements: List> = (this[name] as? ArrayValue)?.value ?: return null if (elements.isEmpty()) return emptyList() val result = ArrayList(elements.size) @@ -223,10 +218,7 @@ private class DeprecatedAnnotationCommonizer : Commonizer Unit = {} - fun List.patchCallables(generated: Boolean, newNames: List): () -> Unit { + fun List.patchCallables(generated: Boolean, newNames: List): () -> Unit { val callablesToPatch = filter { it.originalNames is ValueParameterNames.Generated == generated } .takeIf { it.isNotEmpty() } ?: return doNothing() @@ -72,10 +71,10 @@ class CallableValueParametersCommonizer( private sealed class ValueParameterNames { object Generated : ValueParameterNames() - data class Real(val names: List) : ValueParameterNames() + data class Real(val names: List) : ValueParameterNames() class MultipleReal(valueParameters: List) : ValueParameterNames() { - val generatedNames: List = generatedNames(valueParameters) + val generatedNames: List = generatedNames(valueParameters) } companion object { @@ -87,7 +86,7 @@ class CallableValueParametersCommonizer( var real = false val names = callable.valueParameters.mapIndexed { index, valueParameter -> val name = valueParameter.name - val plainName = name.asString() + val plainName = name.name if (valueParameter.varargElementType != null) { if (plainName != VARIADIC_ARGUMENTS) { @@ -107,7 +106,7 @@ class CallableValueParametersCommonizer( return if (real) Real(names) else Generated } - fun generatedNames(valueParameters: List): List = + fun generatedNames(valueParameters: List): List = valueParameters.mapIndexed { index, valueParameter -> if (valueParameter.varargElementType != null) { VARIADIC_ARGUMENTS_NAME @@ -223,9 +222,9 @@ class CallableValueParametersCommonizer( private const val VARIADIC_ARGUMENTS = "variadicArguments" private const val REGULAR_ARGUMENT_PREFIX = "arg" - private val VARIADIC_ARGUMENTS_NAME = Name.identifier(VARIADIC_ARGUMENTS).intern() - private val REGULAR_ARGUMENT_NAMES = FactoryMap.create { index -> - Name.identifier(REGULAR_ARGUMENT_PREFIX + index).intern() + private val VARIADIC_ARGUMENTS_NAME = CirName.create(VARIADIC_ARGUMENTS) + private val REGULAR_ARGUMENT_NAMES = FactoryMap.create { index -> + CirName.create(REGULAR_ARGUMENT_PREFIX + index) } private fun CirCallableMemberWithParameters.canNamesBeOverwritten(): Boolean { diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ClassCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ClassCommonizer.kt index 577e4a8e8b8..8fa13fbd82d 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ClassCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ClassCommonizer.kt @@ -7,12 +7,12 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassFactory import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers -import org.jetbrains.kotlin.name.Name class ClassCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { - private lateinit var name: Name + private lateinit var name: CirName private lateinit var kind: ClassKind private val typeParameters = TypeParameterListCommonizer(classifiers) private val modality = ModalityCommonizer() diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ClassConstructorCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ClassConstructorCommonizer.kt index b1b42efa23c..b8e9a9d84b5 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ClassConstructorCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ClassConstructorCommonizer.kt @@ -5,10 +5,11 @@ package org.jetbrains.kotlin.descriptors.commonizer.core +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassConstructor +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirContainingClass import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassConstructorFactory -import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirContainingClassDetailsFactory import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers class ClassConstructorCommonizer( @@ -27,7 +28,7 @@ class ClassConstructorCommonizer( annotations = emptyList(), typeParameters = typeParameters.result, visibility = visibility.result, - containingClassDetails = CirContainingClassDetailsFactory.DOES_NOT_MATTER, + containingClass = CONTAINING_CLASS_DOES_NOT_MATTER, // does not matter valueParameters = valueParameters.valueParameters, hasStableParameterNames = valueParameters.hasStableParameterNames, isPrimary = isPrimary @@ -39,11 +40,19 @@ class ClassConstructorCommonizer( } override fun doCommonizeWith(next: CirClassConstructor): Boolean { - return !next.containingClassDetails.kind.isSingleton // don't commonize constructors for objects and enum entries - && next.containingClassDetails.modality != Modality.SEALED // don't commonize constructors for sealed classes (not not their subclasses) + return !next.containingClass.kind.isSingleton // don't commonize constructors for objects and enum entries + && next.containingClass.modality != Modality.SEALED // don't commonize constructors for sealed classes (not not their subclasses) && isPrimary == next.isPrimary && visibility.commonizeWith(next) && typeParameters.commonizeWith(next.typeParameters) && valueParameters.commonizeWith(next) } + + companion object { + private val CONTAINING_CLASS_DOES_NOT_MATTER = object : CirContainingClass { + override val modality get() = Modality.FINAL + override val kind get() = ClassKind.CLASS + override val isData get() = false + } + } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt index d69afd980bf..17e2832692c 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt @@ -6,13 +6,12 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.* import org.jetbrains.kotlin.descriptors.commonizer.utils.* import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMapNotNull -import org.jetbrains.kotlin.descriptors.commonizer.utils.internedClassId -import org.jetbrains.kotlin.name.ClassId internal class CommonizationVisitor( private val classifiers: CirKnownClassifiers, @@ -88,7 +87,7 @@ internal class CommonizationVisitor( // companion object should have the same name for each target class, then it could be set to common class val companionObjectName = node.targetDeclarations.mapTo(HashSet()) { it!!.companion }.singleOrNull() if (companionObjectName != null) { - val companionObjectClassId = internedClassId(node.classId, companionObjectName) + val companionObjectClassId = node.classifierId.createNestedEntityId(companionObjectName) val companionObjectNode = classifiers.commonized.classNode(companionObjectClassId) ?: error("Can't find companion object with class ID $companionObjectClassId") @@ -99,7 +98,7 @@ internal class CommonizationVisitor( } // find out common (and commonized) supertypes - commonClass.commonizeSupertypes(node.classId, node.collectCommonSupertypes()) + commonClass.commonizeSupertypes(node.classifierId, node.collectCommonSupertypes()) } } @@ -112,7 +111,7 @@ internal class CommonizationVisitor( if (commonClassifier is CirClass) { // find out common (and commonized) supertypes - commonClassifier.commonizeSupertypes(node.classId, node.collectCommonSupertypes()) + commonClassifier.commonizeSupertypes(node.classifierId, node.collectCommonSupertypes()) } } @@ -135,7 +134,7 @@ internal class CommonizationVisitor( val expandedClassNode = classifiers.commonized.classNode(expandedClassId) ?: return null val expandedClass = expandedClassNode.targetDeclarations[index] - ?: error("Can't find expanded class with class ID $expandedClassId and index $index for type alias $classId") + ?: error("Can't find expanded class with class ID $expandedClassId and index $index for type alias $classifierId") for (supertype in expandedClass.supertypes) { supertypesMap.getOrPut(supertype) { CommonizedGroup(targetDeclarations.size) }[index] = supertype @@ -145,7 +144,7 @@ internal class CommonizationVisitor( } private fun CirClass.commonizeSupertypes( - classId: ClassId, + classId: CirEntityId, supertypesMap: Map>? ) { val commonSupertypes = supertypesMap?.values?.compactMapNotNull { supertypesGroup -> diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt index 3c301a3fcaa..1992bc6dc2f 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt @@ -24,7 +24,7 @@ class FunctionCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrP typeParameters = typeParameters.result, visibility = visibility.result, modality = modality.result, - containingClassDetails = null, + containingClass = null, // does not matter valueParameters = valueParameters.valueParameters, hasStableParameterNames = valueParameters.hasStableParameterNames, extensionReceiver = extensionReceiver.result, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ModuleCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ModuleCommonizer.kt index 44a0ed87fcc..636c557c36e 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ModuleCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ModuleCommonizer.kt @@ -6,11 +6,11 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.commonizer.cir.CirModule +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirModuleFactory -import org.jetbrains.kotlin.name.Name class ModuleCommonizer : AbstractStandardCommonizer() { - private lateinit var name: Name + private lateinit var name: CirName override fun commonizationResult() = CirModuleFactory.create(name = name) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PackageCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PackageCommonizer.kt index a6d763d8ded..5fa9dc2b15e 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PackageCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PackageCommonizer.kt @@ -6,16 +6,16 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackage +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPackageFactory -import org.jetbrains.kotlin.name.FqName class PackageCommonizer : AbstractStandardCommonizer() { - private lateinit var fqName: FqName + private lateinit var packageName: CirPackageName - override fun commonizationResult() = CirPackageFactory.create(fqName = fqName) + override fun commonizationResult() = CirPackageFactory.create(packageName = packageName) override fun initialize(first: CirPackage) { - fqName = first.fqName + packageName = first.packageName } override fun doCommonizeWith(next: CirPackage) = true diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt index 74e25eea2d4..fb38ab2ab64 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt @@ -5,12 +5,12 @@ package org.jetbrains.kotlin.descriptors.commonizer.core +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue import org.jetbrains.kotlin.descriptors.commonizer.cir.CirProperty import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPropertyFactory import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirPropertyGetterFactory import org.jetbrains.kotlin.descriptors.commonizer.core.PropertyCommonizer.ConstCommonizationState.* import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers -import org.jetbrains.kotlin.resolve.constants.ConstantValue class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrPropertyCommonizer(classifiers) { private val setter = PropertySetterCommonizer() @@ -34,7 +34,7 @@ class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrP typeParameters = typeParameters.result, visibility = visibility.result, modality = modality.result, - containingClassDetails = null, + containingClass = null, // does not matter isExternal = isExternal, extensionReceiver = extensionReceiver.result, returnType = returnType.result, @@ -109,7 +109,7 @@ class PropertyCommonizer(classifiers: CirKnownClassifiers) : AbstractFunctionOrP val properties: MutableList = mutableListOf() } - class ConstSameValue(val compileTimeInitializer: ConstantValue<*>) : Const() + class ConstSameValue(val compileTimeInitializer: CirConstantValue<*>) : Const() class ConstMultipleValues(previous: ConstSameValue) : Const() { init { properties += previous.properties diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeAliasCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeAliasCommonizer.kt index 1c3d6629fd5..200502317c3 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeAliasCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeAliasCommonizer.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.descriptors.commonizer.cir.* import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassFactory import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeAliasFactory import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers -import org.jetbrains.kotlin.name.Name /** * Primary (optimistic) branch: @@ -45,7 +44,7 @@ class TypeAliasCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCo private class TypeAliasShortCircuitingCommonizer( private val classifiers: CirKnownClassifiers ) : AbstractStandardCommonizer() { - private lateinit var name: Name + private lateinit var name: CirName private val typeParameters = TypeParameterListCommonizer(classifiers) private var underlyingType: CirClassOrTypeAliasType? = null // null means not computed yet private val expandedType = TypeCommonizer(classifiers) @@ -79,7 +78,7 @@ private class TypeAliasShortCircuitingCommonizer( } private class TypeAliasLiftingUpCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { - private lateinit var name: Name + private lateinit var name: CirName private val typeParameters = TypeParameterListCommonizer(classifiers) private val underlyingType = TypeCommonizer(classifiers) private val visibility = VisibilityCommonizer.lowering() @@ -111,7 +110,7 @@ private class TypeAliasLiftingUpCommonizer(classifiers: CirKnownClassifiers) : A } private class TypeAliasExpectClassCommonizer : AbstractStandardCommonizer() { - private lateinit var name: Name + private lateinit var name: CirName private val classVisibility = VisibilityCommonizer.equalizing() override fun commonizationResult(): CirClass = CirClassFactory.create( diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt index 114d9d3c0e0..9225ec14d1a 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.descriptors.commonizer.core.CommonizedTypeAliasAnswe import org.jetbrains.kotlin.descriptors.commonizer.core.CommonizedTypeAliasAnswer.Companion.SUCCESS_FROM_DEPENDEE_LIBRARY import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderKotlinNativeSyntheticPackages -import org.jetbrains.kotlin.name.ClassId class TypeCommonizer(private val classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { private lateinit var wrapped: Commonizer<*, CirType> @@ -38,7 +37,7 @@ class TypeCommonizer(private val classifiers: CirKnownClassifiers) : AbstractSta } private class ClassTypeCommonizer(private val classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { - private lateinit var classId: ClassId + private lateinit var classId: CirEntityId private val outerType = OuterClassTypeCommonizer(classifiers) private lateinit var anyVisibility: DescriptorVisibility private val arguments = TypeArgumentListCommonizer(classifiers) @@ -80,7 +79,7 @@ private class OuterClassTypeCommonizer(classifiers: CirKnownClassifiers) : private class TypeAliasTypeCommonizer(private val classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { - private lateinit var typeAliasId: ClassId + private lateinit var typeAliasId: CirEntityId private val arguments = TypeArgumentListCommonizer(classifiers) private var isMarkedNullable = false private var commonizedTypeBuilder: CommonizedTypeAliasTypeBuilder? = null // null means not selected yet @@ -122,12 +121,12 @@ private class TypeAliasTypeCommonizer(private val classifiers: CirKnownClassifie // builds a new type for "common" library fragment for the given combination of type alias types in "platform" fragments private interface CommonizedTypeAliasTypeBuilder { - fun build(typeAliasId: ClassId, arguments: List, isMarkedNullable: Boolean): CirClassOrTypeAliasType + fun build(typeAliasId: CirEntityId, arguments: List, isMarkedNullable: Boolean): CirClassOrTypeAliasType companion object { // type alias has been commonized to expect class, need to build type for expect class fun forClass(commonClass: CirClass) = object : CommonizedTypeAliasTypeBuilder { - override fun build(typeAliasId: ClassId, arguments: List, isMarkedNullable: Boolean) = + override fun build(typeAliasId: CirEntityId, arguments: List, isMarkedNullable: Boolean) = CirTypeFactory.createClassType( classId = typeAliasId, outerType = null, // there can't be outer type @@ -143,7 +142,7 @@ private class TypeAliasTypeCommonizer(private val classifiers: CirKnownClassifie // type alias don't needs to be commonized because it is from the standard library fun forKnownUnderlyingType(underlyingType: CirClassOrTypeAliasType) = object : CommonizedTypeAliasTypeBuilder { - override fun build(typeAliasId: ClassId, arguments: List, isMarkedNullable: Boolean): CirTypeAliasType { + override fun build(typeAliasId: CirEntityId, arguments: List, isMarkedNullable: Boolean): CirTypeAliasType { val underlyingTypeWithProperNullability = if (isMarkedNullable && !underlyingType.isMarkedNullable) CirTypeFactory.makeNullable(underlyingType) else @@ -192,11 +191,11 @@ private class FlexibleTypeCommonizer(classifiers: CirKnownClassifiers) : Abstrac lowerBound.commonizeWith(next.lowerBound) && upperBound.commonizeWith(next.upperBound) } -private fun commonizeClass(classId: ClassId, classifiers: CirKnownClassifiers): Boolean { +private fun commonizeClass(classId: CirEntityId, classifiers: CirKnownClassifiers): Boolean { if (classifiers.commonDependeeLibraries.hasClassifier(classId)) { // The class is from common fragment of dependee library (ex: stdlib). Already commonized. return true - } else if (classId.packageFqName.isUnderKotlinNativeSyntheticPackages) { + } else if (classId.packageName.isUnderKotlinNativeSyntheticPackages) { // C/Obj-C forward declarations are: // - Either resolved to real classes/interfaces from other interop libraries (which are generated by C-interop tool and // are known to have modality/visibility/other attributes to successfully pass commonization). @@ -219,7 +218,7 @@ private fun commonizeClass(classId: ClassId, classifiers: CirKnownClassifiers): } } -private fun commonizeTypeAlias(typeAliasId: ClassId, classifiers: CirKnownClassifiers): CommonizedTypeAliasAnswer { +private fun commonizeTypeAlias(typeAliasId: CirEntityId, classifiers: CirKnownClassifiers): CommonizedTypeAliasAnswer { if (classifiers.commonDependeeLibraries.hasClassifier(typeAliasId)) { // The type alias is from common fragment of dependee library (ex: stdlib). Already commonized. return SUCCESS_FROM_DEPENDEE_LIBRARY diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizer.kt index 70aa038131e..dd205c4efef 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizer.kt @@ -5,15 +5,15 @@ package org.jetbrains.kotlin.descriptors.commonizer.core +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeParameter import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeParameterFactory import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance class TypeParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { - private lateinit var name: Name + private lateinit var name: CirName private var isReified = false private lateinit var variance: Variance private val upperBounds = TypeParameterUpperBoundsCommonizer(classifiers) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt index 1df5409fee9..3503b61479d 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt @@ -5,15 +5,15 @@ package org.jetbrains.kotlin.descriptors.commonizer.core +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType import org.jetbrains.kotlin.descriptors.commonizer.cir.CirValueParameter import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirValueParameterFactory import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers import org.jetbrains.kotlin.descriptors.commonizer.utils.isNull -import org.jetbrains.kotlin.name.Name class ValueParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStandardCommonizer() { - private lateinit var name: Name + private lateinit var name: CirName private val returnType = TypeCommonizer(classifiers) private var varargElementType: CirType? = null private var isCrossinline = true @@ -49,7 +49,7 @@ class ValueParameterCommonizer(classifiers: CirKnownClassifiers) : AbstractStand return result } - fun overwriteName(name: Name) { + fun overwriteName(name: CirName) { this.name = name } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterListCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterListCommonizer.kt index 7293af81380..4d628f36d45 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterListCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterListCommonizer.kt @@ -5,14 +5,14 @@ package org.jetbrains.kotlin.descriptors.commonizer.core +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirValueParameter import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers -import org.jetbrains.kotlin.name.Name class ValueParameterListCommonizer(classifiers: CirKnownClassifiers) : AbstractListCommonizer( singleElementCommonizerFactory = { ValueParameterCommonizer(classifiers) } ) { - fun overwriteNames(names: List) { + fun overwriteNames(names: List) { forEachSingleElementCommonizer { index, singleElementCommonizer -> (singleElementCommonizer as ValueParameterCommonizer).overwriteName(names[index]) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassNode.kt index 5dcb5a586d9..71fca5e3f9a 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassNode.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirClassNode.kt @@ -7,21 +7,21 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree import gnu.trove.THashMap import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.storage.NullableLazyValue class CirClassNode( override val targetDeclarations: CommonizedGroup, override val commonDeclaration: NullableLazyValue, - override val classId: ClassId -) : CirNodeWithClassId { + override val classifierId: CirEntityId +) : CirNodeWithClassifierId, CirNodeWithMembers { val constructors: MutableMap = THashMap() - val properties: MutableMap = THashMap() - val functions: MutableMap = THashMap() - val classes: MutableMap = THashMap() + override val properties: MutableMap = THashMap() + override val functions: MutableMap = THashMap() + override val classes: MutableMap = THashMap() override fun accept(visitor: CirNodeVisitor, data: T): R = visitor.visitClassNode(this, data) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirModuleNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirModuleNode.kt index 53c889c18e2..f55a8d1632f 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirModuleNode.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirModuleNode.kt @@ -7,15 +7,15 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree import gnu.trove.THashMap import org.jetbrains.kotlin.descriptors.commonizer.cir.CirModule +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.storage.NullableLazyValue class CirModuleNode( override val targetDeclarations: CommonizedGroup, override val commonDeclaration: NullableLazyValue ) : CirNode { - val packages: MutableMap = THashMap() + val packages: MutableMap = THashMap() override fun accept(visitor: CirNodeVisitor, data: T) = visitor.visitModuleNode(this, data) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNode.kt index f9074553a01..b6069ae877c 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNode.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNode.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirDeclaration +import org.jetbrains.kotlin.descriptors.commonizer.cir.* import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup import org.jetbrains.kotlin.storage.NullableLazyValue @@ -23,11 +23,11 @@ interface CirNode { get() = targetDeclarations.size + 1 fun toString(node: CirNode<*, *>) = buildString { - if (node is CirNodeWithFqName) { - append("fqName=").append(node.fqName.asString()).append(", ") + if (node is CirPackageNode) { + append("packageName=").append(node.packageName).append(", ") } - if (node is CirNodeWithClassId) { - append("classId=").append(node.classId.asString()).append(", ") + if (node is CirNodeWithClassifierId) { + append("classifierId=").append(node.classifierId).append(", ") } append("target=") node.targetDeclarations.joinTo(this) @@ -37,3 +37,17 @@ interface CirNode { } } +interface CirNodeWithClassifierId : CirNode { + val classifierId: CirEntityId +} + +interface CirNodeWithLiftingUp : CirNode { + val isLiftedUp: Boolean + get() = (commonDeclaration() as? CirLiftedUpDeclaration)?.isLiftedUp == true +} + +interface CirNodeWithMembers : CirNode { + val properties: MutableMap + val functions: MutableMap + val classes: MutableMap +} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithClassId.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithClassId.kt deleted file mode 100644 index 997d0cbe48c..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithClassId.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.descriptors.commonizer.mergedtree - -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifier -import org.jetbrains.kotlin.name.ClassId - -interface CirNodeWithClassId : CirNode { - val classId: ClassId -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithFqName.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithFqName.kt deleted file mode 100644 index 2f4757cfba8..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithFqName.kt +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.descriptors.commonizer.mergedtree - -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirDeclaration -import org.jetbrains.kotlin.name.FqName - -interface CirNodeWithFqName : CirNode { - val fqName: FqName -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithLiftingUp.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithLiftingUp.kt deleted file mode 100644 index 864728f4497..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirNodeWithLiftingUp.kt +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.descriptors.commonizer.mergedtree - -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirDeclaration -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirLiftedUpDeclaration - -interface CirNodeWithLiftingUp : CirNode { - val isLiftedUp: Boolean - get() = (commonDeclaration() as? CirLiftedUpDeclaration)?.isLiftedUp == true -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPackageNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPackageNode.kt index f30272ff899..5762cce7327 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPackageNode.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirPackageNode.kt @@ -6,23 +6,25 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree import gnu.trove.THashMap +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackage +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.descriptors.commonizer.utils.firstNonNull import org.jetbrains.kotlin.storage.NullableLazyValue class CirPackageNode( override val targetDeclarations: CommonizedGroup, - override val commonDeclaration: NullableLazyValue, - override val fqName: FqName, - val moduleName: Name -) : CirNodeWithFqName { + override val commonDeclaration: NullableLazyValue +) : CirNodeWithMembers { - val properties: MutableMap = THashMap() - val functions: MutableMap = THashMap() - val classes: MutableMap = THashMap() - val typeAliases: MutableMap = THashMap() + override val properties: MutableMap = THashMap() + override val functions: MutableMap = THashMap() + override val classes: MutableMap = THashMap() + val typeAliases: MutableMap = THashMap() + + val packageName: CirPackageName + get() = targetDeclarations.firstNonNull().packageName override fun accept(visitor: CirNodeVisitor, data: T) = visitor.visitPackageNode(this, data) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirRootNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirRootNode.kt index df6d0c66263..ae6f9024762 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirRootNode.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirRootNode.kt @@ -7,17 +7,17 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree import gnu.trove.THashMap import org.jetbrains.kotlin.descriptors.commonizer.CommonizerTarget +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirRoot import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.storage.NullableLazyValue class CirRootNode( override val targetDeclarations: CommonizedGroup, override val commonDeclaration: NullableLazyValue ) : CirNode { - val modules: MutableMap = THashMap() + val modules: MutableMap = THashMap() fun getTarget(targetIndex: Int): CommonizerTarget = (if (targetIndex == indexOfCommon) commonDeclaration() else targetDeclarations[targetIndex])!!.target diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTreeMerger.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTreeMerger.kt index b26574d092f..200d2bf29bb 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTreeMerger.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTreeMerger.kt @@ -10,15 +10,11 @@ import org.jetbrains.kotlin.descriptors.commonizer.LeafTarget import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.ModuleInfo import org.jetbrains.kotlin.descriptors.commonizer.CommonizerParameters import org.jetbrains.kotlin.descriptors.commonizer.TargetProvider -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.* -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern -import org.jetbrains.kotlin.descriptors.commonizer.utils.internedClassId -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.storage.NullableLazyValue import org.jetbrains.kotlin.storage.StorageManager /** @@ -76,7 +72,7 @@ class CirTreeMerger( val allModuleInfos: List> = parameters.targetProviders.map { targetProvider -> targetProvider.modulesProvider.loadModuleInfos().associateBy { it.name } } - val commonModuleNames = allModuleInfos.map { it.keys }.reduce { a, b -> a intersect b } + val commonModuleNames = parameters.getCommonModuleNames() parameters.targetProviders.forEachIndexed { targetIndex, targetProvider -> val commonModuleInfos = allModuleInfos[targetIndex].filterKeys { it in commonModuleNames } @@ -110,159 +106,147 @@ class CirTreeMerger( val allDependeeModules = targetDependeeModules + dependeeModules val moduleDescriptors: Map = targetProvider.modulesProvider.loadModules(allDependeeModules) - val modules: MutableMap = rootNode.modules moduleDescriptors.forEach { (name, moduleDescriptor) -> val moduleInfo = commonModuleInfos[name] ?: return@forEach - processModule(modules, targetIndex, moduleInfo, moduleDescriptor) + processModule(rootNode, targetIndex, moduleInfo, moduleDescriptor) } } private fun processModule( - modules: MutableMap, + rootNode: CirRootNode, targetIndex: Int, moduleInfo: ModuleInfo, moduleDescriptor: ModuleDescriptor ) { processCInteropModuleAttributes(moduleInfo) - val moduleName: Name = moduleDescriptor.name.intern() - val moduleNode: CirModuleNode = modules.getOrPut(moduleName) { + val moduleName: CirName = CirName.create(moduleDescriptor.name) + val moduleNode: CirModuleNode = rootNode.modules.getOrPut(moduleName) { buildModuleNode(storageManager, size) } - moduleNode.targetDeclarations[targetIndex] = CirModuleFactory.create(moduleDescriptor) + moduleNode.targetDeclarations[targetIndex] = CirModuleFactory.create(moduleName) - val packages: MutableMap = moduleNode.packages - - moduleDescriptor.collectNonEmptyPackageMemberScopes { packageFqName, packageMemberScope -> - processPackage(packages, targetIndex, packageFqName.intern(), packageMemberScope, moduleName) + moduleDescriptor.collectNonEmptyPackageMemberScopes { packageName, packageMemberScope -> + processPackage(moduleNode, targetIndex, packageName, packageMemberScope) } } private fun processPackage( - packages: MutableMap, + moduleNode: CirModuleNode, targetIndex: Int, - packageFqName: FqName, - packageMemberScope: MemberScope, - moduleName: Name + packageName: CirPackageName, + packageMemberScope: MemberScope ) { - val packageNode: CirPackageNode = packages.getOrPut(packageFqName) { - buildPackageNode(storageManager, size, packageFqName, moduleName) + val packageNode: CirPackageNode = moduleNode.packages.getOrPut(packageName) { + buildPackageNode(storageManager, size) } - packageNode.targetDeclarations[targetIndex] = CirPackageFactory.create(packageFqName) - - val properties: MutableMap = packageNode.properties - val functions: MutableMap = packageNode.functions - val classes: MutableMap = packageNode.classes - val typeAliases: MutableMap = packageNode.typeAliases + packageNode.targetDeclarations[targetIndex] = CirPackageFactory.create(packageName) packageMemberScope.collectMembers( PropertyCollector { propertyDescriptor -> - processProperty(properties, targetIndex, propertyDescriptor, null) + processProperty(packageNode, targetIndex, propertyDescriptor) }, FunctionCollector { functionDescriptor -> - processFunction(functions, targetIndex, functionDescriptor, null) + processFunction(packageNode, targetIndex, functionDescriptor) }, ClassCollector { classDescriptor -> - processClass(classes, targetIndex, classDescriptor, null) { className -> - internedClassId(packageFqName, className) + processClass(packageNode, targetIndex, classDescriptor) { className -> + CirEntityId.create(packageName, className) } }, TypeAliasCollector { typeAliasDescriptor -> - processTypeAlias(typeAliases, targetIndex, typeAliasDescriptor, packageFqName) + processTypeAlias(packageNode, targetIndex, typeAliasDescriptor) } ) } private fun processProperty( - properties: MutableMap, + ownerNode: CirNodeWithMembers<*, *>, targetIndex: Int, - propertyDescriptor: PropertyDescriptor, - parentCommonDeclaration: NullableLazyValue<*>? + propertyDescriptor: PropertyDescriptor ) { - val propertyNode: CirPropertyNode = properties.getOrPut(PropertyApproximationKey(propertyDescriptor)) { - buildPropertyNode(storageManager, size, classifiers, parentCommonDeclaration) + val propertyNode: CirPropertyNode = ownerNode.properties.getOrPut(PropertyApproximationKey(propertyDescriptor)) { + buildPropertyNode(storageManager, size, classifiers, (ownerNode as? CirClassNode)?.commonDeclaration) } - propertyNode.targetDeclarations[targetIndex] = CirPropertyFactory.create(propertyDescriptor) + propertyNode.targetDeclarations[targetIndex] = CirPropertyFactory.create( + source = propertyDescriptor, + containingClass = (ownerNode as? CirClassNode)?.targetDeclarations?.get(targetIndex) + ) } private fun processFunction( - functions: MutableMap, + ownerNode: CirNodeWithMembers<*, *>, targetIndex: Int, - functionDescriptor: SimpleFunctionDescriptor, - parentCommonDeclaration: NullableLazyValue<*>? + functionDescriptor: SimpleFunctionDescriptor ) { - val functionNode: CirFunctionNode = functions.getOrPut(FunctionApproximationKey(functionDescriptor)) { - buildFunctionNode(storageManager, size, classifiers, parentCommonDeclaration) + val functionNode: CirFunctionNode = ownerNode.functions.getOrPut(FunctionApproximationKey(functionDescriptor)) { + buildFunctionNode(storageManager, size, classifiers, (ownerNode as? CirClassNode)?.commonDeclaration) } - functionNode.targetDeclarations[targetIndex] = CirFunctionFactory.create(functionDescriptor) + functionNode.targetDeclarations[targetIndex] = CirFunctionFactory.create( + source = functionDescriptor, + containingClass = (ownerNode as? CirClassNode)?.targetDeclarations?.get(targetIndex) + ) } private fun processClass( - classes: MutableMap, + ownerNode: CirNodeWithMembers<*, *>, targetIndex: Int, classDescriptor: ClassDescriptor, - parentCommonDeclaration: NullableLazyValue<*>?, - classIdFunction: (Name) -> ClassId + classIdFunction: (CirName) -> CirEntityId ) { - val className = classDescriptor.name.intern() + val className = CirName.create(classDescriptor.name) val classId = classIdFunction(className) - val classNode: CirClassNode = classes.getOrPut(className) { - buildClassNode(storageManager, size, classifiers, parentCommonDeclaration, classId) + val classNode: CirClassNode = ownerNode.classes.getOrPut(className) { + buildClassNode(storageManager, size, classifiers, (ownerNode as? CirClassNode)?.commonDeclaration, classId) } classNode.targetDeclarations[targetIndex] = CirClassFactory.create(classDescriptor) - val parentCommonDeclarationForMembers: NullableLazyValue = classNode.commonDeclaration - - val constructors: MutableMap = classNode.constructors - val properties: MutableMap = classNode.properties - val functions: MutableMap = classNode.functions - val nestedClasses: MutableMap = classNode.classes - if (classDescriptor.kind != ClassKind.ENUM_ENTRY) { classDescriptor.constructors.forEach { constructorDescriptor -> - processClassConstructor(constructors, targetIndex, constructorDescriptor, parentCommonDeclarationForMembers) + processClassConstructor(classNode, targetIndex, constructorDescriptor) } } classDescriptor.unsubstitutedMemberScope.collectMembers( PropertyCollector { propertyDescriptor -> - processProperty(properties, targetIndex, propertyDescriptor, parentCommonDeclarationForMembers) + processProperty(classNode, targetIndex, propertyDescriptor) }, FunctionCollector { functionDescriptor -> - processFunction(functions, targetIndex, functionDescriptor, parentCommonDeclarationForMembers) + processFunction(classNode, targetIndex, functionDescriptor) }, ClassCollector { nestedClassDescriptor -> - processClass(nestedClasses, targetIndex, nestedClassDescriptor, parentCommonDeclarationForMembers) { nestedClassName -> - internedClassId(classId, nestedClassName) + processClass(classNode, targetIndex, nestedClassDescriptor) { nestedClassName -> + classId.createNestedEntityId(nestedClassName) } } ) } private fun processClassConstructor( - constructors: MutableMap, + classNode: CirClassNode, targetIndex: Int, - constructorDescriptor: ClassConstructorDescriptor, - parentCommonDeclaration: NullableLazyValue<*>? + constructorDescriptor: ClassConstructorDescriptor ) { - val constructorNode: CirClassConstructorNode = constructors.getOrPut(ConstructorApproximationKey(constructorDescriptor)) { - buildClassConstructorNode(storageManager, size, classifiers, parentCommonDeclaration) + val constructorNode: CirClassConstructorNode = classNode.constructors.getOrPut(ConstructorApproximationKey(constructorDescriptor)) { + buildClassConstructorNode(storageManager, size, classifiers, classNode.commonDeclaration) } - constructorNode.targetDeclarations[targetIndex] = CirClassConstructorFactory.create(constructorDescriptor) + constructorNode.targetDeclarations[targetIndex] = CirClassConstructorFactory.create( + source = constructorDescriptor, + containingClass = classNode.targetDeclarations[targetIndex]!! + ) } private fun processTypeAlias( - typeAliases: MutableMap, + packageNode: CirPackageNode, targetIndex: Int, - typeAliasDescriptor: TypeAliasDescriptor, - packageFqName: FqName + typeAliasDescriptor: TypeAliasDescriptor ) { - val typeAliasName = typeAliasDescriptor.name.intern() - val typeAliasClassId = internedClassId(packageFqName, typeAliasName) + val typeAliasName = CirName.create(typeAliasDescriptor.name) + val typeAliasClassId = CirEntityId.create(packageNode.packageName, typeAliasName) - val typeAliasNode: CirTypeAliasNode = typeAliases.getOrPut(typeAliasName) { + val typeAliasNode: CirTypeAliasNode = packageNode.typeAliases.getOrPut(typeAliasName) { buildTypeAliasNode(storageManager, size, classifiers, typeAliasClassId) } typeAliasNode.targetDeclarations[targetIndex] = CirTypeAliasFactory.create(typeAliasDescriptor) @@ -271,12 +255,12 @@ class CirTreeMerger( private fun processCInteropModuleAttributes(moduleInfo: ModuleInfo) { val cInteropAttributes = moduleInfo.cInteropAttributes ?: return val exportForwardDeclarations = cInteropAttributes.exportForwardDeclarations.takeIf { it.isNotEmpty() } ?: return - val mainPackageFqName = FqName(cInteropAttributes.mainPackageFqName).intern() + val mainPackageFqName = CirPackageName.create(cInteropAttributes.mainPackageFqName) exportForwardDeclarations.forEach { classFqName -> // Class has synthetic package FQ name (cnames/objcnames). Need to transfer it to the main package. - val className = Name.identifier(classFqName.substringAfterLast('.')).intern() - classifiers.forwardDeclarations.addExportedForwardDeclaration(internedClassId(mainPackageFqName, className)) + val className = CirName.create(classFqName.substringAfterLast('.')) + classifiers.forwardDeclarations.addExportedForwardDeclaration(CirEntityId.create(mainPackageFqName, className)) } } } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTypeAliasNode.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTypeAliasNode.kt index 06f0a464fbd..cddfbfb982e 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTypeAliasNode.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/CirTypeAliasNode.kt @@ -6,16 +6,16 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifier +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAlias import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.storage.NullableLazyValue class CirTypeAliasNode( override val targetDeclarations: CommonizedGroup, override val commonDeclaration: NullableLazyValue, - override val classId: ClassId -) : CirNodeWithClassId, CirNodeWithLiftingUp { + override val classifierId: CirEntityId +) : CirNodeWithClassifierId, CirNodeWithLiftingUp { override fun accept(visitor: CirNodeVisitor, data: T): R = visitor.visitTypeAliasNode(this, data) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/approximationKeys.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/approximationKeys.kt index 8679475a246..2dff588cb1d 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/approximationKeys.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/approximationKeys.kt @@ -6,33 +6,32 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeSignature import org.jetbrains.kotlin.descriptors.commonizer.core.Commonizer import org.jetbrains.kotlin.descriptors.commonizer.utils.* -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern import org.jetbrains.kotlin.descriptors.commonizer.utils.signature -import org.jetbrains.kotlin.name.Name /** Used for approximation of [PropertyDescriptor]s before running concrete [Commonizer]s */ data class PropertyApproximationKey( - val name: Name, + val name: CirName, val extensionReceiverParameterType: CirTypeSignature? ) { constructor(property: PropertyDescriptor) : this( - property.name.intern(), + CirName.create(property.name), property.extensionReceiverParameter?.type?.signature ) } /** Used for approximation of [SimpleFunctionDescriptor]s before running concrete [Commonizer]s */ data class FunctionApproximationKey( - val name: Name, + val name: CirName, val valueParametersTypes: Array, private val additionalValueParametersNamesHash: Int, val extensionReceiverParameterType: CirTypeSignature? ) { constructor(function: SimpleFunctionDescriptor) : this( - function.name.intern(), + CirName.create(function.name), function.valueParameters.toTypeSignatures(), additionalValueParameterNamesHash(function), function.extensionReceiverParameter?.type?.signature diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/classifierContainers.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/classifierContainers.kt index f047224bcff..2138318d4aa 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/classifierContainers.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/classifierContainers.kt @@ -10,11 +10,10 @@ import gnu.trove.THashSet import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.commonizer.SharedTarget import org.jetbrains.kotlin.descriptors.commonizer.CommonizerTarget -import org.jetbrains.kotlin.descriptors.commonizer.utils.intern +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderKotlinNativeSyntheticPackages import org.jetbrains.kotlin.descriptors.commonizer.utils.resolveClassOrTypeAlias -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.getValue @@ -31,27 +30,27 @@ class CirKnownClassifiers( interface CirCommonizedClassifiers { /* Accessors */ - fun classNode(classId: ClassId): CirClassNode? - fun typeAliasNode(typeAliasId: ClassId): CirTypeAliasNode? + fun classNode(classId: CirEntityId): CirClassNode? + fun typeAliasNode(typeAliasId: CirEntityId): CirTypeAliasNode? /* Mutators */ - fun addClassNode(classId: ClassId, node: CirClassNode) - fun addTypeAliasNode(typeAliasId: ClassId, node: CirTypeAliasNode) + fun addClassNode(classId: CirEntityId, node: CirClassNode) + fun addTypeAliasNode(typeAliasId: CirEntityId, node: CirTypeAliasNode) companion object { fun default() = object : CirCommonizedClassifiers { - private val classNodes = THashMap() - private val typeAliases = THashMap() + private val classNodes = THashMap() + private val typeAliases = THashMap() - override fun classNode(classId: ClassId) = classNodes[classId] - override fun typeAliasNode(typeAliasId: ClassId) = typeAliases[typeAliasId] + override fun classNode(classId: CirEntityId) = classNodes[classId] + override fun typeAliasNode(typeAliasId: CirEntityId) = typeAliases[typeAliasId] - override fun addClassNode(classId: ClassId, node: CirClassNode) { + override fun addClassNode(classId: CirEntityId, node: CirClassNode) { val oldNode = classNodes.put(classId, node) check(oldNode == null) { "Rewriting class node $classId" } } - override fun addTypeAliasNode(typeAliasId: ClassId, node: CirTypeAliasNode) { + override fun addTypeAliasNode(typeAliasId: CirEntityId, node: CirTypeAliasNode) { val oldNode = typeAliases.put(typeAliasId, node) check(oldNode == null) { "Rewriting type alias node $typeAliasId" } } @@ -61,19 +60,19 @@ interface CirCommonizedClassifiers { interface CirForwardDeclarations { /* Accessors */ - fun isExportedForwardDeclaration(classId: ClassId): Boolean + fun isExportedForwardDeclaration(classId: CirEntityId): Boolean /* Mutators */ - fun addExportedForwardDeclaration(classId: ClassId) + fun addExportedForwardDeclaration(classId: CirEntityId) companion object { fun default() = object : CirForwardDeclarations { - private val exportedForwardDeclarations = THashSet() + private val exportedForwardDeclarations = THashSet() - override fun isExportedForwardDeclaration(classId: ClassId) = classId in exportedForwardDeclarations + override fun isExportedForwardDeclaration(classId: CirEntityId) = classId in exportedForwardDeclarations - override fun addExportedForwardDeclaration(classId: ClassId) { - check(!classId.packageFqName.isUnderKotlinNativeSyntheticPackages) + override fun addExportedForwardDeclaration(classId: CirEntityId) { + check(!classId.packageName.isUnderKotlinNativeSyntheticPackages) exportedForwardDeclarations += classId } } @@ -81,45 +80,43 @@ interface CirForwardDeclarations { } interface CirProvidedClassifiers { - fun hasClassifier(classifierId: ClassId): Boolean + fun hasClassifier(classifierId: CirEntityId): Boolean // TODO: implement later //fun classifier(classifierId: ClassId): Any? companion object { internal val EMPTY = object : CirProvidedClassifiers { - override fun hasClassifier(classifierId: ClassId) = false + override fun hasClassifier(classifierId: CirEntityId) = false } // N.B. This is suboptimal implementation. It will be replaced by another implementation that will // retrieve classifier information directly from the metadata. fun fromModules(storageManager: StorageManager, modules: () -> Collection) = object : CirProvidedClassifiers { - private val nonEmptyMemberScopes: Map by storageManager.createLazyValue { - THashMap().apply { + private val nonEmptyMemberScopes: Map by storageManager.createLazyValue { + THashMap().apply { for (module in modules()) { - module.collectNonEmptyPackageMemberScopes(probeRootPackageForEmptiness = true) { packageFqName, memberScope -> - this[packageFqName.intern()] = memberScope + module.collectNonEmptyPackageMemberScopes(probeRootPackageForEmptiness = true) { packageName, memberScope -> + this[packageName] = memberScope } } } } - private val presentClassifiers = THashSet() - private val missingClassifiers = THashSet() + private val presentClassifiers = THashSet() + private val missingClassifiers = THashSet() - override fun hasClassifier(classifierId: ClassId): Boolean { - val relativeClassName: FqName = classifierId.relativeClassName - if (relativeClassName.isRoot) + override fun hasClassifier(classifierId: CirEntityId): Boolean { + if (classifierId.relativeNameSegments.isEmpty()) return false - val packageFqName = classifierId.packageFqName - val memberScope = nonEmptyMemberScopes[packageFqName] ?: return false + val memberScope = nonEmptyMemberScopes[classifierId.packageName] ?: return false return when (classifierId) { in presentClassifiers -> true in missingClassifiers -> false else -> { - val found = memberScope.resolveClassOrTypeAlias(relativeClassName) != null + val found = memberScope.resolveClassOrTypeAlias(classifierId.relativeNameSegments) != null when (found) { true -> presentClassifiers += classifierId false -> missingClassifiers += classifierId diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/collectors.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/collectors.kt index 2f7a34f7033..ba08a232890 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/collectors.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/collectors.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ClassifierAliasingPackageFragmentDescriptor import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName import org.jetbrains.kotlin.descriptors.commonizer.utils.* import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope @@ -65,7 +66,7 @@ internal inline fun FunctionCollector( // collects member scopes for every non-empty package provided by this module internal fun ModuleDescriptor.collectNonEmptyPackageMemberScopes( probeRootPackageForEmptiness: Boolean = false, // false is the default as probing might be expensive and is not always necessary - collector: (FqName, MemberScope) -> Unit + collector: (CirPackageName, MemberScope) -> Unit ) { // we don's need to process fragments from other modules which are the dependencies of this module, so // let's use the appropriate package fragment provider @@ -88,7 +89,7 @@ internal fun ModuleDescriptor.collectNonEmptyPackageMemberScopes( "package member scope for $packageFqName in $name", ownPackageMemberScopes ) - collector(packageFqName, memberScope) + collector(CirPackageName.create(packageFqName), memberScope) } packageFragmentProvider.getSubPackagesOf(packageFqName, alwaysTrue()).toSet().map { recurse(it) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodeBuilders.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodeBuilders.kt index 4407ff92f0b..dada2dfd93f 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodeBuilders.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/nodeBuilders.kt @@ -5,14 +5,12 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree -import org.jetbrains.kotlin.descriptors.commonizer.cir.* +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirDeclaration +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassRecursionMarker import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.CirClassifierRecursionMarker import org.jetbrains.kotlin.descriptors.commonizer.core.* import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.storage.NullableLazyValue import org.jetbrains.kotlin.storage.StorageManager @@ -38,16 +36,12 @@ internal fun buildModuleNode( internal fun buildPackageNode( storageManager: StorageManager, - size: Int, - fqName: FqName, - moduleName: Name + size: Int ): CirPackageNode = buildNode( storageManager = storageManager, size = size, commonizerProducer = ::PackageCommonizer, - nodeProducer = { targetDeclarations, commonDeclaration -> - CirPackageNode(targetDeclarations, commonDeclaration, fqName, moduleName) - } + nodeProducer = ::CirPackageNode ) internal fun buildPropertyNode( @@ -81,7 +75,7 @@ internal fun buildClassNode( size: Int, classifiers: CirKnownClassifiers, parentCommonDeclaration: NullableLazyValue<*>?, - classId: ClassId + classId: CirEntityId ): CirClassNode = buildNode( storageManager = storageManager, size = size, @@ -112,7 +106,7 @@ internal fun buildTypeAliasNode( storageManager: StorageManager, size: Int, classifiers: CirKnownClassifiers, - typeAliasId: ClassId + typeAliasId: CirEntityId ): CirTypeAliasNode = buildNode( storageManager = storageManager, size = size, diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/entityBuilders.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/entityBuilders.kt index bf0f33c0724..85405edf513 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/entityBuilders.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/entityBuilders.kt @@ -15,16 +15,13 @@ import org.jetbrains.kotlin.descriptors.commonizer.core.computeExpandedType import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.* import org.jetbrains.kotlin.descriptors.commonizer.metadata.TypeAliasExpansion.* import org.jetbrains.kotlin.descriptors.commonizer.utils.DEFAULT_SETTER_VALUE_NAME -import org.jetbrains.kotlin.descriptors.commonizer.utils.strip -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.constants.* +import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap import org.jetbrains.kotlin.types.Variance internal fun CirModule.buildModule( fragments: Collection ): KlibModuleMetadata = KlibModuleMetadata( - name = name.strip(), + name = name.toStrippedString(), fragments = fragments.toList(), annotations = emptyList() ) @@ -35,7 +32,7 @@ internal fun CirPackage.buildModuleFragment( topLevelFunctions: Collection, topLevelProperties: Collection ): KmModuleFragment = KmModuleFragment().also { fragment -> - fragment.fqName = fqName.asString() + fragment.fqName = packageName.toString() allClasses.forEach { fragment.classes += it fragment.className += it.name @@ -43,7 +40,7 @@ internal fun CirPackage.buildModuleFragment( if (topLevelTypeAliases.isNotEmpty() || topLevelFunctions.isNotEmpty() || topLevelProperties.isNotEmpty()) { fragment.pkg = KmPackage().also { pkg -> - pkg.fqName = fqName.asString() + pkg.fqName = packageName.toString() pkg.typeAliases += topLevelTypeAliases pkg.functions += topLevelFunctions pkg.properties += topLevelProperties @@ -101,15 +98,15 @@ internal fun CirClass.buildClass( } } - clazz.companionObject = companion?.asString() + clazz.companionObject = companion?.name supertypes.mapTo(clazz.supertypes) { it.buildType(context) } } -internal fun linkSealedClassesWithSubclasses(packageFqName: FqName, classConsumer: ClassConsumer) { +internal fun linkSealedClassesWithSubclasses(packageName: CirPackageName, classConsumer: ClassConsumer) { if (classConsumer.allClasses.isEmpty() || classConsumer.sealedClasses.isEmpty()) return - val packageName = packageFqName.asString().replace('.', '/') - fun ClassName.isInSamePackage(): Boolean = substringBeforeLast('/', "") == packageName + val metadataPackageName = packageName.toMetadataString() + fun ClassName.isInSamePackage(): Boolean = substringBeforeLast('/', "") == metadataPackageName val sealedClassesMap: Map = classConsumer.sealedClasses.associateBy { it.name } @@ -136,7 +133,7 @@ internal fun CirTypeAlias.buildTypeAlias( context: MetadataBuildingVisitorContext ): KmTypeAlias = KmTypeAlias( flags = typeAliasFlags(), - name = name.asString() + name = name.name ).also { typeAlias -> annotations.mapTo(typeAlias.annotations) { it.buildAnnotation() } typeParameters.buildTypeParameters(context, output = typeAlias.typeParameters) @@ -148,7 +145,7 @@ internal fun CirProperty.buildProperty( context: MetadataBuildingVisitorContext, ): KmProperty = KmProperty( flags = propertyFlags(isExpect = context.isCommon && !isLiftedUp), - name = name.asString(), + name = name.name, getterFlags = getter?.propertyAccessorFlags(this, this) ?: NO_FLAGS, setterFlags = setter?.let { setter -> setter.propertyAccessorFlags(setter, this) } ?: NO_FLAGS ).also { property -> @@ -156,7 +153,7 @@ internal fun CirProperty.buildProperty( annotations.mapTo(property.annotations) { it.buildAnnotation() } getter?.annotations?.mapTo(property.getterAnnotations) { it.buildAnnotation() } setter?.annotations?.mapTo(property.setterAnnotations) { it.buildAnnotation() } - property.compileTimeValue = compileTimeInitializer?.takeIf { it !is NullValue }?.buildAnnotationArgument() + property.compileTimeValue = compileTimeInitializer?.takeIf { it !is CirConstantValue.NullValue }?.buildAnnotationArgument() typeParameters.buildTypeParameters(context, output = property.typeParameters) extensionReceiver?.let { receiver -> // TODO nowhere to write receiver annotations, see KT-42490 @@ -180,7 +177,7 @@ internal fun CirFunction.buildFunction( context: MetadataBuildingVisitorContext, ): KmFunction = KmFunction( flags = functionFlags(isExpect = context.isCommon && kind != CallableMemberDescriptor.Kind.SYNTHESIZED), - name = name.asString() + name = name.name ).also { function -> annotations.mapTo(function.annotations) { it.buildAnnotation() } typeParameters.buildTypeParameters(context, output = function.typeParameters) @@ -195,49 +192,52 @@ internal fun CirFunction.buildFunction( private fun CirAnnotation.buildAnnotation(): KmAnnotation { val arguments = LinkedHashMap>(constantValueArguments.size + annotationValueArguments.size, 1F) - constantValueArguments.forEach { (name: Name, value: ConstantValue<*>) -> - arguments[name.asString()] = value.buildAnnotationArgument() + constantValueArguments.forEach { (name: CirName, value: CirConstantValue<*>) -> + arguments[name.name] = value.buildAnnotationArgument() + ?: error("Unexpected constant value inside of $this") } - annotationValueArguments.forEach { (name: Name, nested: CirAnnotation) -> - arguments[name.asString()] = KmAnnotationArgument.AnnotationValue(nested.buildAnnotation()) + annotationValueArguments.forEach { (name: CirName, nested: CirAnnotation) -> + arguments[name.name] = KmAnnotationArgument.AnnotationValue(nested.buildAnnotation()) } return KmAnnotation( - className = type.classifierId.asString(), + className = type.classifierId.toString(), arguments = arguments ) } -private fun ConstantValue<*>.buildAnnotationArgument(): KmAnnotationArgument<*> = when (this) { - is StringValue -> KmAnnotationArgument.StringValue(value) - is CharValue -> KmAnnotationArgument.CharValue(value) +private fun CirConstantValue<*>.buildAnnotationArgument(): KmAnnotationArgument<*>? = when (this) { + is CirConstantValue.StringValue -> KmAnnotationArgument.StringValue(value) + is CirConstantValue.CharValue -> KmAnnotationArgument.CharValue(value) - is ByteValue -> KmAnnotationArgument.ByteValue(value) - is ShortValue -> KmAnnotationArgument.ShortValue(value) - is IntValue -> KmAnnotationArgument.IntValue(value) - is LongValue -> KmAnnotationArgument.LongValue(value) + is CirConstantValue.ByteValue -> KmAnnotationArgument.ByteValue(value) + is CirConstantValue.ShortValue -> KmAnnotationArgument.ShortValue(value) + is CirConstantValue.IntValue -> KmAnnotationArgument.IntValue(value) + is CirConstantValue.LongValue -> KmAnnotationArgument.LongValue(value) - is UByteValue -> KmAnnotationArgument.UByteValue(value) - is UShortValue -> KmAnnotationArgument.UShortValue(value) - is UIntValue -> KmAnnotationArgument.UIntValue(value) - is ULongValue -> KmAnnotationArgument.ULongValue(value) + is CirConstantValue.UByteValue -> KmAnnotationArgument.UByteValue(value) + is CirConstantValue.UShortValue -> KmAnnotationArgument.UShortValue(value) + is CirConstantValue.UIntValue -> KmAnnotationArgument.UIntValue(value) + is CirConstantValue.ULongValue -> KmAnnotationArgument.ULongValue(value) - is FloatValue -> KmAnnotationArgument.FloatValue(value) - is DoubleValue -> KmAnnotationArgument.DoubleValue(value) - is BooleanValue -> KmAnnotationArgument.BooleanValue(value) + is CirConstantValue.FloatValue -> KmAnnotationArgument.FloatValue(value) + is CirConstantValue.DoubleValue -> KmAnnotationArgument.DoubleValue(value) + is CirConstantValue.BooleanValue -> KmAnnotationArgument.BooleanValue(value) - is EnumValue -> KmAnnotationArgument.EnumValue(enumClassId.asString(), enumEntryName.asString()) - is ArrayValue -> KmAnnotationArgument.ArrayValue(value.map { it.buildAnnotationArgument() }) + is CirConstantValue.EnumValue -> KmAnnotationArgument.EnumValue(enumClassId.toString(), enumEntryName.name) + is CirConstantValue.NullValue -> null - else -> error("Unsupported annotation argument type: ${this::class.java}, $this") + is CirConstantValue.ArrayValue -> KmAnnotationArgument.ArrayValue(value.compactMap { element -> + element.buildAnnotationArgument() ?: error("Unexpected constant value inside of $this") + }) } private fun CirValueParameter.buildValueParameter( context: MetadataBuildingVisitorContext ): KmValueParameter = KmValueParameter( flags = valueParameterFlags(), - name = name.asString() + name = name.name ).also { parameter -> annotations.mapTo(parameter.annotations) { it.buildAnnotation() } parameter.type = returnType.buildType(context) @@ -253,7 +253,7 @@ private fun List.buildTypeParameters( mapIndexedTo(output) { index, cirTypeParameter -> KmTypeParameter( flags = cirTypeParameter.typeParameterFlags(), - name = cirTypeParameter.name.asString(), + name = cirTypeParameter.name.name, id = context.typeParameterIndexOffset + index, variance = cirTypeParameter.variance.buildVariance() ).also { parameter -> @@ -289,7 +289,7 @@ private fun CirClassType.buildType( context: MetadataBuildingVisitorContext, expansion: TypeAliasExpansion ): KmType = KmType(typeFlags()).also { type -> - type.classifier = KmClassifier.Class(classifierId.asString()) + type.classifier = KmClassifier.Class(classifierId.toString()) arguments.mapTo(type.arguments) { it.buildArgument(context, expansion) } outerType?.let { type.outerType = it.buildType(context, expansion) } } @@ -313,7 +313,7 @@ private fun CirTypeAliasType.buildAbbreviationType( expansion: TypeAliasExpansion ): KmType { val abbreviationType = KmType(typeFlags()) - abbreviationType.classifier = KmClassifier.TypeAlias(classifierId.asString()) + abbreviationType.classifier = KmClassifier.TypeAlias(classifierId.toString()) arguments.mapTo(abbreviationType.arguments) { it.buildArgument(context, expansion) } return abbreviationType } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/flags.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/flags.kt index ea8a338be6f..2b97f1b2d6a 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/flags.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/flags.kt @@ -13,7 +13,6 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.commonizer.cir.* -import org.jetbrains.kotlin.resolve.constants.NullValue internal const val NO_FLAGS: Flags = 0 @@ -172,7 +171,7 @@ private inline val CirProperty.modifiersFlags: Flags get() = flagsOfNotNull( Flag.Property.IS_VAR.takeIf { isVar }, Flag.Property.IS_CONST.takeIf { isConst }, - Flag.Property.HAS_CONSTANT.takeIf { compileTimeInitializer.takeIf { it !is NullValue } != null }, + Flag.Property.HAS_CONSTANT.takeIf { compileTimeInitializer.takeIf { it !is CirConstantValue.NullValue } != null }, Flag.Property.IS_LATEINIT.takeIf { isLateInit }, Flag.Property.IS_EXTERNAL.takeIf { isExternal } ) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/metadataBuilder.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/metadataBuilder.kt index 443ca93498b..9b707ff9a72 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/metadataBuilder.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/metadata/metadataBuilder.kt @@ -15,10 +15,6 @@ import org.jetbrains.kotlin.descriptors.commonizer.stats.DeclarationType import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsCollector import org.jetbrains.kotlin.descriptors.commonizer.stats.StatsCollector.StatsKey import org.jetbrains.kotlin.descriptors.commonizer.utils.DEFAULT_CONSTRUCTOR_NAME -import org.jetbrains.kotlin.descriptors.commonizer.utils.strip -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.descriptors.commonizer.utils.firstNonNull import org.jetbrains.kotlin.descriptors.commonizer.metadata.MetadataBuildingVisitorContext.Path @@ -65,8 +61,8 @@ private class MetadataBuildingVisitor( val cirModule = moduleContext.get(node) ?: return null val fragments: MutableCollection = mutableListOf() - node.packages.mapNotNullTo(fragments) { (packageFqName, packageNode) -> - val packageContext = moduleContext.packageContext(packageFqName) + node.packages.mapNotNullTo(fragments) { (packageName, packageNode) -> + val packageContext = moduleContext.packageContext(packageName) packageNode.accept(this, packageContext)?.cast() } @@ -106,7 +102,7 @@ private class MetadataBuildingVisitor( } } - linkSealedClassesWithSubclasses(cirPackage.fqName, classConsumer) + linkSealedClassesWithSubclasses(cirPackage.packageName, classConsumer) val topLevelFunctions: Collection = node.functions.mapNotNull { (functionKey, functionNode) -> val functionContext = packageContext.callableMemberContext(functionKey.name) @@ -221,12 +217,12 @@ private class MetadataBuildingVisitor( Flag.Class.IS_ENUM_CLASS(clazz.flags) -> DeclarationType.ENUM_CLASS Flag.Class.IS_ENUM_ENTRY(clazz.flags) -> DeclarationType.ENUM_ENTRY Flag.Class.IS_INTERFACE(clazz.flags) -> when { - (classContext.currentPath as Path.Classifier).classifierId.isNestedClass -> DeclarationType.NESTED_INTERFACE + (classContext.currentPath as Path.Classifier).classifierId.isNestedEntity -> DeclarationType.NESTED_INTERFACE else -> DeclarationType.TOP_LEVEL_INTERFACE } else -> when { Flag.Class.IS_COMPANION_OBJECT(clazz.flags) -> DeclarationType.COMPANION_OBJECT - (classContext.currentPath as Path.Classifier).classifierId.isNestedClass -> DeclarationType.NESTED_CLASS + (classContext.currentPath as Path.Classifier).classifierId.isNestedEntity -> DeclarationType.NESTED_CLASS else -> DeclarationType.TOP_LEVEL_CLASS } } @@ -246,7 +242,7 @@ private class MetadataBuildingVisitor( propertyNode: CirPropertyNode ) = logDeclaration(propertyContext.targetIndex) { val declarationType = when { - (propertyContext.currentPath as Path.CallableMember).memberId.isNestedClass -> DeclarationType.NESTED_VAL + (propertyContext.currentPath as Path.CallableMember).memberId.isNestedEntity -> DeclarationType.NESTED_VAL propertyNode.targetDeclarations.firstNonNull().isConst -> DeclarationType.TOP_LEVEL_CONST_VAL else -> DeclarationType.TOP_LEVEL_VAL } @@ -266,7 +262,7 @@ private class MetadataBuildingVisitor( functionKey: FunctionApproximationKey ) = logDeclaration(functionContext.targetIndex) { val declarationType = when { - (functionContext.currentPath as Path.CallableMember).memberId.isNestedClass -> DeclarationType.NESTED_FUN + (functionContext.currentPath as Path.CallableMember).memberId.isNestedEntity -> DeclarationType.NESTED_FUN else -> DeclarationType.TOP_LEVEL_FUN } @@ -308,31 +304,30 @@ internal data class MetadataBuildingVisitorContext( } @Suppress("MemberVisibilityCanBePrivate") - class Module(val moduleName: Name) : Path() { - override fun toString() = moduleName.strip() + class Module(val moduleName: CirName) : Path() { + override fun toString() = moduleName.toStrippedString() } - class Package(val packageFqName: FqName) : Path() { - fun nestedClassifier(classifierName: Name) = Classifier(ClassId(packageFqName, classifierName)) - fun nestedCallableMember(memberName: Name) = CallableMember(ClassId(packageFqName, memberName)) + class Package(val packageName: CirPackageName) : Path() { + fun nestedClassifier(classifierName: CirName) = Classifier(CirEntityId.create(packageName, classifierName)) + fun nestedCallableMember(memberName: CirName) = CallableMember(CirEntityId.create(packageName, memberName)) - override fun toString() = packageFqName.asString() + override fun toString() = packageName.toString() } - class Classifier(val classifierId: ClassId) : Path() { - fun nestedClassifier(classifierName: Name) = Classifier(classifierId.createNestedClassId(classifierName)) - fun nestedCallableMember(memberName: Name) = CallableMember(classifierId.createNestedClassId(memberName)) + class Classifier(val classifierId: CirEntityId) : Path() { + fun nestedClassifier(classifierName: CirName) = Classifier(classifierId.createNestedEntityId(classifierName)) + fun nestedCallableMember(memberName: CirName) = CallableMember(classifierId.createNestedEntityId(memberName)) - override fun toString() = classifierId.asString() + override fun toString() = classifierId.toString() } - class CallableMember(val memberId: ClassId) : Path() { - override fun toString() = memberId.asString() + class CallableMember(val memberId: CirEntityId) : Path() { + override fun toString() = memberId.toString() } } - fun moduleContext(moduleName: Name): MetadataBuildingVisitorContext { - check(moduleName.isSpecial) + fun moduleContext(moduleName: CirName): MetadataBuildingVisitorContext { check(currentPath is Path.Empty) return MetadataBuildingVisitorContext( @@ -344,7 +339,7 @@ internal data class MetadataBuildingVisitorContext( ) } - fun packageContext(packageFqName: FqName): MetadataBuildingVisitorContext { + fun packageContext(packageName: CirPackageName): MetadataBuildingVisitorContext { check(currentPath is Path.Module) return MetadataBuildingVisitorContext( @@ -352,12 +347,12 @@ internal data class MetadataBuildingVisitorContext( target = target, isCommon = isCommon, typeParameterIndexOffset = 0, - currentPath = Path.Package(packageFqName) + currentPath = Path.Package(packageName) ) } fun classifierContext( - classifierName: Name, + classifierName: CirName, outerClassTypeParametersCount: Int = 0 ): MetadataBuildingVisitorContext { val newPath = when (currentPath) { @@ -382,7 +377,7 @@ internal data class MetadataBuildingVisitorContext( } fun callableMemberContext( - memberName: Name, + memberName: CirName, ownerClassTypeParametersCount: Int = 0 ): MetadataBuildingVisitorContext { val newPath = when (currentPath) { diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/constants.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/constants.kt deleted file mode 100644 index 2f5099ac568..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/constants.kt +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.descriptors.commonizer.utils - -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.constants.* - -internal fun checkConstantSupportedInCommonization( - constantValue: ConstantValue<*>, - constantName: Name? = null, - owner: Any, - allowAnnotationValues: Boolean, - onError: (String) -> Nothing = ::error -) { - checkConstantSupportedInCommonization( - constantValue = constantValue, - location = { "${owner::class.java}, $owner" + constantName?.asString()?.let { "[$it]" } }, - allowAnnotationValues = allowAnnotationValues, - onError = onError - ) -} - -private fun checkConstantSupportedInCommonization( - constantValue: ConstantValue<*>, - location: () -> String, - allowAnnotationValues: Boolean, - onError: (String) -> Nothing -) { - @Suppress("TrailingComma") - when (constantValue) { - is StringValue, - is IntegerValueConstant<*>, - is UnsignedValueConstant<*>, - is BooleanValue, - is NullValue, - is DoubleValue, - is FloatValue, - is EnumValue -> { - return // OK - } - is AnnotationValue -> { - if (allowAnnotationValues) { - return // OK - } // else fail (see below) - } - is ArrayValue -> { - constantValue.value.forEachIndexed { index, innerConstantValue -> - checkConstantSupportedInCommonization( - constantValue = innerConstantValue, - location = { "${location()}[$index]" }, - allowAnnotationValues = allowAnnotationValues, - onError = onError - ) - } - return // OK - } - } - - onError("Unsupported const value type: ${constantValue::class.java}, $constantValue at ${location()}") -} - diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/fqName.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/fqName.kt index ef3085ea234..cb356d0d220 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/fqName.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/fqName.kt @@ -8,72 +8,61 @@ package org.jetbrains.kotlin.descriptors.commonizer.utils import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor -import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.konan.impl.ForwardDeclarationsFqNames -internal val DEPRECATED_ANNOTATION_FQN: FqName = FqName(Deprecated::class.java.name).intern() -internal val DEPRECATED_ANNOTATION_CLASS_ID: ClassId = internedClassId(DEPRECATED_ANNOTATION_FQN) +internal val DEPRECATED_ANNOTATION_FQN: FqName = FqName(Deprecated::class.java.name) +internal val DEPRECATED_ANNOTATION_CLASS_ID: CirEntityId = CirEntityId.create("kotlin/Deprecated") -internal val ANY_CLASS_ID: ClassId = internedClassId(StandardNames.FqNames.any.toSafe().intern()) -private val NOTHING_CLASS_ID: ClassId = internedClassId(StandardNames.FqNames.nothing.toSafe().intern()) +internal val ANY_CLASS_ID: CirEntityId = CirEntityId.create("kotlin/Any") +private val NOTHING_CLASS_ID: CirEntityId = CirEntityId.create("kotlin/Nothing") -internal val SPECIAL_CLASS_WITHOUT_SUPERTYPES_CLASS_IDS = listOf( +internal val SPECIAL_CLASS_WITHOUT_SUPERTYPES_CLASS_IDS: List = listOf( ANY_CLASS_ID, NOTHING_CLASS_ID ) -private val STANDARD_KOTLIN_PACKAGES = listOf( - StandardNames.BUILT_INS_PACKAGE_FQ_NAME.asString(), - "kotlinx" +private val STANDARD_KOTLIN_PACKAGES: List = listOf( + CirPackageName.create(StandardNames.BUILT_INS_PACKAGE_FQ_NAME), + CirPackageName.create("kotlinx") ) -private val KOTLIN_NATIVE_SYNTHETIC_PACKAGES = ForwardDeclarationsFqNames.syntheticPackages - .map { fqName -> - check(!fqName.isRoot) - fqName.asString() +private val KOTLIN_NATIVE_SYNTHETIC_PACKAGES: List = ForwardDeclarationsFqNames.syntheticPackages + .map { packageFqName -> + check(!packageFqName.isRoot) + CirPackageName.create(packageFqName) } -private const val CINTEROP_PACKAGE = "kotlinx.cinterop" +private val CINTEROP_PACKAGE: CirPackageName = CirPackageName.create("kotlinx.cinterop") -private val OBJC_INTEROP_CALLABLE_ANNOTATIONS = listOf( - "ObjCMethod", - "ObjCConstructor", - "ObjCFactory" +private val OBJC_INTEROP_CALLABLE_ANNOTATIONS: List = listOf( + CirName.create("ObjCMethod"), + CirName.create("ObjCConstructor"), + CirName.create("ObjCFactory") ) -internal val DEFAULT_CONSTRUCTOR_NAME = Name.identifier("").intern() -internal val DEFAULT_SETTER_VALUE_NAME = Name.identifier("value").intern() +internal val DEFAULT_CONSTRUCTOR_NAME: CirName = CirName.create("") +internal val DEFAULT_SETTER_VALUE_NAME: CirName = CirName.create("value") internal fun Name.strip(): String = asString().removeSurrounding("<", ">") -internal val FqName.isUnderStandardKotlinPackages: Boolean - get() = hasAnyPrefix(STANDARD_KOTLIN_PACKAGES) +internal val CirPackageName.isUnderStandardKotlinPackages: Boolean + get() = STANDARD_KOTLIN_PACKAGES.any(::startsWith) -internal val FqName.isUnderKotlinNativeSyntheticPackages: Boolean - get() = hasAnyPrefix(KOTLIN_NATIVE_SYNTHETIC_PACKAGES) +internal val CirPackageName.isUnderKotlinNativeSyntheticPackages: Boolean + get() = KOTLIN_NATIVE_SYNTHETIC_PACKAGES.any(::startsWith) -@Suppress("NOTHING_TO_INLINE") -private inline fun FqName.hasAnyPrefix(prefixes: List): Boolean = - asString().let { fqName -> prefixes.any(fqName::hasPrefix) } - -private fun String.hasPrefix(prefix: String): Boolean { - val lengthDifference = length - prefix.length - return when { - lengthDifference == 0 -> this == prefix - lengthDifference > 0 -> this[prefix.length] == '.' && this.startsWith(prefix) - else -> false - } -} - -internal val ClassId.isObjCInteropCallableAnnotation: Boolean - get() = packageFqName.asString() == CINTEROP_PACKAGE && relativeClassName.asString() in OBJC_INTEROP_CALLABLE_ANNOTATIONS +internal val CirEntityId.isObjCInteropCallableAnnotation: Boolean + get() = packageName == CINTEROP_PACKAGE && relativeNameSegments.singleOrNull() in OBJC_INTEROP_CALLABLE_ANNOTATIONS internal val AnnotationDescriptor.isObjCInteropCallableAnnotation: Boolean get() { val classifier = type.declarationDescriptor - return classifier.name.asString() in OBJC_INTEROP_CALLABLE_ANNOTATIONS - && (classifier.containingDeclaration as? PackageFragmentDescriptor)?.fqName?.asString() == CINTEROP_PACKAGE + return CirName.create(classifier.name) in OBJC_INTEROP_CALLABLE_ANNOTATIONS + && (classifier.containingDeclaration as? PackageFragmentDescriptor)?.fqName?.let(CirPackageName::create) == CINTEROP_PACKAGE } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/interners.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/interners.kt deleted file mode 100644 index e72e708c02a..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/interners.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package org.jetbrains.kotlin.descriptors.commonizer.utils - -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name - -internal fun FqName.intern(): FqName = fqNameInterner.intern(this) -internal fun Name.intern(): Name = nameInterner.intern(this) - -@Suppress("NOTHING_TO_INLINE") -internal inline fun internedClassId(topLevelFqName: FqName): ClassId { - val packageFqName = topLevelFqName.parent().intern() - val className = topLevelFqName.shortName().intern() - return internedClassId(packageFqName, className) -} - -internal fun internedClassId(packageFqName: FqName, classifierName: Name): ClassId { - val relativeClassName = FqName.topLevel(classifierName).intern() - return ClassId(packageFqName, relativeClassName, false).intern() -} - -internal fun internedClassId(ownerClassId: ClassId, nestedClassName: Name): ClassId { - val relativeClassName = ownerClassId.relativeClassName.child(nestedClassName).intern() - return ClassId(ownerClassId.packageFqName, relativeClassName, ownerClassId.isLocal).intern() -} - -@Suppress("NOTHING_TO_INLINE") -private inline fun ClassId.intern(): ClassId = classIdInterner.intern(this) - -private val fqNameInterner = Interner() -private val nameInterner = Interner() -private val classIdInterner = Interner() diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/moduleDescriptor.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/moduleDescriptor.kt index 6a621fe419e..c1d5f843939 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/moduleDescriptor.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/moduleDescriptor.kt @@ -8,12 +8,13 @@ package org.jetbrains.kotlin.descriptors.commonizer.utils import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.konan.util.KlibMetadataFactories import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer -import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.serialization.konan.impl.KlibResolvedModuleDescriptorsFactoryImpl import org.jetbrains.kotlin.storage.StorageManager @@ -31,27 +32,29 @@ internal fun createKotlinNativeForwardDeclarationsModule( storageManager = storageManager ) -internal fun MemberScope.resolveClassOrTypeAlias(relativeClassName: FqName): ClassifierDescriptorWithTypeParameters? { +internal fun MemberScope.resolveClassOrTypeAlias(relativeNameSegments: Array): ClassifierDescriptorWithTypeParameters? { var memberScope: MemberScope = this if (memberScope is MemberScope.Empty) return null - val classifierName = if ('.' in relativeClassName.asString()) { - // resolve member scope of the nested class - relativeClassName.pathSegments().reduce { first, second -> - memberScope = (memberScope.getContributedClassifier( - first, - NoLookupLocation.FOR_ALREADY_TRACKED - ) as? ClassDescriptor)?.unsubstitutedMemberScope ?: return null + val classifierName = when (relativeNameSegments.size) { + 0 -> return null + 1 -> relativeNameSegments[0] + else -> { + // resolve member scope of the nested class + relativeNameSegments.reduce { first, second -> + memberScope = (memberScope.getContributedClassifier( + Name.identifier(first.name), + NoLookupLocation.FOR_ALREADY_TRACKED + ) as? ClassDescriptor)?.unsubstitutedMemberScope ?: return null - second + second + } } - } else { - relativeClassName.shortName() } return memberScope.getContributedClassifier( - classifierName, + Name.identifier(classifierName.name), NoLookupLocation.FOR_ALREADY_TRACKED ) as? ClassifierDescriptorWithTypeParameters } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/type.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/type.kt index afea96fd00a..d56c1f07fb0 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/type.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/type.kt @@ -9,8 +9,10 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeSignature -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.typeUtil.makeNotNullable @@ -30,10 +32,13 @@ internal fun extractExpandedType(abbreviated: AbbreviatedType): SimpleType { return expanded } -internal val ClassifierDescriptorWithTypeParameters.internedClassId: ClassId +internal val ClassifierDescriptorWithTypeParameters.classifierId: CirEntityId get() = when (val owner = containingDeclaration) { - is PackageFragmentDescriptor -> internedClassId(owner.fqName.intern(), name.intern()) - is ClassDescriptor -> internedClassId(owner.internedClassId, name.intern()) + is PackageFragmentDescriptor -> CirEntityId.create( + packageName = CirPackageName.create(owner.fqName), + relativeName = CirName.create(name) + ) + is ClassDescriptor -> owner.classifierId.createNestedEntityId(CirName.create(name)) else -> error("Unexpected containing declaration type for $this: ${owner::class}, $owner") } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/AnnotationsCommonizerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/AnnotationsCommonizerTest.kt index 26a7a0e365a..c6a9a3e36de 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/AnnotationsCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/AnnotationsCommonizerTest.kt @@ -5,18 +5,11 @@ package org.jetbrains.kotlin.descriptors.commonizer.core -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation -import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassType +import org.jetbrains.kotlin.descriptors.commonizer.cir.* +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirConstantValue.* import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirAnnotationFactory import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.resolve.constants.ArrayValue -import org.jetbrains.kotlin.resolve.constants.ConstantValue -import org.jetbrains.kotlin.resolve.constants.EnumValue -import org.jetbrains.kotlin.resolve.constants.StringValue import org.junit.Test import kotlin.DeprecationLevel.* @@ -287,8 +280,8 @@ class AnnotationsCommonizerTest : AbstractCommonizerTest, Li private fun mockAnnotation( fqName: String, - constantValueArguments: Map> = emptyMap(), - annotationValueArguments: Map = emptyMap() + constantValueArguments: Map> = emptyMap(), + annotationValueArguments: Map = emptyMap() ): CirAnnotation = CirAnnotationFactory.create( type = CirTypeFactory.create(mockClassType(fqName)) as CirClassType, constantValueArguments = constantValueArguments, @@ -305,10 +298,8 @@ private fun mockDeprecated( mockAnnotation( fqName = "kotlin.ReplaceWith", constantValueArguments = mapOf( - Name.identifier("expression") to StringValue(replaceWithExpression), - Name.identifier("imports") to ArrayValue(replaceWithImports.map(::StringValue)) { - it.builtIns.getArrayElementType(it.builtIns.stringType) - } + CirName.create("expression") to StringValue(replaceWithExpression), + CirName.create("imports") to ArrayValue(replaceWithImports.map(::StringValue)) ), annotationValueArguments = emptyMap() ) @@ -316,15 +307,12 @@ private fun mockDeprecated( return mockAnnotation( fqName = "kotlin.Deprecated", - constantValueArguments = HashMap>().apply { - this[Name.identifier("message")] = StringValue(message) + constantValueArguments = HashMap>().apply { + this[CirName.create("message")] = StringValue(message) if (level != WARNING) - this[Name.identifier("level")] = EnumValue( - ClassId.topLevel(FqName("kotlin.DeprecationLevel")), - Name.identifier(level.name) - ) + this[CirName.create("level")] = EnumValue(CirEntityId.create("kotlin/DeprecationLevel"), CirName.create(level.name)) }, - annotationValueArguments = if (replaceWith != null) mapOf(Name.identifier("replaceWith") to replaceWith) else emptyMap() + annotationValueArguments = if (replaceWith != null) mapOf(CirName.create("replaceWith") to replaceWith) else emptyMap() ) } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/CirEntityIdTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/CirEntityIdTest.kt new file mode 100644 index 00000000000..c0e93bea0f8 --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/CirEntityIdTest.kt @@ -0,0 +1,251 @@ +/* + * 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.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName +import org.jetbrains.kotlin.name.ClassId +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertSame +import kotlin.test.assertTrue + +class CirEntityIdTest { + @Test + fun createAndIntern() { + class TestRow( + val rawEntityId: String, + val packageSegments: Array, + val rawRelativeNameSegments: List + ) + + listOf( + TestRow( + rawEntityId = "", + packageSegments = emptyArray(), + rawRelativeNameSegments = emptyList() + ), + TestRow( + rawEntityId = "/", + packageSegments = emptyArray(), + rawRelativeNameSegments = emptyList() + ), + TestRow( + rawEntityId = "foo/", + packageSegments = arrayOf("foo"), + rawRelativeNameSegments = emptyList() + ), + TestRow( + rawEntityId = "foo/bar/", + packageSegments = arrayOf("foo", "bar"), + rawRelativeNameSegments = emptyList() + ), + TestRow( + rawEntityId = "foo/bar/baz/", + packageSegments = arrayOf("foo", "bar", "baz"), + rawRelativeNameSegments = emptyList() + ), + TestRow( + rawEntityId = "My", + packageSegments = emptyArray(), + rawRelativeNameSegments = listOf("My") + ), + TestRow( + rawEntityId = "My.Test", + packageSegments = emptyArray(), + rawRelativeNameSegments = listOf("My", "Test") + ), + TestRow( + rawEntityId = "My.Test.Class", + packageSegments = emptyArray(), + rawRelativeNameSegments = listOf("My", "Test", "Class") + ), + TestRow( + rawEntityId = "/My", + packageSegments = emptyArray(), + rawRelativeNameSegments = listOf("My") + ), + TestRow( + rawEntityId = "/My.Test", + packageSegments = emptyArray(), + rawRelativeNameSegments = listOf("My", "Test") + ), + TestRow( + rawEntityId = "/My.Test.Class", + packageSegments = emptyArray(), + rawRelativeNameSegments = listOf("My", "Test", "Class") + ), + TestRow( + rawEntityId = "foo/My", + packageSegments = arrayOf("foo"), + rawRelativeNameSegments = listOf("My") + ), + TestRow( + rawEntityId = "foo/My.Test", + packageSegments = arrayOf("foo"), + rawRelativeNameSegments = listOf("My", "Test") + ), + TestRow( + rawEntityId = "foo/My.Test.Class", + packageSegments = arrayOf("foo"), + rawRelativeNameSegments = listOf("My", "Test", "Class") + ), + TestRow( + rawEntityId = "foo/bar/My", + packageSegments = arrayOf("foo", "bar"), + rawRelativeNameSegments = listOf("My") + ), + TestRow( + rawEntityId = "foo/bar/My.Test", + packageSegments = arrayOf("foo", "bar"), + rawRelativeNameSegments = listOf("My", "Test") + ), + TestRow( + rawEntityId = "foo/bar/My.Test.Class", + packageSegments = arrayOf("foo", "bar"), + rawRelativeNameSegments = listOf("My", "Test", "Class") + ), + TestRow( + rawEntityId = "foo/bar/baz/My", + packageSegments = arrayOf("foo", "bar", "baz"), + rawRelativeNameSegments = listOf("My") + ), + TestRow( + rawEntityId = "foo/bar/baz/My.Test", + packageSegments = arrayOf("foo", "bar", "baz"), + rawRelativeNameSegments = listOf("My", "Test") + ), + TestRow( + rawEntityId = "foo/bar/baz/My.Test.Class", + packageSegments = arrayOf("foo", "bar", "baz"), + rawRelativeNameSegments = listOf("My", "Test", "Class") + ) + ).forEach { testRow -> + with(testRow) { + // nullable, because ClassId may not have empty class name + val classifierId: ClassId? = if (rawRelativeNameSegments.isNotEmpty()) ClassId.fromString(rawEntityId) else null + + val packageName = CirPackageName.create(packageSegments) + val relativeNameSegments = rawRelativeNameSegments.map(CirName::create).toTypedArray() + + val entityIds = listOfNotNull( + CirEntityId.create(rawEntityId), + CirEntityId.create(rawEntityId), + classifierId?.let(CirEntityId::create), + classifierId?.let(CirEntityId::create), + CirEntityId.create(packageName, relativeNameSegments), + CirEntityId.create(packageName, relativeNameSegments) + ) + + val first = entityIds.first() + entityIds.forEach { entityId -> + assertSame(first, entityId) + assertSame(packageName, entityId.packageName) + assertTrue(relativeNameSegments.contentEquals(entityId.relativeNameSegments)) + } + } + } + } + + @Test + fun toStringConversion() { + listOf( + "" to "/", + "/" to "/", + "foo/" to "foo/", + "foo/bar/" to "foo/bar/", + "foo/bar/baz/" to "foo/bar/baz/", + "My" to "/My", + "My.Test" to "/My.Test", + "My.Test.Class" to "/My.Test.Class", + "foo/My" to "foo/My", + "foo/bar/My.Test" to "foo/bar/My.Test", + "foo/bar/baz/My.Test.Class" to "foo/bar/baz/My.Test.Class" + ).forEach { (rawEntityId, asStringRepresentation) -> + assertEquals(asStringRepresentation, CirEntityId.create(rawEntityId).toString()) + } + } + + @Test + fun isNested() { + listOf( + "" to false, + "/" to false, + "foo/" to false, + "foo/bar/" to false, + "My" to false, + "My.Test" to true, + "My.Test.Class" to true, + "/My" to false, + "/My.Test" to true, + "/My.Test.Class" to true, + "foo/My" to false, + "foo/My.Test" to true, + "foo/My.Test.Class" to true, + "foo/bar/My" to false, + "foo/bar/My.Test" to true, + "foo/bar/My.Test.Class" to true, + ).forEach { (rawEntityId, isNested) -> + assertEquals(isNested, CirEntityId.create(rawEntityId).isNestedEntity) + } + } + + @Test + fun createNested() { + val nested1 = CirName.create("Nested1") + val nested2 = CirName.create("Nested2") + + listOf( + "", + "/", + "foo/", + "foo/bar/", + "Outer", + "/Outer", + "foo/Outer", + "foo/bar/Outer", + "Outer.Nested", + "/Outer.Nested", + "foo/Outer.Nested", + "foo/bar/Outer.Nested" + ).forEach { rawEntityId -> + val entityId = CirEntityId.create(rawEntityId) + val n1 = entityId.createNestedEntityId(nested1) + assertSame(entityId.packageName, n1.packageName) + assertEquals(entityId.relativeNameSegments.isNotEmpty(), n1.isNestedEntity) + assertEquals(entityId.relativeNameSegments.toList(), n1.relativeNameSegments.dropLast(1)) + + val n2 = n1.createNestedEntityId(nested2) + assertSame(entityId.packageName, n2.packageName) + assertTrue(n2.isNestedEntity) + assertEquals(entityId.relativeNameSegments.toList(), n2.relativeNameSegments.dropLast(2)) + } + } + + @Test + fun createParent() { + listOf( + "" to null, + "foo/" to null, + "foo/bar/" to null, + "Outer" to null, + "foo/Outer" to null, + "foo/bar/Outer" to null, + "Outer.Nested1" to "Outer", + "foo/Outer.Nested1" to "foo/Outer", + "foo/bar/Outer.Nested1" to "foo/bar/Outer", + "Outer.Nested1.Nested2" to "Outer.Nested1", + "foo/Outer.Nested1.Nested2" to "foo/Outer.Nested1", + "foo/bar/Outer.Nested1.Nested2" to "foo/bar/Outer.Nested1" + ).forEach { (rawEntityId, rawParentEntityId) -> + val entityId = CirEntityId.create(rawEntityId) + val parentEntityId = rawParentEntityId?.let(CirEntityId::create) + assertSame(parentEntityId, entityId.getParentEntityId()) + } + } +} + diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/CirNameTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/CirNameTest.kt new file mode 100644 index 00000000000..f551dda6eea --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/CirNameTest.kt @@ -0,0 +1,54 @@ +/* + * 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.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName +import org.jetbrains.kotlin.name.Name +import org.junit.Test +import kotlin.test.assertSame +import kotlin.test.assertEquals + +class CirNameTest { + @Test + fun createAndIntern() { + listOf("", "foo", "bar", "").forEach { rawName -> + val kotlinName = Name.guessByFirstCharacter(rawName) + + val names = listOf( + CirName.create(rawName), + CirName.create(rawName), + CirName.create(kotlinName), + CirName.create(kotlinName) + ) + + val first = names.first() + names.forEach { name -> + assertSame(first, name) + } + } + } + + @Test + fun toStringConversion() { + listOf("", "foo", "bar", "").forEach { rawName -> + val name = CirName.create(rawName) + assertEquals(rawName, name.name) + assertEquals(rawName, name.toString()) + } + } + + @Test + fun toStrippedStringConversion() { + listOf( + "" to "", + "foo" to "foo", + "bar" to "bar", + "" to "stdlib" + ).forEach { (rawName, strippedName) -> + assertEquals(strippedName, CirName.create(rawName).toStrippedString()) + } + } +} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/CirPackageNameTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/CirPackageNameTest.kt new file mode 100644 index 00000000000..bc2807d3886 --- /dev/null +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/CirPackageNameTest.kt @@ -0,0 +1,109 @@ +/* + * 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.descriptors.commonizer.core + +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackageName +import org.jetbrains.kotlin.name.FqName +import org.junit.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertSame +import kotlin.test.assertTrue + +class CirPackageNameTest { + @Test + fun createAndIntern() { + listOf( + "" to emptyArray(), + "foo" to arrayOf("foo"), + "foo.bar" to arrayOf("foo", "bar"), + "foo.bar.baz" to arrayOf("foo", "bar", "baz") + ).forEach { (rawPackageFqName, segments) -> + val packageFqName = FqName(rawPackageFqName) + + val packageNames = listOf( + CirPackageName.create(rawPackageFqName), + CirPackageName.create(rawPackageFqName), + CirPackageName.create(packageFqName), + CirPackageName.create(packageFqName), + CirPackageName.create(segments), + CirPackageName.create(segments) + ) + + val first = packageNames.first() + packageNames.forEach { packageName -> + assertTrue(segments.contentEquals(packageName.segments)) + assertSame(first, packageName) + } + } + } + + @Test + fun createRoot() { + val rootPackageNames = listOf( + CirPackageName.create(""), + CirPackageName.create(FqName("")), + CirPackageName.create(FqName.ROOT), + CirPackageName.create(emptyArray()) + ) + + val first = rootPackageNames.first() + rootPackageNames.forEach { rootPackageName -> + assertSame(first, rootPackageName) + assertTrue(rootPackageName.segments.isEmpty()) + assertTrue(rootPackageName.isRoot()) + assertSame(CirPackageName.ROOT, rootPackageName) + } + } + + @Test + fun toStringConversion() { + listOf( + "" to emptyArray(), + "foo" to arrayOf("foo"), + "foo.bar" to arrayOf("foo", "bar"), + "foo.bar.baz" to arrayOf("foo", "bar", "baz") + ).forEach { (rawPackageFqName, segments) -> + assertEquals(rawPackageFqName, CirPackageName.create(segments).toString()) + } + } + + @Test + fun toMetadataStringConversion() { + listOf( + "" to "", + "foo" to "foo", + "foo.bar" to "foo/bar", + "foo.bar.baz" to "foo/bar/baz" + ).forEach { (rawPackageFqName, metadataPackageFqName) -> + assertEquals(metadataPackageFqName, CirPackageName.create(rawPackageFqName).toMetadataString()) + } + } + + @Test + fun startsWith() { + val packageNames = listOf("", "foo", "foo.bar", "foo.bar.baz").map(CirPackageName::create) + + for (i in packageNames.indices) { + val a = packageNames[i] + for (j in packageNames.indices) { + val b = packageNames[j] + assertEquals(i >= j, a.startsWith(b)) + } + } + } + + @Test + fun notStartsWith() { + listOf( + "aa" to "ab", + "aa.bb" to "aa.bc", + "aa.bb" to "aa.bb.cc" + ).forEach { (a, b) -> + assertFalse(CirPackageName.create(a).startsWith(CirPackageName.create(b))) + } + } +} diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/LoweringVisibilityCommonizerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/LoweringVisibilityCommonizerTest.kt index fd50b7fde7d..4c93eeff426 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/LoweringVisibilityCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/LoweringVisibilityCommonizerTest.kt @@ -9,9 +9,9 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities.* import org.jetbrains.kotlin.descriptors.DescriptorVisibility +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirContainingClass import org.jetbrains.kotlin.descriptors.commonizer.cir.CirFunctionOrProperty import org.jetbrains.kotlin.descriptors.commonizer.cir.CirHasVisibility -import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirContainingClassDetailsFactory import org.jetbrains.kotlin.descriptors.commonizer.cir.impl.unsupported import org.junit.Test @@ -50,12 +50,12 @@ abstract class LoweringVisibilityCommonizerTest( override val typeParameters get() = unsupported() override val visibility = this@toMock override val modality get() = if (areMembersVirtual) Modality.OPEN else Modality.FINAL - override val containingClassDetails = if (areMembersVirtual) - CirContainingClassDetailsFactory.create( - kind = ClassKind.CLASS, - modality = Modality.OPEN, - isData = false - ) else null + override val containingClass = if (areMembersVirtual) + object : CirContainingClass { + override val modality get() = Modality.OPEN + override val kind get() = ClassKind.CLASS + override val isData get() = false + } else null override val extensionReceiver get() = unsupported() override val returnType get() = unsupported() override val kind get() = unsupported() diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizerTest.kt index 1d482ce5c20..d1dd0ab3eed 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizerTest.kt @@ -9,16 +9,16 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.descriptors.commonizer.LeafTarget import org.jetbrains.kotlin.descriptors.commonizer.SharedTarget +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassFactory import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeAliasFactory import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.* +import org.jetbrains.kotlin.descriptors.commonizer.utils.classifierId import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderStandardKotlinPackages import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType import org.jetbrains.kotlin.descriptors.commonizer.utils.mockTAType -import org.jetbrains.kotlin.name.ClassId -import org.jetbrains.kotlin.resolve.descriptorUtil.classId import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.getAbbreviation @@ -37,7 +37,7 @@ class TypeCommonizerTest : AbstractCommonizerTest() { forwardDeclarations = CirForwardDeclarations.default(), dependeeLibraries = mapOf( FAKE_SHARED_TARGET to object : CirProvidedClassifiers { - override fun hasClassifier(classifierId: ClassId): Boolean = classifierId.packageFqName.isUnderStandardKotlinPackages + override fun hasClassifier(classifierId: CirEntityId): Boolean = classifierId.packageName.isUnderStandardKotlinPackages } ) ) @@ -476,7 +476,7 @@ class TypeCommonizerTest : AbstractCommonizerTest() { val descriptor = (type.getAbbreviation() ?: type).constructor.declarationDescriptor when (descriptor) { is ClassDescriptor -> { - val classId = descriptor.classId ?: error("No class ID for ${descriptor::class.java}, $descriptor") + val classId = descriptor.classifierId val node = classifiers.classNode(classId) { buildClassNode( storageManager = LockBasedStorageManager.NO_LOCKS, @@ -489,7 +489,7 @@ class TypeCommonizerTest : AbstractCommonizerTest() { node.targetDeclarations[index] = CirClassFactory.create(descriptor) } is TypeAliasDescriptor -> { - val typeAliasId = descriptor.classId ?: error("No class ID for ${descriptor::class.java}, $descriptor") + val typeAliasId = descriptor.classifierId val node = classifiers.typeAliasNode(typeAliasId) { buildTypeAliasNode( storageManager = LockBasedStorageManager.NO_LOCKS, @@ -539,10 +539,10 @@ class TypeCommonizerTest : AbstractCommonizerTest() { private val FAKE_SHARED_TARGET = SharedTarget(setOf(LeafTarget("a"), LeafTarget("b"))) - private fun CirKnownClassifiers.classNode(classId: ClassId, computation: () -> CirClassNode) = + private fun CirKnownClassifiers.classNode(classId: CirEntityId, computation: () -> CirClassNode) = commonized.classNode(classId) ?: computation() - private fun CirKnownClassifiers.typeAliasNode(typeAliasId: ClassId, computation: () -> CirTypeAliasNode) = + private fun CirKnownClassifiers.typeAliasNode(typeAliasId: CirEntityId, computation: () -> CirTypeAliasNode) = commonized.typeAliasNode(typeAliasId) ?: computation() } } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizerTest.kt index 3057e51eb13..425d53aa1b7 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizerTest.kt @@ -5,12 +5,12 @@ package org.jetbrains.kotlin.descriptors.commonizer.core +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeParameter import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeParameterFactory import org.jetbrains.kotlin.descriptors.commonizer.utils.MOCK_CLASSIFIERS import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.Variance import org.junit.Test @@ -90,7 +90,7 @@ class TypeParameterCommonizerTest : AbstractCommonizerTest = listOf("kotlin.Any") ) = CirTypeParameterFactory.create( annotations = emptyList(), - name = Name.identifier(name), + name = CirName.create(name), isReified = isReified, variance = variance, upperBounds = upperBounds.map { CirTypeFactory.create(mockClassType(it)) } diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizerTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizerTest.kt index 59d129249de..65e80ef656b 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizerTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizerTest.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType import org.jetbrains.kotlin.descriptors.commonizer.cir.CirValueParameter import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirTypeFactory @@ -14,7 +15,6 @@ import org.jetbrains.kotlin.descriptors.commonizer.core.TypeCommonizerTest.Compa import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirKnownClassifiers import org.jetbrains.kotlin.descriptors.commonizer.utils.MOCK_CLASSIFIERS import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType -import org.jetbrains.kotlin.name.Name import org.junit.Test class ValueParameterCommonizerTest : AbstractCommonizerTest() { @@ -158,7 +158,7 @@ class ValueParameterCommonizerTest : AbstractCommonizerTest, override val returnType: CirType, override val varargElementType: CirType?, diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/utils/mocks.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/utils/mocks.kt index 62f37b967d5..24cb7675972 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/utils/mocks.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/utils/mocks.kt @@ -13,14 +13,14 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.commonizer.* import org.jetbrains.kotlin.descriptors.commonizer.ResultsConsumer.ModuleResult import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.ModuleInfo +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirEntityId +import org.jetbrains.kotlin.descriptors.commonizer.cir.CirName import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassFactory import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.* import org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl import org.jetbrains.kotlin.library.SerializedMetadata -import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.parentOrNull import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.storage.LockBasedStorageManager @@ -126,7 +126,7 @@ internal val MOCK_CLASSIFIERS = CirKnownClassifiers( LockBasedStorageManager.NO_LOCKS.createNullableLazyValue { CirClassFactory.create( annotations = emptyList(), - name = Name.identifier("kotlin.Any"), + name = CirName.create("Any"), typeParameters = emptyList(), visibility = DescriptorVisibilities.PUBLIC, modality = Modality.OPEN, @@ -139,17 +139,17 @@ internal val MOCK_CLASSIFIERS = CirKnownClassifiers( isExternal = false ) }, - ClassId.fromString("kotlin/Any") + CirEntityId.create("kotlin/Any") ) - override fun classNode(classId: ClassId) = MOCK_CLASS_NODE - override fun typeAliasNode(typeAliasId: ClassId) = error("This method should not be called") - override fun addClassNode(classId: ClassId, node: CirClassNode) = error("This method should not be called") - override fun addTypeAliasNode(typeAliasId: ClassId, node: CirTypeAliasNode) = error("This method should not be called") + override fun classNode(classId: CirEntityId) = MOCK_CLASS_NODE + override fun typeAliasNode(typeAliasId: CirEntityId) = error("This method should not be called") + override fun addClassNode(classId: CirEntityId, node: CirClassNode) = error("This method should not be called") + override fun addTypeAliasNode(typeAliasId: CirEntityId, node: CirTypeAliasNode) = error("This method should not be called") }, forwardDeclarations = object : CirForwardDeclarations { - override fun isExportedForwardDeclaration(classId: ClassId) = false - override fun addExportedForwardDeclaration(classId: ClassId) = error("This method should not be called") + override fun isExportedForwardDeclaration(classId: CirEntityId) = false + override fun addExportedForwardDeclaration(classId: CirEntityId) = error("This method should not be called") }, dependeeLibraries = emptyMap() ) diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt index 64e78bf12ca..0dde6f9dfb7 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/J2kPostProcessor.kt @@ -133,7 +133,7 @@ private val errorsFixingDiagnosticBasedPostProcessingGroup = Errors.VIRTUAL_MEMBER_HIDDEN ), diagnosticBasedProcessing( - RemoveModifierFix.createRemoveModifierFromListOwnerFactory(KtTokens.OPEN_KEYWORD), + RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(KtTokens.OPEN_KEYWORD), Errors.NON_FINAL_MEMBER_IN_FINAL_CLASS, Errors.NON_FINAL_MEMBER_IN_OBJECT ), diagnosticBasedProcessing( diff --git a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/diagnosticBasedPostProcessing.kt b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/diagnosticBasedPostProcessing.kt index bd6c15fa25f..3d80bb185fd 100644 --- a/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/diagnosticBasedPostProcessing.kt +++ b/nj2k/nj2k-services/src/org/jetbrains/kotlin/nj2k/postProcessing/diagnosticBasedPostProcessing.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.idea.core.util.range import org.jetbrains.kotlin.idea.quickfix.AddExclExclCallFix import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionsFactory import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory +import org.jetbrains.kotlin.idea.quickfix.QuickFixFactory import org.jetbrains.kotlin.idea.resolve.ResolutionFacade import org.jetbrains.kotlin.idea.util.application.runReadAction import org.jetbrains.kotlin.nj2k.NewJ2kConverterContext @@ -86,11 +87,12 @@ inline fun diagnosticBasedProcessing( } } -fun diagnosticBasedProcessing(fixFactory: KotlinIntentionActionsFactory, vararg diagnosticFactory: DiagnosticFactory<*>) = +fun diagnosticBasedProcessing(fixFactory: QuickFixFactory, vararg diagnosticFactory: DiagnosticFactory<*>) = object : DiagnosticBasedProcessing { override val diagnosticFactories = diagnosticFactory.toList() override fun fix(diagnostic: Diagnostic) { - val fix = runReadAction { fixFactory.createActions(diagnostic).singleOrNull() } ?: return + val actionFactory = fixFactory.asKotlinIntentionActionsFactory() + val fix = runReadAction { actionFactory.createActions(diagnostic).singleOrNull() } ?: return runUndoTransparentActionInEdt(inWriteAction = true) { fix.invoke(diagnostic.psiElement.project, null, diagnostic.psiFile) } diff --git a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableQuickFixContributor.kt b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableQuickFixContributor.kt index 727fa4f7d88..a0366b07c87 100644 --- a/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableQuickFixContributor.kt +++ b/plugins/android-extensions/android-extensions-idea/src/org/jetbrains/kotlin/android/parcel/quickfixes/ParcelableQuickFixContributor.kt @@ -25,7 +25,7 @@ import org.jetbrains.kotlin.lexer.KtTokens class ParcelableQuickFixContributor : QuickFixContributor { override fun registerQuickFixes(quickFixes: QuickFixes) { quickFixes.register(ErrorsAndroid.PARCELABLE_CANT_BE_INNER_CLASS, - RemoveModifierFix.createRemoveModifierFromListOwnerFactory(KtTokens.INNER_KEYWORD, false)) + RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(KtTokens.INNER_KEYWORD, false)) quickFixes.register(ErrorsAndroid.NO_PARCELABLE_SUPERTYPE, ParcelableAddSupertypeQuickfix.Factory) quickFixes.register(ErrorsAndroid.PARCELABLE_SHOULD_HAVE_PRIMARY_CONSTRUCTOR, ParcelableAddPrimaryConstructorQuickfix.Factory) diff --git a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/javac/KaptJavaLog.kt b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/javac/KaptJavaLog.kt index b43e68d34f1..748a571fb49 100644 --- a/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/javac/KaptJavaLog.kt +++ b/plugins/kapt3/kapt3-base/src/org/jetbrains/kotlin/kapt3/base/javac/KaptJavaLog.kt @@ -210,6 +210,7 @@ class KaptJavaLog( "compiler.err.already.defined", "compiler.err.annotation.type.not.applicable", "compiler.err.doesnt.exist", + "compiler.err.cant.resolve.location", "compiler.err.duplicate.annotation.missing.container", "compiler.err.not.def.access.package.cant.access", "compiler.err.package.not.visible", diff --git a/plugins/kapt3/kapt3-cli/test/org/jetbrains/kotlin/kapt/cli/test/KaptToolIntegrationTestGenerated.java b/plugins/kapt3/kapt3-cli/test/org/jetbrains/kotlin/kapt/cli/test/KaptToolIntegrationTestGenerated.java index 9c880effdfb..b14aae95ffd 100644 --- a/plugins/kapt3/kapt3-cli/test/org/jetbrains/kotlin/kapt/cli/test/KaptToolIntegrationTestGenerated.java +++ b/plugins/kapt3/kapt3-cli/test/org/jetbrains/kotlin/kapt/cli/test/KaptToolIntegrationTestGenerated.java @@ -29,9 +29,9 @@ public class KaptToolIntegrationTestGenerated extends AbstractKaptToolIntegratio KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("plugins/kapt3/kapt3-cli/testData/integration"), Pattern.compile("^([^\\.]+)$"), null, false); } - @TestMetadata("argfile") + @TestMetadata("defaultPackage") public void testArgfile() throws Exception { - runTest("plugins/kapt3/kapt3-cli/testData/integration/argfile/"); + runTest("plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/"); } @TestMetadata("correctErrorTypesOff") @@ -49,6 +49,11 @@ public class KaptToolIntegrationTestGenerated extends AbstractKaptToolIntegratio runTest("plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGeneration/"); } + @TestMetadata("kotlinFileGenerationCorrectErrorTypes") + public void testKotlinFileGenerationCorrectErrorTypes() throws Exception { + runTest("plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGenerationCorrectErrorTypes/"); + } + @TestMetadata("kotlinFileGenerationDefaultOutput") public void testKotlinFileGenerationDefaultOutput() throws Exception { runTest("plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGenerationDefaultOutput/"); diff --git a/plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/RootClass.kt b/plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/RootClass.kt new file mode 100644 index 00000000000..568ed8a64f4 --- /dev/null +++ b/plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/RootClass.kt @@ -0,0 +1 @@ +class RootClass diff --git a/plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/Usage.kt b/plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/Usage.kt new file mode 100644 index 00000000000..d6e1e0c3cec --- /dev/null +++ b/plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/Usage.kt @@ -0,0 +1,7 @@ +package test + +import RootClass + +interface Usage { + fun test(): RootClass +} diff --git a/plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/build.txt b/plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/build.txt new file mode 100644 index 00000000000..08ef3b796e3 --- /dev/null +++ b/plugins/kapt3/kapt3-cli/testData/integration/defaultPackage/build.txt @@ -0,0 +1,36 @@ +# copy +../simple/ap +ap + +# mkdir +output/ap +output/stubs +output/classes +output/javaClasses +output/sources + +# kotlinc +-cp %KOTLIN_STDLIB% +-d output/ap +ap/Processor.kt + +# kapt +-Kapt-stubs=output/stubs +-Kapt-classes=output/classes +-Kapt-sources=output/sources +-Kapt-classpath=output/ap +-Kapt-processors=apt.SampleApt +-d output/classes +-cp output/ap:%KOTLIN_STDLIB% +RootClass.kt +Usage.kt + +# after +Return code: 1 + +warning: [kapt] test.Usage: Can't reference type 'RootClass' from default package in Java stub. +error: output/stubs/test/Usage.java:9: error: cannot find symbol + public abstract RootClass test(); + ^ + symbol: class RootClass + location: interface Usage diff --git a/plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGenerationCorrectErrorTypes/Test.kt b/plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGenerationCorrectErrorTypes/Test.kt new file mode 100644 index 00000000000..a8643f0be03 --- /dev/null +++ b/plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGenerationCorrectErrorTypes/Test.kt @@ -0,0 +1,28 @@ +package test + +import apt.Anno +import generated.Test as TestGenerated +import generated.Property + +@Anno +class Test { + + @field:Anno + val property: String = "" + + @Anno + fun function() { + + } + +} + +interface Usage { + fun test(): TestGenerated + fun test1(): generated.Function + fun test2(): Property +} + +fun main() { + println("Generated class: " + TestGenerated::class.java.name) +} diff --git a/plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGenerationCorrectErrorTypes/build.txt b/plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGenerationCorrectErrorTypes/build.txt new file mode 100644 index 00000000000..3feb71f53fe --- /dev/null +++ b/plugins/kapt3/kapt3-cli/testData/integration/kotlinFileGenerationCorrectErrorTypes/build.txt @@ -0,0 +1,37 @@ +# copy +../kotlinFileGeneration/ap +ap + +# mkdir +output/ap +output/stubs +output/classes +output/sources +output/kotlin-sources + +# kotlinc +-cp %KOTLIN_STDLIB% +-d output/ap +ap/Processor.kt + +# copy +../kotlinFileGeneration/ap/META-INF/services/javax.annotation.processing.Processor +output/ap/META-INF/services/javax.annotation.processing.Processor + +# kapt +-Kapt-stubs=output/stubs +-Kapt-classes=output/classes +-Kapt-sources=output/sources +-Kapt-classpath=output/ap +-Kapt-option:kapt.kotlin.generated=output/kotlin-sources +-Kapt-correct-error-types=true +-d output/classes +-cp output/ap:%KOTLIN_STDLIB% +Test.kt + +# java +-cp output/classes:output/ap:%KOTLIN_STDLIB% +test.TestKt + +# after +Generated class: generated.Test diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt index 3b414ca500a..28d4c3a64c6 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/ClassFileToSourceStubConverter.kt @@ -51,6 +51,7 @@ import org.jetbrains.kotlin.kapt3.util.* import org.jetbrains.kotlin.load.java.sources.JavaSourceElement import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.isOneSegmentFQN import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DelegatingBindingTrace @@ -130,6 +131,8 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati private val kdocCommentKeeper = KDocCommentKeeper(kaptContext) + private val importsFromRoot by lazy(::collectImportsFromRootPackage) + private var done = false fun convert(): List { @@ -249,7 +252,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati } private fun convertImports(file: KtFile, classDeclaration: JCClassDecl): JavacList { - val imports = mutableListOf() + val imports = mutableListOf() val importedShortNames = mutableSetOf() // We prefer ordinary imports over aliased ones. @@ -321,6 +324,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati val isAnnotation = clazz.isAnnotation() val modifiers = convertModifiers( + clazz, flags, if (isEnum) ElementKind.ENUM else ElementKind.CLASS, packageFqName, clazz.visibleAnnotations, clazz.invisibleAnnotations, descriptor.annotations @@ -375,7 +379,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati it.name == "" && Type.getArgumentsAndReturnSizes(it.desc).shr(2) >= 2 }?.desc ?: "()Z") - val args = mapJList(constructorArguments.drop(2)) { convertLiteralExpression(getDefaultValue(it)) } + val args = mapJList(constructorArguments.drop(2)) { convertLiteralExpression(clazz, getDefaultValue(it)) } val def = data.correspondingClass?.let { convertClass(it, lineMappings, packageFqName, false) } @@ -624,6 +628,8 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati return false } + reportIfIllegalTypeUsage(containingClass, type) + return true } @@ -684,6 +690,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati } ?: Annotations.EMPTY val modifiers = convertModifiers( + containingClass, field.access, ElementKind.FIELD, packageFqName, field.visibleAnnotations, field.invisibleAnnotations, fieldAnnotations ) @@ -714,7 +721,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati lineMappings.registerField(containingClass, field) - val initializer = explicitInitializer ?: convertPropertyInitializer(field) + val initializer = explicitInitializer ?: convertPropertyInitializer(containingClass, field) return treeMaker.VarDef(modifiers, treeMaker.name(name), typeExpression, initializer).also { if (keepKdocComments) { it.keepKdocComments(field) @@ -722,7 +729,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati } } - private fun convertPropertyInitializer(field: FieldNode): JCExpression? { + private fun convertPropertyInitializer(containingClass: ClassNode, field: FieldNode): JCExpression? { val value = field.value val origin = kaptContext.origins[field] @@ -735,7 +742,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati if (value != null) { if (propertyInitializer != null) { - return convertConstantValueArguments(value, listOf(propertyInitializer)) + return convertConstantValueArguments(containingClass, value, listOf(propertyInitializer)) } return convertValueOfPrimitiveTypeOrString(value) @@ -759,14 +766,14 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati if (constValue != null) { val asmValue = mapConstantValueToAsmRepresentation(constValue) if (asmValue !== UnknownConstantValue) { - return convertConstantValueArguments(asmValue, listOf(propertyInitializer)) + return convertConstantValueArguments(containingClass, asmValue, listOf(propertyInitializer)) } } } if (isFinal(field.access)) { val type = Type.getType(field.desc) - return convertLiteralExpression(getDefaultValue(type)) + return convertLiteralExpression(containingClass, getDefaultValue(type)) } return null @@ -879,6 +886,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati if (!isValidIdentifier(name, canBeConstructor = isConstructor)) return null val modifiers = convertModifiers( + containingClass, if (containingClass.isEnum() && isConstructor) (method.access.toLong() and VISIBILITY_MODIFIERS.inv()) else @@ -908,6 +916,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati val varargs = if (lastParameter && isArrayType && method.isVarargs()) Flags.VARARGS else 0L val modifiers = convertModifiers( + containingClass, info.flags or varargs or Flags.PARAMETER, ElementKind.PARAMETER, packageFqName, @@ -925,9 +934,9 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati val valueParametersFromDescriptor = descriptor.valueParameters val (genericSignature, returnType) = - extractMethodSignatureTypes(descriptor, exceptionTypes, jcReturnType, method, parameters, valueParametersFromDescriptor) + extractMethodSignatureTypes(descriptor, exceptionTypes, jcReturnType, method, parameters, valueParametersFromDescriptor) - val defaultValue = method.annotationDefault?.let { convertLiteralExpression(it) } + val defaultValue = method.annotationDefault?.let { convertLiteralExpression(containingClass, it) } val body = if (defaultValue != null) { null @@ -943,7 +952,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati val superClassConstructorCall = if (superClassConstructor != null) { val args = mapJList(superClassConstructor.valueParameters) { param -> - convertLiteralExpression(getDefaultValue(typeMapper.mapType(param.type))) + convertLiteralExpression(containingClass, getDefaultValue(typeMapper.mapType(param.type))) } val call = treeMaker.Apply(JavacList.nil(), treeMaker.SimpleName("super"), args) JavacList.of(treeMaker.Exec(call)) @@ -955,7 +964,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati } else if (asmReturnType == Type.VOID_TYPE) { treeMaker.Block(0, JavacList.nil()) } else { - val returnStatement = treeMaker.Return(convertLiteralExpression(getDefaultValue(asmReturnType))) + val returnStatement = treeMaker.Return(convertLiteralExpression(containingClass, getDefaultValue(asmReturnType))) treeMaker.Block(0, JavacList.of(returnStatement)) } @@ -1023,10 +1032,10 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati val returnType = getNonErrorType( descriptor.returnType, RETURN_TYPE, ktTypeProvider = { - val element = kaptContext.origins[method]?.element - when (element) { + when (val element = kaptContext.origins[method]?.element) { is KtFunction -> element.typeReference is KtProperty -> if (descriptor is PropertyGetterDescriptor) element.typeReference else null + is KtPropertyAccessor -> if (descriptor is PropertyGetterDescriptor) element.property.typeReference else null is KtParameter -> if (descriptor is PropertyGetterDescriptor) element.typeReference else null else -> null } @@ -1112,15 +1121,25 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati @Suppress("NOTHING_TO_INLINE") private inline fun convertModifiers( + containingClass: ClassNode, access: Int, kind: ElementKind, packageFqName: String, visibleAnnotations: List?, invisibleAnnotations: List?, descriptorAnnotations: Annotations - ): JCModifiers = convertModifiers(access.toLong(), kind, packageFqName, visibleAnnotations, invisibleAnnotations, descriptorAnnotations) + ): JCModifiers = convertModifiers( + containingClass, + access.toLong(), + kind, + packageFqName, + visibleAnnotations, + invisibleAnnotations, + descriptorAnnotations + ) private fun convertModifiers( + containingClass: ClassNode, access: Long, kind: ElementKind, packageFqName: String, @@ -1135,7 +1154,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati seenOverride = true } val annotationDescriptor = descriptorAnnotations.singleOrNull { checkIfAnnotationValueMatches(annotation, AnnotationValue(it)) } - val annotationTree = convertAnnotation(annotation, packageFqName, annotationDescriptor) ?: return list + val annotationTree = convertAnnotation(containingClass, annotation, packageFqName, annotationDescriptor) ?: return list return list.prepend(annotationTree) } @@ -1159,6 +1178,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati } private fun convertAnnotation( + containingClass: ClassNode, annotation: AnnotationNode, packageFqName: String? = "", annotationDescriptor: AnnotationDescriptor? = null, @@ -1190,25 +1210,30 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati val values = if (argMapping.isNotEmpty()) { argMapping.mapNotNull { (parameterName, arg) -> if (arg is DefaultValueArgument) return@mapNotNull null - convertAnnotationArgumentWithName(constantValues[parameterName], arg, parameterName) + convertAnnotationArgumentWithName(containingClass, constantValues[parameterName], arg, parameterName) } } else { constantValues.mapNotNull { (parameterName, arg) -> - convertAnnotationArgumentWithName(arg, null, parameterName) + convertAnnotationArgumentWithName(containingClass, arg, null, parameterName) } } return treeMaker.Annotation(annotationFqName, JavacList.from(values)) } - private fun convertAnnotationArgumentWithName(constantValue: Any?, value: ResolvedValueArgument?, name: String): JCExpression? { + private fun convertAnnotationArgumentWithName( + containingClass: ClassNode, + constantValue: Any?, + value: ResolvedValueArgument?, + name: String + ): JCExpression? { if (!isValidIdentifier(name)) return null val args = value?.arguments?.mapNotNull { it.getArgumentExpression() } ?: emptyList() - val expr = convertConstantValueArguments(constantValue, args) ?: return null + val expr = convertConstantValueArguments(containingClass, constantValue, args) ?: return null return treeMaker.Assign(treeMaker.SimpleName(name), expr) } - private fun convertConstantValueArguments(constantValue: Any?, args: List): JCExpression? { + private fun convertConstantValueArguments(containingClass: ClassNode, constantValue: Any?, args: List): JCExpression? { val singleArg = args.singleOrNull() if (constantValue.isOfPrimitiveType()) { @@ -1280,7 +1305,7 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati } } - return convertLiteralExpression(constantValue) + return convertLiteralExpression(containingClass, constantValue) } private fun tryParseReferenceToIntConstant(expression: KtExpression?): JCExpression? { @@ -1369,20 +1394,22 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati } } - private fun convertLiteralExpression(value: Any?): JCExpression { + private fun convertLiteralExpression(containingClass: ClassNode, value: Any?): JCExpression { + fun convertDeeper(value: Any?) = convertLiteralExpression(containingClass, value) + convertValueOfPrimitiveTypeOrString(value)?.let { return it } return when (value) { null -> treeMaker.Literal(TypeTag.BOT, null) - is ByteArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable()) { convertLiteralExpression(it) }) - is BooleanArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable()) { convertLiteralExpression(it) }) - is CharArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable()) { convertLiteralExpression(it) }) - is ShortArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable()) { convertLiteralExpression(it) }) - is IntArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable()) { convertLiteralExpression(it) }) - is LongArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable()) { convertLiteralExpression(it) }) - is FloatArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable()) { convertLiteralExpression(it) }) - is DoubleArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable()) { convertLiteralExpression(it) }) + is ByteArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable(), ::convertDeeper)) + is BooleanArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable(), ::convertDeeper)) + is CharArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable(), ::convertDeeper)) + is ShortArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable(), ::convertDeeper)) + is IntArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable(), ::convertDeeper)) + is LongArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable(), ::convertDeeper)) + is FloatArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable(), ::convertDeeper)) + is DoubleArray -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value.asIterable(), ::convertDeeper)) is Array<*> -> { // Two-element String array for enumerations ([desc, fieldName]) assert(value.size == 2) val enumType = Type.getType(value[0] as String) @@ -1393,10 +1420,13 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati treeMaker.Select(treeMaker.Type(enumType), treeMaker.name(valueName)) } - is List<*> -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value) { convertLiteralExpression(it) }) + is List<*> -> treeMaker.NewArray(null, JavacList.nil(), mapJList(value, ::convertDeeper)) - is Type -> treeMaker.Select(treeMaker.Type(value), treeMaker.name("class")) - is AnnotationNode -> convertAnnotation(value, packageFqName = null, filtered = false)!! + is Type -> { + checkIfValidTypeName(containingClass, value) + treeMaker.Select(treeMaker.Type(value), treeMaker.name("class")) + } + is AnnotationNode -> convertAnnotation(containingClass, value, packageFqName = null, filtered = false)!! else -> throw IllegalArgumentException("Illegal literal expression value: $value (${value::class.java.canonicalName})") } } @@ -1441,6 +1471,30 @@ class ClassFileToSourceStubConverter(val kaptContext: KaptContextForStubGenerati private fun convertKotlinType(type: KotlinType): Type = typeMapper.mapType(type, null, TypeMappingMode.GENERIC_ARGUMENT) + private fun getFileForClass(c: ClassNode): KtFile? = kaptContext.origins[c]?.element?.containingFile as? KtFile + + private fun reportIfIllegalTypeUsage(containingClass: ClassNode, type: Type) { + val file = getFileForClass(containingClass) + importsFromRoot[file]?.let { importsFromRoot -> + val typeName = type.className + if (importsFromRoot.contains(typeName)) { + val msg = "${containingClass.className}: Can't reference type '${typeName}' from default package in Java stub." + if (strictMode) kaptContext.reportKaptError(msg) + else kaptContext.logger.warn(msg) + } + } + } + + private fun collectImportsFromRootPackage(): Map> = + kaptContext.compiledClasses.mapNotNull(::getFileForClass).distinct().map { file -> + val importsFromRoot = + file.importDirectives + .filter { !it.isAllUnder } + .mapNotNull { im -> im.importPath?.fqName?.takeIf { it.isOneSegmentFQN() } } + file to importsFromRoot.mapTo(mutableSetOf()) { it.asString() } + }.toMap() + + } private fun Any?.isOfPrimitiveType(): Boolean = when (this) { diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java index 90cbc6b0d38..da291216b2b 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java @@ -99,6 +99,16 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi runTest("plugins/kapt3/kapt3-compiler/testData/converter/defaultImpls.kt"); } + @TestMetadata("defaultPackage.kt") + public void testDefaultPackage() throws Exception { + runTest("plugins/kapt3/kapt3-compiler/testData/converter/defaultPackage.kt"); + } + + @TestMetadata("defaultPackageCorrectErrorTypes.kt") + public void testDefaultPackageCorrectErrorTypes() throws Exception { + runTest("plugins/kapt3/kapt3-compiler/testData/converter/defaultPackageCorrectErrorTypes.kt"); + } + @TestMetadata("defaultParameterValueOff.kt") public void testDefaultParameterValueOff() throws Exception { runTest("plugins/kapt3/kapt3-compiler/testData/converter/defaultParameterValueOff.kt"); diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java index 752f8d3aae8..1273f9ded3e 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/IrClassFileToSourceStubConverterTestGenerated.java @@ -100,6 +100,16 @@ public class IrClassFileToSourceStubConverterTestGenerated extends AbstractIrCla runTest("plugins/kapt3/kapt3-compiler/testData/converter/defaultImpls.kt"); } + @TestMetadata("defaultPackage.kt") + public void testDefaultPackage() throws Exception { + runTest("plugins/kapt3/kapt3-compiler/testData/converter/defaultPackage.kt"); + } + + @TestMetadata("defaultPackageCorrectErrorTypes.kt") + public void testDefaultPackageCorrectErrorTypes() throws Exception { + runTest("plugins/kapt3/kapt3-compiler/testData/converter/defaultPackageCorrectErrorTypes.kt"); + } + @TestMetadata("defaultParameterValueOff.kt") public void testDefaultParameterValueOff() throws Exception { runTest("plugins/kapt3/kapt3-compiler/testData/converter/defaultParameterValueOff.kt"); diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackage.kt b/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackage.kt new file mode 100644 index 00000000000..6d3ab608bb6 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackage.kt @@ -0,0 +1,43 @@ +// STRICT + +//FILE: test/ClassRefAnnotation.java + +package test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface ClassRefAnnotation { + Class[] value(); +} + +//FILE: a.kt + +class RootClass + +class AnotherRootClass + +//FILE: b.kt +package test + +import java.lang.Number as JavaNumber +import RootClass +import AnotherRootClass as Arc + +interface PackedClass { + fun someMethod(): RootClass + fun otherMethod(): JavaNumber + fun oneMoreMethod(): Arc +} + +@ClassRefAnnotation(RootClass::class) +class PackedWithAnnotation + +// EXPECTED_ERROR(kotlin:14:1) cannot find symbol +// EXPECTED_ERROR(other:-1:-1) test.PackedClass: Can't reference type 'RootClass' from default package in Java stub. +// EXPECTED_ERROR(other:-1:-1) test.PackedClass: Can't reference type 'AnotherRootClass' from default package in Java stub. +// EXPECTED_ERROR(other:-1:-1) test.PackedWithAnnotation: Can't reference type 'RootClass' from default package in Java stub. diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackage.txt b/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackage.txt new file mode 100644 index 00000000000..1636b3e06f0 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackage.txt @@ -0,0 +1,72 @@ +import java.lang.System; + +@kotlin.Metadata() +public final class AnotherRootClass { + + public AnotherRootClass() { + super(); + } +} + +//////////////////// + + +import java.lang.System; + +@kotlin.Metadata() +public final class RootClass { + + public RootClass() { + super(); + } +} + +//////////////////// + +package test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@Target(value = {ElementType.TYPE, ElementType.METHOD}) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface ClassRefAnnotation { + + Class[] value(); +} + +//////////////////// + +package test; + +import java.lang.System; + +@kotlin.Metadata() +public abstract interface PackedClass { + + @org.jetbrains.annotations.NotNull() + public abstract RootClass someMethod(); + + @org.jetbrains.annotations.NotNull() + public abstract java.lang.Number otherMethod(); + + @org.jetbrains.annotations.NotNull() + public abstract AnotherRootClass oneMoreMethod(); +} + +//////////////////// + +package test; + +import java.lang.System; + +@kotlin.Metadata() +@ClassRefAnnotation(value = {RootClass.class}) +public final class PackedWithAnnotation { + + public PackedWithAnnotation() { + super(); + } +} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackageCorrectErrorTypes.kt b/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackageCorrectErrorTypes.kt new file mode 100644 index 00000000000..cf6f0c15663 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackageCorrectErrorTypes.kt @@ -0,0 +1,44 @@ +// CORRECT_ERROR_TYPES +// STRICT + +//FILE: test/ClassRefAnnotation.java + +package test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@Target({ ElementType.TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +public @interface ClassRefAnnotation { + Class[] value(); +} + +//FILE: a.kt + +class RootClass + +class AnotherRootClass + +//FILE: b.kt +package test + +import java.lang.Number as JavaNumber +import RootClass +import AnotherRootClass as Arc + +interface PackedClass { + fun someMethod(): RootClass + fun otherMethod(): JavaNumber + fun oneMoreMethod(): Arc +} + +@ClassRefAnnotation(RootClass::class) +class PackedWithAnnotation + +// EXPECTED_ERROR(kotlin:14:1) cannot find symbol +// EXPECTED_ERROR(other:-1:-1) test.PackedClass: Can't reference type 'RootClass' from default package in Java stub. +// EXPECTED_ERROR(other:-1:-1) test.PackedClass: Can't reference type 'AnotherRootClass' from default package in Java stub. +// EXPECTED_ERROR(other:-1:-1) test.PackedWithAnnotation: Can't reference type 'RootClass' from default package in Java stub. diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackageCorrectErrorTypes.txt b/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackageCorrectErrorTypes.txt new file mode 100644 index 00000000000..7d444abd084 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/defaultPackageCorrectErrorTypes.txt @@ -0,0 +1,72 @@ +import java.lang.System; + +@kotlin.Metadata() +public final class AnotherRootClass { + + public AnotherRootClass() { + super(); + } +} + +//////////////////// + + +import java.lang.System; + +@kotlin.Metadata() +public final class RootClass { + + public RootClass() { + super(); + } +} + +//////////////////// + +package test; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.ElementType; + +@Target(value = {ElementType.TYPE, ElementType.METHOD}) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface ClassRefAnnotation { + + Class[] value(); +} + +//////////////////// + +package test; + +import java.lang.Number; + +@kotlin.Metadata() +public abstract interface PackedClass { + + @org.jetbrains.annotations.NotNull() + public abstract RootClass someMethod(); + + @org.jetbrains.annotations.NotNull() + public abstract java.lang.Number otherMethod(); + + @org.jetbrains.annotations.NotNull() + public abstract AnotherRootClass oneMoreMethod(); +} + +//////////////////// + +package test; + +import java.lang.Number; + +@kotlin.Metadata() +@ClassRefAnnotation(value = {RootClass.class}) +public final class PackedWithAnnotation { + + public PackedWithAnnotation() { + super(); + } +} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/errorLocationMapping.kt b/plugins/kapt3/kapt3-compiler/testData/converter/errorLocationMapping.kt index fdefd42d9ba..3e914d7114f 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/errorLocationMapping.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/errorLocationMapping.kt @@ -28,13 +28,5 @@ class ErrorInDeclarations { annotation class Anno(val a: KClass) // EXPECTED_ERROR(kotlin:11:1) cannot find symbol -// EXPECTED_ERROR(kotlin:12:1) cannot find symbol -// EXPECTED_ERROR(kotlin:16:5) cannot find symbol -// EXPECTED_ERROR(kotlin:17:5) cannot find symbol -// EXPECTED_ERROR(kotlin:20:5) cannot find symbol -// EXPECTED_ERROR(kotlin:22:5) cannot find symbol -// EXPECTED_ERROR(kotlin:25:5) cannot find symbol // EXPECTED_ERROR(kotlin:6:1) cannot find symbol -// EXPECTED_ERROR(kotlin:9:34) cannot find symbol -// EXPECTED_ERROR(kotlin:9:50) cannot find symbol -// EXPECTED_ERROR(kotlin:9:62) cannot find symbol \ No newline at end of file +// EXPECTED_ERROR(kotlin:12:1) cannot find symbol diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/invalidFieldName.kt b/plugins/kapt3/kapt3-compiler/testData/converter/invalidFieldName.kt index 8d632996be4..00144698f89 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/invalidFieldName.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/invalidFieldName.kt @@ -5,5 +5,5 @@ enum class Color { @Anno(Color.`WHI-TE`) annotation class Anno(val color: Color) -// EXPECTED_ERROR(kotlin:5:1) cannot find symbol -// EXPECTED_ERROR(other:-1:-1) 'WHI-TE' is an invalid Java enum value name \ No newline at end of file +// EXPECTED_ERROR(kotlin:5:1) an enum annotation value must be an enum constant +// EXPECTED_ERROR(other:-1:-1) 'WHI-TE' is an invalid Java enum value name diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/kt24272.kt b/plugins/kapt3/kapt3-compiler/testData/converter/kt24272.kt index 3106eb438a2..0e3c4995bab 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/kt24272.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/kt24272.kt @@ -10,5 +10,4 @@ class Foo(private val string: String) { } } -// EXPECTED_ERROR(kotlin:9:9) cannot find symbol -// EXPECTED_ERROR(other:-1:-1) Can't generate a stub for 'Foo$Bar$Bar'. \ No newline at end of file +// EXPECTED_ERROR(other:-1:-1) Can't generate a stub for 'Foo$Bar$Bar'. diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.kt b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.kt index ba54f7c0676..9f86ee574cc 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.kt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.kt @@ -8,7 +8,9 @@ object NonExistentType { val b: List? = null val c: (ABCDEF) -> Unit = { f -> } val d: ABCDEF) -> Unit>? = null + + val foo: Foo get() = Foo() fun a(a: ABCDEF, s: String): ABCDEF {} fun b(s: String): ABCDEF {} -} \ No newline at end of file +} diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.txt b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.txt index 48b215d42b8..292f74b2bc9 100644 --- a/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.txt +++ b/plugins/kapt3/kapt3-compiler/testData/converter/nonExistentClass.txt @@ -38,6 +38,11 @@ public final class NonExistentType { return null; } + @org.jetbrains.annotations.NotNull() + public final Foo getFoo() { + return null; + } + @org.jetbrains.annotations.NotNull() public final ABCDEF a(@org.jetbrains.annotations.NotNull() ABCDEF a, @org.jetbrains.annotations.NotNull() diff --git a/plugins/parcelize/parcelize-ide/src/org/jetbrains/kotlin/parcelize/ide/quickfixes/ParcelizeQuickFixContributor.kt b/plugins/parcelize/parcelize-ide/src/org/jetbrains/kotlin/parcelize/ide/quickfixes/ParcelizeQuickFixContributor.kt index 2c6da3b93b4..9625e4d7e52 100644 --- a/plugins/parcelize/parcelize-ide/src/org/jetbrains/kotlin/parcelize/ide/quickfixes/ParcelizeQuickFixContributor.kt +++ b/plugins/parcelize/parcelize-ide/src/org/jetbrains/kotlin/parcelize/ide/quickfixes/ParcelizeQuickFixContributor.kt @@ -26,7 +26,7 @@ class ParcelizeQuickFixContributor : QuickFixContributor { override fun registerQuickFixes(quickFixes: QuickFixes) { quickFixes.register( ErrorsParcelize.PARCELABLE_CANT_BE_INNER_CLASS, - RemoveModifierFix.createRemoveModifierFromListOwnerFactory(KtTokens.INNER_KEYWORD, false) + RemoveModifierFix.createRemoveModifierFromListOwnerPsiBasedFactory(KtTokens.INNER_KEYWORD, false) ) quickFixes.register(ErrorsParcelize.NO_PARCELABLE_SUPERTYPE, ParcelizeAddSupertypeQuickFix.Factory) diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDependenciesProvider.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDependenciesProvider.kt index 0b63a528807..8435b8cde6a 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDependenciesProvider.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDependenciesProvider.kt @@ -13,6 +13,7 @@ import com.intellij.psi.PsiManager import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper +import kotlin.script.experimental.api.ScriptCompilationConfiguration import kotlin.script.experimental.api.valueOrNull import kotlin.script.experimental.dependencies.ScriptDependencies @@ -35,6 +36,11 @@ open class ScriptDependenciesProvider constructor( open fun getScriptConfigurationResult(file: KtFile): ScriptCompilationConfigurationResult? = null + // TODO: consider fixing implementations and removing default implementation + open fun getScriptConfigurationResult( + file: KtFile, providedConfiguration: ScriptCompilationConfiguration? + ): ScriptCompilationConfigurationResult? = getScriptConfigurationResult(file) + open fun getScriptConfiguration(file: KtFile): ScriptCompilationConfigurationWrapper? = getScriptConfigurationResult(file)?.valueOrNull() companion object { diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/refineCompilationConfiguration.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/refineCompilationConfiguration.kt index 6d2ea8ca635..7b418e8c180 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/refineCompilationConfiguration.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/resolve/refineCompilationConfiguration.kt @@ -103,7 +103,7 @@ class ScriptLightVirtualFile(name: String, private val _path: String?, text: Str override fun getPath(): String = _path ?: if (parent != null) parent.path + "/" + name else name - override fun getCanonicalPath(): String? = path + override fun getCanonicalPath() = path } abstract class ScriptCompilationConfigurationWrapper(val script: SourceCode) { @@ -187,8 +187,8 @@ abstract class ScriptCompilationConfigurationWrapper(val script: SourceCode) { override val configuration: ScriptCompilationConfiguration? get() { val legacy = legacyDependencies ?: return null - return definition?.compilationConfiguration?.let { - ScriptCompilationConfiguration(it) { + return definition?.compilationConfiguration?.let { config -> + ScriptCompilationConfiguration(config) { updateClasspath(legacy.classpath) defaultImports.append(legacy.imports) importScripts.append(legacy.scripts.map { FileScriptSource(it) }) @@ -221,13 +221,14 @@ typealias ScriptCompilationConfigurationResult = ResultWithDiagnostics() if (legacyDefinition == null) { - val compilationConfiguration = definition.compilationConfiguration + val compilationConfiguration = providedConfiguration ?: definition.compilationConfiguration val collectedData = runReadAction { getScriptCollectedData(ktFileSource.ktFile, compilationConfiguration, project, definition.contextClassLoader) diff --git a/plugins/scripting/scripting-compiler/build.gradle.kts b/plugins/scripting/scripting-compiler/build.gradle.kts index 128a2797476..ba2e9705874 100644 --- a/plugins/scripting/scripting-compiler/build.gradle.kts +++ b/plugins/scripting/scripting-compiler/build.gradle.kts @@ -45,8 +45,6 @@ sourceSets { tasks.withType> { kotlinOptions { - languageVersion = "1.3" - apiVersion = "1.3" freeCompilerArgs = freeCompilerArgs - "-progressive" + "-Xskip-metadata-version-check" } } diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/definitions/CliScriptDependenciesProvider.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/definitions/CliScriptDependenciesProvider.kt index 231ef32ea30..adfad3e952c 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/definitions/CliScriptDependenciesProvider.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/definitions/CliScriptDependenciesProvider.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.scripting.compiler.plugin.definitions import com.intellij.openapi.components.ServiceManager -import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.project.Project import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider @@ -15,28 +14,36 @@ import org.jetbrains.kotlin.scripting.resolve.KtFileScriptSource import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult import org.jetbrains.kotlin.scripting.resolve.ScriptReportSink import org.jetbrains.kotlin.scripting.resolve.refineScriptCompilationConfiguration -import java.io.File import java.util.concurrent.locks.ReentrantReadWriteLock import kotlin.concurrent.read import kotlin.concurrent.write -import kotlin.script.experimental.api.ResultWithDiagnostics +import kotlin.script.experimental.api.ScriptCompilationConfiguration class CliScriptDependenciesProvider(project: Project) : ScriptDependenciesProvider(project) { private val cacheLock = ReentrantReadWriteLock() private val cache = hashMapOf() override fun getScriptConfigurationResult(file: KtFile): ScriptCompilationConfigurationResult? = cacheLock.read { - calculateRefinedConfiguration(file) + calculateRefinedConfiguration(file, null) } - private fun calculateRefinedConfiguration(file: KtFile): ScriptCompilationConfigurationResult? { + override fun getScriptConfigurationResult( + file: KtFile, + providedConfiguration: ScriptCompilationConfiguration? + ): ScriptCompilationConfigurationResult? = cacheLock.read { + calculateRefinedConfiguration(file, providedConfiguration) + } + + private fun calculateRefinedConfiguration( + file: KtFile, providedConfiguration: ScriptCompilationConfiguration? + ): ScriptCompilationConfigurationResult? { val path = file.virtualFilePath val cached = cache[path] return if (cached != null) cached else { val scriptDef = file.findScriptDefinition() if (scriptDef != null) { - val result = refineScriptCompilationConfiguration(KtFileScriptSource(file), scriptDef, project) + val result = refineScriptCompilationConfiguration(KtFileScriptSource(file), scriptDef, project, providedConfiguration) ServiceManager.getService(project, ScriptReportSink::class.java)?.attachReports(file.virtualFile, result.reports) diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt index b3b27e39116..40edc1de32a 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/dependencies/ScriptsCompilationDependencies.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider import java.io.File import kotlin.script.experimental.api.ResultWithDiagnostics +import kotlin.script.experimental.api.ScriptCompilationConfiguration import kotlin.script.experimental.api.asSuccess import kotlin.script.experimental.host.FileBasedScriptSource @@ -32,7 +33,8 @@ data class ScriptsCompilationDependencies( fun collectScriptsCompilationDependencies( configuration: CompilerConfiguration, project: Project, - initialSources: Iterable + initialSources: Iterable, + providedConfiguration: ScriptCompilationConfiguration? = null ): ScriptsCompilationDependencies { val collectedClassPath = ArrayList() val collectedSources = ArrayList() @@ -44,7 +46,7 @@ fun collectScriptsCompilationDependencies( while (true) { val newRemainingSources = ArrayList() for (source in remainingSources) { - when (val refinedConfiguration = importsProvider.getScriptConfigurationResult(source)) { + when (val refinedConfiguration = importsProvider.getScriptConfigurationResult(source, providedConfiguration)) { null -> {} is ResultWithDiagnostics.Failure -> { collectedSourceDependencies.add(ScriptsCompilationDependencies.SourceDependencies(source, refinedConfiguration)) diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt index 03f105a733e..b102c2bdd82 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt @@ -19,10 +19,10 @@ import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.descriptors.ScriptDescriptor import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.calls.tower.ImplicitsExtensionsResolutionFilter -import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplImplicitsExtensionsResolutionFilter import org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerStageHistory import org.jetbrains.kotlin.scripting.compiler.plugin.repl.JvmReplCompilerState import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplCodeAnalyzerBase +import org.jetbrains.kotlin.scripting.compiler.plugin.repl.ReplImplicitsExtensionsResolutionFilter import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider import org.jetbrains.kotlin.scripting.resolve.skipExtensionsResolutionForImplicits import org.jetbrains.kotlin.scripting.resolve.skipExtensionsResolutionForImplicitsExceptInnermost @@ -90,6 +90,7 @@ open class KJvmReplCompilerBase protected cons val (sourceFiles, sourceDependencies) = collectRefinedSourcesAndUpdateEnvironment( context, snippetKtFile, + initialConfiguration, messageCollector ) diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt index 2dd85ee1592..2404a322cdc 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt @@ -50,7 +50,7 @@ class ScriptJvmCompilerIsolated(val hostConfiguration: ScriptingHostConfiguratio initialConfiguration, hostConfiguration, messageCollector, disposable ) - compileImpl(script, context, messageCollector) + compileImpl(script, context, initialConfiguration, messageCollector) } } } @@ -74,7 +74,7 @@ class ScriptJvmCompilerFromEnvironment(val environment: KotlinCoreEnvironment) : try { environment.configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector) - compileImpl(script, context, messageCollector) + compileImpl(script, context, initialConfiguration, messageCollector) } finally { if (parentMessageCollector != null) environment.configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, parentMessageCollector) @@ -105,6 +105,7 @@ private fun withScriptCompilationCache( private fun compileImpl( script: SourceCode, context: SharedScriptCompilationContext, + initialConfiguration: ScriptCompilationConfiguration, messageCollector: ScriptDiagnosticsMessageCollector ): ResultWithDiagnostics { val mainKtFile = @@ -121,6 +122,7 @@ private fun compileImpl( val (sourceFiles, sourceDependencies) = collectRefinedSourcesAndUpdateEnvironment( context, mainKtFile, + initialConfiguration, messageCollector ) diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/compilationContext.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/compilationContext.kt index e44fbe24eb7..48ae6cd4c60 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/compilationContext.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/compilationContext.kt @@ -32,11 +32,11 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.extensions.AnnotationBasedExtension import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor -import org.jetbrains.kotlin.resolve.sam.SamWithReceiverResolver import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtModifierListOwner +import org.jetbrains.kotlin.resolve.sam.SamWithReceiverResolver import org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar import org.jetbrains.kotlin.scripting.compiler.plugin.dependencies.ScriptsCompilationDependencies import org.jetbrains.kotlin.scripting.compiler.plugin.dependencies.collectScriptsCompilationDependencies @@ -273,6 +273,7 @@ private fun createInitialCompilerConfiguration( internal fun collectRefinedSourcesAndUpdateEnvironment( context: SharedScriptCompilationContext, mainKtFile: KtFile, + initialConfiguration: ScriptCompilationConfiguration, messageCollector: ScriptDiagnosticsMessageCollector ): Pair, List> { val sourceFiles = arrayListOf(mainKtFile) @@ -280,7 +281,8 @@ internal fun collectRefinedSourcesAndUpdateEnvironment( collectScriptsCompilationDependencies( context.environment.configuration, context.environment.project, - sourceFiles + sourceFiles, + initialConfiguration ) context.environment.updateClasspath(classpath.map(::JvmClasspathRoot)) diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/repl/ReplFromTerminal.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/repl/ReplFromTerminal.kt index 65aa5d0ffc6..cf5f9faaf15 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/repl/ReplFromTerminal.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/repl/ReplFromTerminal.kt @@ -111,6 +111,7 @@ class ReplFromTerminal( is ReplEvalResult.Error.Runtime -> writer.outputRuntimeError(evalResult.message) is ReplEvalResult.Error.CompileTime -> writer.outputRuntimeError(evalResult.message) is ReplEvalResult.Incomplete -> writer.notifyIncomplete() + is ReplEvalResult.HistoryMismatch -> {} // assuming handled elsewhere } return evalResult } diff --git a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/test/CompileTimeFibonacciTest.kt b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/test/CompileTimeFibonacciTest.kt index e1e91cac27e..570dbd99f54 100644 --- a/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/test/CompileTimeFibonacciTest.kt +++ b/plugins/scripting/scripting-compiler/tests/org/jetbrains/kotlin/scripting/compiler/test/CompileTimeFibonacciTest.kt @@ -157,7 +157,7 @@ object CompileTimeFibonacciConfiguration : ScriptCompilationConfiguration( ) } ?.valueOr { return@onAnnotations it } - ?.max() ?: return@onAnnotations context.compilationConfiguration.asSuccess() + ?.maxOrNull() ?: return@onAnnotations context.compilationConfiguration.asSuccess() val sourceCode = fibUntil(maxFibonacciNumber) .mapIndexed { index, number -> "val FIB_${index + 1} = $number" } diff --git a/settings.gradle b/settings.gradle index 5e9da894abf..aea202ba2eb 100644 --- a/settings.gradle +++ b/settings.gradle @@ -333,6 +333,7 @@ include ":compiler:test-infrastructure", ":compiler:tests-common-new" include ":idea:idea-frontend-fir:idea-fir-low-level-api" +include ":idea:idea-frontend-fir:idea-frontend-fir-generator" include ":idea:idea-fir-performance-tests" include ":plugins:parcelize:parcelize-compiler",