[MERGE] KT: build-1.5.20-dev-576 KT/N: 8519223d0 OLD: 3164709fb

This commit is contained in:
Vasily Levchenko
2021-02-15 10:16:21 +01:00
915 changed files with 16662 additions and 4543 deletions
+121 -17
View File
@@ -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 <sdk 1.8> 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 '<get-...>' 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).
+2 -2
View File
@@ -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:
+1 -1
View File
@@ -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"
+2 -2
View File
@@ -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)
+6
View File
@@ -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 {
@@ -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<KotlinBaseTest.TestFile>,
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<FqName>()
val isJvmName = Ref<Boolean>(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 =
@@ -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<File>,
@@ -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<TemporaryDirectoryManager>(::TemporaryDirectoryManagerImpl)
useAdditionalService<BackendKindExtractor>(::BackendKindExtractorImpl)
useSourcePreprocessor(*AbstractKotlinCompilerTest.defaultPreprocessors.toTypedArray())
useDirectives(*AbstractKotlinCompilerTest.defaultDirectiveContainers.toTypedArray())
}
private fun createTestFiles(file: File, expectedText: String): List<KotlinBaseTest.TestFile> =
CodegenTestCase.createTestFilesFromFile(file, expectedText, false, TargetBackend.JVM)
@@ -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<AnalysisFlag<*>, Any> {
return HashMap<AnalysisFlag<*>, 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)
}
}
@@ -22,6 +22,7 @@ abstract class CommonCompilerPerformanceManager(private val presentableName: Str
private var startGCData = mutableMapOf<String, GCData>()
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()
}
@@ -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())
}
}
@@ -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
}
}
@@ -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);
}
@@ -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()
@@ -50,4 +50,7 @@ object AnalysisFlags {
@JvmStatic
val libraryToSourceAnalysis by AnalysisFlag.Delegates.Boolean
@JvmStatic
val extendedCompilerChecks by AnalysisFlag.Delegates.Boolean
}
@@ -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<Server.KeepAliveAcknowledgement<*>>(id)
} ?: if (!keepAliveSuccess()) readActor.send(StopAllRequests()).also {
}
if (keepAliveAcknowledgement == null && !keepAliveSuccess()) {
readActor.send(StopAllRequests())
}
}
}
@@ -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");
@@ -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)
@@ -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<JavaSymbolProvider>().first()
val topLevelJavaClasses = topPsiClasses.map { it.classId(FqName.ROOT) }
@@ -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|<local>/x|?.{ $subj$.R|kotlin/let|<R|() -> kotlin/String?|, R|kotlin/String|>(<L> = let@fun <anonymous>(y: R|() -> kotlin/String?|): R|kotlin/String| <kind=EXACTLY_ONCE> {
R|<local>/x|?.{ $subj$.R|kotlin/let|<R|() -> kotlin/String?|, R|kotlin/String?|>(<L> = let@fun <anonymous>(y: R|() -> kotlin/String?|): R|kotlin/String?| <kind=EXACTLY_ONCE> {
^ R|<local>/y|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/String?|>|()?.{ $subj$.R|kotlin/let|<R|kotlin/String|, R|kotlin/String|>(<L> = let@fun <anonymous>(result: R|kotlin/String|): R|kotlin/String| <kind=EXACTLY_ONCE> {
^ R|/bar|(R|<local>/result|)
}
@@ -11,7 +11,7 @@ var x2: Int = 1
field = 1
}
val x3 = run {
val x3 = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>run {
fun foo() {
val c = 1 + 1
throw Exception()
@@ -25,7 +25,7 @@ val x3 = run {
}
throw Exception()
}
}<!>
get() {
class GetterLocalClass {
init {
@@ -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<R|kotlin/Any|>()
this@R|/C|.R|<local>/<$$delegate_0>| = R|<local>/b|
}
local final field <$$delegate_0>: R|A| = R|<local>/b|
public final val b: R|B| = R|<local>/b|
public get(): R|B|
@@ -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|<anonymous>| {
super<R|kotlin/Any|>()
this@R|/<anonymous>|.R|<local>/<$$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|<anonymous>| {
super<R|kotlin/Any|>()
this@R|/<anonymous>|.R|<local>/<$$delegate_0>| = this@R|/test_2|.R|/A.b|
}
local final field <$$delegate_0>: R|B| = this@R|/test_2|.R|/A.b|
}
}
@@ -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| = <Unresolved name: 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|
}
@@ -1,6 +1,6 @@
class A
interface B : <!DELEGATION_IN_INTERFACE, INTERFACE_WITH_SUPERCLASS!>A<!> by a {
interface B : <!DELEGATION_IN_INTERFACE, INTERFACE_WITH_SUPERCLASS!>A<!> by <!UNRESOLVED_REFERENCE!>a<!> {
val a: A
}
@@ -3,7 +3,7 @@ open class A {
}
open class B : A {
override var test: Double = 20.0
override var test: <!VAR_TYPE_MISMATCH_ON_OVERRIDE!>Double<!> = 20.0
}
class C() : A() {
@@ -15,7 +15,7 @@ open class D() : B() {
}
class E<T : Double>(val value: T) : B() {
override var test: T = value
override var test: <!VAR_TYPE_MISMATCH_ON_OVERRIDE!>T<!> = value
}
open class F<T : Number>(val value: T) {
@@ -29,7 +29,7 @@ sealed class P {
class K : P()
<!REDECLARATION!>object B<!> {
class I : <!SEALED_SUPERTYPE!>P<!>()
class I : P()
}
fun test() {
@@ -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<R|kotlin/Any|>()
this@R|/B|.R|<local>/<$$delegate_0>| = R|<local>/a|
}
local final field <$$delegate_0>: R|A| = R|<local>/a|
private final val a: R|A| = R|<local>/a|
private get(): R|A|
@@ -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|<local>/cond|) {
==($subj$, Boolean(true)) -> {
Int(1)
}
}
lval y: R|kotlin/Unit| = when (R|<local>/cond|) {
==($subj$, Boolean(false)) -> {
Int(2)
}
}
lval z: R|kotlin/Int| = when (R|<local>/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|<local>/cond|) {
==($subj$, Boolean(true)) -> {
Int(1)
}
==($subj$, Boolean(false)) -> {
Int(2)
}
}
lval x: R|kotlin/Int| = when (R|<local>/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|<local>/cond|) {
==($subj$, Boolean(true)) -> {
Int(1)
}
}
}
@@ -0,0 +1,33 @@
fun test_1(cond: Boolean) {
val x = <!NO_ELSE_IN_WHEN!>when<!> (cond) {
true -> 1
}
val y = <!NO_ELSE_IN_WHEN!>when<!> (cond) {
false -> 2
}
val z = when (cond) {
true -> 1
false -> 2
}
}
fun test_2(cond: Boolean?) {
val x = <!NO_ELSE_IN_WHEN!>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
}
}
@@ -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|<local>/a|) {
($subj$ is R|kotlin/Int|) -> {
Int(1)
}
($subj$ is R|kotlin/String|) -> {
Int(2)
}
}
lval y: R|kotlin/Int| = when (R|<local>/a|) {
else -> {
Int(1)
}
}
lval z: R|kotlin/Int| = when (R|<local>/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|<local>/a|) {
($subj$ is R|kotlin/String|) -> {
Int(1)
}
($subj$ is R|kotlin/Int|) -> {
Int(2)
}
}
}
@@ -0,0 +1,23 @@
fun test(a: Any) {
val x = <!NO_ELSE_IN_WHEN!>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
}
}
@@ -0,0 +1,63 @@
FILE: missingEnumEntry.kt
public final enum class SomeEnum : R|kotlin/Enum<SomeEnum>| {
private constructor(): R|SomeEnum| {
super<R|kotlin/Enum<SomeEnum>|>()
}
public final static enum entry A: R|SomeEnum|
public final static enum entry B: R|SomeEnum|
public final static fun values(): R|kotlin/Array<SomeEnum>| {
}
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|<local>/enum|) {
==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> {
Int(1)
}
}
lval y: R|kotlin/Int| = when (R|<local>/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|<local>/enum|) {
==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> {
Int(1)
}
==($subj$, Q|SomeEnum|.R|/SomeEnum.B|) -> {
Int(2)
}
}
lval y: R|kotlin/Int| = when (R|<local>/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|<local>/enum|) {
==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> {
Int(1)
}
}
}
@@ -0,0 +1,33 @@
enum class SomeEnum {
A, B
}
fun test_1(enum: SomeEnum) {
val x = <!NO_ELSE_IN_WHEN!>when<!> (enum) {
SomeEnum.A -> 1
}
val y = when (enum) {
SomeEnum.A -> 1
SomeEnum.B -> 2
}
}
fun test_2(enum: SomeEnum?) {
val x = <!NO_ELSE_IN_WHEN!>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
}
}
@@ -0,0 +1,84 @@
FILE: a.kt
public sealed class Base : R|kotlin/Any| {
private constructor(): R|Base| {
super<R|kotlin/Any|>()
}
}
public final class A : R|Base| {
public constructor(): R|A| {
super<R|Base|>()
}
}
FILE: b.kt
public final object B : R|Base| {
private constructor(): R|B| {
super<R|Base|>()
}
}
FILE: c.kt
public final fun test_1(base: R|Base|): R|kotlin/Unit| {
lval x: R|kotlin/Unit| = when (R|<local>/base|) {
($subj$ is R|A|) -> {
Int(1)
}
}
lval y: R|kotlin/Unit| = when (R|<local>/base|) {
==($subj$, Q|B|) -> {
Int(1)
}
}
lval z: R|kotlin/Int| = when (R|<local>/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|<local>/base|) {
($subj$ is R|A|) -> {
Int(1)
}
($subj$ is R|B|) -> {
Int(2)
}
}
lval y: R|kotlin/Unit| = when (R|<local>/base|) {
($subj$ is R|A|) -> {
Int(1)
}
==($subj$, Q|B|) -> {
Int(2)
}
}
lval z: R|kotlin/Int| = when (R|<local>/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|<local>/base|) {
($subj$ is R|A|) -> {
Int(1)
}
}
}
@@ -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 = <!NO_ELSE_IN_WHEN!>when<!> (base) {
is A -> 1
}
val y = <!NO_ELSE_IN_WHEN!>when<!> (base) {
B -> 1
}
val z = when (base) {
is A -> 1
B -> 2
}
}
fun test_2(base: Base?) {
val x = <!NO_ELSE_IN_WHEN!>when<!> (base) {
is A -> 1
is B -> 2
}
val y = <!NO_ELSE_IN_WHEN!>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
}
}
@@ -0,0 +1,15 @@
FILE: nonExhaustiveWhenWithoutCoercionToUnit.kt
public final fun <T> run(block: R|() -> T|): R|T| {
^run R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
}
public final fun test(a: R|kotlin/Any|): R|kotlin/Unit| {
R|/run|<R|kotlin/Unit|>(<L> = run@fun <anonymous>(): R|kotlin/Unit| {
when (R|<local>/a|) {
($subj$ is R|kotlin/String|) -> {
Int(1)
}
}
}
)
}
@@ -0,0 +1,10 @@
fun <T> run(block: () -> T): T = block()
fun test(a: Any) {
run {
// Should be an error, see KT-44810
when (a) {
is String -> 1
}
}
}
@@ -1,5 +1,5 @@
fun test_1(b: Boolean) {
val x = when (b) {
val x = <!NO_ELSE_IN_WHEN!>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 = <!NO_ELSE_IN_WHEN!>when<!> (b) {
true -> 1
false -> 2
}
@@ -3,12 +3,12 @@ enum class Enum {
}
fun test_1(e: Enum) {
val a = when (e) {
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
Enum.A -> 1
Enum.B -> 2
}
val b = when (e) {
val b = <!NO_ELSE_IN_WHEN!>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 = <!NO_ELSE_IN_WHEN!>when<!> (e) {
Enum.A -> 1
Enum.B -> 2
Enum.C -> 3
@@ -7,12 +7,12 @@ public enum JavaEnum {
// FILE: main.kt
fun test_1(e: JavaEnum) {
val a = when (e) {
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
JavaEnum.A -> 1
JavaEnum.B -> 2
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
val b = when (e) {
val b = <!NO_ELSE_IN_WHEN!>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 = <!NO_ELSE_IN_WHEN!>when<!> (e) {
JavaEnum.A -> 1
JavaEnum.B -> 2
JavaEnum.C -> 3
@@ -7,12 +7,12 @@ sealed class Base {
class C : Base()
fun test_1(e: Base) {
val a = when (e) {
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
is Base.A -> 1
is Base.A.B -> 2
}
val b = when (e) {
val b = <!NO_ELSE_IN_WHEN!>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 = <!NO_ELSE_IN_WHEN!>when<!> (e) {
is Base.A -> 1
is Base.A.B -> 2
is C -> 3
@@ -107,10 +107,10 @@ FILE: exhaustiveness_sealedSubClass.kt
}
}
.<Unresolved name: plus>#(Int(0))
lval d: R|ERROR CLASS: Unresolved name: plus| = when (R|<local>/e|) {
lval d: R|kotlin/Int| = when (R|<local>/e|) {
($subj$ is R|C|) -> {
Int(1)
}
}
.<Unresolved name: plus>#(Int(0))
.R|kotlin/Int.plus|(Int(0))
}
@@ -32,23 +32,23 @@ fun test_1(e: A) {
}
fun test_2(e: A) {
val a = when (e) {
val a = <!NO_ELSE_IN_WHEN!>when<!> (e) {
is D -> 1
is E -> 2
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
val b = when (e) {
val b = <!NO_ELSE_IN_WHEN!>when<!> (e) {
is B -> 1
is D -> 2
is E -> 3
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
val c = when (e) {
val c = <!NO_ELSE_IN_WHEN!>when<!> (e) {
is B -> 1
is D -> 2
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
val d = when (e) {
is C -> 1
}.<!UNRESOLVED_REFERENCE{LT}!><!UNRESOLVED_REFERENCE{PSI}!>plus<!>(0)<!>
}.plus(0)
}
@@ -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|(<L> = run@fun <anonymous>(): R|kotlin/Unit| {
when () {
R|<local>/b1| -> {
when () {
R|<local>/b2| -> {
R|<local>/result| = Boolean(true)
}
}
}
}
}
)
}
@@ -0,0 +1,10 @@
fun run(block: () -> Unit) {}
fun test(b1: Boolean, b2: Boolean) {
var result = false
run {
if (b1)
if (b2)
result = true
}
}
@@ -0,0 +1,21 @@
FILE: nonExhaustiveWhenWithCoercionToUnit.kt
public final fun <T> run(block: R|() -> T|): R|T| {
^run R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()
}
public final fun test(a: R|kotlin/Any|, b: R|kotlin/Boolean|): R|kotlin/Unit| {
R|/run|<R|kotlin/Unit|>(<L> = run@fun <anonymous>(): R|kotlin/Unit| {
when () {
R|<local>/b| -> {
^@run Unit
}
}
when (R|<local>/a|) {
($subj$ is R|kotlin/String|) -> {
Int(1)
}
}
}
)
}
@@ -0,0 +1,10 @@
fun <T> run(block: () -> T): T = block()
fun test(a: Any, b: Boolean) {
run {
if (b) return@run
when (a) {
is String -> 1
}
}
}
@@ -18,7 +18,7 @@ public interface ResolvedCall<D extends Descriptor> {
// FILE: test.kt
val Descriptor.name = "123"
val Descriptor.name = <!EXTENSION_PROPERTY_WITH_BACKING_FIELD!>"123"<!>
fun Descriptor.correct(): Boolean = true
fun Descriptor.foo() {}
@@ -80,7 +80,7 @@ open class J {
field = value
}
var bar = 0
var bar = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>
get() = 3.1415926535
set(value) {}
}
@@ -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<R|kotlin/Any|>()
}
public final val b: R|kotlin/Int| = R|<local>/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|
}
@@ -0,0 +1,5 @@
// ISSUE: KT-44554
data class Foo(a: Int, val b: Int) {
val c = 4
}
@@ -14,6 +14,5 @@ fun main(x: A?) {
x?.unit()
}
// lambda has a type (() -> Unit?)
foo(lambda)
}
@@ -8,7 +8,7 @@ interface Some {
<!REDUNDANT_OPEN_IN_INTERFACE!>open<!> var xx: Int
open var yy = <!PROPERTY_INITIALIZER_IN_INTERFACE!>1<!>
open var zz: Int
<!BACKING_FIELD_IN_INTERFACE!>open var zz: Int<!>
set(value) {
field = value
}
@@ -0,0 +1,35 @@
FILE: booleanElvisBoundSmartcast.kt
public final class A : R|kotlin/Any| {
public constructor(b: R|kotlin/Boolean|): R|A| {
super<R|kotlin/Any|>()
}
public final val b: R|kotlin/Boolean| = R|<local>/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|<local>/a|?.{ $subj$.R|/A.b| } ?: Boolean(false) -> {
R|<local>/a|.R|/A.foo|()
}
else -> {
R|<local>/a|.<Inapplicable(INAPPLICABLE_WRONG_RECEIVER): /A.foo>#()
}
}
}
public final fun test_2(a: R|A?|): R|kotlin/Unit| {
when () {
R|<local>/a|?.{ $subj$.R|/A.b| } ?: Boolean(true) -> {
R|<local>/a|.<Inapplicable(INAPPLICABLE_WRONG_RECEIVER): /A.foo>#()
}
else -> {
R|<local>/a|.R|/A.foo|()
}
}
}
@@ -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<!UNSAFE_CALL!>.<!>foo() // Error
}
}
fun test_2(a: A?) {
if (a?.b ?: true) {
a<!UNSAFE_CALL!>.<!>foo() // Error
} else {
a.foo() // OK
}
}
+6 -6
View File
@@ -16,12 +16,12 @@ fun get(f: Boolean) = if (f) {A.A1} else {""}
<!CONFLICTING_OVERLOADS!>fun case2()<!> {
val flag: Any = get(false) //string
val l1 = when (flag!!) { // should be NO_ELSE_IN_WHEN
val l1 = <!NO_ELSE_IN_WHEN!>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 = <!NO_ELSE_IN_WHEN!>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 {""}
<!CONFLICTING_OVERLOADS!>fun case2()<!> {
val flag: Any = get(true) //A
val l1 = when (flag!!) {// should be NO_ELSE_IN_WHEN
val l1 = <!NO_ELSE_IN_WHEN!>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 = <!NO_ELSE_IN_WHEN!>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 = <!NO_ELSE_IN_WHEN!>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 = <!NO_ELSE_IN_WHEN!>when<!> (flag) {// should be NO_ELSE_IN_WHEN
A.A1 -> B() //should be INCOMPATIBLE_TYPES
A.A2 -> B() //should be INCOMPATIBLE_TYPES
}
@@ -0,0 +1,16 @@
FILE: whenWithWhenAsStatement.kt
public final fun test(value: R|kotlin/Int|): R|kotlin/Unit| {
when (R|<local>/value|) {
==($subj$, Int(0)) -> {
}
==($subj$, Int(1)) -> {
when (R|<local>/value|) {
==($subj$, Int(2)) -> {
Boolean(false)
}
}
}
}
}
@@ -0,0 +1,8 @@
fun test(value: Int) {
when (value) {
0 -> {}
1 -> when (value) {
2 -> false
}
}
}
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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<tasks.WriteCopyrightToFile> {
@@ -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()
@@ -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<String>) {
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<String>) {
with(ImportPrinter) { printImports(imports) }
}
@@ -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<String>) {
@@ -23,6 +21,7 @@ fun main(args: Array<String>) {
alias<FirFunctionCall>("FunctionCallChecker")
alias<FirVariableAssignment>("VariableAssignmentChecker")
alias<FirTryExpression>("TryExpressionChecker")
alias<FirWhenExpression>("WhenExpressionChecker")
}
val declarationPackage = "org.jetbrains.kotlin.fir.analysis.checkers.declaration"
@@ -46,6 +45,9 @@ fun main(args: Array<String>) {
classFqn = "org.jetbrains.kotlin.fir.analysis.cfa.AbstractFirPropertyInitializationChecker"
)
}
val diagnosticsPackage = "org.jetbrains.kotlin.fir.analysis.diagnostics"
generateDiagnostics(generationPath, diagnosticsPackage, DIAGNOSTICS_LIST)
}
/*
@@ -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<DiagnosticParameter>,
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<DiagnosticData>,
)
@@ -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<DiagnosticData>()
@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 <reified E : FirSourceElement, reified P : PsiElement> error(
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT,
crossinline init: DiagnosticBuilder.() -> Unit = {}
) = diagnosticDelegateProvider<E, P>(Severity.ERROR, positioningStrategy, init)
@OptIn(PrivateForInline::class)
inline fun <reified E : FirSourceElement, reified P : PsiElement> warning(
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT,
crossinline init: DiagnosticBuilder.() -> Unit = {}
) = diagnosticDelegateProvider<E, P>(Severity.WARNING, positioningStrategy, init)
@PrivateForInline
@OptIn(ExperimentalStdlibApi::class)
inline fun <reified E : FirSourceElement, reified P : PsiElement> diagnosticDelegateProvider(
severity: Severity,
positioningStrategy: PositioningStrategy,
crossinline init: DiagnosticBuilder.() -> Unit = {}
) = PropertyDelegateProvider<Any?, AlwaysReturningUnitPropertyDelegate> { _, property ->
diagnostics += DiagnosticBuilder(
severity,
name = property.name,
sourceElementType = typeOf<E>(),
psiType = typeOf<P>(),
positioningStrategy,
group = currentGroupName,
).apply(init).build()
AlwaysReturningUnitPropertyDelegate
}
@PrivateForInline
object AlwaysReturningUnitPropertyDelegate : ReadOnlyProperty<Any?, Unit> {
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<DiagnosticParameter>()
@OptIn(PrivateForInline::class, ExperimentalStdlibApi::class)
inline fun <reified T> parameter(name: String) {
if (parameters.size == 3) {
error("Diagnostic cannot have more than 3 parameters")
}
parameters += DiagnosticParameter(
name = name,
type = typeOf<T>()
)
}
@OptIn(PrivateForInline::class)
fun build() = DiagnosticData(
severity,
name,
sourceElementType,
psiType,
parameters,
positioningStrategy,
group
)
}
@@ -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)
}
@@ -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)
}
@@ -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<DiagnosticData>
) {
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<KType> = buildList {
add(sourceElementType)
add(psiType)
parameters.mapTo(this) { it.type }
}
private fun SmartPrinter.printTypeArguments(typeArguments: List<KType>) {
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<String> = 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 <T> SmartPrinter.printSeparatedWithComma(list: List<T>, printItem: (T) -> Unit) {
list.forEachIndexed { index, element ->
printItem(element)
if (index != list.lastIndex) {
print(", ")
}
}
}
@@ -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<FirSourceElement, PsiElement>()
val OTHER_ERROR by error<FirSourceElement, PsiElement>()
}
group("General syntax") {
val ILLEGAL_CONST_EXPRESSION by error<FirSourceElement, PsiElement>()
val ILLEGAL_UNDERSCORE by error<FirSourceElement, PsiElement>()
val EXPRESSION_REQUIRED by error<FirSourceElement, PsiElement>()
val BREAK_OR_CONTINUE_OUTSIDE_A_LOOP by error<FirSourceElement, PsiElement>()
val NOT_A_LOOP_LABEL by error<FirSourceElement, PsiElement>()
val VARIABLE_EXPECTED by error<FirSourceElement, PsiElement>()
val RETURN_NOT_ALLOWED by error<FirSourceElement, PsiElement>()
val DELEGATION_IN_INTERFACE by error<FirSourceElement, PsiElement>()
}
group("Unresolved") {
val HIDDEN by error<FirSourceElement, PsiElement> {
parameter<AbstractFirBasedSymbol<*>>("hidden")
}
val UNRESOLVED_REFERENCE by error<FirSourceElement, PsiElement> {
parameter<String>("reference")
}
val UNRESOLVED_LABEL by error<FirSourceElement, PsiElement>()
val DESERIALIZATION_ERROR by error<FirSourceElement, PsiElement>()
val ERROR_FROM_JAVA_RESOLUTION by error<FirSourceElement, PsiElement>()
val UNKNOWN_CALLABLE_KIND by error<FirSourceElement, PsiElement>()
val MISSING_STDLIB_CLASS by error<FirSourceElement, PsiElement>()
val NO_THIS by error<FirSourceElement, PsiElement>()
}
group("Super") {
val SUPER_IS_NOT_AN_EXPRESSION by error<FirSourceElement, PsiElement>()
val SUPER_NOT_AVAILABLE by error<FirSourceElement, PsiElement>()
val ABSTRACT_SUPER_CALL by error<FirSourceElement, PsiElement>()
val INSTANCE_ACCESS_BEFORE_SUPER_CALL by error<FirSourceElement, PsiElement> {
parameter<String>("target")
}
}
group("Supertypes") {
val TYPE_PARAMETER_AS_SUPERTYPE by error<FirSourceElement, PsiElement>()
val ENUM_AS_SUPERTYPE by error<FirSourceElement, PsiElement>()
val RECURSION_IN_SUPERTYPES by error<FirSourceElement, PsiElement>()
val NOT_A_SUPERTYPE by error<FirSourceElement, PsiElement>()
val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error<FirSourceElement, PsiElement>()
val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error<FirSourceElement, PsiElement> {
parameter<FirClass<*>>("otherSuperType")
}
val SUPERTYPE_INITIALIZED_IN_INTERFACE by error<FirSourceElement, PsiElement>()
val INTERFACE_WITH_SUPERCLASS by error<FirSourceElement, PsiElement>()
val CLASS_IN_SUPERTYPE_FOR_ENUM by error<FirSourceElement, PsiElement>()
val SEALED_SUPERTYPE by error<FirSourceElement, PsiElement>()
val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error<FirSourceElement, PsiElement>()
}
group(" Constructor problems") {
val CONSTRUCTOR_IN_OBJECT by error<FirSourceElement, KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
val CONSTRUCTOR_IN_INTERFACE by error<FirSourceElement, KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by error<FirSourceElement, PsiElement>()
val NON_PRIVATE_CONSTRUCTOR_IN_SEALED by error<FirSourceElement, PsiElement>()
val CYCLIC_CONSTRUCTOR_DELEGATION_CALL by warning<FirSourceElement, PsiElement>()
val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning<FirSourceElement, PsiElement>(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning<FirSourceElement, PsiElement>()
val DELEGATION_SUPER_CALL_IN_ENUM_CONSTRUCTOR by warning<FirSourceElement, PsiElement>()
val PRIMARY_CONSTRUCTOR_REQUIRED_FOR_DATA_CLASS by warning<FirSourceElement, PsiElement>()
val EXPLICIT_DELEGATION_CALL_REQUIRED by warning<FirSourceElement, PsiElement>(PositioningStrategy.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
val SEALED_CLASS_CONSTRUCTOR_CALL by error<FirSourceElement, PsiElement>()
}
group("Annotations") {
val ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR by error<FirSourceElement, KtExpression>()
val ANNOTATION_ARGUMENT_MUST_BE_CONST by error<FirSourceElement, KtExpression>()
val ANNOTATION_ARGUMENT_MUST_BE_ENUM_CONST by error<FirSourceElement, KtExpression>()
val ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL by error<FirSourceElement, KtExpression>()
val ANNOTATION_CLASS_MEMBER by error<FirSourceElement, PsiElement>()
val ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT by error<FirSourceElement, KtExpression>()
val INVALID_TYPE_OF_ANNOTATION_MEMBER by error<FirSourceElement, KtTypeReference>()
val LOCAL_ANNOTATION_CLASS_ERROR by error<FirSourceElement, KtClassOrObject>()
val MISSING_VAL_ON_ANNOTATION_PARAMETER by error<FirSourceElement, KtParameter>()
val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by error<FirSourceElement, KtExpression>()
val NOT_AN_ANNOTATION_CLASS by error<FirSourceElement, PsiElement> {
parameter<String>("annotationName")
}
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by error<FirSourceElement, KtTypeReference>()
val VAR_ANNOTATION_PARAMETER by error<FirSourceElement, KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE)
}
group("Exposed visibility group") {
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
val EXPOSED_FUNCTION_RETURN_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
val EXPOSED_RECEIVER_TYPE by exposedVisibilityError<KtTypeReference>()
val EXPOSED_PROPERTY_TYPE by exposedVisibilityError<KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
val EXPOSED_PARAMETER_TYPE by exposedVisibilityError<KtParameter>(/* // NB: for parameter FE 1.0 reports not on a name for some reason */)
val EXPOSED_SUPER_INTERFACE by exposedVisibilityError<KtTypeReference>()
val EXPOSED_SUPER_CLASS by exposedVisibilityError<KtTypeReference>()
val EXPOSED_TYPE_PARAMETER_BOUND by exposedVisibilityError<KtTypeReference>()
}
group("Modifiers") {
val INAPPLICABLE_INFIX_MODIFIER by error<FirSourceElement, PsiElement>()
val REPEATED_MODIFIER by error<FirSourceElement, PsiElement> {
parameter<KtModifierKeywordToken>("modifier")
}
val REDUNDANT_MODIFIER by error<FirSourceElement, PsiElement> {
parameter<KtModifierKeywordToken>("redundantModifier")
parameter<KtModifierKeywordToken>("conflictingModifier")
}
val DEPRECATED_MODIFIER_PAIR by error<FirSourceElement, PsiElement> {
parameter<KtModifierKeywordToken>("deprecatedModifier")
parameter<KtModifierKeywordToken>("conflictingModifier")
}
val INCOMPATIBLE_MODIFIERS by error<FirSourceElement, PsiElement> {
parameter<KtModifierKeywordToken>("modifier1")
parameter<KtModifierKeywordToken>("modifier2")
}
val REDUNDANT_OPEN_IN_INTERFACE by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.OPEN_MODIFIER)
}
group("Applicability") {
val NONE_APPLICABLE by error<FirSourceElement, PsiElement> {
parameter<Collection<AbstractFirBasedSymbol<*>>>("candidates")
}
val INAPPLICABLE_CANDIDATE by error<FirSourceElement, PsiElement> {
parameter<AbstractFirBasedSymbol<*>>("candidate")
}
val INAPPLICABLE_LATEINIT_MODIFIER by error<FirSourceElement, PsiElement> {
parameter<String>("reason")
}
}
group("Ambiguity") {
val AMBIGUITY by error<FirSourceElement, PsiElement> {
parameter<Collection<AbstractFirBasedSymbol<*>>>("candidates")
}
val ASSIGN_OPERATOR_AMBIGUITY by error<FirSourceElement, PsiElement> {
parameter<Collection<AbstractFirBasedSymbol<*>>>("candidates")
}
}
group("Types & type parameters") {
val TYPE_MISMATCH by error<FirSourceElement, PsiElement> {
parameter<ConeKotlinType>("expectedType")
parameter<ConeKotlinType>("actualType")
}
val RECURSION_IN_IMPLICIT_TYPES by error<FirSourceElement, PsiElement>()
val INFERENCE_ERROR by error<FirSourceElement, PsiElement>()
val PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT by error<FirSourceElement, PsiElement>()
val UPPER_BOUND_VIOLATED by error<FirSourceElement, PsiElement> {
parameter<FirTypeParameterSymbol>("typeParameter")
parameter<ConeKotlinType>("violatedType")
}
val TYPE_ARGUMENTS_NOT_ALLOWED by error<FirSourceElement, PsiElement>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error<FirSourceElement, PsiElement> {
parameter<Int>("expectedCount")
parameter<FirClassLikeSymbol<*>>("classifier")
}
val NO_TYPE_FOR_TYPE_PARAMETER by error<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_OBJECT by error<FirSourceElement, PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error<FirSourceElement, PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error<FirSourceElement, PsiElement>()
val CONFLICTING_PROJECTION by error<FirSourceElement, PsiElement> {
parameter<String>("type") // TODO use ConeType instead of String
}
val VARIANCE_ON_TYPE_PARAMETER_NOT_ALLOWED by error<FirSourceElement, KtTypeParameter>(PositioningStrategy.VARIANCE_MODIFIER)
val CATCH_PARAMETER_WITH_DEFAULT_VALUE by error<FirSourceElement, PsiElement>()
val REIFIED_TYPE_IN_CATCH_CLAUSE by error<FirSourceElement, PsiElement>()
val TYPE_PARAMETER_IN_CATCH_CLAUSE by error<FirSourceElement, PsiElement>()
val GENERIC_THROWABLE_SUBCLASS by error<FirSourceElement, KtTypeParameterList>()
val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error<FirSourceElement, KtClassOrObject>(PositioningStrategy.DECLARATION_NAME)
}
group("overrides") {
val NOTHING_TO_OVERRIDE by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.OVERRIDE_MODIFIER) {
parameter<FirMemberDeclaration>("declaration")
}
val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) {
parameter<Visibility>("overridingVisibility")
parameter<FirCallableDeclaration<*>>("overridden")
parameter<Name>("containingClassName")
}
val CANNOT_CHANGE_ACCESS_PRIVILEGE by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) {
parameter<Visibility>("overridingVisibility")
parameter<FirCallableDeclaration<*>>("overridden")
parameter<Name>("containingClassName")
}
val OVERRIDING_FINAL_MEMBER by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.OVERRIDE_MODIFIER) {
parameter<FirCallableDeclaration<*>>("overriddenDeclaration")
parameter<Name>("containingClassName")
}
val RETURN_TYPE_MISMATCH_ON_OVERRIDE by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_RETURN_TYPE) {
parameter<FirMemberDeclaration>("function")
parameter<FirMemberDeclaration>("superFunction")
}
val PROPERTY_TYPE_MISMATCH_ON_OVERRIDE by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_RETURN_TYPE) {
parameter<FirMemberDeclaration>("property")
parameter<FirMemberDeclaration>("superProperty")
}
val VAR_TYPE_MISMATCH_ON_OVERRIDE by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_RETURN_TYPE) {
parameter<FirMemberDeclaration>("variable")
parameter<FirMemberDeclaration>("superVariable")
}
val VAR_OVERRIDDEN_BY_VAL by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.VAL_OR_VAR_NODE) {
parameter<FirMemberDeclaration>("overridingDeclaration")
parameter<FirMemberDeclaration>("overriddenDeclaration")
}
}
group("Redeclarations") {
val MANY_COMPANION_OBJECTS by error<FirSourceElement, PsiElement>()
val CONFLICTING_OVERLOADS by error<FirSourceElement, PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
parameter<String>("conflictingOverloads") // TODO use Collection<Symbol> instead of String
}
val REDECLARATION by error<FirSourceElement, PsiElement>() {
parameter<String>("conflictingDeclaration") // TODO use Collection<Symbol> instead of String
}
val ANY_METHOD_IMPLEMENTED_IN_INTERFACE by error<FirSourceElement, PsiElement>()
}
group("Invalid local declarations") {
val LOCAL_OBJECT_NOT_ALLOWED by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) {
parameter<Name>("objectName")
}
val LOCAL_INTERFACE_NOT_ALLOWED by error<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME) {
parameter<Name>("interfaceName")
}
}
group("Functions") {
val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error<FirSourceElement, KtFunction>(PositioningStrategy.MODALITY_MODIFIER) {
parameter<FirMemberDeclaration>("function")
parameter<FirMemberDeclaration>("containingClass") // TODO use FirClass instead of FirMemberDeclaration
}
val ABSTRACT_FUNCTION_WITH_BODY by error<FirSourceElement, KtFunction>(PositioningStrategy.MODALITY_MODIFIER) {
parameter<FirMemberDeclaration>("function")
}
val NON_ABSTRACT_FUNCTION_WITH_NO_BODY by error<FirSourceElement, KtFunction>(PositioningStrategy.DECLARATION_SIGNATURE) {
parameter<FirMemberDeclaration>("function")
}
val PRIVATE_FUNCTION_WITH_NO_BODY by error<FirSourceElement, KtFunction>(PositioningStrategy.VISIBILITY_MODIFIER) {
parameter<FirMemberDeclaration>("function")
}
val NON_MEMBER_FUNCTION_NO_BODY by error<FirSourceElement, KtFunction>(PositioningStrategy.DECLARATION_SIGNATURE) {
parameter<FirMemberDeclaration>("function")
}
val FUNCTION_DECLARATION_WITH_NO_NAME by error<FirSourceElement, KtFunction>(PositioningStrategy.DECLARATION_SIGNATURE)
// TODO: val ANONYMOUS_FUNCTION_WITH_NAME by error1<FirSourceElement, PsiElement, Name>(SourceElementPositioningStrategies.DECLARATION_NAME)
val ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE by error<FirSourceElement, KtParameter>(PositioningStrategy.PARAMETER_DEFAULT_VALUE)
val USELESS_VARARG_ON_PARAMETER by warning<FirSourceElement, KtParameter>()
}
group("Properties & accessors") {
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER) {
parameter<FirMemberDeclaration>("property")
parameter<FirMemberDeclaration>("containingClass") // TODO use FirClass instead of FirMemberDeclaration
}
val PRIVATE_PROPERTY_IN_INTERFACE by error<FirSourceElement, KtProperty>(PositioningStrategy.VISIBILITY_MODIFIER)
val ABSTRACT_PROPERTY_WITH_INITIALIZER by error<FirSourceElement, KtExpression>()
val PROPERTY_INITIALIZER_IN_INTERFACE by error<FirSourceElement, KtExpression>()
val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error<FirSourceElement, KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
val BACKING_FIELD_IN_INTERFACE by error<FirSourceElement, KtProperty>(PositioningStrategy.DECLARATION_SIGNATURE)
val EXTENSION_PROPERTY_WITH_BACKING_FIELD by error<FirSourceElement, KtExpression>()
val PROPERTY_INITIALIZER_NO_BACKING_FIELD by error<FirSourceElement, KtExpression>()
val ABSTRACT_DELEGATED_PROPERTY by error<FirSourceElement, KtPropertyDelegate>()
val DELEGATED_PROPERTY_IN_INTERFACE by error<FirSourceElement, KtPropertyDelegate>()
// TODO: val ACCESSOR_FOR_DELEGATED_PROPERTY by error1<FirSourceElement, PsiElement, FirPropertyAccessorSymbol>()
val ABSTRACT_PROPERTY_WITH_GETTER by error<FirSourceElement, KtPropertyAccessor>()
val ABSTRACT_PROPERTY_WITH_SETTER by error<FirSourceElement, KtPropertyAccessor>()
val PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY by error<FirSourceElement, PsiElement>()
val PRIVATE_SETTER_FOR_OPEN_PROPERTY by error<FirSourceElement, PsiElement>()
val EXPECTED_PRIVATE_DECLARATION by error<FirSourceElement, KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
}
group("Multi-platform projects") {
val EXPECTED_DECLARATION_WITH_BODY by error<FirSourceElement, KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
val EXPECTED_PROPERTY_INITIALIZER by error<FirSourceElement, KtExpression>()
// TODO: need to cover `by` as well as delegate expression
val EXPECTED_DELEGATED_PROPERTY by error<FirSourceElement, KtPropertyDelegate>()
}
group("Destructuring declaration") {
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error<FirSourceElement, KtDestructuringDeclaration>()
val COMPONENT_FUNCTION_MISSING by error<FirSourceElement, PsiElement> {
parameter<Name>("missingFunctionName")
parameter<ConeKotlinType>("destructingType")
}
val COMPONENT_FUNCTION_AMBIGUITY by error<FirSourceElement, PsiElement> {
parameter<Name>("functionWithAmbiguityName")
parameter<Collection<AbstractFirBasedSymbol<*>>>("candidates")
}
val COMPONENT_FUNCTION_ON_NULLABLE by error<FirSourceElement, KtExpression> {
parameter<Name>("componentFunctionName")
}
// TODO: val COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH by ...
}
group("Control flow diagnostics") {
val UNINITIALIZED_VARIABLE by error<FirSourceElement, PsiElement> {
parameter<FirPropertySymbol>("variable")
}
val WRONG_INVOCATION_KIND by warning<FirSourceElement, PsiElement> {
parameter<AbstractFirBasedSymbol<*>>("declaration")
parameter<EventOccurrencesRange>("requiredRange")
parameter<EventOccurrencesRange>("actualRange")
}
val LEAKED_IN_PLACE_LAMBDA by error<FirSourceElement, PsiElement> {
parameter<AbstractFirBasedSymbol<*>>("lambda")
}
val WRONG_IMPLIES_CONDITION by warning<FirSourceElement, PsiElement>()
}
group("Nullability") {
val UNSAFE_CALL by error<FirSourceElement, PsiElement>(PositioningStrategy.DOT_BY_SELECTOR) {
parameter<ConeKotlinType>("receiverType")
}
val UNSAFE_IMPLICIT_INVOKE_CALL by error<FirSourceElement, PsiElement> {
parameter<ConeKotlinType>("receiverType")
}
val UNSAFE_INFIX_CALL by error<FirSourceElement, KtExpression> {
parameter<FirExpression>("lhs")
parameter<String>("operator")
parameter<FirExpression>("rhs")
}
val UNSAFE_OPERATOR_CALL by error<FirSourceElement, KtExpression> {
parameter<FirExpression>("lhs")
parameter<String>("operator")
parameter<FirExpression>("rhs")
}
// TODO: val UNEXPECTED_SAFE_CALL by ...
}
group("When expressions") {
val NO_ELSE_IN_WHEN by error<FirSourceElement, KtWhenExpression>(PositioningStrategy.WHEN_EXPRESSION) {
parameter<List<WhenMissingCase>>("missingWhenCases")
}
val INVALID_IF_AS_EXPRESSION by error<FirSourceElement, KtIfExpression>(PositioningStrategy.IF_EXPRESSION)
}
group("Extended checkers") {
val REDUNDANT_VISIBILITY_MODIFIER by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
val REDUNDANT_MODALITY_MODIFIER by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER)
val REDUNDANT_RETURN_UNIT_TYPE by warning<FirSourceElement, PsiTypeElement>()
val REDUNDANT_EXPLICIT_TYPE by warning<FirSourceElement, PsiElement>()
val REDUNDANT_SINGLE_EXPRESSION_STRING_TEMPLATE by warning<FirSourceElement, PsiElement>()
val CAN_BE_VAL by warning<FirSourceElement, KtDeclaration>(PositioningStrategy.VAL_OR_VAR_NODE)
val CAN_BE_REPLACED_WITH_OPERATOR_ASSIGNMENT by warning<FirSourceElement, KtExpression>(PositioningStrategy.OPERATOR)
val REDUNDANT_CALL_OF_CONVERSION_METHOD by warning<FirSourceElement, PsiElement>()
val ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS by warning<FirSourceElement, KtExpression>(PositioningStrategy.OPERATOR)
val EMPTY_RANGE by warning<FirSourceElement, PsiElement>()
val REDUNDANT_SETTER_PARAMETER_TYPE by warning<FirSourceElement, PsiElement>()
val UNUSED_VARIABLE by warning<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
val ASSIGNED_VALUE_IS_NEVER_READ by warning<FirSourceElement, PsiElement>()
val VARIABLE_INITIALIZER_IS_REDUNDANT by warning<FirSourceElement, PsiElement>()
val VARIABLE_NEVER_READ by warning<FirSourceElement, KtNamedDeclaration>(PositioningStrategy.DECLARATION_NAME)
val USELESS_CALL_ON_NOT_NULL by warning<FirSourceElement, PsiElement>()
}
}
private inline fun <reified P : PsiElement> DiagnosticListBuilder.exposedVisibilityError(
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT
) = error<FirSourceElement, P>(positioningStrategy) {
parameter<FirEffectiveVisibility>("elementVisibility")
parameter<FirMemberDeclaration>("restrictingDeclaration")
parameter<FirEffectiveVisibility>("restrictingVisibility")
}
@@ -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("}")
}
@@ -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<String>) {
(classifier as? KClass<*>)?.qualifiedName?.let(set::add)
for (argument in arguments) {
argument.type?.collectClassNamesTo(set)
}
}
@@ -23,12 +23,15 @@ internal class ComposedExpressionCheckers : ExpressionCheckers() {
get() = _variableAssignmentCheckers
override val tryExpressionCheckers: Set<FirTryExpressionChecker>
get() = _tryExpressionCheckers
override val whenExpressionCheckers: Set<FirWhenExpressionChecker>
get() = _whenExpressionCheckers
private val _basicExpressionCheckers: MutableSet<FirBasicExpressionChecker> = mutableSetOf()
private val _qualifiedAccessCheckers: MutableSet<FirQualifiedAccessChecker> = mutableSetOf()
private val _functionCallCheckers: MutableSet<FirFunctionCallChecker> = mutableSetOf()
private val _variableAssignmentCheckers: MutableSet<FirVariableAssignmentChecker> = mutableSetOf()
private val _tryExpressionCheckers: MutableSet<FirTryExpressionChecker> = mutableSetOf()
private val _whenExpressionCheckers: MutableSet<FirWhenExpressionChecker> = 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
}
}
@@ -22,10 +22,12 @@ abstract class ExpressionCheckers {
open val functionCallCheckers: Set<FirFunctionCallChecker> = emptySet()
open val variableAssignmentCheckers: Set<FirVariableAssignmentChecker> = emptySet()
open val tryExpressionCheckers: Set<FirTryExpressionChecker> = emptySet()
open val whenExpressionCheckers: Set<FirWhenExpressionChecker> = emptySet()
@CheckersComponentInternal internal val allBasicExpressionCheckers: Set<FirBasicExpressionChecker> get() = basicExpressionCheckers
@CheckersComponentInternal internal val allQualifiedAccessCheckers: Set<FirQualifiedAccessChecker> get() = qualifiedAccessCheckers + allBasicExpressionCheckers
@CheckersComponentInternal internal val allFunctionCallCheckers: Set<FirFunctionCallChecker> get() = functionCallCheckers + allQualifiedAccessCheckers
@CheckersComponentInternal internal val allVariableAssignmentCheckers: Set<FirVariableAssignmentChecker> get() = variableAssignmentCheckers + allBasicExpressionCheckers
@CheckersComponentInternal internal val allTryExpressionCheckers: Set<FirTryExpressionChecker> get() = tryExpressionCheckers + allBasicExpressionCheckers
@CheckersComponentInternal internal val allWhenExpressionCheckers: Set<FirWhenExpressionChecker> get() = whenExpressionCheckers + allBasicExpressionCheckers
}
@@ -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<FirStatement>
typealias FirQualifiedAccessChecker = FirExpressionChecker<FirQualifiedAccessExpression>
typealias FirFunctionCallChecker = FirExpressionChecker<FirFunctionCall>
typealias FirVariableAssignmentChecker = FirExpressionChecker<FirVariableAssignment>
typealias FirTryExpressionChecker = FirExpressionChecker<FirTryExpression>
typealias FirWhenExpressionChecker = FirExpressionChecker<FirWhenExpression>
@@ -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<FirSourceElement, PsiElement>()
val SEALED_SUPERTYPE_IN_LOCAL_CLASS by error0<FirSourceElement, PsiElement>()
// Constructor problems
// Constructor problems
val CONSTRUCTOR_IN_OBJECT by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val CONSTRUCTOR_IN_INTERFACE by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by existing0<FirSourceElement, PsiElement>()
val NON_PRIVATE_CONSTRUCTOR_IN_SEALED by existing0<FirSourceElement, PsiElement>()
val NON_PRIVATE_CONSTRUCTOR_IN_ENUM by error0<FirSourceElement, PsiElement>()
val NON_PRIVATE_CONSTRUCTOR_IN_SEALED by error0<FirSourceElement, PsiElement>()
val CYCLIC_CONSTRUCTOR_DELEGATION_CALL by warning0<FirSourceElement, PsiElement>()
val PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED by warning0<FirSourceElement, PsiElement>(SourceElementPositioningStrategies.SECONDARY_CONSTRUCTOR_DELEGATION_CALL)
val SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR by warning0<FirSourceElement, PsiElement>()
@@ -81,18 +104,18 @@ object FirErrors {
val SEALED_CLASS_CONSTRUCTOR_CALL by error0<FirSourceElement, PsiElement>()
// Annotations
val ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR by existing0<FirSourceElement, KtExpression>()
val ANNOTATION_ARGUMENT_MUST_BE_CONST by existing0<FirSourceElement, KtExpression>()
val ANNOTATION_ARGUMENT_MUST_BE_ENUM_CONST by existing0<FirSourceElement, KtExpression>()
val ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL by existing0<FirSourceElement, KtExpression>()
val ANNOTATION_CLASS_MEMBER by existing0<FirSourceElement, PsiElement>()
val ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT by existing0<FirSourceElement, KtExpression>()
val INVALID_TYPE_OF_ANNOTATION_MEMBER by existing0<FirSourceElement, KtTypeReference>()
val LOCAL_ANNOTATION_CLASS_ERROR by existing0<FirSourceElement, KtClassOrObject>()
val MISSING_VAL_ON_ANNOTATION_PARAMETER by existing0<FirSourceElement, KtParameter>()
val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by existing0<FirSourceElement, KtExpression>()
val ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR by error0<FirSourceElement, KtExpression>()
val ANNOTATION_ARGUMENT_MUST_BE_CONST by error0<FirSourceElement, KtExpression>()
val ANNOTATION_ARGUMENT_MUST_BE_ENUM_CONST by error0<FirSourceElement, KtExpression>()
val ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL by error0<FirSourceElement, KtExpression>()
val ANNOTATION_CLASS_MEMBER by error0<FirSourceElement, PsiElement>()
val ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT by error0<FirSourceElement, KtExpression>()
val INVALID_TYPE_OF_ANNOTATION_MEMBER by error0<FirSourceElement, KtTypeReference>()
val LOCAL_ANNOTATION_CLASS_ERROR by error0<FirSourceElement, KtClassOrObject>()
val MISSING_VAL_ON_ANNOTATION_PARAMETER by error0<FirSourceElement, KtParameter>()
val NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION by error0<FirSourceElement, KtExpression>()
val NOT_AN_ANNOTATION_CLASS by error1<FirSourceElement, PsiElement, String>()
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by existing0<FirSourceElement, KtTypeReference>()
val NULLABLE_TYPE_OF_ANNOTATION_MEMBER by error0<FirSourceElement, KtTypeReference>()
val VAR_ANNOTATION_PARAMETER by error0<FirSourceElement, KtParameter>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
// Exposed visibility group
@@ -100,7 +123,7 @@ object FirErrors {
val EXPOSED_FUNCTION_RETURN_TYPE by error3<FirSourceElement, KtNamedDeclaration, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_RECEIVER_TYPE by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_PROPERTY_TYPE by error3<FirSourceElement, KtNamedDeclaration, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
val EXPOSED_PARAMETER_TYPE by error3<FirSourceElement, KtParameter, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>(/* // NB: for parameter FE 1.0 reports not on a name for some reason */)
val EXPOSED_PARAMETER_TYPE by error3<FirSourceElement, KtParameter, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_SUPER_INTERFACE by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_SUPER_CLASS by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
val EXPOSED_TYPE_PARAMETER_BOUND by error3<FirSourceElement, KtTypeReference, FirEffectiveVisibility, FirMemberDeclaration, FirEffectiveVisibility>()
@@ -142,17 +165,14 @@ object FirErrors {
val GENERIC_THROWABLE_SUBCLASS by error0<FirSourceElement, KtTypeParameterList>()
val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error0<FirSourceElement, KtClassOrObject>(SourceElementPositioningStrategies.DECLARATION_NAME)
// Overrides
// overrides
val NOTHING_TO_OVERRIDE by error1<FirSourceElement, KtModifierListOwner, FirMemberDeclaration>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
val OVERRIDING_FINAL_MEMBER by error2<FirSourceElement, KtNamedDeclaration, FirCallableDeclaration<*>, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
val CANNOT_WEAKEN_ACCESS_PRIVILEGE by error3<FirSourceElement, KtModifierListOwner, Visibility, FirCallableDeclaration<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val CANNOT_CHANGE_ACCESS_PRIVILEGE by error3<FirSourceElement, KtModifierListOwner, Visibility, FirCallableDeclaration<*>, Name>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val OVERRIDING_FINAL_MEMBER by error2<FirSourceElement, KtNamedDeclaration, FirCallableDeclaration<*>, Name>(SourceElementPositioningStrategies.OVERRIDE_MODIFIER)
val RETURN_TYPE_MISMATCH_ON_OVERRIDE by error2<FirSourceElement, KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
val PROPERTY_TYPE_MISMATCH_ON_OVERRIDE by error2<FirSourceElement, KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
val VAR_TYPE_MISMATCH_ON_OVERRIDE by error2<FirSourceElement, KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_RETURN_TYPE)
val VAR_OVERRIDDEN_BY_VAL by error2<FirSourceElement, KtNamedDeclaration, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
// Redeclarations
@@ -166,56 +186,42 @@ object FirErrors {
val LOCAL_INTERFACE_NOT_ALLOWED by error1<FirSourceElement, KtNamedDeclaration, Name>(SourceElementPositioningStrategies.DECLARATION_NAME)
// Functions
val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error2<FirSourceElement, KtFunction, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.ABSTRACT_MODIFIER)
val ABSTRACT_FUNCTION_WITH_BODY by error1<FirSourceElement, KtFunction, FirMemberDeclaration>(SourceElementPositioningStrategies.ABSTRACT_MODIFIER)
val ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS by error2<FirSourceElement, KtFunction, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
val ABSTRACT_FUNCTION_WITH_BODY by error1<FirSourceElement, KtFunction, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
val NON_ABSTRACT_FUNCTION_WITH_NO_BODY by error1<FirSourceElement, KtFunction, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val PRIVATE_FUNCTION_WITH_NO_BODY by error1<FirSourceElement, KtFunction, FirMemberDeclaration>(SourceElementPositioningStrategies.PRIVATE_MODIFIER)
val PRIVATE_FUNCTION_WITH_NO_BODY by error1<FirSourceElement, KtFunction, FirMemberDeclaration>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val NON_MEMBER_FUNCTION_NO_BODY by error1<FirSourceElement, KtFunction, FirMemberDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val FUNCTION_DECLARATION_WITH_NO_NAME by error0<FirSourceElement, KtFunction>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
// TODO: val ANONYMOUS_FUNCTION_WITH_NAME by error1<FirSourceElement, PsiElement, Name>(SourceElementPositioningStrategies.DECLARATION_NAME)
val ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE by error0<FirSourceElement, KtParameter>(SourceElementPositioningStrategies.PARAMETER_DEFAULT_VALUE)
val USELESS_VARARG_ON_PARAMETER by warning0<FirSourceElement, KtParameter>()
// Properties & accessors
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<FirSourceElement, KtModifierListOwner, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.ABSTRACT_MODIFIER)
val PRIVATE_PROPERTY_IN_INTERFACE by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.PRIVATE_MODIFIER)
val ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS by error2<FirSourceElement, KtModifierListOwner, FirMemberDeclaration, FirMemberDeclaration>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
val PRIVATE_PROPERTY_IN_INTERFACE by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val ABSTRACT_PROPERTY_WITH_INITIALIZER by error0<FirSourceElement, KtExpression>()
// TODO: val MUST_BE_INITIALIZED by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
// TODO: val MUST_BE_INITIALIZED_OR_BE_ABSTRACT by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
// TODO: val EXTENSION_PROPERTY_MUST_HAVE_ACCESSORS_OR_BE_ABSTRACT by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
// TODO: val EXTENSION_PROPERTY_WITH_BACKING_FIELD by error0<FirSourceElement, KtExpression>()
// TODO: val PROPERTY_INITIALIZER_NO_BACKING_FIELD by error0<FirSourceElement, KtExpression>()
val PROPERTY_INITIALIZER_IN_INTERFACE by error0<FirSourceElement, KtExpression>()
val PROPERTY_WITH_NO_TYPE_NO_INITIALIZER by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
// TODO: val BACKING_FIELD_IN_INTERFACE by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val BACKING_FIELD_IN_INTERFACE by error0<FirSourceElement, KtProperty>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val EXTENSION_PROPERTY_WITH_BACKING_FIELD by error0<FirSourceElement, KtExpression>()
val PROPERTY_INITIALIZER_NO_BACKING_FIELD by error0<FirSourceElement, KtExpression>()
val ABSTRACT_DELEGATED_PROPERTY by error0<FirSourceElement, KtPropertyDelegate>()
val DELEGATED_PROPERTY_IN_INTERFACE by error0<FirSourceElement, KtPropertyDelegate>()
// TODO: val ACCESSOR_FOR_DELEGATED_PROPERTY by error1<FirSourceElement, KtPropertyAccessor, FirPropertyAccessorSymbol>()
val ABSTRACT_PROPERTY_WITH_GETTER by error0<FirSourceElement, KtPropertyAccessor>()
val ABSTRACT_PROPERTY_WITH_SETTER by error0<FirSourceElement, KtPropertyAccessor>()
val PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY by error0<FirSourceElement, PsiElement>()
val PRIVATE_SETTER_FOR_OPEN_PROPERTY by error0<FirSourceElement, PsiElement>()
val EXPECTED_PRIVATE_DECLARATION by error0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
// Multi-platform projects
val EXPECTED_DECLARATION_WITH_BODY by error0<FirSourceElement, KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val EXPECTED_PROPERTY_INITIALIZER by error0<FirSourceElement, KtExpression>()
// TODO: need to cover `by` as well as delegate expression
val EXPECTED_DELEGATED_PROPERTY by error0<FirSourceElement, KtPropertyDelegate>()
val EXPECTED_PRIVATE_DECLARATION by error0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
// Destructuring declaration
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<FirSourceElement, KtDestructuringDeclaration>()
val COMPONENT_FUNCTION_MISSING by error2<FirSourceElement, KtExpression, Name, ConeKotlinType>()
val COMPONENT_FUNCTION_AMBIGUITY by error2<FirSourceElement, KtExpression, Name, Collection<AbstractFirBasedSymbol<*>>>()
val COMPONENT_FUNCTION_MISSING by error2<FirSourceElement, PsiElement, Name, ConeKotlinType>()
val COMPONENT_FUNCTION_AMBIGUITY by error2<FirSourceElement, PsiElement, Name, Collection<AbstractFirBasedSymbol<*>>>()
val COMPONENT_FUNCTION_ON_NULLABLE by error1<FirSourceElement, KtExpression, Name>()
// TODO: val COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH by ...
// Control flow diagnostics
val UNINITIALIZED_VARIABLE by error1<FirSourceElement, PsiElement, FirPropertySymbol>()
@@ -225,12 +231,15 @@ object FirErrors {
// Nullability
val UNSAFE_CALL by error1<FirSourceElement, PsiElement, ConeKotlinType>(SourceElementPositioningStrategies.DOT_BY_SELECTOR)
// TODO: val UNSAFE_IMPLICIT_INVOKE_CALL by error1<FirSourceElement, PsiElement, ConeKotlinType>()
// 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<FirSourceElement, PsiElement, ConeKotlinType>()
val UNSAFE_INFIX_CALL by error3<FirSourceElement, KtExpression, FirExpression, String, FirExpression>()
val UNSAFE_OPERATOR_CALL by error3<FirSourceElement, KtExpression, FirExpression, String, FirExpression>()
// Extended checkers group
// When expressions
val NO_ELSE_IN_WHEN by error1<FirSourceElement, KtWhenExpression, List<WhenMissingCase>>(SourceElementPositioningStrategies.WHEN_EXPRESSION)
val INVALID_IF_AS_EXPRESSION by error0<FirSourceElement, KtIfExpression>(SourceElementPositioningStrategies.IF_EXPRESSION)
// Extended checkers
val REDUNDANT_VISIBILITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val REDUNDANT_MODALITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
val REDUNDANT_RETURN_UNIT_TYPE by warning0<FirSourceElement, PsiTypeElement>()
@@ -247,4 +256,5 @@ object FirErrors {
val VARIABLE_INITIALIZER_IS_REDUNDANT by warning0<FirSourceElement, PsiElement>()
val VARIABLE_NEVER_READ by warning0<FirSourceElement, KtNamedDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
val USELESS_CALL_ON_NOT_NULL by warning0<FirSourceElement, PsiElement>()
}
@@ -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<IElementType>, 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<IElementType>, index: Int, depth: Int): FirSourceElement? {
val visitor = PsiElementFinderByType(types, index, depth)
return visitor.find(psi)?.toFirPsiSourceElement()
}
private fun FirLightSourceElement.getChild(types: Set<IElementType>, index: Int, depth: Int): FirSourceElement? {
val visitor = LighterTreeElementFinderByType(treeStructure, types, index, depth)
return visitor.find(lighterASTNode)?.toFirLightSourceElement(treeStructure)
}
@@ -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<FirResolvedTypeRef>()?.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<FirResolvedTypeRef>()
?.type.safeAs<ConeClassLikeType>()
?.lookupTag
?: continue
for (superTypeRef in superTypeRefs) {
val lookupTag = superTypeRef.coneType.safeAs<ConeClassLikeType>()?.lookupTag ?: continue
val fir = lookupTag.toSymbol(context.session)
?.fir.safeAs<FirClass<*>>()
?: 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))
throwableClassLikeType(session).isSupertypeOf(session.typeCheckerContext, this.fullyExpandedType(session))
@@ -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<FirResolvedTypeRef>()
?.coneTypeSafe<ConeClassLikeType>()
?.lookupTag
@@ -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)
}
}
}
@@ -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
)
@@ -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<FirRegularClass>()
?.declarations
?.filterIsInstance<FirSimpleFunction>()
@@ -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<FirTypeParametersOwner>()
val parametersOwner = baseDeclaration.safeAs<FirTypeParametersOwner>()
?: return this
val map = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
@@ -130,27 +130,34 @@ object FirOverrideChecker : FirRegularClassChecker() {
}
}
// See [OverrideResolver#isReturnTypeOkForOverride]
private fun FirCallableMemberDeclaration<*>.checkReturnType(
overriddenSymbols: List<FirCallableSymbol<*>>,
typeCheckerContext: AbstractTypeCheckerContext,
context: CheckerContext,
): FirMemberDeclaration? {
val returnType = returnTypeRef.safeAs<FirResolvedTypeRef>()?.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()
}
}
@@ -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<FirClass<*>>()
?: return
val initializer = declaration.initializer.safeAs<FirClass<*>>() ?: 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<FirResolvedTypeRef>()
?.type.safeAs<ConeClassLikeType>()
?.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<FirRegularClass>()
?: 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<FirResolvedTypeRef>()
?.type.safeAs<ConeClassLikeType>()
?.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<FirRegularClass>()
?: 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<FirResolvedTypeRef>()
?.type.safeAs<ConeClassLikeType>()
?.lookupTag?.classId
?: continue
if (classId.isLocal) {
continue
}
val fir = context.session.firSymbolProvider.getClassLikeSymbolByFqName(classId)
?.fir.safeAs<FirRegularClass>()
?: continue
if (fir.status.modality == Modality.SEALED && !context.containingDeclarations.contains(fir)) {
reporter.reportOn(it.source, FirErrors.SEALED_SUPERTYPE, context)
return
}
}
}
}
@@ -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
@@ -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
}
@@ -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<FirResolvedTypeRef>()
?.firClassLike(context.session)
val explicitType = superReference.superTypeRef
.firClassLike(context.session)
?.followAllAlias(context.session).safeAs<FirClass<*>>()
?: return
@@ -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<FirConstructor>()
?: return
val typeFir = constructorFir.returnTypeRef.safeAs<FirResolvedTypeRef>()
?.type.safeAs<ConeClassLikeType>()
val typeFir = constructorFir.returnTypeRef.coneType
.safeAs<ConeClassLikeType>()
?.lookupTag?.toSymbol(context.session)
?.fir as? FirRegularClass
?: return

Some files were not shown because too many files have changed in this diff Show More