Compare commits

...

309 Commits

Author SHA1 Message Date
Igor Laevsky
6129c5d3de WASM: Add different debug levels to the test runner 2021-08-06 15:24:10 +03:00
Igor Laevsky
790a1e3b2f WASM: Don't use intrinsics to specify NaN's 2021-08-06 15:03:59 +03:00
Igor Laevsky
ad42941679 WASM: Fix JS runner for standalone compiles 2021-08-06 15:03:08 +03:00
Aleksei.Cherepanov
c3344549a8 Avoid overwriting counters file of Lookups storage if it hasn't changed 2021-08-06 02:27:18 +03:00
Aleksei.Cherepanov
cb92413cd8 Change hashcode evaluation for portable caches
Use canonical path and strictly evaluation of hash instead of using insensitive hashcode

#KTIJ-17296 Fixed
2021-08-06 02:27:17 +03:00
Aleksei.Cherepanov
f16b1c2d69 Add flag to cache storage to reduce number of disk accesses 2021-08-06 02:27:15 +03:00
Sergey Igushkin
395b2119a1 Fixup for the fix of KT-47506 interfering with CInterop changes
As the `*Default` configurations are gone, each K/N target now has two
consumable configuration, the `*ApiElements` and the
`*CInteropApiElements`. They have diverging sets of attributes (both
more concrete than `*Default` had).

To make their attribute sets non-diverging, we set the
local-to-project=public on the `*CInteropApiElements` in order to match
the same attribute on the `*ApiElements` configuration

Related to the original fix of KT-47506
2021-08-05 17:53:37 +00:00
Mikhail Glukhikh
11f951e6d1 RawFirBuilder: don't convert scripts to prevent exceptions 2021-08-05 19:24:06 +03:00
Mikhail Glukhikh
8d27f102e7 Fix typo: addCompetedCall -> addCompletedCall 2021-08-05 19:24:06 +03:00
Mikhail Glukhikh
469b3b9d02 Raw FIR: re-use OperatorNameConventions for delegate-related names 2021-08-05 19:24:05 +03:00
Mikhail Glukhikh
22ccb7a943 FIR: discriminate generics during callable reference resolve 2021-08-05 19:24:04 +03:00
Mikhail Glukhikh
e924ee3150 FIR: add test with minOf ambiguity 2021-08-05 19:24:02 +03:00
sebastian.sellmair
ee0b64cb29 [Gradle] BuildKotlinToolingMetadataTask: Ensure clean output directory
This is done to prevent unwanted files from also being located
in the output directory. If the task is executed it is expected
that the output directory only contains this one file.

This is necessary, since *everything* located in the output directory
will potentially be bundled into release apks.

^KT-48019
2021-08-05 16:00:08 +00:00
sebastian.sellmair
e897c60ef1 [Gradle] [Android] Only bundle kotlin tooling metadata for non debuggable variants
^KT-48019
2021-08-05 16:00:08 +00:00
sebastian.sellmair
79565da904 [Gradle] [Android] Implement 'test KotlinToolingMetadataArtifact is bundled into apk'
Covers ^KT-48019
2021-08-05 16:00:08 +00:00
sebastian.sellmair
82a70a205b [Gradle] [Android] Include kotlin-tooling-metadata.json in apk artifact
^KT-48019 Verification Pending
2021-08-05 16:00:07 +00:00
Svyatoslav Scherbina
a22ef02e47 Native: disable compiler caches for experimental memory model
Experimental MM doesn't support compiler caches yet.
2021-08-05 15:22:00 +00:00
Svyatoslav Scherbina
4abbac1ff1 Native: improve code that handles unsupported compiler caches 2021-08-05 15:22:00 +00:00
Dmitry Petrov
02d8c7527e JVM_IR more aggressive if-null expressions fusion
Assume that changing a return type from T to T?
is not a binary-compatible change.
2021-08-05 17:51:49 +03:00
Dmitriy Novozhilov
6f0bf766f2 [Test] Add single service for checking that codegen test is ingored
This approach is better than manual check for `IGNORE_BACKEND` directive
  because it also tracks `IGNORE_BACKEND_FIR` directive and reduces
  duplicating code
2021-08-05 16:59:00 +03:00
Dmitriy Novozhilov
c8386ad1c7 [Test] Properly handle output from separate jvm instance in box tests 2021-08-05 16:58:59 +03:00
Dmitriy Novozhilov
13b5f87f3a [Build] Add gradle properties for different sets of modularized testdata 2021-08-05 15:22:42 +03:00
Dmitriy Novozhilov
d7368c341e [Build] Update kotlin-build-gradle-plugin version to 0.0.32 2021-08-05 15:22:41 +03:00
Dmitriy Novozhilov
adbeda12a6 [Build] Remove pathToKotlinModularizedTestData from kotlin-build-gradle-plugin 2021-08-05 15:22:40 +03:00
Dmitriy Novozhilov
79ff02fd97 [Build] Add documentation for some useful properties in gradle.properties 2021-08-05 15:22:39 +03:00
Alexander Udalov
0925e1b497 Enable JVM IR for stdlib/reflect/test libraries
Changes in Gradle integration tests are needed because:
- in new-mpp-android, kotlin-stdlib-jdk8 is used, and JVM IR generates
  JDK 8-specific bytecode (invokedynamic). D8 needs to be configured to
  desugar it with source/target versions set to 1.8, otherwise it
  reports an error.
- in AndroidExtensionsManyVariants and AndroidIcepickProject, D8 fails
  with assertions enabled if AGP < 4.0.0 is used because of
  https://issuetracker.google.com/issues/148661132. The tests which use
  old AGP versions are probably not relevant anymore anyway.

Changes in kotlin-stdlib-runtime-merged.txt are caused by a slightly
different generation scheme of collection subclasses in JVM IR, and are
harmless.

(Previous attempt was at 15e978dbd311c2ba78ec32b394c21acde9811ccb.)
2021-08-05 12:36:35 +02:00
Abduqodiri Qurbonzoda
29ac9b33ca Add Duration.parse/parseIsoString samples 2021-08-05 10:32:33 +00:00
Abduqodiri Qurbonzoda
5004735366 Add Regex matchAt samples 2021-08-05 10:32:32 +00:00
Abduqodiri Qurbonzoda
d7b10f31b4 Add Regex splitToSequence samples 2021-08-05 10:32:32 +00:00
Sergey Igushkin
e691de6e4c Cleanup configuration to fix corner cases in HMPP dependency resolution
* Set the local-to-project attribute on the compatibility metadata
  variant's "elements" configuration; not setting this attribute could
  lead to ambiguity because of diverging sets of non-matched attributes

* Don't create the `runtimeOnly` configuration for the Kotlin/Native
  targets (or potentially other targets with no runtime dependencies),
  as the K/N target configurator is not aware of the configuration and
  would not set the configuration up properly

* Don't create the legacy `*Default` configurations, as they basically
  duplicate the `*ApiElements` / `*RuntimeElements` configurations but
  don't have all the right attributes, so they are reckoned compatible
  with some consumers unnecessarily and pollute the dependency
  resolution error reports.

Issue #KT-47506
2021-08-05 10:03:13 +00:00
Roman Golyshev
126f6eff28 Add jvm-run-configurations module to the settings.gradle 2021-08-04 22:20:00 +03:00
Dmitriy Novozhilov
8578f0beea [FE 1.0] Check for type mismatch for empty when statements
^KT-47922 Fixed
2021-08-04 19:33:45 +03:00
Dmitriy Novozhilov
60195114c1 [FIR] Properly create class scopes while resolving of annotations arguments 2021-08-04 18:23:06 +03:00
Sergey Bogolepov
4c58954967 [K/N] Don't perform --gc-sections when producing DLL
Due to a bug, lld-link might be a bit too aggressive.
Let's disable --gc-sections for DLL until we update LLD.
Patches:
https://reviews.llvm.org/D101522
https://reviews.llvm.org/D101615
https://reviews.llvm.org/D102138
2021-08-04 14:50:58 +00:00
Victor Petukhov
13cb3c138a Update FE tests 2021-08-04 17:36:53 +03:00
Victor Petukhov
b6cb393796 Check postponed type variables to determine suitability for builder inference (during shouldRunCompletion check) more careful
^KT-42139 Fixed
2021-08-04 17:36:53 +03:00
Victor Petukhov
cf3bd016be Always complete calls not related to the builder inference
^KT-47830 Fixed
2021-08-04 17:36:52 +03:00
Victor Petukhov
dc8dbad0bc Add compiler X-flag to enable self upper bound type inference
^KT-48026 Fixed
2021-08-04 17:36:52 +03:00
Victor Petukhov
7567597be6 Java nullability checker: take type arguments' types from resolution atom if possible, instead of from resolved call directly
^KT-47833 Fixed
2021-08-04 17:36:51 +03:00
Victor Petukhov
93f9d9dacd Check if the intersecting types aren't empty during finding the result type for variable fixation
^KT-47941 Fixed
2021-08-04 17:36:50 +03:00
Victor Petukhov
3eaa452f9e Take into account SimpleTypeWithEnhancement and subtyping related places
^KT-47854 Fixed
2021-08-04 17:36:50 +03:00
Andrey Zinovyev
6ab632f6ad [FIR] Fix mutable context usage in inline diagnostics
Also some minor fixes
2021-08-04 17:33:15 +03:00
Andrey Zinovyev
c46a393a19 [FIR] Add REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE diagnostic 2021-08-04 17:33:15 +03:00
Andrey Zinovyev
e56deb4525 [FIR] Add INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED diagnostic 2021-08-04 17:33:14 +03:00
Andrey Zinovyev
b2f3485d7c [FIR] Add ILLEGAL_INLINE_PARAMETER_MODIFIER diagnostic 2021-08-04 17:33:14 +03:00
Andrey Zinovyev
dabc983f6a [FIR] Add INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE diagnostic 2021-08-04 17:33:13 +03:00
Andrey Zinovyev
efce3fc2e0 [FIR] Add NON_INTERNAL_PUBLISHED_API diagnostic 2021-08-04 17:33:12 +03:00
Andrey Zinovyev
46d1b63f70 [FIR] Add INLINE_PROPERTY_WITH_BACKING_FIELD diagnostic 2021-08-04 17:33:11 +03:00
Andrey Zinovyev
38cecf8b12 [FIR] Add REIFIED_TYPE_PARAMETER_IN_OVERRIDE diagnostic 2021-08-04 17:33:10 +03:00
Andrey Zinovyev
29dbaa4ae1 [FIR] Add OVERRIDE_BY_INLINE diagnostic 2021-08-04 17:33:10 +03:00
Andrey Zinovyev
d8b7b7b2dc [FIR] Add DECLARATION_CANT_BE_INLINED diagnostic 2021-08-04 17:33:09 +03:00
Andrey Zinovyev
4e06814bc5 [FIR] Add NULLABLE_INLINE_PARAMETER diagnostic 2021-08-04 17:33:08 +03:00
Andrey Zinovyev
015c2d1875 [FIR] Add NOTHING_TO_INLINE diagnostic 2021-08-04 17:33:08 +03:00
Andrey Zinovyev
28344c8530 [FIR] Add NOT_YET_SUPPORTED_IN_INLINE diagnostic 2021-08-04 17:33:07 +03:00
Denis.Zharkov
bc75a21852 Optimize Strings representation at FastJarHandler 2021-08-04 17:04:50 +03:00
Denis.Zharkov
4e66fd29e0 Minor. Rename properties in FastJarVirtualFile 2021-08-04 17:04:49 +03:00
Denis.Zharkov
6cd3d84e74 Optimize parseCentralDirectory
Avoid creating redundant IntRange
2021-08-04 17:04:47 +03:00
Denis.Zharkov
f81f28569f Get rid of last map in FastJarHandler 2021-08-04 17:04:44 +03:00
Igor Laevsky
d46f7738c6 WASM: NFC. Add reference to the asmscript license 2021-08-04 16:23:39 +03:00
Igor Laevsky
d8569b6a03 WASM: NFC. Remove dead code 2021-08-04 16:23:38 +03:00
Igor Laevsky
af865544ff WASM: Implement string hashcode 2021-08-04 16:23:38 +03:00
Igor Laevsky
c526145a48 WASM: Disable bunch of tests which expose the same issue after switch to the wasm native strings 2021-08-04 16:23:37 +03:00
Igor Laevsky
80140207b5 WASM: Properly handle nullable exported strings 2021-08-04 16:23:36 +03:00
Igor Laevsky
468fe4196d WASM: Implement string.compareTo and string.subSequence 2021-08-04 16:23:35 +03:00
Igor Laevsky
0eba74a9d2 WASM: Impelment float to string conversion operations 2021-08-04 16:23:32 +03:00
Igor Laevsky
f34a079699 WASM: Implement integer to string conversion operations 2021-08-04 16:23:32 +03:00
Igor Laevsky
2538caa84f WASM: NFC. Rename string import/export functions 2021-08-04 16:23:31 +03:00
Igor Laevsky
ebde1e5491 WASM: Crude println implementation with the wasm-native strings 2021-08-04 16:23:30 +03:00
Igor Laevsky
fc0ae851a2 WASM: Don't special case string equality, it now goes through normal .equals method 2021-08-04 16:23:29 +03:00
Igor Laevsky
d90e3618f9 WASM: NFC. Rename WasmReinterpret into WasmNoOpCast. 2021-08-04 16:23:28 +03:00
Igor Laevsky
0f84525bdc WASM: Implement wasm-native strings part 1
There are several changes here but they all required for at least one test to pass.
- Implemented String class and several utility functions using built-in CharArray
- Added new constant memory segment to hold string literals and required funcs to work with them
- Added very crude mostly incorrect rudimentary ability to pass strings back to javascript
2021-08-04 16:23:28 +03:00
Igor Laevsky
9ccdffe8ad WASM: NFC. Rename WasmPrimitive into WasmAutoboxed and add few comments. 2021-08-04 16:23:27 +03:00
Jinseong Jeon
59ad7e0e04 FIR IDE: create call target for super reference 2021-08-04 15:10:04 +02:00
Jinseong Jeon
c597ee0e34 FIR IDE: fix kotlin origin of annotation call 2021-08-04 15:10:03 +02:00
Jinseong Jeon
c559adc0fb FIR IDE: render list of symbols with indentation
Also, render `psi` of annotation call
(to showcase they're always null for now)
2021-08-04 15:10:02 +02:00
Jinseong Jeon
5b40f291bd FIR IDE: resolve KtTypeReference from super type entry to KtType
which will be mapped to delegated constructor call where we can still
find the referred type.
2021-08-04 15:09:58 +02:00
Jinseong Jeon
d4e1ecd9d3 FIR IDE: fix scope processing for enum entry with members 2021-08-04 15:09:57 +02:00
Stanislav Erokhin
748a2d2e7c [MPP] Performance optimization in expect/actual checker
Previously, the checker executed for every declaration i.e. every
declaration was considered as expect declaration. Because of that in
some cases this checker could eat 6% of compilation time.
After this commit only declarations marked with expect or actual
are checked. To achieve that, logic, that do reporting about missing
actual modifier was moved to the Actual part.

Please note, that in cases where there is no expect/actual modifier at
all other errors (like redeclaration and missing body on "actual"
declaration) would be reported.

Useful nodes:
- In this checker reportOn is always the same as
descriptor.sourceElement.ktElement. This is because the only case when
it isn't true is PropertyAccessors and they are filtered
- Annotation constructor descriptor isActual == true all the time
- previously for weak incompatible members ACTUAL_MISSING
was not reported
- the logic here is super complicated and crazy, but I don't think that
there is sense to refactor it in the old FE
2021-08-04 15:19:34 +03:00
Stanislav Erokhin
e9a2997f7e Minor refactoring -- use util function 2021-08-04 15:19:32 +03:00
Andrey Zinovyev
cea6081d36 [FIR] LT positioning strategy for UNREACHABLE_CODE 2021-08-04 14:42:24 +03:00
Andrey Zinovyev
ec4cbfef59 [FIR] UNREACHABLE_CODE diagnostic (wip)
Implementation for PSI only
2021-08-04 14:42:24 +03:00
Elena Lepilkina
dcd61c292d [K/N][perf] Fix kotlin language version in kotlin-dsl plugin for performance subproject 2021-08-04 10:39:53 +00:00
Sergey Bogolepov
d5e2ac0efc Fix KotlinLibraryResolverImpl.kt on Windows
`absoluteFile` is not enough to make path unique. For example, it doesn't
expand things like '..' and 'IDEAPR~1' on Windows. `canonicalFile` seems
to solve the problem.
2021-08-04 05:44:27 +00:00
Ivan Kochurkin
3c3e51c6de [FIR] Temporary change TYPE_VARIANCE_CONFLICT to warning to unblock bootstrap tests 2021-08-04 01:04:22 +03:00
Ivan Kochurkin
5291648d39 [FIR] Temporary change UPPER_BOUND_VIOLATED to warning to unblock bootstrap tests 2021-08-03 23:15:40 +03:00
Dmitry Petrov
bd71fbe982 JVM_IR KT-34594 strip fake variable initialization during inlining 2021-08-03 20:41:31 +03:00
Dmitry Petrov
37050e0616 JVM_IR KT-34594 don't generate fake local variable for @InlineOnly 2021-08-03 20:41:31 +03:00
Simon Ogorodnik
32b380e187 [FP] Fix compiler arguments for intellij-community building 2021-08-03 19:52:23 +03:00
Simon Ogorodnik
872b6b7e81 [FE 1.0 FP] Fix compiler arguments to avoid errors 2021-08-03 19:52:23 +03:00
Simon Ogorodnik
a7961a4a45 [FIR MT] Add reading of packagePrefix from model of java roots 2021-08-03 19:52:22 +03:00
Simon Ogorodnik
97bfc49ed6 [FIR Test] Fix file counting for global passes 2021-08-03 19:52:21 +03:00
Simon Ogorodnik
1188d311b3 [FIR MT] Add sorting by timestamp from model, reading of modularJdkRoot 2021-08-03 19:52:20 +03:00
Mikhail Glukhikh
77f0bd3834 FirOuterClassArgumentsRequiredChecker: read containingClass safely 2021-08-03 19:52:18 +03:00
Nikolay Krasko
bb718f2e0b Allow reading signing parameters from environment variables (KTI-552) 2021-08-03 17:54:09 +03:00
Denis.Zharkov
fa9f0d588d Optimize FastJarHandler
- Do not use normalization as it seems unnecessary
2021-08-03 16:24:51 +03:00
Denis.Zharkov
2266a348c3 Get rid of another map built in FastJarHandler 2021-08-03 16:24:50 +03:00
Denis.Zharkov
42b2605c2a Minor. Rename local vals 2021-08-03 16:24:50 +03:00
Denis.Zharkov
1a262c9c31 Adapt FastJarVirtualFile constructor to its usages 2021-08-03 16:24:49 +03:00
Denis.Zharkov
920d57563b Add fast-path for filename String creation
In most cases, it's encoded with ASCI
2021-08-03 16:24:48 +03:00
Denis.Zharkov
cd51264940 Avoid using FactoryMap at FastJarHandler
It has quite a slow entrySet implementation
2021-08-03 16:24:48 +03:00
Denis.Zharkov
979f5e8443 Rework FastJarHandler
1. Do not inherit from ZipHandler
2. Previously, the following computations have been happening:
- Map<String, ZipEntryDescription> -> Map<String, EntryInfo> (see createEntriesMap)
- Map<String, EntryInfo> -> VirtualFile tree

But the intermediate computations (Map<String, EntryInfo>)
were only used in the constructor, thus they've eliminated in this commit

3. Unclear magic semantic from `getOrCreate` with "/" and "\\" (copy-pasted from CoreJarHandler)
has been replaced with `normalizePath`
2021-08-03 16:24:47 +03:00
Denis.Zharkov
edf9f5e647 FIR: Minor. Clarify name for containingClassForStaticMemberAttr 2021-08-03 16:24:46 +03:00
Denis.Zharkov
956bf22191 FIR: Optimize AbstractAnnotationDeserializer
Do not search for annotation constructors unless we really need it
2021-08-03 16:24:45 +03:00
Viacheslav Kormushkin
1654824467 Commonization of CocoaPods libraries
#KT-41631
2021-08-03 12:50:05 +00:00
Pavel Punegov
73bb6d5d34 [Native] Move JavaLauncher property from global scope to the KonanPlugin 2021-08-03 10:15:08 +00:00
Pavel Punegov
6bbfe0d503 [Native] Add project property that holds JavaLauncher provider
This property is initialized once to make ToolRunner do not query for
the launcher. Also set JDK 11 as a default in case of an unavailable JDK
set as the toolchain, like JDK 17 that is not available in the auto mode
in Gradle and requires environment variable to be set.
2021-08-03 10:15:08 +00:00
Pavel Punegov
2656c94535 [Native] Use common toolchain configuration 2021-08-03 10:15:08 +00:00
Pavel Punegov
ba5bd0b069 [Native] Add java plugin dependency to Konan plugin
Change required version of Gradle to 6.7
2021-08-03 10:15:07 +00:00
Pavel Punegov
ad2fabb7cb Add environments for JDK 16 and 17 2021-08-03 10:15:07 +00:00
Pavel Punegov
afa8e16c25 [Native] JDK toolchains in KonanToolRunner
Use JDK toolchains in KonanToolRunner to make build able to change JDK
Use JDK 17 for MacOS aarch64 hosts
2021-08-03 10:15:06 +00:00
Pavel Punegov
5338705402 [Native] Enable parallel platform libs generation on parameter
Use kotlin.native.platformLibs.parallel to control parallel generation.
Disable parallel execution of platform libs on MacOS aarch64
2021-08-03 10:15:06 +00:00
Ilmir Usmanov
cbe0de6111 Extend local variable ranges
when it is safe. Otherwise, they will not be visible in
debugger as soon as they become dead.
 #KT-47749 Fixed
2021-08-03 08:00:51 +00:00
Dmitriy Novozhilov
ca9cbf7eb7 Fix warnings in K/Native code 2021-08-03 07:40:57 +00:00
Mikhael Bogdanov
0a5991d6e7 Update bootstrap to 1.6.0-dev-2117 2021-08-03 07:40:56 +00:00
Svyatoslav Scherbina
fb27459b2e Native: fix downloading dependencies when producing cache 2021-08-03 07:01:08 +00:00
Sergey Bogolepov
e177cecd50 [K/N] Specify -target-cpu for all targets
Motivation:
1. Avoid things like KT-47911.
2. Generate a bit more effective code in some cases.
3. A bit easier -Xoverride-konan-properties.
2021-08-03 05:54:36 +00:00
Sergey Bogolepov
b37cdae966 [K/N] Fix KT-47911
Specify target-cpu when compiling for AArch64 Darwin targets, because
Apple's CPU might execute "movi.2d vD, #0" incorrectly.

See https://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20171218/511205.html.
2021-08-03 05:54:35 +00:00
Sergey Bogolepov
84d06f35e9 [K/N] Update usages of LLVM bin directory on Windows 2021-08-03 05:42:09 +00:00
Sergey Bogolepov
7d8360f38b [K/N] Set target-features for host targets
Benchmarks on CI show that there are some performance regressions after
LLVM update due to worse inliner results. Explicit specification of
target-features fixes the problem. Interestingly, it seems that this is
not required for Darwin AArch64 target.
2021-08-03 05:42:08 +00:00
Sergey Bogolepov
adc1ca76f4 [K/N] Update requirements in readme
* Updated Windows requirements for building from source
* Removed Linux requirements on ncurses because LLVM is built without it
* Explicitly stated glibc version
2021-08-03 05:42:08 +00:00
Sergey Bogolepov
bfc3f35d94 [K/N] Disable stress_gc_allocations for watchos_simulator_arm64 2021-08-03 05:42:07 +00:00
Sergey Bogolepov
8803a69c9d [K/N] Add ARM Neon intrinsic to CallsChecker whitelist 2021-08-03 05:42:07 +00:00
Sergey Bogolepov
922fcc4049 [K/N] Fix windows dynamic tests for LLD
Adjust compilation and linking flags to workaround absence of direct
DLL linkage in LLD.
2021-08-03 05:42:07 +00:00
Sergey Bogolepov
c7c78e0e1a [K/N] Use LLD 12.0.1 for MinGW targets
Clang-produced and GCC-produced binaries might be ABI-incompatible on
MinGW. Explanation on GitHub: msys2/MINGW-packages/issues/6855#issuecomment-680859662.
TL;DR: GCC-generated sections are 16-byte-padded, while Clang ones are
not. It causes problems during merge of COMDAT sections.
I observed the problem during compilation of runtime tests, but it is
possible that the problem could affect main compilation pipeline as well.
https://reviews.llvm.org/D86659 (which landed in LLVM 12) fixes
the problem. So we have another motivation for switching to LLD besides
https://youtrack.jetbrains.com/issue/KT-47605.

The only known downside is unsupported defsym which causes slight binary
size increase. I think it is doable.
2021-08-03 05:42:06 +00:00
Sergey Bogolepov
6e093b0beb [K/N] Update libffi for Windows
MinGW and MSVC are hardly compatible in case of static linkage, so we
need to use a native libffi.
2021-08-03 05:42:06 +00:00
Sergey Bogolepov
a525f3f357 [K/N] Fix path to ld.gold on Windows
targetToolchain.mingw_x64-linux_* are changed, so we should their usages
Probably, we could switch to LLD, but it requires additional testing.
2021-08-03 05:42:05 +00:00
Sergey Bogolepov
66ddd15798 [K/N] Support compiler compilation in MSVC environment
The right way is to add something like KonanTarget.MSVC_X64, but doing
so requires changes throughout whole compiler. It would be especially
painful in HostManager, where we would need to deprecate
KonanTarget.MINGW_X64 as host. Instead we "hack" ClangArgs to compile
for x86_64-pc-windows-msvc instead of x86_64-pc-windows-gnu in JNI case.

CI may contain custom MSVC and Windows Kit installation path, so we
should support it. Things might break when machine has several MSVC
installed (at custom and default path), but it sounds more like
incorrect environment setup problem than ours.
2021-08-03 05:42:05 +00:00
Sergey Bogolepov
a78fcd6b64 [K/N] Separate ClangArgs for jni and native
Since LLVM for Windows is now native instead on MinGW, we have to
compile code in a different environment in case of JNI. This commits
just separates ClangArgs into two subclasses without actual behavior
changes.
2021-08-03 05:42:05 +00:00
Sergey Bogolepov
fbbbc1c092 [K/N] Drop Configurables interface for ClangArgs
ClangArgs abused delegation mechanism and it complicated its interface.
2021-08-03 05:42:04 +00:00
Sergey Bogolepov
a783ee9ae7 [K/N] Drop -D_GLIBCXX_USE_CXX11_ABI=0 for LLVM
We don't use old glibc++ ABI for LLVM, so this flag have to be dropped.
(Otherwise you'll find yourself fighting sporadic runtime crushes,
trust me).
2021-08-03 05:42:04 +00:00
Sergey Bogolepov
0d39442a5e [K/N] Update linux_arm32_hfp llvm target features
Set of target features has changed between LLVM 8 and LLVM 11.
Update the list for linux_arm32_hfp to make clang stop complaining.
2021-08-03 05:42:03 +00:00
Sergey Bogolepov
1c7a27ce42 [K/N] Fix mxgot flag for MIPS
It was dropped from cc1 interface, so use -target-feature +xgot instead.
2021-08-03 05:42:03 +00:00
Sergey Bogolepov
e8b025f267 [K/N] Drop obsolete --no-threads LLD flags
--no-threads flag was used, because LLD had deadlock long time ago.
This flag is removed from LLD (in favor of --threads=N) and it looks
like that the bug is gone now. So we can just drop --no-threads flag!
2021-08-03 05:42:03 +00:00
Sergey Bogolepov
572f08151a [K/N] Disable code coverage testing
Since LLVM 8, coverage format has changed.
We don't officially provide code coverage for end-users, so it's ok to
disable it for now and fix later.
2021-08-03 05:42:02 +00:00
Sergey Bogolepov
02aebd6565 [K/N] Update LLVM stubs to 11.1.0
Also add necessary changes to CoverageMappingC.cpp to make it compile.
2021-08-03 05:42:02 +00:00
Sergey Bogolepov
601465fa81 [K/N] Change how common polyhash function are included
Recent versions of LLVM complain when caller and callee have
different vector attributes: https://reviews.llvm.org/D82562.

To mitigate this problem this commit changes how we include
polyHashUnroll* and polyHashTail into Traits: we duplicate them
inside each trait with correct attributes by using
```
#pragma clang attribute push(ATTRIBUTE, apply_to = function)
```
This solution is not pretty for sure, but Clang is not complaining
anymore.
2021-08-03 05:42:02 +00:00
Sergey Bogolepov
493fa1c1e3 [K/N] Update Clang stubs for 11.1.0
Removed hacks for CXType_ExtVector type because now it is included in
Clang C API.
2021-08-03 05:42:01 +00:00
Sergey Bogolepov
023c775188 [K/N] Bump macOS minimal version 2021-08-03 05:42:01 +00:00
Sergey Bogolepov
7dda04a1c9 [K/N] Update LLVM distributions to 11.1.0
This commit is important for several reasons:
1. Finally, LLVM update from 8.0.0 to 11.1.0
At the time of writing, LLVM 12.0.0 already came out, but we need to be
compatible with LLVM from Xcode 12.5, so that's why we stick to a bit
older version of LLVM.
2. These LLVM distributions are built with tools/llvm_builder/package.py
We finally managed to introduce an explicit process of building our LLVM
distributions, so we will be able to updated them more frequently and
adapt to our needs.
3. Native Windows LLVM instead of MinGW
Last but not least, we now use native Windows LLVM distribution. While
it might be harder to use (no more posix everywhere), simpler build
process (building msys2 is not that easy) and no need for MinGW-specific
patches makes such distribution way more convenient.
2021-08-03 05:42:00 +00:00
Sergey Bogolepov
44256db824 [K/N] Update minimal Xcode version
The next LLVM version will be 11.1.0, and we need to be sure that
Xcode supports bitcode of this version. So we bump minimal Xcode version
to 12.5, which should be OK, because by the time Kotlin 1.6.0 comes out,
Xcode 12.5 will be around 6 month old.

Also this commit simplifies tarball naming.
2021-08-03 05:42:00 +00:00
Sergey Bogolepov
017c8d8211 [K/N] Drop linuxArm32Hfp from tetris sample
Its sysroot doesn't include SDL2 anymore, so it won't compile anyway.
2021-08-03 05:38:07 +00:00
Sergey Bogolepov
0923d13d55 [K/N] Fix gtk sample compilation on MinGW 2021-08-03 05:38:06 +00:00
Nikolay Krasko
6c49a18770 Fix exhaustive when in HierarchicalStructureOptOutIT.kt 2021-08-03 06:53:33 +03:00
Dmitriy Novozhilov
0ac96b4973 [Test] Remove redundant out variance from TestStep 2021-08-03 00:26:10 +03:00
Dmitriy Novozhilov
b584fed93d [FIR] Migrate warning/error pairs to DiagnosticFactoryForDeprecation 2021-08-03 00:20:11 +03:00
Dmitriy Novozhilov
adfeab1bd0 [FIR] Add ability to generate special diagnostic factories for deprecation warnings
This kind of diagnostic factory has two different factories with warning
  and error severity and language feature with turns on reporting of error
2021-08-03 00:17:33 +03:00
Dmitriy Novozhilov
d17f984edf [FE 1.0] Migrate most of warning/error pairs to DiagnosticFactoryForDeprecation 2021-08-03 00:17:33 +03:00
Dmitriy Novozhilov
7c73840e4a [FE 1.0] Introduce new kind of diagnostic factories for deprecation warnings/errors 2021-08-03 00:17:33 +03:00
sebastian.sellmair
ff9643b70e [Gradle] CInteropCommonizerTask: Refine local variable names
^KT-47775
^KT-47053
2021-08-02 20:38:28 +00:00
sebastian.sellmair
153df1dd1a [Gradle] CommonizerIT: Parameterize test on commonizeMultipleCInteropsWithTests
Testing the project w/ and w/o the commonon mistake
of declaring dependsOn edges from test to main source sets

^KT-47775
^KT-47053
2021-08-02 20:38:27 +00:00
sebastian.sellmair
db10732d6c [Gradle] Add integration test project 'commonizeMultipleCInteropsWithTests'
Implemented `test multiple cinterops with test source sets and compilations`

This test will assert source set dependencies
and shared native compilations.

^KT-47775
^KT-47053
2021-08-02 20:38:27 +00:00
sebastian.sellmair
4ae51e1d02 [Gradle] AbstractCInteropCommonizerTask: Ensure outputDirectory path is unique and short enough
^KT-47056 Verification Pending
2021-08-02 20:38:27 +00:00
sebastian.sellmair
02d4c866ca [Gradle] CInterop commonization: Improve grouping and dependency management
^KT-47775 Verification Pending
This implementation will be lenient toward the common
*Test.dependsOn(*Main) mistake.

^KT-47053 Verification Pending
Support source sets that do not have a dedicated
shared native compilation. Also support additional visible source sets
coming from associate compilations.
2021-08-02 20:38:26 +00:00
Ivan Kochurkin
a7e81d5154 Fix test data OverridenSetterVisibility.kt 2021-08-02 20:43:24 +03:00
Igor Yakovlev
bbd21da835 [FIR] Move ARGUMENTS_OF_ANNOTATIONS on top of STATUS phase 2021-08-02 20:29:09 +03:00
Igor Yakovlev
0f3f56f676 [FIR] Update resolve status of annotations to partially resolved 2021-08-02 20:29:08 +03:00
Igor Yakovlev
8fd2ddad12 [FIR] Downgrade ensure resolves to types instead of status 2021-08-02 20:29:07 +03:00
Igor Yakovlev
c0949fbc18 [FIR] Remove redundant ensure to status in FirPackageMemberScope 2021-08-02 20:29:06 +03:00
Igor Yakovlev
9fdd3dc53f [FIR IDE] Add support of lazy phase for annotation arguments 2021-08-02 20:29:06 +03:00
Dmitriy Novozhilov
71def0666e [FIR] Introduce special phase for resolve of enums and class literals 2021-08-02 20:29:05 +03:00
Ivan Kochurkin
afb85026c4 Revert "[FIR] Implement INVISIBLE_SETTER"
This reverts commit b3d7ed56
2021-08-02 20:10:22 +03:00
Ivan Kochurkin
b264a2e5dd [FIR] Fix Consider getter and setter for CANNOT_WEAKEN_ACCESS_PRIVILEGE
Hash: 0e2d765a2d
2021-08-02 20:10:22 +03:00
Dmitriy Novozhilov
17bbedbc50 [Test] Fix FileComparisonFailureFirst comparator to keep sorting stability 2021-08-02 20:07:49 +03:00
Dmitriy Novozhilov
ca40cbede5 [Test] Get rid of BackendKindExtractor 2021-08-02 20:07:49 +03:00
Dmitriy Novozhilov
d43d0071a4 [Test] Add documentation to test infrastructure 2021-08-02 20:07:48 +03:00
Dmitriy Novozhilov
08a1134fff [Test] Remove abstract MultiModuleInfoDumper 2021-08-02 20:07:47 +03:00
Dmitriy Novozhilov
90e06bf403 [Test] Reformat AbstractIrSerializeCompileKotlinAgainstInlineKotlinTest
- Extract IrInlineBodiesHandler to separate file
- Replace SerializeSetter environment configurator with SERIALIZE_IR
    directive
2021-08-02 20:07:46 +03:00
Dmitriy Novozhilov
a66f3d26fd [Test] Replace three fixed phases of tests with step system
Now each test is just a sequence of any number of different steps. There
  are two kinds of steps:
1. Run some facade
2. Run handlers of specific artifact kind

Through the test each module passed to each step (if it is compatible
  by kinds of artifacts)
2021-08-02 20:07:45 +03:00
Dmitriy Novozhilov
ba48f80e53 [Test] Introduce single interface for all entities which provides directive containers and test services 2021-08-02 20:07:44 +03:00
Sergey Shanshin
b42d6a3e85 Fix creating of lazy delegated property in kotlinx.serialization
Fixes Kotlin/kotlinx.serialization#1616
2021-08-02 16:27:03 +00:00
Alexander Shabalin
4c3fb8697b Add FormatToSpan 2021-08-02 16:07:50 +00:00
Igor Chevdar
2c068b8c5a [K/N][IR] Fix for https://youtrack.jetbrains.com/issue/KT-47814 2021-08-02 19:22:08 +05:00
Igor Chevdar
da4113af88 [K/N][runtime] Lazy initialization fix for wasm 2021-08-02 19:20:33 +05:00
Simon Ogorodnik
ed07e1c778 [FIR] Add missing type-alias unwrap in CompletionModeCalculator 2021-08-02 17:07:15 +03:00
Simon Ogorodnik
8e890eba3e [FIR] Hack-in indirectly nested locals resolution 2021-08-02 17:07:15 +03:00
Simon Ogorodnik
7422571c72 [FIR] Fix cycle when loading nested enum within java annotation 2021-08-02 17:07:15 +03:00
sebastian.sellmair
947e97511b [Gradle] CInteropProcess: Prevent compilation when depending on project without c-interops 2021-08-02 12:26:46 +00:00
sebastian.sellmair
4ce3f87361 [Gradle] CommonizerIT: Add failing test when depending on project without c-interops
Adapted existing `test KT-47641 commonizing c-interops does not depend on any source compilation`
to add a project dependency from a project with c-interops (p2)
to a project without any c-interops (p0)

This leads to compilation of project p0, since the
cinteropApiElements configuration was not created on p0
2021-08-02 12:26:45 +00:00
sebastian.sellmair
329991217a [Gradle] Prevent cinterop's from depending on compile tasks
- KotlinNativeCompilation
Change how associate compilations are connected.
Instead of using the implementation configuration, it now uses
the `compileDependencyFiles` directly. This will keep the
implementation configuration from containing any main compilation's
output. Therefore this configuration can still be forwarded to the
cinterop tool.

- KotlinNativeTargetConfigurator.kt CInteropConfigurations.kt
Create special configurations for cinteropApiElements and
cinterop dependencies. This configuration is tries to resolve
only cinterop dependencies when such variants are offered by a project.

^KT-47641 Verification Pending
2021-08-02 12:26:45 +00:00
sebastian.sellmair
7b5a3f8d1b [Gradle] Remove c-interop dependency to main compilation's output 2021-08-02 12:26:45 +00:00
sebastian.sellmair
8e6f84d5cd [Gradle] CommonizerIT: Add test asserting that cinterop commonization does not depend on any source compilation
^KT-47641
2021-08-02 12:26:44 +00:00
Simon Ogorodnik
a353719a6b [FIR] Add dump for fir blocks 2021-08-02 11:24:56 +03:00
Dmitriy Novozhilov
199ec60742 [JVM] Reduce number of param slots for string concatenation
With paramSlot = 200 those tests fails on JDKs which are newer than JDK 9
- testConcatDynamic200Long
- testConcatDynamicIndy200Long()
2021-08-01 22:23:48 +03:00
Dmitriy Novozhilov
5206b45ce3 [Test] Use JDK 11 instead of JDK 9 in modern jdk tests 2021-08-01 22:23:47 +03:00
Dmitriy Novozhilov
fd537e7d5a [Build] Detect JDK 17 in old way using environment variables
There is a problem that toolchains can not detect JDK 17 EAP
  on windows agents. This commit will be reverted after JDK 17 release
  in adoptopenjdk.net
2021-08-01 22:23:47 +03:00
Dmitriy Novozhilov
17fc1da719 [Reflection] Support java records in kotlin reflection
^KT-47760
2021-08-01 22:23:46 +03:00
Dmitriy Novozhilov
8dad8fa813 [Reflection] Support java sealed classes in kotlin reflection
^KT-46778
2021-08-01 22:23:45 +03:00
Dmitriy Novozhilov
fa1d09c778 [FE 1.0] Support java sealed classes
^KT-46778 Fixed
2021-08-01 22:23:45 +03:00
Dmitriy Novozhilov
972211f8e6 [Test] Add directive which allows to attach debugger to instance of JVM in box test 2021-08-01 22:23:44 +03:00
Dmitriy Novozhilov
1fa74ef939 [Test] Move test on modern jdk to separate test runners
This is needed to avoid problems with installation of proper jdk
  on developer machines. Those tests will be moved back to main box
  suites after migrating our tests on LTS versions of jdk (11 and 17
  instead of 9 and 15)
2021-08-01 22:23:43 +03:00
Dmitriy Novozhilov
89bd52c7d2 [Test] Provide path to JDK 9/15/17 via toolchains 2021-08-01 22:23:42 +03:00
Dmitriy Novozhilov
de73622af9 [Test] Mark BB tests on modern jdks with tag and ignore them in different-jdk tests 2021-08-01 22:23:42 +03:00
Dmitriy Novozhilov
c2e2068682 [Test] Add ability to mark group of tests with specific tags
Currently tags can be applied to all tests in specific testdata
  directory by placing `_tags.txt` file in it, where all tags should
  be listed on separate lines. Test generator adds those tags to
  corresponding generated test classes with `@Tag` annotation

Please note that is applicable only to JUnit 5 tests
2021-08-01 22:23:41 +03:00
Dmitriy Novozhilov
b9c549803d [Test] Replace public fun box() with fun box() in all box tests 2021-08-01 22:23:40 +03:00
Dmitriy Novozhilov
c168a561df [Test] Migrate tests for java 15 to regular test infrastructure 2021-08-01 22:23:39 +03:00
Dmitriy Novozhilov
4f73ebbcbd [Test] Migrate tests for java 9 to regular test infrastructure 2021-08-01 22:23:39 +03:00
Dmitriy Novozhilov
ca214bef30 [Test] Add ability to run box test in separate jvm for common codegen tests 2021-08-01 22:23:36 +03:00
Dmitriy Novozhilov
04d9d243de [Test] Convert TestJdkKind.java to Kotlin 2021-08-01 22:23:35 +03:00
Dmitriy Novozhilov
4a09fba3a4 Rename .java to .kt 2021-08-01 22:23:34 +03:00
Dmitriy Novozhilov
e4d2351e03 [Build] Add JDK_17 to list of toolchains 2021-08-01 22:23:34 +03:00
Igor Chevdar
448376f073 [K/N][IR][optmz] Global analysis for top-level initializers
The analysis' goal is to remove redundant calls to initializers
2021-07-31 01:40:00 +05:00
Igor Chevdar
9c6943b8c4 [K/N][IR] Split Devirtualization onto phases
The analysis itself and applying its results to the IR
2021-07-31 01:40:00 +05:00
Igor Chevdar
b11201be81 [K/N][IR][runtime] Implemented lazy per-file initialization strategy 2021-07-31 01:39:59 +05:00
Mark Punzalan
504449f03e FIR: Report UNSAFE_CALL instead of SMARTCAST_IMPOSSIBLE when smartcast
to null.

Currently the error message shows the expression is impossible to
smartcast to the nullable type, which is nonsensical since it's already
that type.
2021-07-30 21:49:50 +03:00
Mark Punzalan
0627dbcb78 FIR IDE: Check stability of smartcast expressions in
KtFirExpressionTypeProvider.getDefiniteNullability().
2021-07-30 21:49:49 +03:00
Mikhail Glukhikh
5283f7b7c6 Make EXPERIMENTAL_API_USAGE_ERR warning till 1.6 for fake override case 2021-07-30 21:21:51 +03:00
Alexander Udalov
3636118743 Introduce typealias JvmRepeatable for j.l.a.Repeatable
#KT-12794 Fixed
2021-07-30 19:53:44 +02:00
Alexander Udalov
847c58d574 Report error on class named Container inside repeatable annotation
#KT-12794
 #KT-47971
2021-07-30 19:53:44 +02:00
Alexander Udalov
5f7803f2db Use double-checked locking in some reflection internals
Note that `volatile` is not needed because in both cases we initialize
an object with a final field, which is subject to safe initialization.
2021-07-30 19:53:33 +02:00
Alexander Udalov
e20b354dbd Check repeatable annotation container parameters, retention, target
#KT-12794
 #KT-47928
2021-07-30 19:53:33 +02:00
Alexander Udalov
0a6d010d1c Support new repeatable annotations in kotlin-reflect
- Unwrap Kotlin-repeatable annotations (with implicit container)
- Introduce `KAnnotatedElement.findAnnotations` to find instances of
  repeated annotations

 #KT-12794
2021-07-30 19:53:33 +02:00
Alexander Udalov
67128c022a Report error if both repeatable annotation and its container are used
#KT-12794
2021-07-30 19:53:32 +02:00
Alexander Udalov
b2550f69bc Report error if repeated annotation is used with JVM target 1.6
#KT-12794
2021-07-30 19:53:32 +02:00
Alexander Udalov
26043f3968 Generate Java @Repeatable on Kotlin-repeatable annotation classes
#KT-12794
2021-07-30 19:53:32 +02:00
Alexander Udalov
92a73d7636 Generate container class for repeatable annotations
#KT-12794
2021-07-30 19:53:32 +02:00
Alexander Udalov
87130edfa2 Support using Java-repeatable annotations in Kotlin
#KT-12794
2021-07-30 19:53:32 +02:00
Alexander Udalov
f723389565 Remove mapping of java.Repeatable to kotlin.Repeatable in JavaAnnotationMapper
The main motivation for this change is that
java.lang.annotation.Repeatable has a parameter for the container
annotation, which is lost during conversion to
kotlin.annotation.Repeatable. To support j.l.a.Repeatable in backend
properly, it's absolutely necessary to be able to load the container
annotation for any repeatable annotation class, so the original
j.l.a.Repeatable needs to be stored in the descriptor and accessible
from the backend.

Instead of mapping j.l.a.Repeatable -> k.a.Repeatable, add a frontend
service PlatformAnnotationFeaturesSupport that will determine if an
annotation is repeatable "according to the platform rules", which for
JVM means that it's annotated with j.l.a.Repeatable.

Some effects of this change include:
- Usages of j.l.a.Repeatable are no longer reported as "deprecated", the
  corresponding test is deleted
- Usages of repeatable annotations declared in Java with non-SOURCE
  retention with LV 1.5 and earlier will now result in a slightly
  different error (REPEATED_ANNOTATION instead of
  NON_SOURCE_REPEATED_ANNOTATION)

 #KT-12794
2021-07-30 19:53:32 +02:00
Dmitry Petrov
ebf837c135 JVM_IR disable IR and bytecode validation by default 2021-07-30 20:21:41 +03:00
Ivan Kochurkin
1a40164ef0 [FIR] Fix resolving of single underscore _
Now compiler throws `UNRESOLVED_REFERENCE` here:

```
val boo = { _: Exception -> `_`.stackTrace }
```
2021-07-30 16:58:07 +00:00
Ivan Kochurkin
8bfaa39a5c [FIR] Implement RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER
Split underscore checkers
2021-07-30 16:58:07 +00:00
Ivan Kochurkin
10d9988824 [FIR] Implement DANGEROUS_CHARACTERS 2021-07-30 16:58:06 +00:00
Ivan Kochurkin
83895c49c5 [FIR] Implement INVALID_CHARACTERS 2021-07-30 16:58:06 +00:00
Ivan Kochurkin
63fc3645ab [FIR] Optimize performance and fix UNDERSCORE_IS_RESERVED, simplify code 2021-07-30 16:58:05 +00:00
Ivan Kochurkin
2fbb700ec6 [FIR] Add nonFatalDiagnostics to FirQualifierAccess 2021-07-30 16:58:05 +00:00
Ivan Kochurkin
b307358f69 [FIR] buildErrorExpression for labels with underscored name
Add ConeDiagnosticWithSource, ConeUnderscoreIsReserved, ConeUnderscoreUsageWithoutBackticks diagnostics
2021-07-30 16:58:05 +00:00
Ivan Kochurkin
f5d8535dc5 [FIR] Add aliasSource to FirImport, FirImportImpl 2021-07-30 16:58:04 +00:00
Mikhail Glukhikh
354a06b94a FirSuspendCallChecker: make infix call check more clear 2021-07-30 19:06:55 +03:00
Mikhail Glukhikh
3c2e266c31 FirSuspendCallChecker: use symbol accessor API instead of symbol.fir 2021-07-30 19:06:54 +03:00
Mikhail Glukhikh
e0b1d0db53 FirSuspendCallChecker: drop support of experimental coroutines 2021-07-30 19:06:53 +03:00
Mikhail Glukhikh
807f031dcc FIR: introduce RETURN_FOR_BUILT_IN_SUSPEND diagnostic 2021-07-30 19:06:53 +03:00
Mikhail Glukhikh
229dfd3f5f FIR: introduce builtin suspend related diagnostics 2021-07-30 19:06:51 +03:00
Mikhail Glukhikh
391c4db87c FIR: introduce ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL diagnostics 2021-07-30 19:06:49 +03:00
Mikhail Glukhikh
2397650c24 FIR: introduce NON_LOCAL_SUSPENSION_POINT diagnostic 2021-07-30 19:06:48 +03:00
Mikhail Glukhikh
8f1d07084b FIR: introduce ILLEGAL_SUSPEND_FUNCTION_CALL & PROPERTY_ACCESS diagnostics 2021-07-30 19:06:46 +03:00
Ilya Kirillov
e4992176c1 FIR LC: fix inheritance checking for light classes
Before it was not able to check inheritance with type parameters substitutions like

class A<T>
class B: A<Int>
2021-07-30 18:59:21 +03:00
Ilya Kirillov
767af0dae0 HL API: fix super declarations search for local classes 2021-07-30 18:59:19 +03:00
Ivan Kochurkin
0e2d765a2d [FIR] Consider getter and setter for CANNOT_WEAKEN_ACCESS_PRIVILEGE
Fill source with correct value instead of null
for FirDefaultPropertySetter in light tree converter
2021-07-30 18:07:35 +03:00
Ivan Kochurkin
b3d7ed569d [FIR] Implement INVISIBLE_SETTER 2021-07-30 18:07:34 +03:00
Nikolay Krasko
ca4410aa53 Stop auto-generating expected test data on TeamCity in assertEqualsToFile 2021-07-30 17:46:45 +03:00
Sergey Igushkin
edaf925b19 Reorder Gradle -Xplugin=... so that serialization goes first (KT-47921)
Ensure that the serialization plugin's artifact (and, possibly, some
other prioritized plugin artifacts) are put first to the -Xplugin=...
classpath passed to the compiler.

This fixes the conflict of the serialization plugin with some other
plugins altering the IR in unexpected ways.

Issue #KT-47921
2021-07-30 16:20:14 +04:00
Dmitriy Dolovov
033a9f1589 Bump konanVersion: 1.6.0 2021-07-30 14:52:08 +03:00
Ilya Matveev
e45b13d582 [K/N][New MM] Check if asserts are enabled in thread state asserts 2021-07-30 10:30:50 +00:00
Aleksandr Samofalov
5ee87e126d KMA-51 Use local ObjCExportMapper in ObjCExportTranslatorMobile 2021-07-30 13:13:26 +03:00
Aleksandr Samofalov
d72a399982 KMA-51 Create API to use ObjCExportTranslator to translate functions in IDE 2021-07-30 13:13:26 +03:00
Yahor Berdnikau
90d15f156b Fix toolchain may fail to find tools.jar and false-fail the build.
This may happen when build itself is running on JDK9+ and toolchain
is set to <=JDK1.8. CompilerEnvironment gets 'tools.jar' from the
current Gradle Daemon JDK, but there was a check if exception should be
thrown that uses 'javaVersion' from toolchain provided JDK.

Additionally also fixed 'tools.jar' was not provided for
 'KotlinCompileWithWorkers' task.

^KT-47940 Fixed
2021-07-30 09:59:49 +00:00
Yahor Berdnikau
bab5a4a6c9 Allow to specify JDK for build.
For now it disables debug option.

^KT-47940 In progress
2021-07-30 09:59:49 +00:00
Alexander Gorshenev
9148094bbd Garbage collection capable wrappers for skia interop 2021-07-30 12:54:51 +03:00
Alexander Shabalin
d9483ccb08 Enable stacktraces for RuntimeAssert, TODO 2021-07-30 08:22:32 +00:00
Pavel Kunyavskiy
d18ade088d [K/N] Help message for disabling quarantine flag on dylibs in distribution 2021-07-30 08:17:45 +00:00
Elena Lepilkina
9142b03df5 [K/N][Samples] Use unsigned types in videoplayer 2021-07-30 08:05:44 +00:00
Dmitry Petrov
ca5ebdc13c PSI2IR KT-44855 propagate smart cast information for property values 2021-07-29 21:41:50 +03:00
Mikhael Bogdanov
cdbd0eb932 Reopen KT-47920 test and add missed .txt files
#KT-47920 Open
2021-07-29 19:52:59 +02:00
Mikhael Bogdanov
824d6ab5cc Update tests affected by 'ProhibitSimplificationOfNonTrivialConstBooleanExpressions' feature 2021-07-29 19:45:57 +02:00
Mikhael Bogdanov
1e2547d0d0 Temporary mute test-lombok-with-kapt test
#KT-47945
2021-07-29 19:45:57 +02:00
Mikhael Bogdanov
588952bc9a Fix maven tests 2021-07-29 19:45:57 +02:00
Mikhael Bogdanov
a1bd728aef Update SNAPSHOT version in maven projects/tests 2021-07-29 19:45:57 +02:00
Mikhail Glukhikh
55f7bb2756 Fix FIR PSI consistency test (definitely not-null types) 2021-07-29 19:45:57 +02:00
Alexander Udalov
d36c56497e Minor, improve CLI test internalArgOverrideOffLanguageFeature
Avoid disabling language features which cannot be disabled anymore.
2021-07-29 19:45:57 +02:00
Dmitriy Novozhilov
262c9e88d1 [FE 1.0] Fix remaining codegen spec tests 2021-07-29 19:45:57 +02:00
Denis.Zharkov
ee68962c02 Ignore Jvm8RuntimeDescriptorLoaderTestGenerated::testMapRemove
For now, JavaResolverSettings in runtime are different from
default language version, so it might have a little bit different API surface

In future, it's worth considering changing JavaResolverSettings.Default
once default language version is changing

  #KT-47903
2021-07-29 19:45:57 +02:00
Mikhael Bogdanov
4fe846fb81 Fix test affected by InstantiationOfAnnotationClasses feature 2021-07-29 19:45:57 +02:00
Mikhael Bogdanov
1347ee8c7d Update DiagnosicTestGenerated affected by 'PrivateInFileEffectiveVisibility' feature 2021-07-29 19:45:57 +02:00
Denis.Zharkov
d2ad421e0b Fix test data for definitelyNotNullType 2021-07-29 19:45:57 +02:00
Denis.Zharkov
8f484fcf88 Fix propagation of definitelyNotNull types from overrides 2021-07-29 19:45:57 +02:00
Victor Petukhov
cba224b7b8 Update spec black box tests 2021-07-29 19:45:56 +02:00
Mikhael Bogdanov
baaa615e09 Update FirOldFrontendDiagnosticsTestGenerated tests 2021-07-29 19:45:56 +02:00
Mikhael Bogdanov
70e4472c99 Update Fir2IrTextTestGenerated tests 2021-07-29 19:45:56 +02:00
Victor Petukhov
d2a7434cff Update testdata 2021-07-29 19:45:56 +02:00
Denis.Zharkov
f34726ff91 Fix test data for ForeignAnnotations 2021-07-29 19:45:56 +02:00
Dmitriy Novozhilov
2ae546576c [FE 1.0] Update DUPLICATE_LABEL_IN_WHEN testdata
New diagnostics started to report because in 1.6 we assume that
  `1` is typed const of type Int instead of literal const
2021-07-29 19:45:56 +02:00
Dmitriy Novozhilov
b1d17cfd7b [FE 1.0] Force resolve annotations on type arguments
^KT-46173
2021-07-29 19:45:56 +02:00
Dmitriy Novozhilov
e316cd04b6 [FIR] Fix consistency of FE 1.0 and FIR test data 2021-07-29 19:45:56 +02:00
Denis.Zharkov
699d53e7f9 Fix ISE when copying a function with @NotNull bounded type parameters
For example in the case:
<_A extends @NotNull B, B> void f4(_A x, B y) { }

ISE had happened because while substituting the function
we've been creating copies of old type parameters and when initializing
bounds for one of them bounds for other may not be initialized yet
at the same time bounds were necessary for makesSenseToBeDefinitelyNotNull
2021-07-29 19:45:56 +02:00
Mikhael Bogdanov
0c419eac1a Update Java8BuiltInsWithJDKMembersTest tests 2021-07-29 19:45:56 +02:00
Mikhael Bogdanov
0f216f4d37 Update LoadJava8TestGenerated tests 2021-07-29 19:45:56 +02:00
Mikhael Bogdanov
a544d6948b Fix simpleUnaryOperators.kt test 2021-07-29 19:45:56 +02:00
Victor Petukhov
f84adcb378 [FE 1.0] Fix some foreign annotation tests 2021-07-29 19:45:56 +02:00
Victor Petukhov
ca0b8be53b [FE 1.0] Fix some diagnostic spec tests 2021-07-29 19:45:55 +02:00
Alexander Udalov
0ed9b75428 Minor, fix diagnostic test data for FIR 2021-07-29 19:45:55 +02:00
Alexander Udalov
b442e598d3 Fix test data of codegen tests for KT-47328 for 1.6 2021-07-29 19:45:55 +02:00
Alexander Udalov
f1ac5796ed Fix test data of compileJavaAgainstKotlin for 1.6
See LanguageFeature.DefinitelyNotNullTypeParameters.
2021-07-29 19:45:55 +02:00
Alexander Udalov
2d0d83a54b Fix AntTaskTestGenerated.testLanguageVersion for 1.6 2021-07-29 19:45:55 +02:00
Alexander Udalov
6af042c1dd Temporarily disable runtime version consistency checks
To be enabled after the project is fully bootstrapped and default
language version is advanced to 1.6.
2021-07-29 19:45:55 +02:00
Victor Petukhov
95492f7370 [FE 1.0] Fix some diagnostic tests 2021-07-29 19:45:55 +02:00
Dmitriy Novozhilov
7250aed3b5 [FE 1.0] Fix some diagnostic tests 2021-07-29 19:45:55 +02:00
Mikhael Bogdanov
c9c82ab3a6 Update test affected by SafeCallsAreAlwaysNullable feature 2021-07-29 19:45:55 +02:00
Mikhael Bogdanov
c8094f7439 Add readable toString for JavaTypeEnhancementState 2021-07-29 19:45:55 +02:00
Mikhael Bogdanov
f590c3201a Update ScriptingHostTest.testCompileOptionsLanguageVersion test 2021-07-29 19:45:55 +02:00
Mikhael Bogdanov
70fe984738 Update classTypeParameter.kt test 2021-07-29 19:45:55 +02:00
Mikhael Bogdanov
cc5ba4c0af Update diagnostic tests 2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
0cccb76652 Update tests affected by ProperTypeInferenceConstraintsProcessing feature 2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
235359e028 Ignore tests cause of KT-47542
#KT-47542
2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
390eda1b9d Fix CompileKotlinAgainstCustomBinariesTest tests 2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
7854e9c3d7 Update CLI tests 2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
1187e786f4 Fix compilation in MappedExtensionProvider.kt 2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
5f3f2e762a Update JS tests 2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
1fe1c197ee Mute WASM safeAccess.kt test
Update JS tests
2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
29f6ec4f40 Update defaultSnapshotVersion to 1.6.255-SNAPSHOT 2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
38fb5e16ef Update test affected by ApproximateIntegerLiteralTypesInReceiverPosition feature 2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
805778e782 Fix compilation cause of KT-47797 problem
#KT-47797
2021-07-29 19:45:54 +02:00
Mikhael Bogdanov
7cbd6908f9 Update test affected by ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated feature 2021-07-29 19:45:53 +02:00
Mikhael Bogdanov
228100ef09 Upgrade toolchain to api/lv 1.4 2021-07-29 19:45:53 +02:00
Mikhael Bogdanov
a919aab3ab Update metadata related logic after switch to 1.6 2021-07-29 19:45:53 +02:00
Mikhael Bogdanov
ee07ff7982 Switch latest stable version to 1.6 2021-07-29 19:45:53 +02:00
Dmitry Petrov
caa13b33b1 JVM_IR minor: update testdata 2021-07-29 20:45:16 +03:00
Dmitry Petrov
b93dff003f JVM_IR configure loop shape in the backend context 2021-07-29 20:45:15 +03:00
Dmitry Petrov
38d6c8ded0 JVM_IR generate range loops as counter loops when possible 2021-07-29 20:45:14 +03:00
Sergey Igushkin
d0f207071c Prepare for enabling HMPP by default and migrating the flags (KT-40245)
* Add a new single flag for enabling HMPP:
  kotlin.mpp.hierarchicalStructureSupport

  When this flag is enabled:

  * The old HMPP flags gets enabled, too, for old consumers
  * The commonizer gets enabled as well
  * An internal flag is set to indicate that the old flags were set by
    the plugin

* Add an internal flag that we should flip when HMPP becomes the
  default: kotlin.internal.mpp.hierarchicalStructureByDefault

  With this flag is enabled:

  * All MPP projects will use the composite artifact and
    compile metadata with the KLIB compiler
  * The compatibility metadata artifact will be gone
  * The new HMPP flag is enabled by default

* Add consistency checks for new VS old flags

Issue #KT-40245
2021-07-29 19:12:53 +03:00
Pavel Kirpichenkov
352c624601 Provide built-ins module name in IrLinker for debugger 2021-07-29 19:04:25 +03:00
1663 changed files with 29206 additions and 10852 deletions

View File

@@ -1,6 +1,7 @@
<component name="ProjectDictionaryState">
<dictionary name="igor">
<words>
<w>addr</w>
<w>descr</w>
<w>exprs</w>
</words>

View File

@@ -4,7 +4,7 @@
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="--tests &quot;org.jetbrains.kotlin.gradle.CommonizerHierarchicalIT&quot; --tests &quot;org.jetbrains.kotlin.gradle.CommonizerIT&quot; --tests &quot;org.jetbrains.kotlin.commonizer.**&quot;" />
<option name="scriptParameters" value="--tests &quot;org.jetbrains.kotlin.gradle.CommonizerHierarchicalIT&quot; --tests &quot;org.jetbrains.kotlin.gradle.CommonizerIT&quot; --tests &quot;org.jetbrains.kotlin.commonizer.**&quot; --tests &quot;org.jetbrains.kotlin.gradle.native.CocoaPodsIT.testCinteropCommonization*&quot;" />
<option name="taskDescriptions">
<list />
</option>

View File

@@ -48,12 +48,14 @@ open class LookupStorage(
@Volatile
private var size: Int = 0
private var oldSize: Int = 0
init {
try {
if (countersFile.exists()) {
val lines = countersFile.readLines()
size = lines[0].toInt()
oldSize = size
}
} catch (e: Exception) {
throw IOException("Could not read $countersFile", e)
@@ -120,13 +122,15 @@ open class LookupStorage(
@Synchronized
override fun flush(memoryCachesOnly: Boolean) {
try {
if (size > 0) {
if (!countersFile.exists()) {
countersFile.parentFile.mkdirs()
countersFile.createNewFile()
}
if (size != oldSize) {
if (size > 0) {
if (!countersFile.exists()) {
countersFile.parentFile.mkdirs()
countersFile.createNewFile()
}
countersFile.writeText("$size\n0")
countersFile.writeText("$size\n0")
}
}
} finally {
super.flush(memoryCachesOnly)

View File

@@ -33,15 +33,19 @@ class CachingLazyStorage<K, V>(
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
private var storage: PersistentHashMap<K, V>? = null
private var isStorageFileExist = true
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
if (storage != null) return storage
if (!isStorageFileExist) return null
if (storageFile.exists()) {
storage = createMap()
return storage
}
isStorageFileExist = false
return null
}

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.incremental.storage
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.EnumeratorStringDescriptor
import com.intellij.util.io.IOUtil
@@ -26,7 +27,6 @@ import org.jetbrains.kotlin.cli.common.toBooleanLenient
import java.io.DataInput
import java.io.DataInputStream
import java.io.DataOutput
import java.io.File
import java.util.*
/**
@@ -162,7 +162,7 @@ object ConstantsMapExternalizer : DataExternalizer<Map<String, Any>> {
}
}
override fun read(input: DataInput): Map<String, Any>? {
override fun read(input: DataInput): Map<String, Any> {
val size = input.readInt()
val map = HashMap<String, Any>(size)
@@ -197,15 +197,33 @@ object IntExternalizer : DataExternalizer<Int> {
}
}
object PathStringDescriptor : EnumeratorStringDescriptor() {
override fun getHashCode(value: String) = FileUtil.pathHashCode(value)
override fun isEqual(val1: String, val2: String?) = FileUtil.pathsEqual(val1, val2)
// Should be consistent with org.jetbrains.jps.incremental.storage.PathStringDescriptor for correct work of portable caches
object PathStringDescriptor : EnumeratorStringDescriptor() {
private const val PORTABLE_CACHES_PROPERTY = "org.jetbrains.jps.portable.caches"
private val PORTABLE_CACHES = java.lang.Boolean.getBoolean(PORTABLE_CACHES_PROPERTY)
override fun getHashCode(path: String): Int {
if (!PORTABLE_CACHES) return FileUtil.pathHashCode(path)
// On case insensitive OS hash calculated from value converted to lower case
return if (StringUtil.isEmpty(path)) 0 else FileUtil.toCanonicalPath(path).hashCode()
}
override fun isEqual(val1: String, val2: String?): Boolean {
if (!PORTABLE_CACHES) return FileUtil.pathsEqual(val1, val2)
// On case insensitive OS hash calculated from path converted to lower case
if (val1 == val2) return true
if (val2 == null) return false
val path1 = FileUtil.toCanonicalPath(val1)
val path2 = FileUtil.toCanonicalPath(val2)
return path1 == path2
}
}
open class CollectionExternalizer<T>(
private val elementExternalizer: DataExternalizer<T>,
private val newCollection: () -> MutableCollection<T>
private val elementExternalizer: DataExternalizer<T>,
private val newCollection: () -> MutableCollection<T>
) : DataExternalizer<Collection<T>> {
override fun read(input: DataInput): Collection<T> {
val result = newCollection()

View File

@@ -29,7 +29,7 @@ buildscript {
dependencies {
bootstrapCompilerClasspath(kotlin("compiler-embeddable", bootstrapKotlinVersion))
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.31")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.32")
classpath(kotlin("gradle-plugin", bootstrapKotlinVersion))
classpath(kotlin("serialization", bootstrapKotlinVersion))
classpath("org.jetbrains.dokka:dokka-gradle-plugin:0.9.17")

View File

@@ -22,7 +22,7 @@ buildscript {
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.31")
classpath("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.32")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:${project.bootstrapKotlinVersion}")
}
@@ -143,7 +143,7 @@ java {
dependencies {
implementation(kotlin("stdlib", embeddedKotlinVersion))
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${project.bootstrapKotlinVersion}")
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.31")
implementation("org.jetbrains.kotlin:kotlin-build-gradle-plugin:0.0.32")
implementation("com.gradle.publish:plugin-publish-plugin:0.14.0")
implementation("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")

View File

@@ -22,5 +22,14 @@ val KotlinBuildProperties.ignoreTestFailures: Boolean get() = getBoolean("ignore
val KotlinBuildProperties.disableWerror: Boolean
get() = getBoolean("kotlin.build.disable.werror") || useFir || isInJpsBuildIdeaSync || getBoolean("test.progressive.mode")
val KotlinBuildProperties.pathToKotlinModularizedTestData: String?
get() = getOrNull("kotlin.fir.modularized.testdata.kotlin") as? String
val KotlinBuildProperties.pathToIntellijModularizedTestData: String?
get() = getOrNull("kotlin.fir.modularized.testdata.intellij") as? String
val KotlinBuildProperties.pathToYoutrackModularizedTestData: String?
get() = getOrNull("kotlin.fir.modularized.testdata.youtrack") as? String
val KotlinBuildProperties.isObsoleteJdkOverrideEnabled: Boolean
get() = getBoolean("kotlin.build.isObsoleteJdkOverrideEnabled", false)

View File

@@ -22,7 +22,8 @@ enum class JdkMajorVersion(
JDK_10(10, mandatory = false, overrideMajorVersion = 11),
JDK_11(11, mandatory = false),
JDK_15(15, mandatory = false),
JDK_16(16, mandatory = false);
JDK_16(16, mandatory = false),
JDK_17(17, mandatory = false);
fun isMandatory(): Boolean = mandatory
@@ -180,4 +181,4 @@ fun Project.getJdkVersionWithOverride(jdkVersion: JdkMajorVersion): JdkMajorVers
} else {
jdkVersion
}
}
}

View File

@@ -37,8 +37,8 @@ configurations {
}
tasks.withType<KotlinCompile> {
kotlinOptions.languageVersion = "1.3"
kotlinOptions.apiVersion = "1.3"
kotlinOptions.languageVersion = "1.4"
kotlinOptions.apiVersion = "1.4"
kotlinOptions.freeCompilerArgs += listOf(
"-Xskip-prerelease-check",
"-Xskip-runtime-version-check",

View File

@@ -171,16 +171,18 @@ fun Project.configureDefaultPublishing() {
.all { configureRepository() }
}
private fun Project.getSensitiveProperty(name: String): String? {
return project.findProperty(name) as? String ?: System.getenv(name)
}
private fun Project.configureSigning() {
configure<SigningExtension> {
sign(extensions.getByType<PublishingExtension>().publications) // all publications
val signKeyId = project.findProperty("signKeyId") as? String
val signKeyId = project.getSensitiveProperty("signKeyId")
if (!signKeyId.isNullOrBlank()) {
val signKeyPrivate = project.findProperty("signKeyPrivate") as? String
?: error("Parameter `signKeyPrivate` not found")
val signKeyPassphrase = project.findProperty("signKeyPassphrase") as? String
?: error("Parameter `signKeyPassphrase` not found")
val signKeyPrivate = project.getSensitiveProperty("signKeyPrivate") ?: error("Parameter `signKeyPrivate` not found")
val signKeyPassphrase = project.getSensitiveProperty("signKeyPassphrase") ?: error("Parameter `signKeyPassphrase` not found")
useInMemoryPgpKeys(signKeyId, signKeyPrivate, signKeyPassphrase)
} else {
useGpgCmd()

View File

@@ -15,7 +15,10 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.codegen.CodegenTestFiles
import org.jetbrains.kotlin.codegen.GenerationUtils
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.psi.KtFile
@@ -23,11 +26,11 @@ import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
import org.jetbrains.kotlin.test.model.DependencyKind
import org.jetbrains.kotlin.test.model.FrontendKinds
import org.jetbrains.kotlin.test.model.ResultingArtifact
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
@@ -382,6 +385,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
"test${testDataFile.nameWithoutExtension.replaceFirstChar(Char::uppercaseChar)}",
emptySet()
)
startingArtifactFactory = { ResultingArtifact.Source() }
}.build(testDataFile.path)
}
@@ -406,7 +410,6 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
assertions = JUnit5Assertions
useAdditionalService<TemporaryDirectoryManager>(::TemporaryDirectoryManagerImpl)
useAdditionalService<BackendKindExtractor>(::BackendKindExtractorImpl)
useSourcePreprocessor(*AbstractKotlinCompilerTest.defaultPreprocessors.toTypedArray())
useDirectives(*AbstractKotlinCompilerTest.defaultDirectiveContainers.toTypedArray())
}

View File

@@ -87,7 +87,7 @@ class StringConcatGenerator(val mode: JvmStringConcat, val mv: InstructionAdapte
paramTypes.add(type)
paramSlots += type.size
template.append("\u0001")
if (paramSlots >= 200) {
if (paramSlots >= 199) {
// Concatenate current arguments into string
// because of `StringConcatFactory` limitation add use it as new argument for further processing:
// "The number of parameter slots in {@code concatType} is less than or equal to 200"
@@ -166,4 +166,4 @@ class StringConcatGenerator(val mode: JvmStringConcat, val mv: InstructionAdapte
StringConcatGenerator(state.runtimeStringConcat, mv)
}
}
}

View File

@@ -1288,8 +1288,8 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
fun nextLabel(node: AbstractInsnNode?): LabelNode? {
var current = node
while (current != null) {
if (current is LabelNode) return current
current = current.next
if (current is LabelNode) return current as LabelNode
current = current!!.next
}
return null
}
@@ -1302,6 +1302,8 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
oldLvt += record
}
method.localVariables.clear()
val oldLvtNodeToLatestNewLvtNode = mutableMapOf<LocalVariableNode, LocalVariableNode>()
// Skip `this` for suspend lambda
val start = if (isForNamedFunction) 0 else 1
for (variableIndex in start until method.maxLocals) {
@@ -1341,33 +1343,41 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
val endLabel = nextLabel(insn.next)?.let { min(lvtRecord.end, it) } ?: lvtRecord.end
// startLabel can be null in case of parameters
@Suppress("NAME_SHADOWING") val startLabel = startLabel ?: lvtRecord.start
val node = LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index)
method.localVariables.add(node)
// Attempt to extend existing local variable node corresponding to the record in
// the original local variable table, if there is no back-edge
val recordToExtend: LocalVariableNode? = oldLvtNodeToLatestNewLvtNode[lvtRecord]
var recordExtended = false
if (recordToExtend != null) {
var hasBackEdgeOrStore = false
var current: AbstractInsnNode? = recordToExtend.end
while (current != null && current != endLabel) {
if (current is JumpInsnNode) {
if (method.instructions.indexOf((current as JumpInsnNode).label) < method.instructions.indexOf(current)) {
hasBackEdgeOrStore = true
break
}
}
if (current!!.isStoreOperation() && (current as VarInsnNode).`var` == recordToExtend.index) {
hasBackEdgeOrStore = true
break
}
current = current!!.next
}
if (!hasBackEdgeOrStore) {
recordToExtend.end = endLabel
recordExtended = true
}
}
if (!recordExtended) {
val node = LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index)
method.localVariables.add(node)
oldLvtNodeToLatestNewLvtNode[lvtRecord] = node
}
}
}
}
// Merge consequent LVT records, otherwise, atomicfu goes crazy (KT-47749)
val toRemove = arrayListOf<LocalVariableNode>()
val sortedLVT = method.localVariables.sortedBy { method.instructions.indexOf(it.start) }
for (i in sortedLVT.indices) {
var endIndex = method.instructions.indexOf(sortedLVT[i].end)
for (j in (i + 1) until sortedLVT.size) {
val startIndex = method.instructions.indexOf(sortedLVT[j].start)
if (endIndex < startIndex) break
if (endIndex != startIndex ||
sortedLVT[i].index != sortedLVT[j].index ||
sortedLVT[i].name != sortedLVT[j].name ||
sortedLVT[i].desc != sortedLVT[j].desc
) continue
sortedLVT[i].end = sortedLVT[j].end
endIndex = method.instructions.indexOf(sortedLVT[j].end)
toRemove += sortedLVT[j]
}
}
method.localVariables.removeAll(toRemove)
for (variable in oldLvt) {
// $continuation and $result are dead, but they are used by debugger, as well as fake inliner variables
// For example, $continuation is used to create async stack trace

View File

@@ -320,7 +320,8 @@ class AnonymousObjectTransformer(
inliningContext.callSiteInfo.isInlineOrInsideInline,
inliningContext.callSiteInfo.file,
inliningContext.callSiteInfo.lineNumber
), null
),
null
).doInline(deferringVisitor, LocalVarRemapper(parameters, 0), false, mapOf())
reifiedTypeParametersUsages?.let(result.reifiedTypeParametersUsages::mergeAll)
deferringVisitor.visitMaxs(-1, -1)

View File

@@ -13,12 +13,8 @@ import org.jetbrains.kotlin.codegen.inline.coroutines.markNoinlineLambdaIfSuspen
import org.jetbrains.kotlin.codegen.inline.coroutines.surroundInvokesWithSuspendMarkersIfNeeded
import org.jetbrains.kotlin.codegen.optimization.ApiVersionCallsPreprocessingMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.common.ControlFlowGraph
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
import org.jetbrains.kotlin.codegen.optimization.common.*
import org.jetbrains.kotlin.codegen.optimization.fixStack.*
import org.jetbrains.kotlin.codegen.optimization.fixStack.FastStackAnalyzer
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNotNull
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
import org.jetbrains.kotlin.config.LanguageFeature
@@ -747,6 +743,8 @@ class MethodInliner(
ApiVersionCallsPreprocessingMethodTransformer(targetApiVersion).transform("fake", node)
}
removeFakeVariablesInitializationIfPresent(node)
val frames = FastStackAnalyzer("<fake>", node, FixStackInterpreter()).analyze()
val localReturnsNormalizer = LocalReturnsNormalizer()
@@ -769,6 +767,73 @@ class MethodInliner(
localReturnsNormalizer.transform(node)
}
private fun removeFakeVariablesInitializationIfPresent(node: MethodNode) {
// Before 1.6, we generated fake variable initialization instructions
// ICONST_0
// ISTORE x
// for all inline functions. Original intent was to mark inline function body for the debugger with corresponding LVT entry.
// However, for @InlineOnly functions corresponding LVT entries were not copied (assuming that nobody is actually debugging
// @InlineOnly functions).
// Since 1.6, we no longer generate fake variables for @InlineOnly functions
// Here we erase fake variable initialization for @InlineOnly functions inlined into existing bytecode (e.g., inline function
// inside third-party library).
// We consider a sequence of instructions 'ICONST_0; ISTORE x' a fake variable initialization if the corresponding variable 'x'
// is not used in the bytecode (see below).
val insnArray = node.instructions.toArray()
// Very conservative variable usage check.
// Here we look at integer variables only (this includes integral primitive types: byte, char, short, boolean).
// Variable is considered "used" if:
// - it's loaded with ILOAD instruction
// - it's incremented with IINC instruction
// - there's a local variable table entry for this variable
val usedIntegerVar = BooleanArray(node.maxLocals)
for (insn in insnArray) {
if (insn.type == AbstractInsnNode.VAR_INSN && insn.opcode == Opcodes.ILOAD) {
usedIntegerVar[(insn as VarInsnNode).`var`] = true
} else if (insn.type == AbstractInsnNode.IINC_INSN) {
usedIntegerVar[(insn as IincInsnNode).`var`] = true
}
}
for (localVariable in node.localVariables) {
val d0 = localVariable.desc[0]
// byte || char || short || int || boolean
if (d0 == 'B' || d0 == 'C' || d0 == 'S' || d0 == 'I' || d0 == 'Z') {
usedIntegerVar[localVariable.index] = true
}
}
// Looking for sequences of instructions:
// p0: ICONST_0
// p1: ISTORE x
// p2: <label>
// If variable 'x' is not "used" (see above), remove p0 and p1 instructions.
var changes = false
for (p0 in insnArray) {
if (p0.opcode != Opcodes.ICONST_0) continue
val p1 = p0.next ?: break
if (p1.opcode != Opcodes.ISTORE) continue
val p2 = p1.next ?: break
if (p2.type != AbstractInsnNode.LABEL) continue
val varIndex = (p1 as VarInsnNode).`var`
if (!usedIntegerVar[varIndex]) {
changes = true
node.instructions.remove(p0)
node.instructions.remove(p1)
}
}
if (changes) {
// If we removed some instructions, some TCBs could (in theory) become empty.
// Remove empty TCBs if there are any.
node.removeEmptyCatchBlocks()
}
}
private fun isAnonymousClassThatMustBeRegenerated(type: Type?): Boolean {
if (type == null || type.sort != Type.OBJECT) return false
return inliningContext.isRegeneratedAnonymousObject(type.internalName)

View File

@@ -23,13 +23,11 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCallWithAssert
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.isInlineClass
import org.jetbrains.kotlin.resolve.jvm.annotations.isCallableMemberCompiledToJvmDefault
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.types.expressions.LabelResolver
import org.jetbrains.kotlin.utils.addIfNotNull

View File

@@ -17,11 +17,13 @@
package org.jetbrains.kotlin.codegen.optimization
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicVerifier
class MethodVerifier(private val checkPoint: String) : MethodTransformer() {
class MethodVerifier(private val checkPoint: String, private val generationState: GenerationState) : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) {
if (!generationState.shouldValidateBytecode) return
try {
analyze(internalClassName, methodNode, BasicVerifier())
} catch (e: Throwable) {

View File

@@ -41,7 +41,7 @@ class OptimizationMethodVisitor(
val normalizationMethodTransformer = CompositeMethodTransformer(
FixStackWithLabelNormalizationMethodTransformer(),
MethodVerifier("AFTER mandatory stack transformations")
MethodVerifier("AFTER mandatory stack transformations", generationState)
)
val optimizationTransformer = CompositeMethodTransformer(
@@ -55,7 +55,7 @@ class OptimizationMethodVisitor(
DeadCodeEliminationMethodTransformer(),
RedundantGotoMethodTransformer(),
RedundantNopsCleanupMethodTransformer(),
MethodVerifier("AFTER optimizations")
MethodVerifier("AFTER optimizations", generationState)
)
override fun performTransformations(methodNode: MethodNode) {

View File

@@ -299,6 +299,8 @@ class GenerationState private constructor(
!configuration.getBoolean(JVMConfigurationKeys.NO_UNIFIED_NULL_CHECKS)
val functionsWithInlineClassReturnTypesMangled: Boolean =
languageVersionSettings.supportsFeature(LanguageFeature.MangleClassMembersReturningInlineClasses)
val shouldValidateIr = configuration.getBoolean(JVMConfigurationKeys.VALIDATE_IR)
val shouldValidateBytecode = configuration.getBoolean(JVMConfigurationKeys.VALIDATE_BYTECODE)
val rootContext: CodegenContext<*> = RootContext(this)
@@ -405,8 +407,8 @@ class GenerationState private constructor(
this[KOTLIN_1_2] = oldMetadataVersion
this[KOTLIN_1_3] = oldMetadataVersion
this[KOTLIN_1_4] = JvmMetadataVersion(1, 4, 3)
this[KOTLIN_1_5] = JvmMetadataVersion.INSTANCE
this[KOTLIN_1_6] = JvmMetadataVersion(1, 6, 0)
this[KOTLIN_1_5] = JvmMetadataVersion(1, 5, 1)
this[KOTLIN_1_6] = JvmMetadataVersion.INSTANCE
this[KOTLIN_1_7] = JvmMetadataVersion(1, 7, 0)
check(size == LanguageVersion.values().size) {

View File

@@ -57,8 +57,8 @@ sourceSets {
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
kotlinOptions {
languageVersion = "1.3"
apiVersion = "1.3"
languageVersion = "1.4"
apiVersion = "1.4"
freeCompilerArgs = freeCompilerArgs - "-progressive" + listOf(
"-Xskip-prerelease-check", "-Xsuppress-version-warnings", "-Xuse-mixed-named-arguments", "-Xnew-inference"
)

View File

@@ -381,6 +381,12 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
var unrestrictedBuilderInference: Boolean by FreezableVar(false)
@Argument(
value = "-Xself-upper-bound-inference",
description = "Support inferring type arguments based on only self upper bounds of the corresponding type parameters"
)
var selfUpperBoundInference: Boolean by FreezableVar(false)
open fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap<AnalysisFlag<*>, Any> {
return HashMap<AnalysisFlag<*>, Any>().apply {
put(AnalysisFlags.skipMetadataVersionCheck, skipMetadataVersionCheck)
@@ -423,6 +429,10 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
put(LanguageFeature.UnrestrictedBuilderInference, LanguageFeature.State.ENABLED)
}
if (selfUpperBoundInference) {
put(LanguageFeature.TypeInferenceOnCallsWithSelfTypes, LanguageFeature.State.ENABLED)
}
if (newInference) {
put(LanguageFeature.NewInference, LanguageFeature.State.ENABLED)
put(LanguageFeature.SamConversionPerArgument, LanguageFeature.State.ENABLED)

View File

@@ -511,6 +511,18 @@ default: `indy-with-constants` for JVM target 9 or greater, `inline` otherwise""
)
var serializeIr: Boolean by FreezableVar(false)
@Argument(
value = "-Xvalidate-ir",
description = "Validate IR before and after lowering"
)
var validateIr: Boolean by FreezableVar(false)
@Argument(
value = "-Xvalidate-bytecode",
description = "Validate generated JVM bytecode before and after optimizations"
)
var validateBytecode: Boolean by FreezableVar(false)
override fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap<AnalysisFlag<*>, Any> {
val result = super.configureAnalysisFlags(collector, languageVersion)
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics

View File

@@ -278,7 +278,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
val runner = """
const wasmBinary = read(String.raw`${outputWasmFile.absoluteFile}`, 'binary');
const wasmModule = new WebAssembly.Module(wasmBinary);
const wasmInstance = new WebAssembly.Instance(wasmModule, { runtime, js_code });
wasmInstance = new WebAssembly.Instance(wasmModule, { runtime, js_code });
wasmInstance.exports.main();
""".trimIndent()

View File

@@ -233,8 +233,8 @@ object JvmRuntimeVersionsConsistencyChecker {
jars: List<KotlinLibraryFile>
): MavenComparableVersion? {
assert(jars.isNotEmpty()) { "'jars' must not be empty" }
val oldestVersion = jars.minBy { it.version }!!.version
val newestVersion = jars.maxBy { it.version }!!.version
val oldestVersion = jars.minOf { it.version }
val newestVersion = jars.maxOf { it.version }
// If the oldest version is the same as the newest version, then all jars have the same version
if (oldestVersion == newestVersion) return oldestVersion
@@ -250,9 +250,9 @@ object JvmRuntimeVersionsConsistencyChecker {
// we suggest to provide an explicit dependency on version X.
// TODO: report this depending on the content of the jars instead
val minReflectJar =
jars.filter { it.file.name.startsWith("kotlin-reflect") }.minBy { it.version }
jars.filter { it.file.name.startsWith("kotlin-reflect") }.minByOrNull { it.version }
val maxStdlibJar =
jars.filter { it.file.name.startsWith("kotlin-runtime") || it.file.name.startsWith("kotlin-stdlib") }.maxBy { it.version }
jars.filter { it.file.name.startsWith("kotlin-runtime") || it.file.name.startsWith("kotlin-stdlib") }.maxByOrNull { it.version }
if (minReflectJar != null && maxStdlibJar != null && minReflectJar.version < maxStdlibJar.version) {
messageCollector.issue(
null,

View File

@@ -267,11 +267,14 @@ class KotlinCoreEnvironment private constructor(
this.initialRoots.addAll(initialRoots)
if (!configuration.getBoolean(JVMConfigurationKeys.SKIP_RUNTIME_VERSION_CHECK) && messageCollector != null) {
/*
// Temporarily disable until compiler is bootstrapped to 1.6.
JvmRuntimeVersionsConsistencyChecker.checkCompilerClasspathConsistency(
messageCollector,
configuration,
initialRoots.mapNotNull { (file, type) -> if (type == JavaRoot.RootType.BINARY) file else null }
)
*/
}
val (roots, singleJavaFileRoots) =

View File

@@ -0,0 +1,40 @@
/*
* 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.cli.jvm.compiler.jarfs
class ByteArrayCharSequence(
private val bytes: ByteArray,
private val start: Int = 0,
private val end: Int = bytes.size
) : CharSequence {
override fun hashCode(): Int {
error("Do not try computing hashCode ByteArrayCharSequence")
}
override fun equals(other: Any?): Boolean {
error("Do not try comparing ByteArrayCharSequence")
}
override val length get() = end - start
override fun get(index: Int): Char = bytes[index + start].toChar()
override fun subSequence(startIndex: Int, endIndex: Int): CharSequence {
if (startIndex == 0 && endIndex == length) return this
return ByteArrayCharSequence(bytes, start + startIndex, start + endIndex)
}
override fun toString(): String {
val chars = CharArray(length)
for (i in 0 until length) {
chars[i] = bytes[i + start].toChar()
}
return String(chars)
}
}

View File

@@ -6,26 +6,26 @@ package org.jetbrains.kotlin.cli.jvm.compiler.jarfs
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.impl.ZipHandler
import com.intellij.util.containers.FactoryMap
import com.intellij.util.text.ByteArrayCharSequence
import java.io.File
import java.io.FileNotFoundException
import java.io.IOException
import java.io.RandomAccessFile
import java.nio.channels.FileChannel
class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) : ZipHandler(path) {
class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) {
private val myRoot: VirtualFile?
internal val file = File(path)
private val ourEntryMap: Map<String, ZipEntryDescription>
private val cachedManifest: ByteArray?
init {
val entries: List<ZipEntryDescription>
RandomAccessFile(file, "r").use { randomAccessFile ->
val mappedByteBuffer = randomAccessFile.channel.map(FileChannel.MapMode.READ_ONLY, 0, randomAccessFile.length())
try {
ourEntryMap = mappedByteBuffer.parseCentralDirectory().associateBy { it.relativePath }
cachedManifest = ourEntryMap[MANIFEST_PATH]?.let(mappedByteBuffer::contentsToByteArray)
entries = mappedByteBuffer.parseCentralDirectory()
cachedManifest =
entries.singleOrNull { StringUtil.equals(MANIFEST_PATH, it.relativePath) }
?.let(mappedByteBuffer::contentsToByteArray)
} finally {
with(fileSystem) {
mappedByteBuffer.unmapBuffer()
@@ -33,114 +33,69 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) : ZipHandl
}
}
val entries: MutableMap<EntryInfo, FastJarVirtualFile> = HashMap()
val entriesMap = entriesMap
val childrenMap = FactoryMap.create<FastJarVirtualFile, MutableList<VirtualFile>> { ArrayList() }
for (info in entriesMap.values) {
val file = getOrCreateFile(info, entries)
val parent = file.parent
if (parent != null) {
childrenMap[parent]?.add(file)
myRoot = FastJarVirtualFile(this, "", -1, parent = null, entryDescription = null)
// ByteArrayCharSequence should not be used instead of String
// because the former class does not support equals/hashCode properly
val filesByRelativePath = HashMap<String, FastJarVirtualFile>(entries.size)
filesByRelativePath[""] = myRoot
for (entryDescription in entries) {
if (!entryDescription.isDirectory) {
createFile(entryDescription, filesByRelativePath)
} else {
getOrCreateDirectory(entryDescription.relativePath, filesByRelativePath)
}
}
val rootInfo = getEntryInfo("")
myRoot = rootInfo?.let { getOrCreateFile(it, entries) }
for ((key, childList) in childrenMap) {
key.children = childList.toTypedArray()
for (node in filesByRelativePath.values) {
node.initChildrenArrayFromList()
}
}
private fun getOrCreateFile(info: EntryInfo, entries: MutableMap<EntryInfo, FastJarVirtualFile>): FastJarVirtualFile {
var file = entries[info]
if (file == null) {
val parent = info.parent
file = FastJarVirtualFile(this, info.shortName,
if (info.isDirectory) -1 else info.length,
info.timestamp,
parent?.let { getOrCreateFile(it, entries) })
entries[info] = file
private fun createFile(entry: ZipEntryDescription, directories: MutableMap<String, FastJarVirtualFile>): FastJarVirtualFile {
val (parentName, shortName) = entry.relativePath.splitPath()
val parentFile = getOrCreateDirectory(parentName, directories)
if ("." == shortName) {
return parentFile
}
return file
return FastJarVirtualFile(
this, shortName,
if (entry.isDirectory) -1 else entry.uncompressedSize,
parentFile,
entry,
)
}
private fun getOrCreateDirectory(entryName: CharSequence, directories: MutableMap<String, FastJarVirtualFile>): FastJarVirtualFile {
return directories.getOrPut(entryName.toString()) {
val (parentPath, shortName) = entryName.splitPath()
val parentFile = getOrCreateDirectory(parentPath, directories)
FastJarVirtualFile(this, shortName, -1, parentFile, entryDescription = null)
}
}
private fun CharSequence.splitPath(): Pair<CharSequence, CharSequence> {
var slashIndex = this.length - 1
while (slashIndex >= 0 && this[slashIndex] != '/') {
slashIndex--
}
if (slashIndex == -1) return Pair("", this)
return Pair(subSequence(0, slashIndex), subSequence(slashIndex + 1, this.length))
}
fun findFileByPath(pathInJar: String): VirtualFile? {
return myRoot?.findFileByRelativePath(pathInJar)
}
@Throws(IOException::class)
override fun createEntriesMap(): Map<String, EntryInfo> {
val mapToEntryInfo = mutableMapOf<String, EntryInfo>()
mapToEntryInfo[""] = EntryInfo("", true, DEFAULT_LENGTH, DEFAULT_TIMESTAMP, null)
for (zipEntry in ourEntryMap.values) {
getOrCreate(zipEntry, mapToEntryInfo)
}
return mapToEntryInfo
}
private fun getOrCreate(entry: ZipEntryDescription, map: MutableMap<String, EntryInfo>): EntryInfo {
var isDirectory = entry.isDirectory
var entryName = entry.relativePath
if (StringUtil.endsWithChar(entryName, '/')) {
entryName = entryName.substring(0, entryName.length - 1)
isDirectory = true
}
if (StringUtil.startsWithChar(entryName, '/') || StringUtil.startsWithChar(entryName, '\\')) {
entryName = entryName.substring(1)
}
var info = map[entryName]
if (info != null) return info
val path = splitPathAndFix(entryName)
val parentInfo = getOrCreateDirectory(path.first, map)
if ("." == path.second) {
return parentInfo
}
info = store(map, parentInfo, path.second, isDirectory, entry.uncompressedSize.toLong(), 0, path.third)
return info
}
private fun getOrCreateDirectory(entryName: String, map: MutableMap<String, EntryInfo>): EntryInfo {
var info = map[entryName]
if (info == null) {
val entry = ourEntryMap["$entryName/"]
if (entry != null) {
return getOrCreate(entry, map)
}
val path = splitPathAndFix(entryName)
require(entryName != path.first) {
"invalid entry name: '" + entryName + "' in " + this.file.absolutePath + "; after split: " + path
}
val parentInfo = getOrCreateDirectory(path.first, map)
info = store(map, parentInfo, path.second, true, DEFAULT_LENGTH, DEFAULT_TIMESTAMP, path.third)
}
return info
}
private fun store(
map: MutableMap<String, EntryInfo>,
parentInfo: EntryInfo?,
shortName: CharSequence,
isDirectory: Boolean,
size: Long,
time: Long,
entryName: String
): EntryInfo {
val sequence = ByteArrayCharSequence.convertToBytesIfPossible(shortName)
val info = EntryInfo(sequence, isDirectory, size, time, parentInfo)
map[entryName] = info
return info
}
override fun contentsToByteArray(relativePath: String): ByteArray {
if (relativePath == MANIFEST_PATH) return cachedManifest ?: throw FileNotFoundException("$file!/$relativePath")
val zipEntryDescription = ourEntryMap[relativePath] ?: throw FileNotFoundException("$file!/$relativePath")
fun contentsToByteArray(zipEntryDescription: ZipEntryDescription): ByteArray {
val relativePath = zipEntryDescription.relativePath
if (StringUtil.equals(relativePath, MANIFEST_PATH)) return cachedManifest ?: throw FileNotFoundException("$file!/$relativePath")
return fileSystem.cachedOpenFileHandles[file].use {
synchronized(it) {
it.get().second.contentsToByteArray(zipEntryDescription)
@@ -150,5 +105,3 @@ class FastJarHandler(val fileSystem: FastJarFileSystem, path: String) : ZipHandl
}
private const val MANIFEST_PATH = "META-INF/MANIFEST.MF"

View File

@@ -4,7 +4,6 @@
*/
package org.jetbrains.kotlin.cli.jvm.compiler.jarfs
import com.intellij.openapi.util.Couple
import com.intellij.openapi.util.io.BufferExposingByteArrayInputStream
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile
@@ -14,41 +13,48 @@ import java.io.InputStream
import java.io.OutputStream
internal class FastJarVirtualFile(
private val myHandler: FastJarHandler,
private val myName: CharSequence,
private val myLength: Long,
private val myTimestamp: Long,
parent: FastJarVirtualFile?
private val handler: FastJarHandler,
private val name: CharSequence,
private val length: Int,
private val parent: FastJarVirtualFile?,
private val entryDescription: ZipEntryDescription?,
) : VirtualFile() {
private val myParent: VirtualFile? = parent
private var myChildren = EMPTY_ARRAY
fun setChildren(children: Array<VirtualFile>) {
myChildren = children
private var myChildrenArray = EMPTY_ARRAY
private val myChildrenList: MutableList<VirtualFile> = mutableListOf()
init {
parent?.myChildrenList?.add(this)
}
fun initChildrenArrayFromList() {
myChildrenArray = myChildrenList.toTypedArray()
myChildrenList.clear()
}
override fun getName(): String {
return myName.toString()
return name.toString()
}
override fun getNameSequence(): CharSequence {
return myName
return name
}
override fun getFileSystem(): VirtualFileSystem {
return myHandler.fileSystem
return handler.fileSystem
}
override fun getPath(): String {
if (myParent == null) {
return FileUtil.toSystemIndependentName(myHandler.file.path) + "!/"
if (parent == null) {
return FileUtil.toSystemIndependentName(handler.file.path) + "!/"
}
val parentPath = myParent.path
val answer = StringBuilder(parentPath.length + 1 + myName.length)
val parentPath = parent.path
val answer = StringBuilder(parentPath.length + 1 + name.length)
answer.append(parentPath)
if (answer[answer.length - 1] != '/') {
answer.append('/')
}
answer.append(myName)
answer.append(name)
return answer.toString()
}
@@ -57,7 +63,7 @@ internal class FastJarVirtualFile(
}
override fun isDirectory(): Boolean {
return myLength < 0
return length < 0
}
override fun isValid(): Boolean {
@@ -65,11 +71,11 @@ internal class FastJarVirtualFile(
}
override fun getParent(): VirtualFile? {
return myParent
return parent
}
override fun getChildren(): Array<VirtualFile> {
return myChildren
return myChildrenArray
}
@Throws(IOException::class)
@@ -79,21 +85,16 @@ internal class FastJarVirtualFile(
@Throws(IOException::class)
override fun contentsToByteArray(): ByteArray {
val pair: Couple<String> = FastJarFileSystem.splitPath(
path
)
return myHandler.contentsToByteArray(pair.second)
if (entryDescription == null) return EMPTY_BYTE_ARRAY
return handler.contentsToByteArray(entryDescription)
}
override fun getTimeStamp(): Long {
return myTimestamp
}
override fun getTimeStamp(): Long = 0
override fun getLength(): Long {
return myLength
}
override fun getLength(): Long = length.toLong()
override fun refresh(asynchronous: Boolean, recursive: Boolean, postRunnable: Runnable?) {}
@Throws(IOException::class)
override fun getInputStream(): InputStream {
return BufferExposingByteArrayInputStream(contentsToByteArray())
@@ -103,3 +104,5 @@ internal class FastJarVirtualFile(
return 0
}
}
private val EMPTY_BYTE_ARRAY = ByteArray(0)

View File

@@ -12,12 +12,12 @@ import java.util.zip.Inflater
class ZipEntryDescription(
val relativePath: String,
val relativePath: CharSequence,
val compressedSize: Int,
val uncompressedSize: Int,
val offsetInFile: Int,
val compressionKind: CompressionKind,
val fileNameSize: Int
val fileNameSize: Int,
) {
enum class CompressionKind {
@@ -62,9 +62,11 @@ fun MappedByteBuffer.contentsToByteArray(
fun MappedByteBuffer.parseCentralDirectory(): List<ZipEntryDescription> {
order(ByteOrder.LITTLE_ENDIAN)
val endOfCentralDirectoryOffset = (capacity() - END_OF_CENTRAL_DIR_SIZE downTo 0).first { offset ->
var endOfCentralDirectoryOffset = capacity() - END_OF_CENTRAL_DIR_SIZE
while (endOfCentralDirectoryOffset >= 0) {
// header of "End of central directory"
getInt(offset) == 0x06054b50
if (getInt(endOfCentralDirectoryOffset) == 0x06054b50) break
endOfCentralDirectoryOffset--
}
val entriesNumber = getUnsignedShort(endOfCentralDirectoryOffset + 10)
@@ -97,7 +99,11 @@ fun MappedByteBuffer.parseCentralDirectory(): List<ZipEntryDescription> {
position(currentOffset + 46)
get(bytesForName)
val name = String(bytesForName)
val name =
if (bytesForName.all { it >= 0 })
ByteArrayCharSequence(bytesForName)
else
String(bytesForName, Charsets.UTF_8)
currentOffset += 46 + fileNameLength + extraLength + fileCommentLength

View File

@@ -254,6 +254,9 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr
put(JVMConfigurationKeys.SERIALIZE_IR, arguments.serializeIr)
put(JVMConfigurationKeys.VALIDATE_IR, arguments.validateIr)
put(JVMConfigurationKeys.VALIDATE_BYTECODE, arguments.validateBytecode)
if (!JVMConstructorCallNormalizationMode.isSupportedValue(arguments.constructorCallNormalizationMode)) {
messageCollector.report(
ERROR,

View File

@@ -157,5 +157,11 @@ public class JVMConfigurationKeys {
CompilerConfigurationKey.create("Don't automatically include kotlin-reflect.jar into the output if the output is a jar");
public static final CompilerConfigurationKey<Boolean> SERIALIZE_IR =
CompilerConfigurationKey.create("serialize IR to class metadata");
CompilerConfigurationKey.create("Serialize IR to class metadata");
public static final CompilerConfigurationKey<Boolean> VALIDATE_IR =
CompilerConfigurationKey.create("Validate IR");
public static final CompilerConfigurationKey<Boolean> VALIDATE_BYTECODE =
CompilerConfigurationKey.create("Validate generated JVM bytecode");
}

View File

@@ -33,6 +33,7 @@ enum class JvmTarget(
JVM_14("14", Opcodes.V12 + 2),
JVM_15("15", Opcodes.V12 + 3),
JVM_16("16", Opcodes.V12 + 4),
JVM_17("17", Opcodes.V12 + 5),
;
companion object {

View File

@@ -49,7 +49,7 @@ dependencies {
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
kotlinOptions {
apiVersion = "1.3"
apiVersion = "1.4"
freeCompilerArgs += "-Xsuppress-version-warnings"
}
}

View File

@@ -40,8 +40,8 @@ dependencies {
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinCompile<*>> {
kotlinOptions {
// This module is being run from within Gradle, older versions of which only have kotlin-stdlib 1.3 in the runtime classpath.
apiVersion = "1.3"
// This module is being run from within Gradle, older versions of which only have older kotlin-stdlib in the runtime classpath.
apiVersion = "1.4"
freeCompilerArgs += "-Xsuppress-version-warnings"
}
}

View File

@@ -29,6 +29,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("annotationOnDeclarationWithDifferentArguments.kt")
public void testAnnotationOnDeclarationWithDifferentArguments() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/annotationOnDeclarationWithDifferentArguments.kt");
}
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/annotationUsedAsAnnotationArgument.kt");
@@ -616,6 +621,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/namedArrayInAnnotation.kt");
}
@TestMetadata("nestedClassInAnnotationArgument.kt")
public void testNestedClassInAnnotationArgument() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/nestedClassInAnnotationArgument.kt");
}
@TestMetadata("noParameterForName.kt")
public void testNoParameterForName() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/noParameterForName.kt");
@@ -2580,6 +2590,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/localClasses"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@TestMetadata("anonymousInAnonymous.kt")
public void testAnonymousInAnonymous() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/anonymousInAnonymous.kt");
}
@TestMetadata("implicitInAnonymous.kt")
public void testImplicitInAnonymous() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/implicitInAnonymous.kt");

View File

@@ -0,0 +1,54 @@
FILE: annotationOnDeclarationWithDifferentArguments.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 annotation class MyAnnotation : R|kotlin/Annotation| {
public constructor(intValue: R|kotlin/Int|, stringValue: R|kotlin/String|, enumValue: R|SomeEnum|, kClasses: R|kotlin/Array<out kotlin/reflect/KClass<*>>|, annotation: R|MyOtherAnnotation|): R|MyAnnotation| {
super<R|kotlin/Any|>()
}
public final val intValue: R|kotlin/Int| = R|<local>/intValue|
public get(): R|kotlin/Int|
public final val stringValue: R|kotlin/String| = R|<local>/stringValue|
public get(): R|kotlin/String|
public final val enumValue: R|SomeEnum| = R|<local>/enumValue|
public get(): R|SomeEnum|
public final val kClasses: R|kotlin/Array<out kotlin/reflect/KClass<*>>| = R|<local>/kClasses|
public get(): R|kotlin/Array<out kotlin/reflect/KClass<*>>|
public final val annotation: R|MyOtherAnnotation| = R|<local>/annotation|
public get(): R|MyOtherAnnotation|
}
public final annotation class MyOtherAnnotation : R|kotlin/Annotation| {
public constructor(intValue: R|kotlin/Int|, stringValue: R|kotlin/String|): R|MyOtherAnnotation| {
super<R|kotlin/Any|>()
}
public final val intValue: R|kotlin/Int| = R|<local>/intValue|
public get(): R|kotlin/Int|
public final val stringValue: R|kotlin/String| = R|<local>/stringValue|
public get(): R|kotlin/String|
}
public final const val constInt: R|kotlin/Int| = Int(10)
public get(): R|kotlin/Int|
public final const val constString: R|kotlin/String| = String()
public get(): R|kotlin/String|
@R|MyAnnotation|(intValue = Int(10), stringValue = R|/constString|, enumValue = Q|SomeEnum|.R|/SomeEnum.A|, kClasses = <implicitArrayOf>(<getClass>(Q|kotlin/String|), <getClass>(R|/constString|)), annotation = R|/MyOtherAnnotation.MyOtherAnnotation|(intValue = R|/constInt|, stringValue = String(hello))) public final fun foo(): R|kotlin/Unit| {
}

View File

@@ -0,0 +1,30 @@
import kotlin.reflect.KClass
enum class SomeEnum {
A, B
}
annotation class MyAnnotation(
val intValue: Int,
val stringValue: String,
val enumValue: SomeEnum,
val kClasses: Array<out KClass<*>>,
val annotation: MyOtherAnnotation
)
annotation class MyOtherAnnotation(val intValue: Int, val stringValue: String)
const val constInt = 10
const val constString = ""
@MyAnnotation(
intValue = 10,
stringValue = constString,
enumValue = SomeEnum.A,
kClasses = [String::class, <!ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL!>constString::class<!>],
annotation = MyOtherAnnotation(
intValue = constInt,
stringValue = "hello"
)
)
fun foo() {}

View File

@@ -0,0 +1,26 @@
FILE: nestedClassInAnnotationArgument.kt
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(kClass: R|kotlin/reflect/KClass<*>|): R|Ann| {
super<R|kotlin/Any|>()
}
public final val kClass: R|kotlin/reflect/KClass<*>| = R|<local>/kClass|
public get(): R|kotlin/reflect/KClass<*>|
}
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
@R|Ann|(<getClass>(Q|A.EmptyList|)) public final fun foo(): R|kotlin/Unit| {
}
public final object EmptyList : R|kotlin/Any| {
private constructor(): R|A.EmptyList| {
super<R|kotlin/Any|>()
}
}
}

View File

@@ -0,0 +1,11 @@
// WITH_STDLIB
import kotlin.reflect.KClass
annotation class Ann(val kClass: KClass<*>)
class A {
@Ann(EmptyList::class)
fun foo() {}
object EmptyList
}

View File

@@ -13,12 +13,12 @@ FILE: cast.kt
}
public get(): R|() -> kotlin/Unit|
public final val h: R|(kotlin/String) -> kotlin/Boolean| = fun <anonymous>(_: R|kotlin/String|): R|kotlin/Boolean| <inline=Unknown> {
public final val h: R|(kotlin/String) -> kotlin/Boolean| = fun <anonymous>(<unused var>: R|kotlin/String|): R|kotlin/Boolean| <inline=Unknown> {
^ Boolean(false)
}
public get(): R|(kotlin/String) -> kotlin/Boolean|
public final val hError: R|(ERROR CLASS: No type for parameter) -> kotlin/Boolean| = fun <anonymous>(_: <ERROR TYPE REF: No type for parameter>): R|kotlin/Boolean| <inline=Unknown> {
public final val hError: R|(ERROR CLASS: No type for parameter) -> kotlin/Boolean| = fun <anonymous>(<unused var>: <ERROR TYPE REF: No type for parameter>): R|kotlin/Boolean| <inline=Unknown> {
^ Boolean(true)
}

View File

@@ -1,5 +1,5 @@
// !DUMP_CFG
inline fun foo(vararg x: Any) {}
<!NOTHING_TO_INLINE!>inline<!> fun foo(vararg x: Any) {}
fun test(a: Any, b: Any, c: Any) {
foo(a, { "" }, b)

View File

@@ -20,7 +20,7 @@ abstract class K {
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> val i2: Int
}
private open <!INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER!>class L<!> : K()
private open <!INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_ERROR!>class L<!> : K()
private abstract class M : K()
class X {

View File

@@ -66,3 +66,9 @@ class Test8<S8 : Test7<S8, <!UPPER_BOUND_VIOLATED!>in Any<!>>>
class Class<V : Any>
typealias Alias <V1> = (Class<V1>) -> Boolean
/* TODO: Should not be errors. Uncomment after fixing of https://youtrack.jetbrains.com/issue/KT-48044
abstract class Base<T : Base<T>> {}
class DerivedOut<out O : Base<out O>> {}
class DerivedIn<in I : Base<in I>> {}*/

View File

@@ -6,7 +6,7 @@ fun f() {
LocalClass().foo = 1
}
internal inline fun internal() {
internal <!NOTHING_TO_INLINE!>inline<!> fun internal() {
f()
}

View File

@@ -0,0 +1,27 @@
FILE: anonymousInAnonymous.kt
public final fun foo(): R|kotlin/Unit| {
lval base: R|<anonymous>| = object : R|kotlin/Any| {
private constructor(): R|<anonymous>| {
super<R|kotlin/Any|>()
}
public final fun bar(): R|<anonymous>| {
^bar object : R|kotlin/Any| {
private constructor(): R|<anonymous>| {
super<R|kotlin/Any|>()
}
public final fun buz(): R|kotlin/String| {
^buz this@R|/<anonymous>|.R|/<anonymous>.foobar|
}
}
}
public final val foobar: R|kotlin/String| = String()
public get(): R|kotlin/String|
}
}

View File

@@ -0,0 +1,8 @@
fun foo() {
val base = object {
fun bar() = object {
fun buz() = foobar
}
val foobar = ""
}
}

View File

@@ -1413,4 +1413,59 @@ digraph nullability_kt {
534 -> {535};
535 -> {536};
subgraph cluster_107 {
color=red
537 [label="Enter function test_14" style="filled" fillcolor=red];
subgraph cluster_108 {
color=blue
538 [label="Enter block"];
subgraph cluster_109 {
color=blue
539 [label="Enter when"];
subgraph cluster_110 {
color=blue
540 [label="Enter when branch condition "];
541 [label="Access variable R|<local>/q|"];
542 [label="Access variable R|/Q.data|"];
543 [label="Const: Null(null)"];
544 [label="Equality operator =="];
545 [label="Exit when branch condition"];
}
546 [label="Synthetic else branch"];
547 [label="Enter when branch result"];
subgraph cluster_111 {
color=blue
548 [label="Enter block"];
549 [label="Access variable R|<local>/q|"];
550 [label="Access variable R|/Q.data|"];
551 [label="Access variable <Inapplicable(UNSAFE_CALL): /MyData.s>#"];
552 [label="Exit block"];
}
553 [label="Exit when branch result"];
554 [label="Exit when"];
}
555 [label="Exit block"];
}
556 [label="Exit function test_14" style="filled" fillcolor=red];
}
537 -> {538};
538 -> {539};
539 -> {540};
540 -> {541};
541 -> {542};
542 -> {543};
543 -> {544};
544 -> {545};
545 -> {547 546};
546 -> {554};
547 -> {548};
548 -> {549};
549 -> {550};
550 -> {551};
551 -> {552};
552 -> {553};
553 -> {554};
554 -> {555};
555 -> {556};
}

View File

@@ -232,3 +232,11 @@ FILE: nullability.kt
}
}
public final fun test_14(q: R|Q|): R|kotlin/Unit| {
when () {
==(R|<local>/q|.R|/Q.data|, Null(null)) -> {
R|<local>/q|.R|/Q.data|.<Inapplicable(UNSAFE_CALL): /MyData.s>#
}
}
}

View File

@@ -175,3 +175,10 @@ fun test_13(q: QImplMutable?) {
<!SMARTCAST_IMPOSSIBLE!>q.data<!>.s.inc() // should be bad
}
}
fun test_14(q: Q) {
// `q.data` is a property that has an open getter
if (q.data == null) {
q.data<!UNSAFE_CALL!>.<!>s // should be UNSAFE_CALL and NOT SMARTCAST_IMPOSSIBLE
}
}

View File

@@ -19,7 +19,7 @@ FILE: delegateTypeMismatch.kt
public get(): R|kotlin/Boolean|
private final fun <T> property(initialValue: R|T|): R|kotlin/properties/ReadWriteProperty<A, T>| {
^property Q|kotlin/properties/Delegates|.R|kotlin/properties/Delegates.vetoable|<R|T|>(R|<local>/initialValue|, <L> = vetoable@fun <anonymous>(_: R|@R|kotlin/ParameterName|(name = String(property)) kotlin/reflect/KProperty<*>|, _: R|T|, _: R|T|): R|kotlin/Boolean| <inline=CrossInline, kind=UNKNOWN> {
^property Q|kotlin/properties/Delegates|.R|kotlin/properties/Delegates.vetoable|<R|T|>(R|<local>/initialValue|, <L> = vetoable@fun <anonymous>(<unused var>: R|@R|kotlin/ParameterName|(name = String(property)) kotlin/reflect/KProperty<*>|, <unused var>: R|T|, <unused var>: R|T|): R|kotlin/Boolean| <inline=CrossInline, kind=UNKNOWN> {
^ when () {
this@R|/A|.R|/A.isLocked| -> {
throw R|java/lang/IllegalStateException.IllegalStateException|(String(Cannot modify readonly DescriptorRendererOptions))

View File

@@ -0,0 +1,9 @@
FILE: DailyAggregatedDoubleFactor.kt
public abstract interface DailyAggregatedDoubleFactor : R|kotlin/Any| {
}
private final fun R|DailyAggregatedDoubleFactor|.aggregateBy(reduce: R|(kotlin/Double, kotlin/Double) -> kotlin/Double|): R|kotlin/collections/Map<kotlin/String, kotlin/Double>| {
^aggregateBy R|kotlin/collections/mutableMapOf|<R|kotlin/String|, R|kotlin/Double|>()
}
public final fun R|DailyAggregatedDoubleFactor|.aggregateMin(): R|kotlin/collections/Map<kotlin/String, kotlin/Double>| {
^aggregateMin this@R|/aggregateMin|.R|/aggregateBy|(::R|kotlin/comparisons/minOf|)
}

View File

@@ -0,0 +1,7 @@
interface DailyAggregatedDoubleFactor
private fun DailyAggregatedDoubleFactor.aggregateBy(reduce: (Double, Double) -> Double): Map<String, Double> {
return mutableMapOf<String, Double>()
}
fun DailyAggregatedDoubleFactor.aggregateMin(): Map<String, Double> = aggregateBy(::minOf)

View File

@@ -0,0 +1,3 @@
FILE: jvm.kt
@R|some/Nls|(R|some/Nls.Capitalization.Title|) public final fun f(): R|kotlin/Unit| {
}

View File

@@ -0,0 +1,17 @@
// FILE: some/Nls.java
package some
public @interface Nls {
Capitalization capitalization() default Capitalization.NotSpecified;
enum Capitalization { NotSpecified, Title, Sentence }
}
// FILE: jvm.kt
import some.Nls.Capitalization.*
import some.Nls
@Nls(Title)
fun f() {
}

View File

@@ -1,6 +1,6 @@
FILE: MapCompute.kt
public final fun <D> R|kotlin/collections/MutableMap<kotlin/String, kotlin/collections/MutableSet<D>>|.initAndAdd(key: R|kotlin/String|, value: R|D|): R|kotlin/Unit| {
this@R|/initAndAdd|.R|SubstitutionOverride<kotlin/collections/MutableMap.compute: R|kotlin/collections/MutableSet<D>?|>|(R|<local>/key|, <L> = compute@fun <anonymous>(_: R|ft<kotlin/String, kotlin/String?>|, maybeValues: R|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>|): R|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>| <inline=NoInline> {
this@R|/initAndAdd|.R|SubstitutionOverride<kotlin/collections/MutableMap.compute: R|kotlin/collections/MutableSet<D>?|>|(R|<local>/key|, <L> = compute@fun <anonymous>(<unused var>: R|ft<kotlin/String, kotlin/String?>|, maybeValues: R|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>|): R|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>| <inline=NoInline> {
lval setOfValues: R|kotlin/collections/MutableSet<D>| = R|<local>/maybeValues| ?: R|kotlin/collections/mutableSetOf|<R|D|>()
R|<local>/setOfValues|.R|SubstitutionOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(R|<local>/value|)
^ R|<local>/setOfValues|

View File

@@ -26,6 +26,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("annotationOnDeclarationWithDifferentArguments.kt")
public void testAnnotationOnDeclarationWithDifferentArguments() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/annotationOnDeclarationWithDifferentArguments.kt");
}
@Test
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
@@ -725,6 +731,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/namedArrayInAnnotation.kt");
}
@Test
@TestMetadata("nestedClassInAnnotationArgument.kt")
public void testNestedClassInAnnotationArgument() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/nestedClassInAnnotationArgument.kt");
}
@Test
@TestMetadata("noParameterForName.kt")
public void testNoParameterForName() throws Exception {
@@ -2925,6 +2937,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/localClasses"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("anonymousInAnonymous.kt")
public void testAnonymousInAnonymous() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/anonymousInAnonymous.kt");
}
@Test
@TestMetadata("implicitInAnonymous.kt")
public void testImplicitInAnonymous() throws Exception {
@@ -4994,6 +5012,22 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
}
}
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij")
@TestDataPath("$PROJECT_ROOT")
public class Intellij {
@Test
public void testAllFilesPresentInIntellij() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("DailyAggregatedDoubleFactor.kt")
public void testDailyAggregatedDoubleFactor() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/DailyAggregatedDoubleFactor.kt");
}
}
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k")
@TestDataPath("$PROJECT_ROOT")
@@ -5003,6 +5037,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("AnnotationWithEnum.kt")
public void testAnnotationWithEnum() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/AnnotationWithEnum.kt");
}
@Test
@TestMetadata("BasicWithAnnotatedJava.kt")
public void testBasicWithAnnotatedJava() throws Exception {

View File

@@ -26,6 +26,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("annotationOnDeclarationWithDifferentArguments.kt")
public void testAnnotationOnDeclarationWithDifferentArguments() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/annotationOnDeclarationWithDifferentArguments.kt");
}
@Test
@TestMetadata("annotationUsedAsAnnotationArgument.kt")
public void testAnnotationUsedAsAnnotationArgument() throws Exception {
@@ -725,6 +731,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/namedArrayInAnnotation.kt");
}
@Test
@TestMetadata("nestedClassInAnnotationArgument.kt")
public void testNestedClassInAnnotationArgument() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/arguments/nestedClassInAnnotationArgument.kt");
}
@Test
@TestMetadata("noParameterForName.kt")
public void testNoParameterForName() throws Exception {
@@ -2925,6 +2937,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolve/localClasses"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("anonymousInAnonymous.kt")
public void testAnonymousInAnonymous() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/localClasses/anonymousInAnonymous.kt");
}
@Test
@TestMetadata("implicitInAnonymous.kt")
public void testImplicitInAnonymous() throws Exception {
@@ -4994,6 +5012,22 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
}
}
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij")
@TestDataPath("$PROJECT_ROOT")
public class Intellij {
@Test
public void testAllFilesPresentInIntellij() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("DailyAggregatedDoubleFactor.kt")
public void testDailyAggregatedDoubleFactor() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/intellij/DailyAggregatedDoubleFactor.kt");
}
}
@Nested
@TestMetadata("compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k")
@TestDataPath("$PROJECT_ROOT")
@@ -5003,6 +5037,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k"), Pattern.compile("^([^.]+)\\.kt$"), null, true);
}
@Test
@TestMetadata("AnnotationWithEnum.kt")
public void testAnnotationWithEnum() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/j+k/AnnotationWithEnum.kt");
}
@Test
@TestMetadata("BasicWithAnnotatedJava.kt")
public void testBasicWithAnnotatedJava() throws Exception {

View File

@@ -680,6 +680,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/SafeCallNonNullReceiver.kt");
}
@Test
@TestMetadata("SafeCallNonNullReceiver2.kt")
public void testSafeCallNonNullReceiver2() throws Exception {
runTest("compiler/testData/diagnostics/tests/SafeCallNonNullReceiver2.kt");
}
@Test
@TestMetadata("SafeCallNonNullReceiverReturnNull.kt")
public void testSafeCallNonNullReceiverReturnNull() throws Exception {
@@ -1133,12 +1139,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/annotations/Deprecated.kt");
}
@Test
@TestMetadata("deprecatedRepeatable.kt")
public void testDeprecatedRepeatable() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/deprecatedRepeatable.kt");
}
@Test
@TestMetadata("dontReportWarningAboutChangingExecutionOrderForVararg.kt")
public void testDontReportWarningAboutChangingExecutionOrderForVararg() throws Exception {
@@ -2095,21 +2095,99 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
}
@Test
@TestMetadata("javaRepeatable.kt")
public void testJavaRepeatable() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaRepeatable.kt");
@TestMetadata("containerAndAnnotationAreBothApplied_1_5.kt")
public void testContainerAndAnnotationAreBothApplied_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerAndAnnotationAreBothApplied_1_5.kt");
}
@Test
@TestMetadata("javaUnrepeatable.kt")
public void testJavaUnrepeatable() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaUnrepeatable.kt");
@TestMetadata("containerAndAnnotationAreBothApplied_1_6.kt")
public void testContainerAndAnnotationAreBothApplied_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerAndAnnotationAreBothApplied_1_6.kt");
}
@Test
@TestMetadata("kotlinRepeatable.kt")
public void testKotlinRepeatable() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/kotlinRepeatable.kt");
@TestMetadata("containerArguments_1_5.kt")
public void testContainerArguments_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_5.kt");
}
@Test
@TestMetadata("containerArguments_1_6.kt")
public void testContainerArguments_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_6.kt");
}
@Test
@TestMetadata("containerRetention_1_5.kt")
public void testContainerRetention_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerRetention_1_5.kt");
}
@Test
@TestMetadata("containerRetention_1_6.kt")
public void testContainerRetention_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerRetention_1_6.kt");
}
@Test
@TestMetadata("containerTarget_1_6.kt")
public void testContainerTarget_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerTarget_1_6.kt");
}
@Test
@TestMetadata("javaRepeatableJvmTarget6.kt")
public void testJavaRepeatableJvmTarget6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaRepeatableJvmTarget6.kt");
}
@Test
@TestMetadata("javaRepeatable_1_5.kt")
public void testJavaRepeatable_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaRepeatable_1_5.kt");
}
@Test
@TestMetadata("javaRepeatable_1_6.kt")
public void testJavaRepeatable_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaRepeatable_1_6.kt");
}
@Test
@TestMetadata("javaUnrepeatable_1_5.kt")
public void testJavaUnrepeatable_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaUnrepeatable_1_5.kt");
}
@Test
@TestMetadata("javaUnrepeatable_1_6.kt")
public void testJavaUnrepeatable_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaUnrepeatable_1_6.kt");
}
@Test
@TestMetadata("kotlinRepeatable_1_5.kt")
public void testKotlinRepeatable_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/kotlinRepeatable_1_5.kt");
}
@Test
@TestMetadata("kotlinRepeatable_1_6.kt")
public void testKotlinRepeatable_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/kotlinRepeatable_1_6.kt");
}
@Test
@TestMetadata("nestedClassContainer_1_5.kt")
public void testNestedClassContainer_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/nestedClassContainer_1_5.kt");
}
@Test
@TestMetadata("nestedClassContainer_1_6.kt")
public void testNestedClassContainer_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/nestedClassContainer_1_6.kt");
}
}
@@ -15156,6 +15234,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt44440.kt");
}
@Test
@TestMetadata("kt47941.kt")
public void testKt47941() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt47941.kt");
}
@Test
@TestMetadata("kt702.kt")
public void testKt702() throws Exception {
@@ -29808,38 +29892,48 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/testsWithJava15/jvmRecord/supertypesCheck.kt");
}
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/testsWithJava17")
@TestDataPath("$PROJECT_ROOT")
public class TestsWithJava17 {
@Test
public void testAllFilesPresentInTestsWithJava17() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/testsWithJava17"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses")
@TestMetadata("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses")
@TestDataPath("$PROJECT_ROOT")
public class SealedClasses {
@Test
public void testAllFilesPresentInSealedClasses() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("javaSealedClassExhaustiveness.kt")
public void testJavaSealedClassExhaustiveness() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses/javaSealedClassExhaustiveness.kt");
runTest("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedClassExhaustiveness.kt");
}
@Test
@TestMetadata("javaSealedInterfaceExhaustiveness.kt")
public void testJavaSealedInterfaceExhaustiveness() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses/javaSealedInterfaceExhaustiveness.kt");
runTest("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedInterfaceExhaustiveness.kt");
}
@Test
@TestMetadata("kotlinInheritsJavaClass.kt")
public void testKotlinInheritsJavaClass() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses/kotlinInheritsJavaClass.kt");
runTest("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/kotlinInheritsJavaClass.kt");
}
@Test
@TestMetadata("kotlinInheritsJavaInterface.kt")
public void testKotlinInheritsJavaInterface() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses/kotlinInheritsJavaInterface.kt");
runTest("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/kotlinInheritsJavaInterface.kt");
}
}
}
@@ -31827,6 +31921,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/when/kt4434.kt");
}
@Test
@TestMetadata("kt47922.kt")
public void testKt47922() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/kt47922.kt");
}
@Test
@TestMetadata("kt9929.kt")
public void testKt9929() throws Exception {

View File

@@ -680,6 +680,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/SafeCallNonNullReceiver.kt");
}
@Test
@TestMetadata("SafeCallNonNullReceiver2.kt")
public void testSafeCallNonNullReceiver2() throws Exception {
runTest("compiler/testData/diagnostics/tests/SafeCallNonNullReceiver2.kt");
}
@Test
@TestMetadata("SafeCallNonNullReceiverReturnNull.kt")
public void testSafeCallNonNullReceiverReturnNull() throws Exception {
@@ -1133,12 +1139,6 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/annotations/Deprecated.kt");
}
@Test
@TestMetadata("deprecatedRepeatable.kt")
public void testDeprecatedRepeatable() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/deprecatedRepeatable.kt");
}
@Test
@TestMetadata("dontReportWarningAboutChangingExecutionOrderForVararg.kt")
public void testDontReportWarningAboutChangingExecutionOrderForVararg() throws Exception {
@@ -2095,21 +2095,99 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
}
@Test
@TestMetadata("javaRepeatable.kt")
public void testJavaRepeatable() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaRepeatable.kt");
@TestMetadata("containerAndAnnotationAreBothApplied_1_5.kt")
public void testContainerAndAnnotationAreBothApplied_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerAndAnnotationAreBothApplied_1_5.kt");
}
@Test
@TestMetadata("javaUnrepeatable.kt")
public void testJavaUnrepeatable() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaUnrepeatable.kt");
@TestMetadata("containerAndAnnotationAreBothApplied_1_6.kt")
public void testContainerAndAnnotationAreBothApplied_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerAndAnnotationAreBothApplied_1_6.kt");
}
@Test
@TestMetadata("kotlinRepeatable.kt")
public void testKotlinRepeatable() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/kotlinRepeatable.kt");
@TestMetadata("containerArguments_1_5.kt")
public void testContainerArguments_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_5.kt");
}
@Test
@TestMetadata("containerArguments_1_6.kt")
public void testContainerArguments_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerArguments_1_6.kt");
}
@Test
@TestMetadata("containerRetention_1_5.kt")
public void testContainerRetention_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerRetention_1_5.kt");
}
@Test
@TestMetadata("containerRetention_1_6.kt")
public void testContainerRetention_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerRetention_1_6.kt");
}
@Test
@TestMetadata("containerTarget_1_6.kt")
public void testContainerTarget_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/containerTarget_1_6.kt");
}
@Test
@TestMetadata("javaRepeatableJvmTarget6.kt")
public void testJavaRepeatableJvmTarget6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaRepeatableJvmTarget6.kt");
}
@Test
@TestMetadata("javaRepeatable_1_5.kt")
public void testJavaRepeatable_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaRepeatable_1_5.kt");
}
@Test
@TestMetadata("javaRepeatable_1_6.kt")
public void testJavaRepeatable_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaRepeatable_1_6.kt");
}
@Test
@TestMetadata("javaUnrepeatable_1_5.kt")
public void testJavaUnrepeatable_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaUnrepeatable_1_5.kt");
}
@Test
@TestMetadata("javaUnrepeatable_1_6.kt")
public void testJavaUnrepeatable_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/javaUnrepeatable_1_6.kt");
}
@Test
@TestMetadata("kotlinRepeatable_1_5.kt")
public void testKotlinRepeatable_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/kotlinRepeatable_1_5.kt");
}
@Test
@TestMetadata("kotlinRepeatable_1_6.kt")
public void testKotlinRepeatable_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/kotlinRepeatable_1_6.kt");
}
@Test
@TestMetadata("nestedClassContainer_1_5.kt")
public void testNestedClassContainer_1_5() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/nestedClassContainer_1_5.kt");
}
@Test
@TestMetadata("nestedClassContainer_1_6.kt")
public void testNestedClassContainer_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/repeatable/nestedClassContainer_1_6.kt");
}
}
@@ -15156,6 +15234,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt44440.kt");
}
@Test
@TestMetadata("kt47941.kt")
public void testKt47941() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/regressions/kt47941.kt");
}
@Test
@TestMetadata("kt702.kt")
public void testKt702() throws Exception {
@@ -29808,38 +29892,48 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/testsWithJava15/jvmRecord/supertypesCheck.kt");
}
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/testsWithJava17")
@TestDataPath("$PROJECT_ROOT")
public class TestsWithJava17 {
@Test
public void testAllFilesPresentInTestsWithJava17() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/testsWithJava17"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses")
@TestMetadata("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses")
@TestDataPath("$PROJECT_ROOT")
public class SealedClasses {
@Test
public void testAllFilesPresentInSealedClasses() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("javaSealedClassExhaustiveness.kt")
public void testJavaSealedClassExhaustiveness() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses/javaSealedClassExhaustiveness.kt");
runTest("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedClassExhaustiveness.kt");
}
@Test
@TestMetadata("javaSealedInterfaceExhaustiveness.kt")
public void testJavaSealedInterfaceExhaustiveness() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses/javaSealedInterfaceExhaustiveness.kt");
runTest("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/javaSealedInterfaceExhaustiveness.kt");
}
@Test
@TestMetadata("kotlinInheritsJavaClass.kt")
public void testKotlinInheritsJavaClass() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses/kotlinInheritsJavaClass.kt");
runTest("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/kotlinInheritsJavaClass.kt");
}
@Test
@TestMetadata("kotlinInheritsJavaInterface.kt")
public void testKotlinInheritsJavaInterface() throws Exception {
runTest("compiler/testData/diagnostics/tests/testsWithJava15/sealedClasses/kotlinInheritsJavaInterface.kt");
runTest("compiler/testData/diagnostics/tests/testsWithJava17/sealedClasses/kotlinInheritsJavaInterface.kt");
}
}
}
@@ -31827,6 +31921,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/when/kt4434.kt");
}
@Test
@TestMetadata("kt47922.kt")
public void testKt47922() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/kt47922.kt");
}
@Test
@TestMetadata("kt9929.kt")
public void testKt9929() throws Exception {

View File

@@ -14,9 +14,10 @@ import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -229,8 +230,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
val DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
val ANNOTATION_ON_SUPERCLASS by error<KtAnnotationEntry>()
val RESTRICTED_RETENTION_FOR_EXPRESSION_ANNOTATION by error<PsiElement>()
val ANNOTATION_ON_SUPERCLASS by deprecationError<KtAnnotationEntry>(LanguageFeature.ProhibitUseSiteTargetAnnotationsOnSuperTypes)
val RESTRICTED_RETENTION_FOR_EXPRESSION_ANNOTATION by deprecationError<PsiElement>(LanguageFeature.RestrictRetentionForExpressionAnnotations)
val WRONG_ANNOTATION_TARGET by error<KtAnnotationEntry> {
parameter<String>("actualTarget")
}
@@ -443,7 +444,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val RECURSION_IN_IMPLICIT_TYPES by error<PsiElement>()
val INFERENCE_ERROR by error<PsiElement>()
val PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT by error<PsiElement>()
val UPPER_BOUND_VIOLATED by error<PsiElement> {
val UPPER_BOUND_VIOLATED by warning<PsiElement> {
parameter<ConeKotlinType>("expectedUpperBound")
parameter<ConeKotlinType>("actualUpperBound")
}
@@ -491,11 +492,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirTypeParameterSymbol>("typeParameter")
}
val TYPE_PARAMETER_AS_REIFIED_ARRAY by error<PsiElement> {
parameter<FirTypeParameterSymbol>("typeParameter")
}
val TYPE_PARAMETER_AS_REIFIED_ARRAY_WARNING by warning<PsiElement> {
val TYPE_PARAMETER_AS_REIFIED_ARRAY by deprecationError<PsiElement>(LanguageFeature.ProhibitNonReifiedArraysAsReifiedTypeArguments) {
parameter<FirTypeParameterSymbol>("typeParameter")
}
@@ -556,7 +553,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<ConeKotlinType>("typeB")
}
val TYPE_VARIANCE_CONFLICT by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
val TYPE_VARIANCE_CONFLICT by warning<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
parameter<FirTypeParameterSymbol>("typeParameter")
parameter<Variance>("typeParameterVariance")
parameter<Variance>("variance")
@@ -664,11 +661,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableSymbol<*>>("missingDeclaration")
}
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by error<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableSymbol<*>>("invisibleDeclaration")
}
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING by warning<KtClassOrObject>(PositioningStrategy.DECLARATION_NAME) {
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by deprecationError<KtClassOrObject>(
LanguageFeature.ProhibitInvisibleAbstractMethodsInSuperclasses,
PositioningStrategy.DECLARATION_NAME
) {
parameter<FirClassSymbol<*>>("classOrObject")
parameter<FirCallableSymbol<*>>("invisibleDeclaration")
}
@@ -922,10 +918,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val VAL_REASSIGNMENT by error<KtExpression> {
parameter<FirVariableSymbol<*>>("variable")
}
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by warning<KtExpression> {
parameter<FirBackingFieldSymbol>("property")
}
val VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR by error<KtExpression> {
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by deprecationError<KtExpression>(LanguageFeature.RestrictionOfValReassignmentViaBackingField) {
parameter<FirBackingFieldSymbol>("property")
}
val CAPTURED_VAL_INITIALIZATION by error<KtExpression> {
@@ -951,6 +944,11 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val INITIALIZATION_BEFORE_DECLARATION by error<KtExpression>() {
parameter<Symbol>("property")
}
val UNREACHABLE_CODE by warning<KtElement>(PositioningStrategy.UNREACHABLE_CODE) {
parameter<Set<FirSourceElement>>("reachable")
parameter<Set<FirSourceElement>>("unreachable")
}
}
val NULLABILITY by object : DiagnosticGroup("Nullability") {
@@ -1062,8 +1060,15 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<ConeKotlinType>("actualType")
}
val UNDERSCORE_IS_RESERVED by error<KtElement>(PositioningStrategy.RESERVED_UNDERSCORE)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error<KtElement>(PositioningStrategy.RESERVED_UNDERSCORE)
val UNDERSCORE_IS_RESERVED by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error<PsiElement>(PositioningStrategy.NAME_IDENTIFIER)
val RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER by warning<KtNameReferenceExpression>()
val INVALID_CHARACTERS by error<KtNamedDeclaration>(PositioningStrategy.NAME_IDENTIFIER) {
parameter<String>("message")
}
val DANGEROUS_CHARACTERS by warning<KtNamedDeclaration>(PositioningStrategy.NAME_IDENTIFIER) {
parameter<String>("characters")
}
val EQUALITY_NOT_APPLICABLE by error<KtBinaryExpression> {
parameter<String>("operator")
@@ -1125,6 +1130,17 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<Symbol>("parameter")
}
val NOT_YET_SUPPORTED_IN_INLINE by error<KtDeclaration>(PositioningStrategy.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT) {
parameter<String>("message")
}
val NOTHING_TO_INLINE by warning<KtDeclaration>(PositioningStrategy.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT)
val NULLABLE_INLINE_PARAMETER by error<KtDeclaration>() {
parameter<FirValueParameterSymbol>("parameter")
parameter<Symbol>("function")
}
val RECURSION_IN_INLINE by error<KtElement>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
parameter<Symbol>("symbol")
}
@@ -1157,6 +1173,27 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val SUPER_CALL_FROM_PUBLIC_INLINE by warning<KtElement>(PositioningStrategy.REFERENCE_BY_QUALIFIED) {
parameter<Symbol>("symbol")
}
val DECLARATION_CANT_BE_INLINED by error<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
val OVERRIDE_BY_INLINE by warning<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
val NON_INTERNAL_PUBLISHED_API by error<KtElement>()
val INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE by error<KtElement>() {
parameter<FirExpression>("defaultValue")
parameter<FirValueParameterSymbol>("parameter")
}
val REIFIED_TYPE_PARAMETER_IN_OVERRIDE by error<KtElement>(PositioningStrategy.REIFIED_MODIFIER)
val INLINE_PROPERTY_WITH_BACKING_FIELD by error<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
val ILLEGAL_INLINE_PARAMETER_MODIFIER by error<KtElement>(PositioningStrategy.INLINE_PARAMETER_MODIFIER)
val INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED by error<KtParameter>()
val REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE by warning<KtElement>(PositioningStrategy.SUSPEND_MODIFIER)
}
val IMPORTS by object : DiagnosticGroup("Imports") {
@@ -1176,6 +1213,20 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val OPERATOR_RENAMED_ON_IMPORT by error<KtImportDirective>(PositioningStrategy.IMPORT_LAST_NAME)
}
val SUSPEND by object : DiagnosticGroup("Suspend errors") {
val ILLEGAL_SUSPEND_FUNCTION_CALL by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
parameter<Symbol>("suspendCallable")
}
val ILLEGAL_SUSPEND_PROPERTY_ACCESS by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
parameter<Symbol>("suspendCallable")
}
val NON_LOCAL_SUSPENSION_POINT by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
val ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
val NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
val MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
val RETURN_FOR_BUILT_IN_SUSPEND by error<KtReturnExpression>()
}
}
private val exposedVisibilityDiagnosticInit: DiagnosticBuilder.() -> Unit = {
@@ -1186,13 +1237,13 @@ private val exposedVisibilityDiagnosticInit: DiagnosticBuilder.() -> Unit = {
private inline fun <reified P : PsiElement> AbstractDiagnosticGroup.exposedVisibilityError(
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT
): PropertyDelegateProvider<Any?, ReadOnlyProperty<AbstractDiagnosticGroup, DiagnosticData>> {
): PropertyDelegateProvider<Any?, ReadOnlyProperty<AbstractDiagnosticGroup, RegularDiagnosticData>> {
return error<P>(positioningStrategy, exposedVisibilityDiagnosticInit)
}
private inline fun <reified P : PsiElement> AbstractDiagnosticGroup.exposedVisibilityWarning(
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT
): PropertyDelegateProvider<Any?, ReadOnlyProperty<AbstractDiagnosticGroup, DiagnosticData>> {
): PropertyDelegateProvider<Any?, ReadOnlyProperty<AbstractDiagnosticGroup, RegularDiagnosticData>> {
return warning<P>(positioningStrategy, exposedVisibilityDiagnosticInit)
}

View File

@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.PrivateForInline
import kotlin.properties.PropertyDelegateProvider
@@ -24,24 +25,31 @@ abstract class AbstractDiagnosticGroup @PrivateForInline constructor(val name: S
@OptIn(PrivateForInline::class)
internal inline fun <reified P : PsiElement> error(
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT,
crossinline init: DiagnosticBuilder.() -> Unit = {}
crossinline init: DiagnosticBuilder.Regular.() -> Unit = {}
) = diagnosticDelegateProvider<P>(Severity.ERROR, positioningStrategy, init)
@OptIn(PrivateForInline::class)
internal inline fun <reified P : PsiElement> warning(
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT,
crossinline init: DiagnosticBuilder.() -> Unit = {}
crossinline init: DiagnosticBuilder.Regular.() -> Unit = {}
) = diagnosticDelegateProvider<P>(Severity.WARNING, positioningStrategy, init)
@OptIn(PrivateForInline::class)
internal inline fun <reified P : PsiElement> deprecationError(
featureForError: LanguageFeature,
positioningStrategy: PositioningStrategy = PositioningStrategy.DEFAULT,
crossinline init: DiagnosticBuilder.Deprecation.() -> Unit = {}
) = deprecationDiagnosticDelegateProvider<P>(featureForError, positioningStrategy, init)
@PrivateForInline
@OptIn(ExperimentalStdlibApi::class)
internal inline fun <reified P : PsiElement> diagnosticDelegateProvider(
severity: Severity,
positioningStrategy: PositioningStrategy,
crossinline init: DiagnosticBuilder.() -> Unit = {}
) = PropertyDelegateProvider<Any?, ReadOnlyProperty<AbstractDiagnosticGroup, DiagnosticData>> { _, property ->
val diagnostic = DiagnosticBuilder(
crossinline init: DiagnosticBuilder.Regular.() -> Unit = {}
) = PropertyDelegateProvider<Any?, ReadOnlyProperty<AbstractDiagnosticGroup, RegularDiagnosticData>> { _, property ->
val diagnostic = DiagnosticBuilder.Regular(
containingObjectName,
severity,
name = property.name,
@@ -52,6 +60,24 @@ abstract class AbstractDiagnosticGroup @PrivateForInline constructor(val name: S
ReadOnlyProperty { _, _ -> diagnostic }
}
@PrivateForInline
@OptIn(ExperimentalStdlibApi::class)
internal inline fun <reified P : PsiElement> deprecationDiagnosticDelegateProvider(
featureForError: LanguageFeature,
positioningStrategy: PositioningStrategy,
crossinline init: DiagnosticBuilder.Deprecation.() -> Unit = {}
) = PropertyDelegateProvider<Any?, ReadOnlyProperty<AbstractDiagnosticGroup, DeprecationDiagnosticData>> { _, property ->
val diagnostic = DiagnosticBuilder.Deprecation(
containingObjectName,
featureForError,
name = property.name,
psiType = typeOf<P>(),
positioningStrategy,
).apply(init).build()
_diagnostics += diagnostic
ReadOnlyProperty { _, _ -> diagnostic }
}
@OptIn(PrivateForInline::class)
operator fun plus(other: AbstractDiagnosticGroup): AbstractDiagnosticGroup {
require(name == other.name)

View File

@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.PrivateForInline
import kotlin.properties.ReadOnlyProperty
@@ -65,13 +66,52 @@ abstract class DiagnosticList(internal val objectName: String) {
abstract inner class DiagnosticGroup(name: String) : AbstractDiagnosticGroup(name, objectName)
}
class DiagnosticBuilder(
private val containingObjectName: String,
private val severity: Severity,
private val name: String,
private val psiType: KType,
private val positioningStrategy: PositioningStrategy,
sealed class DiagnosticBuilder(
protected val containingObjectName: String,
protected val name: String,
protected val psiType: KType,
protected val positioningStrategy: PositioningStrategy,
) {
class Regular(
containingObjectName: String,
private val severity: Severity,
name: String,
psiType: KType,
positioningStrategy: PositioningStrategy,
) : DiagnosticBuilder(containingObjectName, name, psiType, positioningStrategy) {
@OptIn(PrivateForInline::class)
override fun build(): RegularDiagnosticData {
return RegularDiagnosticData(
containingObjectName,
severity,
name,
psiType,
parameters,
positioningStrategy,
)
}
}
class Deprecation(
containingObjectName: String,
private val featureForError: LanguageFeature,
name: String,
psiType: KType,
positioningStrategy: PositioningStrategy,
) : DiagnosticBuilder(containingObjectName, name, psiType, positioningStrategy) {
@OptIn(PrivateForInline::class)
override fun build(): DeprecationDiagnosticData {
return DeprecationDiagnosticData(
containingObjectName,
featureForError,
name,
psiType,
parameters,
positioningStrategy,
)
}
}
@PrivateForInline
val parameters = mutableListOf<DiagnosticParameter>()
@@ -86,15 +126,7 @@ class DiagnosticBuilder(
)
}
@OptIn(PrivateForInline::class)
fun build() = DiagnosticData(
containingObjectName,
severity,
name,
psiType,
parameters,
positioningStrategy,
)
abstract fun build(): DiagnosticData
companion object {
const val MAX_DIAGNOSTIC_PARAMETER_COUNT = 4

View File

@@ -55,16 +55,21 @@ object ErrorListDiagnosticListRenderer : DiagnosticListRenderer() {
private fun SmartPrinter.printDiagnostic(diagnostic: DiagnosticData) {
print("val ${diagnostic.name} by ${diagnostic.getFactoryFunction()}")
printTypeArguments(diagnostic.getAllTypeArguments())
printPositioningStrategy(diagnostic)
printPositioningStrategyAndLanguageFeature(diagnostic)
println()
}
private fun SmartPrinter.printPositioningStrategy(diagnostic: DiagnosticData) {
print("(")
if (!diagnostic.hasDefaultPositioningStrategy()) {
print(diagnostic.positioningStrategy.expressionToCreate)
@OptIn(ExperimentalStdlibApi::class)
private fun SmartPrinter.printPositioningStrategyAndLanguageFeature(diagnostic: DiagnosticData) {
val argumentsList = buildList {
if (diagnostic is DeprecationDiagnosticData) {
add(diagnostic.featureForError.name)
}
if (!diagnostic.hasDefaultPositioningStrategy()) {
add(diagnostic.positioningStrategy.expressionToCreate)
}
}
print(")")
print(argumentsList.joinToString(", ", prefix = "(", postfix = ")"))
}
@@ -124,14 +129,19 @@ object ErrorListDiagnosticListRenderer : DiagnosticListRenderer() {
add(PositioningStrategy.importToAdd)
}
}
for (deprecationDiagnostic in diagnosticList.allDiagnostics.filterIsInstance<DeprecationDiagnosticData>()) {
add("org.jetbrains.kotlin.config.LanguageFeature.${deprecationDiagnostic.featureForError.name}")
}
}
private val KType.kClass: KClass<*>
get() = classifier as KClass<*>
private fun DiagnosticData.getFactoryFunction(): String =
severity.name.lowercase() + parameters.size
private fun DiagnosticData.getFactoryFunction(): String = when (this) {
is RegularDiagnosticData -> severity.name.lowercase()
is DeprecationDiagnosticData -> "deprecationError"
} + parameters.size
}
private inline fun <T> SmartPrinter.printSeparatedWithComma(list: List<T>, printItem: (T) -> Unit) {

View File

@@ -5,17 +5,35 @@
package org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.Severity
import kotlin.reflect.KType
data class DiagnosticData(
val containingObjectName: String,
sealed class DiagnosticData {
abstract val containingObjectName: String
abstract val name: String
abstract val psiType: KType
abstract val parameters: List<DiagnosticParameter>
abstract val positioningStrategy: PositioningStrategy
}
data class RegularDiagnosticData(
override val containingObjectName: String,
val severity: Severity,
val name: String,
val psiType: KType,
val parameters: List<DiagnosticParameter>,
val positioningStrategy: PositioningStrategy,
)
override val name: String,
override val psiType: KType,
override val parameters: List<DiagnosticParameter>,
override val positioningStrategy: PositioningStrategy,
) : DiagnosticData()
data class DeprecationDiagnosticData(
override val containingObjectName: String,
val featureForError: LanguageFeature,
override val name: String,
override val psiType: KType,
override val parameters: List<DiagnosticParameter>,
override val positioningStrategy: PositioningStrategy,
) : DiagnosticData()
data class DiagnosticParameter(
val name: String,
@@ -69,7 +87,7 @@ enum class PositioningStrategy(private val strategy: String? = null) {
FUN_MODIFIER,
SUSPEND_MODIFIER,
FUN_INTERFACE,
RESERVED_UNDERSCORE,
NAME_IDENTIFIER,
QUESTION_MARK_BY_TYPE,
ANNOTATION_USE_SITE,
ASSIGNMENT_LHS,
@@ -77,8 +95,11 @@ enum class PositioningStrategy(private val strategy: String? = null) {
DATA_MODIFIER,
SPREAD_OPERATOR,
DECLARATION_WITH_BODY,
NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT,
INCOMPATIBLE_DECLARATION,
ACTUAL_DECLARATION_NAME,
UNREACHABLE_CODE,
INLINE_PARAMETER_MODIFIER,
;

View File

@@ -8,12 +8,18 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitInvisibleAbstractMethodsInSuperclasses
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitNonReifiedArraysAsReifiedTypeArguments
import org.jetbrains.kotlin.config.LanguageFeature.ProhibitUseSiteTargetAnnotationsOnSuperTypes
import org.jetbrains.kotlin.config.LanguageFeature.RestrictRetentionForExpressionAnnotations
import org.jetbrains.kotlin.config.LanguageFeature.RestrictionOfValReassignmentViaBackingField
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -56,6 +62,7 @@ import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtIfExpression
import org.jetbrains.kotlin.psi.KtImportDirective
import org.jetbrains.kotlin.psi.KtModifierListOwner
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.KtParameter
@@ -206,8 +213,8 @@ object FirErrors {
val DEPRECATED_SINCE_KOTLIN_WITHOUT_DEPRECATED by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val ANNOTATION_ON_SUPERCLASS by error0<KtAnnotationEntry>()
val RESTRICTED_RETENTION_FOR_EXPRESSION_ANNOTATION by error0<PsiElement>()
val ANNOTATION_ON_SUPERCLASS by deprecationError0<KtAnnotationEntry>(ProhibitUseSiteTargetAnnotationsOnSuperTypes)
val RESTRICTED_RETENTION_FOR_EXPRESSION_ANNOTATION by deprecationError0<PsiElement>(RestrictRetentionForExpressionAnnotations)
val WRONG_ANNOTATION_TARGET by error1<KtAnnotationEntry, String>()
val WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET by error2<KtAnnotationEntry, String, String>()
val INAPPLICABLE_TARGET_ON_PROPERTY by error1<KtAnnotationEntry, String>()
@@ -303,7 +310,7 @@ object FirErrors {
val RECURSION_IN_IMPLICIT_TYPES by error0<PsiElement>()
val INFERENCE_ERROR by error0<PsiElement>()
val PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT by error0<PsiElement>()
val UPPER_BOUND_VIOLATED by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
val UPPER_BOUND_VIOLATED by warning2<PsiElement, ConeKotlinType, ConeKotlinType>()
val UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
val TYPE_ARGUMENTS_NOT_ALLOWED by error0<PsiElement>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2<PsiElement, Int, FirRegularClassSymbol>()
@@ -323,8 +330,7 @@ object FirErrors {
val INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS by error0<KtClassOrObject>(SourceElementPositioningStrategies.DECLARATION_NAME)
val KCLASS_WITH_NULLABLE_TYPE_PARAMETER_IN_SIGNATURE by error1<KtNamedDeclaration, FirTypeParameterSymbol>(SourceElementPositioningStrategies.DECLARATION_NAME)
val TYPE_PARAMETER_AS_REIFIED by error1<PsiElement, FirTypeParameterSymbol>()
val TYPE_PARAMETER_AS_REIFIED_ARRAY by error1<PsiElement, FirTypeParameterSymbol>()
val TYPE_PARAMETER_AS_REIFIED_ARRAY_WARNING by warning1<PsiElement, FirTypeParameterSymbol>()
val TYPE_PARAMETER_AS_REIFIED_ARRAY by deprecationError1<PsiElement, FirTypeParameterSymbol>(ProhibitNonReifiedArraysAsReifiedTypeArguments)
val REIFIED_TYPE_FORBIDDEN_SUBSTITUTION by error1<PsiElement, ConeKotlinType>()
val FINAL_UPPER_BOUND by warning1<KtTypeReference, ConeKotlinType>()
val UPPER_BOUND_IS_EXTENSION_FUNCTION_TYPE by error0<KtTypeReference>()
@@ -344,7 +350,7 @@ object FirErrors {
val DYNAMIC_UPPER_BOUND by error0<KtTypeReference>()
val INCOMPATIBLE_TYPES by error2<KtElement, ConeKotlinType, ConeKotlinType>()
val INCOMPATIBLE_TYPES_WARNING by warning2<KtElement, ConeKotlinType, ConeKotlinType>()
val TYPE_VARIANCE_CONFLICT by error4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val TYPE_VARIANCE_CONFLICT by warning4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE by error4<PsiElement, FirTypeParameterSymbol, Variance, Variance, ConeKotlinType>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val SMARTCAST_IMPOSSIBLE by error3<KtExpression, ConeKotlinType, FirExpression, String>()
@@ -372,8 +378,7 @@ object FirErrors {
val CONFLICTING_INHERITED_MEMBERS by error1<KtClassOrObject, List<FirCallableSymbol<*>>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val ABSTRACT_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING by warning2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER by deprecationError2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(ProhibitInvisibleAbstractMethodsInSuperclasses, SourceElementPositioningStrategies.DECLARATION_NAME)
val MANY_IMPL_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val MANY_INTERFACES_MEMBER_NOT_IMPLEMENTED by error2<KtClassOrObject, FirClassSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
val OVERRIDING_FINAL_MEMBER_BY_DELEGATION by error2<KtClassOrObject, FirCallableSymbol<*>, FirCallableSymbol<*>>(SourceElementPositioningStrategies.DECLARATION_NAME)
@@ -492,8 +497,7 @@ object FirErrors {
val UNINITIALIZED_ENUM_ENTRY by error1<KtSimpleNameExpression, FirEnumEntrySymbol>()
val UNINITIALIZED_ENUM_COMPANION by error1<KtSimpleNameExpression, FirRegularClassSymbol>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val VAL_REASSIGNMENT by error1<KtExpression, FirVariableSymbol<*>>()
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by warning1<KtExpression, FirBackingFieldSymbol>()
val VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR by error1<KtExpression, FirBackingFieldSymbol>()
val VAL_REASSIGNMENT_VIA_BACKING_FIELD by deprecationError1<KtExpression, FirBackingFieldSymbol>(RestrictionOfValReassignmentViaBackingField)
val CAPTURED_VAL_INITIALIZATION by error1<KtExpression, FirPropertySymbol>()
val CAPTURED_MEMBER_VAL_INITIALIZATION by error1<KtExpression, FirPropertySymbol>()
val SETTER_PROJECTED_OUT by error1<KtBinaryExpression, FirPropertySymbol>(SourceElementPositioningStrategies.ASSIGNMENT_LHS)
@@ -502,6 +506,7 @@ object FirErrors {
val WRONG_IMPLIES_CONDITION by warning0<PsiElement>()
val VARIABLE_WITH_NO_TYPE_NO_INITIALIZER by error0<KtVariableDeclaration>(SourceElementPositioningStrategies.DECLARATION_NAME)
val INITIALIZATION_BEFORE_DECLARATION by error1<KtExpression, FirBasedSymbol<*>>()
val UNREACHABLE_CODE by warning2<KtElement, Set<FirSourceElement>, Set<FirSourceElement>>(SourceElementPositioningStrategies.UNREACHABLE_CODE)
// Nullability
val UNSAFE_CALL by error2<PsiElement, ConeKotlinType, FirExpression?>(SourceElementPositioningStrategies.DOT_BY_QUALIFIED)
@@ -552,8 +557,11 @@ object FirErrors {
val DELEGATE_SPECIAL_FUNCTION_AMBIGUITY by error2<KtExpression, String, Collection<FirBasedSymbol<*>>>()
val DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE by error2<KtExpression, String, Collection<FirBasedSymbol<*>>>()
val DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH by error3<KtExpression, String, ConeKotlinType, ConeKotlinType>()
val UNDERSCORE_IS_RESERVED by error0<KtElement>(SourceElementPositioningStrategies.RESERVED_UNDERSCORE)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error0<KtElement>(SourceElementPositioningStrategies.RESERVED_UNDERSCORE)
val UNDERSCORE_IS_RESERVED by error0<PsiElement>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val UNDERSCORE_USAGE_WITHOUT_BACKTICKS by error0<PsiElement>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER by warning0<KtNameReferenceExpression>()
val INVALID_CHARACTERS by error1<KtNamedDeclaration, String>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val DANGEROUS_CHARACTERS by warning1<KtNamedDeclaration, String>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val EQUALITY_NOT_APPLICABLE by error3<KtBinaryExpression, String, ConeKotlinType, ConeKotlinType>()
val EQUALITY_NOT_APPLICABLE_WARNING by warning3<KtBinaryExpression, String, ConeKotlinType, ConeKotlinType>()
val INCOMPATIBLE_ENUM_COMPARISON_ERROR by error2<KtElement, ConeKotlinType, ConeKotlinType>()
@@ -590,6 +598,9 @@ object FirErrors {
// Inline
val USAGE_IS_NOT_INLINABLE by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val NON_LOCAL_RETURN_NOT_ALLOWED by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val NOT_YET_SUPPORTED_IN_INLINE by error1<KtDeclaration, String>(SourceElementPositioningStrategies.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT)
val NOTHING_TO_INLINE by warning0<KtDeclaration>(SourceElementPositioningStrategies.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT)
val NULLABLE_INLINE_PARAMETER by error2<KtDeclaration, FirValueParameterSymbol, FirBasedSymbol<*>>()
val RECURSION_IN_INLINE by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val NON_PUBLIC_CALL_FROM_PUBLIC_INLINE by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val PROTECTED_CONSTRUCTOR_CALL_FROM_PUBLIC_INLINE by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
@@ -597,6 +608,15 @@ object FirErrors {
val PROTECTED_CALL_FROM_PUBLIC_INLINE by warning2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val PRIVATE_CLASS_MEMBER_FROM_INLINE by error2<KtElement, FirBasedSymbol<*>, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val SUPER_CALL_FROM_PUBLIC_INLINE by warning1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val DECLARATION_CANT_BE_INLINED by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val OVERRIDE_BY_INLINE by warning0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val NON_INTERNAL_PUBLISHED_API by error0<KtElement>()
val INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE by error2<KtElement, FirExpression, FirValueParameterSymbol>()
val REIFIED_TYPE_PARAMETER_IN_OVERRIDE by error0<KtElement>(SourceElementPositioningStrategies.REIFIED_MODIFIER)
val INLINE_PROPERTY_WITH_BACKING_FIELD by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val ILLEGAL_INLINE_PARAMETER_MODIFIER by error0<KtElement>(SourceElementPositioningStrategies.INLINE_PARAMETER_MODIFIER)
val INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED by error0<KtParameter>()
val REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE by warning0<KtElement>(SourceElementPositioningStrategies.SUSPEND_MODIFIER)
// Imports
val CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON by error1<KtImportDirective, Name>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
@@ -605,4 +625,13 @@ object FirErrors {
val CONFLICTING_IMPORT by error1<KtImportDirective, Name>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
val OPERATOR_RENAMED_ON_IMPORT by error0<KtImportDirective>(SourceElementPositioningStrategies.IMPORT_LAST_NAME)
// Suspend errors
val ILLEGAL_SUSPEND_FUNCTION_CALL by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val ILLEGAL_SUSPEND_PROPERTY_ACCESS by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val NON_LOCAL_SUSPENSION_POINT by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val RETURN_FOR_BUILT_IN_SUSPEND by error0<KtReturnExpression>()
}

View File

@@ -12,7 +12,6 @@ import org.jetbrains.kotlin.fir.analysis.cfa.FirReturnsImpliesAnalyzer
import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.*
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirAnonymousFunctionParametersChecker
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirReservedUnderscoreDeclarationChecker
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirAnonymousFunctionSyntaxChecker
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirDelegationInInterfaceSyntaxChecker
import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirFunctionTypeParametersSyntaxChecker
@@ -30,7 +29,8 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirInfixFunctionDeclarationChecker,
FirExposedVisibilityDeclarationChecker,
FirCyclicTypeBoundsChecker,
FirExpectActualDeclarationChecker
FirExpectActualDeclarationChecker,
FirInvalidAndDangerousCharactersChecker
)
override val functionCheckers: Set<FirFunctionChecker>
@@ -56,6 +56,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirPropertyTypeParametersChecker,
FirInitializerTypeMismatchChecker,
FirDelegatedPropertyChecker,
FirInlinePropertyChecker,
)
override val classCheckers: Set<FirClassChecker>
@@ -129,6 +130,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
override val annotatedDeclarationCheckers: Set<FirAnnotatedDeclarationChecker>
get() = setOf(
FirAnnotationChecker,
FirPublishedApiChecker,
)
override val typeAliasCheckers: Set<FirTypeAliasChecker>

View File

@@ -16,7 +16,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
get() = setOf(
FirReservedUnderscoreExpressionChecker,
FirUnderscoreChecker,
FirExpressionAnnotationChecker,
FirDeprecationChecker
)
@@ -41,7 +41,8 @@ object CommonExpressionCheckers : ExpressionCheckers() {
FirSealedClassConstructorCallChecker,
FirUninitializedEnumChecker,
FirFunInterfaceConstructorReferenceChecker,
FirReifiedChecker
FirReifiedChecker,
FirSuspendCallChecker,
)
override val functionCallCheckers: Set<FirFunctionCallChecker>

View File

@@ -30,6 +30,7 @@ object ExtendedDeclarationCheckers : DeclarationCheckers() {
override val controlFlowAnalyserCheckers: Set<FirControlFlowChecker>
get() = setOf(
UnusedChecker,
UnreachableCodeChecker,
)
override val simpleFunctionCheckers: Set<FirSimpleFunctionChecker>

View File

@@ -0,0 +1,35 @@
/*
* 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
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
fun checkUnderscoreDiagnostics(
source: FirSourceElement?,
context: CheckerContext,
reporter: DiagnosticReporter,
isExpression: Boolean
) {
if (source != null && source.kind !is FirFakeSourceElementKind) {
with(SourceNavigator.forSource(source)) {
if (source.getRawIdentifier()?.isUnderscore == true) {
reporter.reportOn(
source,
if (isExpression) FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS else FirErrors.UNDERSCORE_IS_RESERVED,
context
)
}
}
}
}
val CharSequence.isUnderscore: Boolean
get() = all { it == '_' }

View File

@@ -6,15 +6,22 @@
package org.jetbrains.kotlin.fir.analysis.checkers
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.getAncestors
import org.jetbrains.kotlin.fir.analysis.diagnostics.nameIdentifier
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.psi.KtConstructorCalleeExpression
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.stubs.elements.KtNameReferenceExpressionElementType
import org.jetbrains.kotlin.psi.stubs.elements.KtTypeProjectionElementType
/**
* Service to answer source-related questions in generic fashion.
@@ -26,17 +33,27 @@ interface SourceNavigator {
fun FirTypeRef.isInTypeConstraint(): Boolean
fun FirSourceElement.getRawIdentifier(): String?
fun FirDeclaration.getRawName(): String?
fun FirValueParameterSymbol.isCatchElementParameter(): Boolean
companion object {
private val lightTreeInstance = LightTreeSourceNavigator()
fun forElement(e: FirElement): SourceNavigator = when (e.source) {
fun forElement(e: FirElement): SourceNavigator = forSource(e.source)
fun forSource(e: FirSourceElement?): SourceNavigator = when (e) {
is FirLightSourceElement -> lightTreeInstance
is FirPsiSourceElement -> PsiSourceNavigator
null -> lightTreeInstance //shouldn't matter
}
inline fun <R> FirElement.withNavigator(block: SourceNavigator.() -> R): R = with(forElement(this), block)
inline fun <R> FirElement.withNavigator(block: SourceNavigator.() -> R): R = with(forSource(this.source), block)
inline fun <R> FirSourceElement.withNavigator(block: SourceNavigator.() -> R): R = with(forSource(this), block)
}
}
@@ -55,16 +72,61 @@ open class LightTreeSourceNavigator : SourceNavigator {
.find { it.tokenType == KtNodeTypes.TYPE_CONSTRAINT || it.tokenType == KtNodeTypes.TYPE_PARAMETER }
?.tokenType == KtNodeTypes.TYPE_CONSTRAINT
}
override fun FirSourceElement.getRawIdentifier(): String? {
val tokenType = elementType
return if (tokenType is KtNameReferenceExpressionElementType || tokenType == KtTokens.IDENTIFIER) {
lighterASTNode.toString()
} else if (tokenType is KtTypeProjectionElementType) {
lighterASTNode.getChildren(treeStructure).last().toString()
} else {
null
}
}
override fun FirDeclaration.getRawName(): String? {
return source?.let { it.treeStructure.nameIdentifier(it.lighterASTNode)?.toString() }
}
override fun FirValueParameterSymbol.isCatchElementParameter(): Boolean {
val localSource = source ?: return false
var parent = localSource.treeStructure.getParent(localSource.lighterASTNode)
parent?.let { parent = localSource.treeStructure.getParent(it) }
return parent?.tokenType == KtNodeTypes.CATCH
}
}
//by default psi tree can reuse light tree manipulations
object PsiSourceNavigator : LightTreeSourceNavigator() {
//Swallows incorrect casts!!!
private inline fun <reified P : PsiElement> FirElement.psi(): P? {
val psi = (source as? FirPsiSourceElement)?.psi
private inline fun <reified P : PsiElement> FirElement.psi(): P? = source?.psi()
private inline fun <reified P : PsiElement> FirSourceElement.psi(): P? {
val psi = (this as? FirPsiSourceElement)?.psi
return psi as? P
}
override fun FirTypeRef.isInConstructorCallee(): Boolean = psi<KtTypeReference>()?.parent is KtConstructorCalleeExpression
override fun FirSourceElement.getRawIdentifier(): String? {
val psi = psi<PsiElement>()
return if (psi is KtNameReferenceExpression) {
psi.getReferencedNameElement().node.text
} else if (psi is KtTypeProjection) {
psi.typeReference?.typeElement?.text
} else if (psi is LeafPsiElement && psi.elementType == KtTokens.IDENTIFIER) {
psi.text
} else {
null
}
}
override fun FirDeclaration.getRawName(): String? {
return (this.psi() as? PsiNameIdentifierOwner)?.nameIdentifier?.text
}
override fun FirValueParameterSymbol.isCatchElementParameter(): Boolean {
return source?.psi<PsiElement>()?.parent?.parent is KtCatchClause
}
}

View File

@@ -53,6 +53,15 @@ abstract class CheckerContext {
abstract fun dropDeclaration()
fun <T> withDeclaration(declaration: FirDeclaration, f: (CheckerContext) -> T): T {
val newContext = addDeclaration(declaration)
try {
return f(newContext)
} finally {
newContext.dropDeclaration()
}
}
abstract fun addQualifiedAccessOrAnnotationCall(qualifiedAccessOrAnnotationCall: FirStatement): CheckerContext
abstract fun dropQualifiedAccessOrAnnotationCall()

View File

@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.modality
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.containingClassAttr
import org.jetbrains.kotlin.fir.containingClassForStaticMemberAttr
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyAccessor
import org.jetbrains.kotlin.fir.declarations.utils.*
@@ -207,7 +207,7 @@ internal fun FirRegularClassSymbol.isInlineOrValueClass(): Boolean {
internal val FirDeclaration.isEnumEntryInitializer: Boolean
get() {
if (this !is FirConstructor || !this.isPrimary) return false
return (containingClassAttr as? ConeClassLookupTagWithFixedSymbol)?.symbol?.classKind == ClassKind.ENUM_ENTRY
return (containingClassForStaticMemberAttr as? ConeClassLookupTagWithFixedSymbol)?.symbol?.classKind == ClassKind.ENUM_ENTRY
}
// contract: returns(true) implies (this is FirMemberDeclaration<*>)

View File

@@ -10,38 +10,50 @@ import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isInlineOnly
import org.jetbrains.kotlin.fir.analysis.checkers.unsubstitutedScope
import org.jetbrains.kotlin.fir.analysis.checkers.util.checkChildrenWithCustomVisitor
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.analysis.diagnostics.withSuppressedDiagnostics
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.declarations.utils.effectiveVisibility
import org.jetbrains.kotlin.fir.declarations.utils.isInline
import org.jetbrains.kotlin.fir.declarations.utils.visibility
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.resolve.inference.isBuiltinFunctionalType
import org.jetbrains.kotlin.fir.resolve.inference.isFunctionalType
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.transformers.publishedApiEffectiveVisibility
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenMembers
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isMarkedNullable
import org.jetbrains.kotlin.fir.types.isNullable
import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
import org.jetbrains.kotlin.util.OperatorNameConventions
object FirInlineDeclarationChecker : FirFunctionChecker() {
override fun check(declaration: FirFunction, context: CheckerContext, reporter: DiagnosticReporter) {
if (!declaration.isInline) return
if (!declaration.isInline) {
checkParametersInNotInline(declaration, context, reporter)
return
}
// local inline functions are prohibited
if (declaration.isLocalMember) return
if (declaration.isLocalMember) {
reporter.reportOn(declaration.source, FirErrors.NOT_YET_SUPPORTED_IN_INLINE, "Local inline functions", context)
return
}
if (declaration !is FirPropertyAccessor && declaration !is FirSimpleFunction) return
val effectiveVisibility = declaration.effectiveVisibility
checkInlineFunctionBody(declaration, effectiveVisibility, context, reporter)
withSuppressedDiagnostics(declaration, context) { ctx ->
checkInlineFunctionBody(declaration, effectiveVisibility, ctx, reporter)
checkCallableDeclaration(declaration, ctx, reporter)
}
}
private fun checkInlineFunctionBody(
@@ -64,7 +76,9 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
context.session,
reporter
)
body.checkChildrenWithCustomVisitor(context, visitor)
context.withDeclaration(function) {
body.checkChildrenWithCustomVisitor(it, visitor)
}
}
private class Visitor(
@@ -102,6 +116,22 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
checkQualifiedAccess(variableAssignment, setterSymbol, data)
}
override fun visitRegularClass(regularClass: FirRegularClass, data: CheckerContext) {
if (!regularClass.classKind.isSingleton && data.containingDeclarations.lastOrNull() === inlineFunction) {
reporter.reportOn(regularClass.source, FirErrors.NOT_YET_SUPPORTED_IN_INLINE, "Local classes", data)
} else {
super.visitRegularClass(regularClass, data)
}
}
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: CheckerContext) {
if (data.containingDeclarations.lastOrNull() === inlineFunction) {
reporter.reportOn(simpleFunction.source, FirErrors.NOT_YET_SUPPORTED_IN_INLINE, "Local functions", data)
} else {
super.visitSimpleFunction(simpleFunction, data)
}
}
private fun checkReceiversOfQualifiedAccessExpression(
qualifiedAccessExpression: FirQualifiedAccessExpression,
targetSymbol: FirBasedSymbol<*>?,
@@ -310,4 +340,157 @@ object FirInlineDeclarationChecker : FirFunctionChecker() {
return containingClassVisibility == Visibilities.Private || containingClassVisibility == Visibilities.PrivateToThis
}
}
private fun checkParameters(
function: FirSimpleFunction,
overriddenSymbols: List<FirCallableSymbol<out FirCallableDeclaration>>,
context: CheckerContext,
reporter: DiagnosticReporter
) {
for (param in function.valueParameters) {
val coneType = param.returnTypeRef.coneType
val isFunctionalType = coneType.isFunctionalType(context.session)
val isSuspendFunctionalType = coneType.isSuspendFunctionType(context.session)
val defaultValue = param.defaultValue
if (!(isFunctionalType || isSuspendFunctionalType) && (param.isNoinline || param.isCrossinline)) {
reporter.reportOn(param.source, FirErrors.ILLEGAL_INLINE_PARAMETER_MODIFIER, context)
}
if (param.isNoinline) continue
if (function.isSuspend && defaultValue != null && isSuspendFunctionalType) {
reporter.reportOn(
param.source,
FirErrors.NOT_YET_SUPPORTED_IN_INLINE,
"Suspend functional parameters with default values",
context
)
}
if (isSuspendFunctionalType && !param.isCrossinline) {
if (function.isSuspend) {
reporter.reportOn(param.returnTypeRef.source, FirErrors.REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE, context)
} else {
reporter.reportOn(param.source, FirErrors.INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED, context)
}
}
if (coneType.isNullable && isFunctionalType) {
reporter.reportOn(
param.source,
FirErrors.NULLABLE_INLINE_PARAMETER,
param.symbol,
function.symbol,
context
)
}
if (isFunctionalType && defaultValue != null && !isInlinableDefaultValue(defaultValue)) {
reporter.reportOn(
defaultValue.source,
FirErrors.INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE,
defaultValue,
param.symbol,
context
)
}
}
if (overriddenSymbols.isNotEmpty()) {
for (param in function.typeParameters) {
if (param.isReified) {
reporter.reportOn(param.source, FirErrors.REIFIED_TYPE_PARAMETER_IN_OVERRIDE, context)
}
}
}
//check for inherited default values
val paramsWithDefaults = overriddenSymbols.flatMap {
if (it !is FirFunctionSymbol<*>) return@flatMap emptyList<Int>()
it.valueParameterSymbols.mapIndexedNotNull { idx, param ->
idx.takeIf { param.hasDefaultValue }
}
}.toSet()
function.valueParameters.forEachIndexed { idx, param ->
if (param.defaultValue == null && paramsWithDefaults.contains(idx)) {
reporter.reportOn(
param.source,
FirErrors.NOT_YET_SUPPORTED_IN_INLINE,
"Functional parameters with inherited default values",
context
)
}
}
}
private fun checkParametersInNotInline(function: FirFunction, context: CheckerContext, reporter: DiagnosticReporter) {
for (param in function.valueParameters) {
if (param.isNoinline || param.isCrossinline) {
reporter.reportOn(param.source, FirErrors.ILLEGAL_INLINE_PARAMETER_MODIFIER, context)
}
}
}
private fun FirCallableDeclaration.getOverriddenSymbols(context: CheckerContext): List<FirCallableSymbol<out FirCallableDeclaration>> {
if (!this.isOverride) return emptyList()
val classSymbol = this.containingClass()?.toSymbol(context.session) as? FirClassSymbol<*> ?: return emptyList()
val scope = classSymbol.unsubstitutedScope(context)
//this call is needed because AbstractFirUseSiteMemberScope collect overrides in it only,
//and not in processDirectOverriddenFunctionsWithBaseScope
scope.processFunctionsByName(this.symbol.name) { }
return scope.getDirectOverriddenMembers(this.symbol, true)
}
private fun checkNothingToInline(function: FirSimpleFunction, context: CheckerContext, reporter: DiagnosticReporter) {
if (function.isExpect || function.isSuspend) return
if (function.typeParameters.any { it.symbol.isReified }) return
val hasInlinableParameters =
function.valueParameters.any { param ->
val type = param.returnTypeRef.coneType
!param.isNoinline && !type.isNullable
&& (type.isFunctionalType(context.session) || type.isSuspendFunctionType(context.session))
}
if (hasInlinableParameters) return
if (function.isInlineOnly()) return
reporter.reportOn(function.source, FirErrors.NOTHING_TO_INLINE, context)
}
private fun checkCanBeInlined(
declaration: FirCallableDeclaration,
effectiveVisibility: EffectiveVisibility,
context: CheckerContext,
reporter: DiagnosticReporter
): Boolean {
if (declaration.containingClass() == null) return true
if (effectiveVisibility == EffectiveVisibility.PrivateInClass) return true
if (!declaration.isFinal) {
reporter.reportOn(declaration.source, FirErrors.DECLARATION_CANT_BE_INLINED, context)
return false
}
return true
}
private fun isInlinableDefaultValue(expression: FirExpression): Boolean =
expression is FirCallableReferenceAccess ||
expression is FirFunctionCall ||
expression is FirLambdaArgumentExpression ||
expression is FirAnonymousFunctionExpression ||
(expression is FirConstExpression<*> && expression.value == null) //this will be reported separately
internal fun checkCallableDeclaration(declaration: FirCallableDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration is FirPropertyAccessor) return
val overriddenSymbols = declaration.getOverriddenSymbols(context)
if (declaration is FirSimpleFunction) {
checkParameters(declaration, overriddenSymbols, context, reporter)
checkNothingToInline(declaration, context, reporter)
}
val canBeInlined = checkCanBeInlined(declaration, declaration.effectiveVisibility, context, reporter)
if (canBeInlined && overriddenSymbols.isNotEmpty()) {
reporter.reportOn(declaration.source, FirErrors.OVERRIDE_BY_INLINE, context)
}
}
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.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.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.utils.hasBackingField
import org.jetbrains.kotlin.fir.declarations.utils.isInline
object FirInlinePropertyChecker : FirPropertyChecker() {
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration.getter?.isInline != true && declaration.setter?.isInline != true) return
FirInlineDeclarationChecker.checkCallableDeclaration(declaration, context, reporter)
if (declaration.hasBackingField || declaration.delegate != null) {
reporter.reportOn(declaration.source, FirErrors.INLINE_PROPERTY_WITH_BACKING_FIELD, context)
}
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
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.declarations.*
import org.jetbrains.kotlin.name.Name
object FirInvalidAndDangerousCharactersChecker : FirBasicDeclarationChecker() {
// See The Java Virtual Machine Specification, section 4.7.9.1 https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.9.1
private val INVALID_CHARS = setOf('.', ';', '[', ']', '/', '<', '>', ':', '\\')
// These characters can cause problems on Windows. '?*"|' are not allowed in file names, and % leads to unexpected env var expansion.
private val DANGEROUS_CHARS = setOf('?', '*', '"', '|', '%')
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
val source = declaration.source
when (declaration) {
is FirRegularClass -> checkNameAndReport(declaration.name, source, context, reporter)
is FirSimpleFunction -> checkNameAndReport(declaration.name, source, context, reporter)
is FirTypeParameter -> checkNameAndReport(declaration.name, source, context, reporter)
is FirProperty -> checkNameAndReport(declaration.name, source, context, reporter)
is FirTypeAlias -> checkNameAndReport(declaration.name, source, context, reporter)
is FirValueParameter -> checkNameAndReport(declaration.name, source, context, reporter)
else -> return
}
}
private fun checkNameAndReport(name: Name, source: FirSourceElement?, context: CheckerContext, reporter: DiagnosticReporter) {
if (source != null &&
source.kind !is FirFakeSourceElementKind &&
!name.isSpecial
) {
val nameString = name.asString()
if (nameString.any { it in INVALID_CHARS }) {
reporter.reportOn(
source,
FirErrors.INVALID_CHARACTERS,
"contains illegal characters: ${INVALID_CHARS.intersect(nameString.toSet()).joinToString("")}",
context
)
} else if (nameString.any { it in DANGEROUS_CHARS }) {
reporter.reportOn(
source,
FirErrors.DANGEROUS_CHARACTERS,
DANGEROUS_CHARS.intersect(nameString.toSet()).joinToString(""),
context
)
}
}
}
}

View File

@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_CLASS_ME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_MEMBER_NOT_IMPLEMENTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_IMPL_MEMBER_NOT_IMPLEMENTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER_BY_DELEGATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
@@ -25,7 +24,6 @@ import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.FirClass
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.scopes.getDirectOverriddenMembers
import org.jetbrains.kotlin.fir.scopes.impl.delegatedWrapperData
@@ -112,11 +110,7 @@ object FirNotImplementedOverrideChecker : FirClassChecker() {
}
if (!canHaveAbstractDeclarations && invisibleSymbols.isNotEmpty()) {
val invisible = invisibleSymbols.first()
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitInvisibleAbstractMethodsInSuperclasses)) {
reporter.reportOn(source, INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER, classSymbol, invisible, context)
} else {
reporter.reportOn(source, INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER_WARNING, classSymbol, invisible, context)
}
reporter.reportOn(source, INVISIBLE_ABSTRACT_MEMBER_FROM_SUPER, classSymbol, invisible, context)
}
manyImplementationsDelegationSymbols.firstOrNull()?.let {

View File

@@ -51,7 +51,7 @@ private fun checkOuterClassArgumentsRequired(
for (index in typeArguments.size until typeParameters.size) {
val typeParameter = typeParameters[index]
if (!isValidTypeParameterFromOuterClass(typeParameter, declaration, context.session)) {
val outerClass = typeParameter.containingDeclarationSymbol as FirRegularClassSymbol
val outerClass = typeParameter.containingDeclarationSymbol as? FirRegularClassSymbol ?: break
reporter.reportOn(typeRef.source, FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED, outerClass, context)
break
}

View File

@@ -117,6 +117,7 @@ object FirOverrideChecker : FirClassChecker() {
overriddenSymbols: List<FirCallableSymbol<*>>,
context: CheckerContext
) {
if (overriddenSymbols.isEmpty()) return
val visibilities = overriddenSymbols.map {
it to it.visibility
}.sortedBy { pair ->
@@ -124,17 +125,33 @@ object FirOverrideChecker : FirClassChecker() {
Visibilities.compare(visibility, pair.second) ?: Int.MIN_VALUE
}
for ((overridden, overriddenVisibility) in visibilities) {
val compare = Visibilities.compare(visibility, overriddenVisibility)
if (compare == null) {
reporter.reportCannotChangeAccessPrivilege(this, overridden, context)
return
} else if (compare < 0) {
reporter.reportCannotWeakenAccessPrivilege(this, overridden, context)
return
if (this is FirPropertySymbol) {
getterSymbol?.checkVisibility(
containingClass,
reporter,
overriddenSymbols.map { (it as FirPropertySymbol).getterSymbol ?: it },
context
)
setterSymbol?.checkVisibility(
containingClass,
reporter,
overriddenSymbols.mapNotNull { (it as FirPropertySymbol).setterSymbol },
context
)
} else {
for ((overridden, overriddenVisibility) in visibilities) {
val compare = Visibilities.compare(visibility, overriddenVisibility)
if (compare == null) {
reporter.reportCannotChangeAccessPrivilege(this, overridden, context)
break
} else if (compare < 0) {
reporter.reportCannotWeakenAccessPrivilege(this, overridden, context)
break
}
}
}
if (this is FirPropertyAccessorSymbol) return
val file = context.findClosest<FirFile>() ?: return
val containingDeclarations = context.containingDeclarations + containingClass
val visibilityChecker = context.session.visibilityChecker

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.Visibilities
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.declarations.FirAnnotatedDeclaration
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.getAnnotationByFqName
import org.jetbrains.kotlin.fir.declarations.utils.visibility
object FirPublishedApiChecker : FirAnnotatedDeclarationChecker() {
override fun check(declaration: FirAnnotatedDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirMemberDeclaration) return
if (declaration.visibility == Visibilities.Internal) return
val annotation = declaration.getAnnotationByFqName(StandardNames.FqNames.publishedApi) ?: return
reporter.reportOn(annotation.source, FirErrors.NON_INTERNAL_PUBLISHED_API, context)
}
}

View File

@@ -0,0 +1,89 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.SourceNavigator
import org.jetbrains.kotlin.fir.analysis.checkers.checkUnderscoreDiagnostics
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.isUnderscore
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.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
object FirReservedUnderscoreDeclarationChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (
declaration is FirRegularClass ||
declaration is FirTypeParameter ||
declaration is FirProperty ||
declaration is FirTypeAlias
) {
reportIfUnderscore(declaration, context, reporter)
} else if (declaration is FirFunction) {
if (declaration is FirSimpleFunction) {
reportIfUnderscore(declaration, context, reporter)
}
val isSingleUnderscoreAllowed = declaration is FirAnonymousFunction || declaration is FirPropertyAccessor
for (parameter in declaration.valueParameters) {
reportIfUnderscore(
parameter,
context,
reporter,
isSingleUnderscoreAllowed = isSingleUnderscoreAllowed
)
}
} else if (declaration is FirFile) {
for (import in declaration.imports) {
checkUnderscoreDiagnostics(import.aliasSource, context, reporter, isExpression = false)
}
}
}
private fun reportIfUnderscore(
declaration: FirDeclaration,
context: CheckerContext,
reporter: DiagnosticReporter,
isSingleUnderscoreAllowed: Boolean = false
) {
val declarationSource = declaration.source
if (declarationSource != null && declarationSource.kind !is FirFakeSourceElementKind) {
with(SourceNavigator.forElement(declaration)) {
val rawName = declaration.getRawName()
if (rawName?.isUnderscore == true && !(isSingleUnderscoreAllowed && rawName == "_")) {
reporter.reportOn(
declarationSource,
FirErrors.UNDERSCORE_IS_RESERVED,
context
)
}
}
}
val returnOrReceiverTypeRef = when (declaration) {
is FirValueParameter -> declaration.returnTypeRef
is FirFunction -> declaration.receiverTypeRef
else -> null
}
if (returnOrReceiverTypeRef is FirResolvedTypeRef) {
val delegatedTypeRef = returnOrReceiverTypeRef.delegatedTypeRef
if (delegatedTypeRef is FirUserTypeRef) {
for (qualifierPart in delegatedTypeRef.qualifier) {
checkUnderscoreDiagnostics(qualifierPart.source, context, reporter, isExpression = true)
for (typeArgument in qualifierPart.typeArgumentList.typeArguments) {
checkUnderscoreDiagnostics(typeArgument.source, context, reporter, isExpression = true)
}
}
}
}
}
}

View File

@@ -5,16 +5,11 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.config.LanguageFeature
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.FirDiagnosticFactory1
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
@@ -62,9 +57,7 @@ object FirReifiedChecker : FirQualifiedAccessExpressionChecker() {
lateinit var symbol: FirTypeParameterSymbol
if (typeArgument is ConeTypeParameterType) {
factory = if (isArray) {
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitNonReifiedArraysAsReifiedTypeArguments))
FirErrors.TYPE_PARAMETER_AS_REIFIED_ARRAY else
FirErrors.TYPE_PARAMETER_AS_REIFIED_ARRAY_WARNING
FirErrors.TYPE_PARAMETER_AS_REIFIED_ARRAY.chooseFactory(context)
} else {
FirErrors.TYPE_PARAMETER_AS_REIFIED
}
@@ -82,4 +75,4 @@ object FirReifiedChecker : FirQualifiedAccessExpressionChecker() {
private fun ConeKotlinType.cannotBeReified(): Boolean {
return this.isNothing || this.isNullableNothing || this is ConeCapturedType
}
}
}

View File

@@ -1,209 +0,0 @@
/*
* 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 com.intellij.lang.LighterASTNode
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirBasicDeclarationChecker
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.text
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.stubs.elements.KtDotQualifiedExpressionElementType
import org.jetbrains.kotlin.psi.stubs.elements.KtNameReferenceExpressionElementType
object FirReservedUnderscoreExpressionChecker : FirBasicExpressionChecker() {
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
val source = expression.source
if (expression is FirFunctionCall) {
val calleeReferenceSource = expression.calleeReference.source
if (calleeReferenceSource is FirLightSourceElement && calleeReferenceSource.lighterASTNode.tokenType == KtNodeTypes.OPERATION_REFERENCE) {
return
}
reportIfUnderscore(
expression.calleeReference.source.text, expression.calleeReference.source, context, reporter,
isExpression = true
)
} else if (expression is FirQualifiedAccess) {
if (source is FirPsiSourceElement) {
reportIfUnderscoreInQualifiedAccess(source, expression, context, reporter)
} else if (source is FirLightSourceElement) {
reportIfUnderscoreInQualifiedAccess(source, expression, context, reporter)
}
} else if (expression is FirGetClassCall) {
for (argument in expression.argumentList.arguments) {
reportIfUnderscore(argument.source.text, expression.source, context, reporter, isExpression = true)
}
} else if (expression is FirReturnExpression) {
var labelName: String? = null
if (source is FirPsiSourceElement) {
labelName = (source.psi.parent as? KtLabeledExpression)?.getLabelName()
} else if (source is FirLightSourceElement) {
val parent = source.treeStructure.getParent(source.lighterASTNode)
if (parent != null && parent.tokenType == KtNodeTypes.LABELED_EXPRESSION) {
labelName = source.treeStructure.findDescendantByType(parent, KtNodeTypes.LABEL).toString()
labelName = labelName.substring(0, labelName.length - 1)
}
}
reportIfUnderscore(labelName, expression.source, context, reporter)
}
}
private fun reportIfUnderscoreInQualifiedAccess(
source: FirPsiSourceElement,
expression: FirStatement,
context: CheckerContext,
reporter: DiagnosticReporter
) {
fun processQualifiedAccess(psi: PsiElement?) {
if (psi is KtNameReferenceExpression) {
reportIfUnderscore(psi.text, expression.source, context, reporter, isExpression = true)
} else if (psi is KtDotQualifiedExpression || psi is KtCallableReferenceExpression) {
processQualifiedAccess(psi.firstChild)
processQualifiedAccess(psi.lastChild)
}
}
val psi = source.psi
if (psi.parent !is KtDotQualifiedExpression && psi.parent !is KtCallableReferenceExpression) {
processQualifiedAccess(psi)
}
}
private fun reportIfUnderscoreInQualifiedAccess(
source: FirLightSourceElement,
expression: FirStatement,
context: CheckerContext,
reporter: DiagnosticReporter
) {
fun processQualifiedAccess(lightSourceElement: LighterASTNode?) {
val tokenType = lightSourceElement?.tokenType
if (tokenType is KtNameReferenceExpressionElementType) {
reportIfUnderscore(lightSourceElement.toString(), expression.source, context, reporter, isExpression = true)
} else if (lightSourceElement != null && (tokenType is KtDotQualifiedExpressionElementType || tokenType == KtNodeTypes.CALLABLE_REFERENCE_EXPRESSION)) {
val children = lightSourceElement.getChildren(source.treeStructure)
processQualifiedAccess(children.first())
processQualifiedAccess(children.last())
}
}
val astNode = source.lighterASTNode
val parent = source.treeStructure.getParent(astNode)
if (parent?.tokenType !is KtDotQualifiedExpressionElementType && parent?.tokenType != KtNodeTypes.CALLABLE_REFERENCE_EXPRESSION) {
processQualifiedAccess(astNode)
}
}
}
object FirReservedUnderscoreDeclarationChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (
declaration is FirClass ||
declaration is FirFunction ||
declaration is FirTypeParameter ||
declaration is FirProperty ||
declaration is FirTypeAlias
) {
reportIfUnderscore(declaration, context, reporter)
if (declaration is FirFunction) {
for (parameter in declaration.valueParameters) {
reportIfUnderscore(
parameter,
context,
reporter,
isSingleUnderscoreAllowed = declaration is FirAnonymousFunction || declaration is FirPropertyAccessor
)
}
}
} else if (declaration is FirFile) {
for (import in declaration.imports) {
reportIfUnderscore(import.aliasName?.asString(), import.source, context, reporter)
}
}
}
}
private fun reportIfUnderscore(
declaration: FirDeclaration,
context: CheckerContext,
reporter: DiagnosticReporter,
isSingleUnderscoreAllowed: Boolean = false
) {
val source = declaration.source
val rawIdentifier = when (source) {
is FirPsiSourceElement ->
(source.psi as? PsiNameIdentifierOwner)?.nameIdentifier?.text
is FirLightSourceElement ->
source.treeStructure.nameIdentifier(source.lighterASTNode)?.toString()
else ->
null
}
reportIfUnderscore(rawIdentifier, source, context, reporter, isSingleUnderscoreAllowed)
val returnOrReceiverTypeRef = when (declaration) {
is FirValueParameter -> declaration.returnTypeRef.source
is FirFunction -> declaration.receiverTypeRef?.source
else -> null
}
val isReportUnderscoreInReturnOrReceiverTypeRef = when (returnOrReceiverTypeRef) {
is FirPsiSourceElement -> {
val psi = returnOrReceiverTypeRef.psi
psi is KtTypeReference && psi.anyDescendantOfType<LeafPsiElement> { isUnderscore(it.text) }
}
is FirLightSourceElement -> {
val lighterASTNode = returnOrReceiverTypeRef.lighterASTNode
lighterASTNode.tokenType == KtNodeTypes.TYPE_REFERENCE &&
source?.treeStructure?.findFirstDescendant(lighterASTNode)
{ it.tokenType == KtNodeTypes.REFERENCE_EXPRESSION && isUnderscore(it.toString()) } != null
}
else -> {
false
}
}
if (isReportUnderscoreInReturnOrReceiverTypeRef) {
reporter.reportOn(returnOrReceiverTypeRef, FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS, context)
}
}
private fun reportIfUnderscore(
text: CharSequence?,
source: FirSourceElement?,
context: CheckerContext,
reporter: DiagnosticReporter,
isSingleUnderscoreAllowed: Boolean = false,
isExpression: Boolean = false
) {
if (text == null || isSingleUnderscoreAllowed && text == "_") {
return
}
if (isUnderscore(text)) {
reporter.reportOn(
source,
if (isExpression) FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS else FirErrors.UNDERSCORE_IS_RESERVED,
context
)
}
}
private fun isUnderscore(text: CharSequence) = text.all { it == '_' }

View File

@@ -6,14 +6,18 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirRealSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.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.expressions.FirReturnExpression
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
object FirReturnAllowedChecker : FirReturnExpressionChecker() {
override fun check(expression: FirReturnExpression, context: CheckerContext, reporter: DiagnosticReporter) {
@@ -26,6 +30,25 @@ object FirReturnAllowedChecker : FirReturnExpressionChecker() {
reporter.reportOn(source, FirErrors.RETURN_NOT_ALLOWED, context)
}
if (targetSymbol is FirAnonymousFunctionSymbol) {
val label = targetSymbol.label
if (label?.source?.kind !is FirRealSourceElementKind) {
val functionCall = context.qualifiedAccessOrAnnotationCalls.asReversed().find {
it is FirFunctionCall &&
((it.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol as? FirNamedFunctionSymbol)?.callableId ==
FirSuspendCallChecker.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_CALLABLE_ID
}
if (functionCall is FirFunctionCall &&
functionCall.arguments.any {
it is FirLambdaArgumentExpression &&
(it.expression as? FirAnonymousFunctionExpression)?.anonymousFunction?.symbol == targetSymbol
}
) {
reporter.reportOn(source, FirErrors.RETURN_FOR_BUILT_IN_SUSPEND, context)
}
}
}
val containingDeclaration = context.containingDeclarations.last()
if (containingDeclaration is FirFunction && containingDeclaration.body is FirSingleExpressionBlock) {
reporter.reportOn(source, FirErrors.RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY, context)

View File

@@ -0,0 +1,199 @@
/*
* 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.builtins.StandardNames
import org.jetbrains.kotlin.fir.FirSession
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.analysis.getChild
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_1_3_FQ_NAME
import org.jetbrains.kotlin.serialization.deserialization.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
private val RESTRICTS_SUSPENSION_CLASS_ID =
ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE, Name.identifier("RestrictsSuspension"))
private val BUILTIN_SUSPEND_NAME = KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME.shortName()
internal val KOTLIN_SUSPEND_BUILT_IN_FUNCTION_CALLABLE_ID = CallableId(StandardClassIds.BASE_KOTLIN_PACKAGE, BUILTIN_SUSPEND_NAME)
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
val reference = expression.calleeReference as? FirResolvedNamedReference ?: return
val symbol = reference.resolvedSymbol as? FirCallableSymbol ?: return
if (reference.name == BUILTIN_SUSPEND_NAME ||
symbol is FirNamedFunctionSymbol && symbol.name == BUILTIN_SUSPEND_NAME
) {
checkSuspendModifierForm(expression, reference, symbol, context, reporter)
}
if (reference is FirResolvedCallableReference) return
when (symbol) {
is FirNamedFunctionSymbol -> if (!symbol.isSuspend) return
is FirPropertySymbol -> if (symbol.callableId.asSingleFqName() != COROUTINE_CONTEXT_1_3_FQ_NAME) return
else -> return
}
val enclosingSuspendFunction = findEnclosingSuspendFunction(context)
if (enclosingSuspendFunction == null) {
when (symbol) {
is FirNamedFunctionSymbol -> reporter.reportOn(expression.source, FirErrors.ILLEGAL_SUSPEND_FUNCTION_CALL, symbol, context)
is FirPropertySymbol -> reporter.reportOn(expression.source, FirErrors.ILLEGAL_SUSPEND_PROPERTY_ACCESS, symbol, context)
else -> {
}
}
} else {
if (!checkNonLocalReturnUsage(enclosingSuspendFunction, context)) {
reporter.reportOn(expression.source, FirErrors.NON_LOCAL_SUSPENSION_POINT, context)
}
if (!checkRestrictsSuspension(expression, enclosingSuspendFunction, symbol, context)) {
reporter.reportOn(expression.source, FirErrors.ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL, context)
}
}
}
private fun checkSuspendModifierForm(
expression: FirQualifiedAccessExpression,
reference: FirResolvedNamedReference,
symbol: FirCallableSymbol<*>,
context: CheckerContext,
reporter: DiagnosticReporter
) {
if (symbol.callableId == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_CALLABLE_ID) {
if (reference.name != BUILTIN_SUSPEND_NAME ||
expression.explicitReceiver != null ||
!expression.hasFormOfSuspendModifierForLambda()
) {
reporter.reportOn(expression.source, FirErrors.NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND, context)
}
} else {
if (reference.name == BUILTIN_SUSPEND_NAME && expression.hasFormOfSuspendModifierForLambda()) {
reporter.reportOn(expression.source, FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND, context)
}
}
}
private fun FirQualifiedAccessExpression.hasFormOfSuspendModifierForLambda(): Boolean {
if (this !is FirFunctionCall) return false
val reference = this.calleeReference
if (reference is FirResolvedCallableReference) return false
if (typeArguments.any { it.source != null }) return false
if (arguments.singleOrNull() is FirLambdaArgumentExpression) {
// No brackets should be in a selector call
val callExpressionSource =
if (explicitReceiver == null) source
else source?.getChild(KtNodeTypes.CALL_EXPRESSION, index = 1, depth = 1)
if (callExpressionSource?.getChild(KtNodeTypes.VALUE_ARGUMENT_LIST, depth = 1) == null) {
return true
}
}
if (origin == FirFunctionCallOrigin.Infix) {
val lastArgument = arguments.lastOrNull()
if (lastArgument is FirAnonymousFunctionExpression && source?.getChild(KtNodeTypes.PARENTHESIZED, depth = 1) == null) {
return true
}
}
return false
}
private fun findEnclosingSuspendFunction(context: CheckerContext): FirFunction? {
return context.containingDeclarations.lastOrNull {
when (it) {
is FirAnonymousFunction -> it.typeRef.coneType.isSuspendFunctionType(context.session)
is FirSimpleFunction -> it.isSuspend
else -> false
}
} as? FirFunction
}
private fun checkNonLocalReturnUsage(enclosingSuspendFunction: FirFunction, context: CheckerContext): Boolean {
val containingFunction = context.containingDeclarations.lastIsInstanceOrNull<FirFunction>() ?: return false
return if (containingFunction is FirAnonymousFunction && enclosingSuspendFunction !== containingFunction) {
containingFunction.inlineStatus.returnAllowed
} else {
enclosingSuspendFunction === containingFunction
}
}
private fun checkRestrictsSuspension(
expression: FirQualifiedAccessExpression,
enclosingSuspendFunction: FirFunction,
calledDeclarationSymbol: FirCallableSymbol<*>,
context: CheckerContext
): Boolean {
val session = context.session
val enclosingSuspendFunctionDispatchReceiverOwner =
(enclosingSuspendFunction.dispatchReceiverType as? ConeClassLikeType)?.lookupTag?.toFirRegularClass(session)
val enclosingSuspendFunctionExtensionReceiverOwner = enclosingSuspendFunction.takeIf { it.receiverTypeRef != null }
val dispatchReceiverExpression = expression.dispatchReceiver.takeIf { it !is FirNoReceiverExpression }
val extensionReceiverExpression = expression.extensionReceiver.takeIf { it !is FirNoReceiverExpression }
for (receiverExpression in listOfNotNull(dispatchReceiverExpression, extensionReceiverExpression)) {
if (!receiverExpression.typeRef.coneType.isRestrictSuspensionReceiver(session)) continue
if (sameInstanceOfReceiver(receiverExpression, enclosingSuspendFunctionDispatchReceiverOwner)) continue
if (sameInstanceOfReceiver(receiverExpression, enclosingSuspendFunctionExtensionReceiverOwner)) continue
return false
}
if (enclosingSuspendFunctionExtensionReceiverOwner?.receiverTypeRef?.coneType?.isRestrictSuspensionReceiver(session) != true) {
return true
}
if (sameInstanceOfReceiver(dispatchReceiverExpression, enclosingSuspendFunctionExtensionReceiverOwner)) {
return true
}
if (sameInstanceOfReceiver(extensionReceiverExpression, enclosingSuspendFunctionExtensionReceiverOwner)) {
if (calledDeclarationSymbol.resolvedReceiverTypeRef?.coneType?.isRestrictSuspensionReceiver(session) == true) {
return true
}
}
return false
}
private fun ConeKotlinType.isRestrictSuspensionReceiver(session: FirSession): Boolean {
when (this) {
is ConeClassLikeType -> {
val regularClass = fullyExpandedType(session).lookupTag.toFirRegularClass(session) ?: return false
if (regularClass.hasAnnotation(RESTRICTS_SUSPENSION_CLASS_ID)) {
return true
}
return regularClass.superTypeRefs.any { it.coneType.isRestrictSuspensionReceiver(session) }
}
is ConeTypeParameterType -> {
return lookupTag.typeParameterSymbol.resolvedBounds.any { it.coneType.isRestrictSuspensionReceiver(session) }
}
else -> return false
}
}
private fun sameInstanceOfReceiver(useSiteReceiverExpression: FirExpression?, declarationSiteReceiverOwner: FirDeclaration?): Boolean {
if (declarationSiteReceiverOwner == null || useSiteReceiverExpression == null) return false
if (useSiteReceiverExpression is FirThisReceiverExpression) {
return useSiteReceiverExpression.calleeReference.boundSymbol == declarationSiteReceiverOwner.symbol
}
return false
}
}

View File

@@ -0,0 +1,56 @@
/*
* 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.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.checkUnderscoreDiagnostics
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.diagnostics.ConeUnderscoreUsageWithoutBackticks
import org.jetbrains.kotlin.fir.expressions.FirResolvable
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.expressions.FirStatement
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.fir.analysis.checkers.SourceNavigator
object FirUnderscoreChecker : FirBasicExpressionChecker() {
private val singleUnderscore: Name = Name.identifier("_")
override fun check(expression: FirStatement, context: CheckerContext, reporter: DiagnosticReporter) {
when (expression) {
is FirResolvable -> {
checkUnderscoreDiagnostics(expression.calleeReference.source, context, reporter, true)
checkResolvedToUnderscoreNamedCatchParameter(expression, context, reporter)
}
is FirResolvedQualifier -> {
for (reservedUnderscoreDiagnostic in expression.nonFatalDiagnostics.filterIsInstance<ConeUnderscoreUsageWithoutBackticks>()) {
reporter.reportOn(reservedUnderscoreDiagnostic.source, FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS, context)
}
}
}
}
private fun checkResolvedToUnderscoreNamedCatchParameter(
expression: FirResolvable,
context: CheckerContext,
reporter: DiagnosticReporter
) {
val calleeReference = expression.calleeReference
val symbol = calleeReference.toResolvedCallableSymbol()
with(SourceNavigator.forElement(expression)) {
if (symbol is FirValueParameterSymbol && symbol.isCatchElementParameter() && symbol.name == singleUnderscore) {
reporter.reportOn(
calleeReference.source,
FirErrors.RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER,
context
)
}
}
}
}

View File

@@ -35,13 +35,7 @@ object FirValReassignmentChecker : FirVariableAssignmentChecker() {
val closestGetter = context.findClosest<FirPropertyAccessor> { it.isGetter }?.symbol ?: return
if (propertySymbol.getterSymbol != closestGetter) return
backingFieldReference.source?.let {
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.RestrictionOfValReassignmentViaBackingField)) {
reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR, propertySymbol, context)
} else {
reporter.reportOn(it, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD, propertySymbol, context)
}
}
reporter.reportOn(backingFieldReference.source, FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD, propertySymbol, context)
}
private fun checkValReassignmentOnValueParameter(

View File

@@ -0,0 +1,81 @@
/*
* 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.extended
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.cfa.FirControlFlowChecker
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.FirTryExpression
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
object UnreachableCodeChecker : FirControlFlowChecker() {
override fun analyze(graph: ControlFlowGraph, reporter: DiagnosticReporter, context: CheckerContext) {
val nodes = graph.allNodes()
val (unreachableNodes, reachableNodes) = nodes.filterNot { it.skipNode() }.partition { it.isDead }
if (unreachableNodes.isEmpty()) return
val unreachableSources = unreachableNodes.mapNotNull { it.fir.source }.toSet()
val reachableSources = reachableNodes.mapNotNull { it.fir.source }.toSet()
val unreachableElements = unreachableNodes.map { it.fir }
val innerNodes = mutableSetOf<FirElement>()
unreachableElements.forEach { it.collectInnerNodes(innerNodes) }
//todo cfg is broken in catch and finally blocks, so exclude reporting anything
nodes.mapNotNull { it.fir as? FirTryExpression }.distinct().forEach { tryNode ->
tryNode.finallyBlock?.collectInnerNodes(innerNodes)
tryNode.catches.forEach { it.collectInnerNodes(innerNodes) }
}
unreachableElements.distinctBy { it.source }.forEach { element ->
if (element !in innerNodes) {
reporter.reportOn(element.source, FirErrors.UNREACHABLE_CODE, reachableSources, unreachableSources, context)
}
}
}
private fun ControlFlowGraph.allNodes(acc: MutableList<CFGNode<*>> = mutableListOf()): List<CFGNode<*>> {
acc.addAll(this.nodes)
subGraphs.forEach { it.allNodes(acc) }
return acc
}
private val sourceKindsToSkip = setOf(
FirFakeSourceElementKind.ImplicitReturn,
FirFakeSourceElementKind.DesugaredForLoop
)
private fun CFGNode<*>.skipNode(): Boolean {
val skipType = this is ExitNodeMarker ||
this is EnterNodeMarker ||
this is StubNode ||
this is BinaryOrExitLeftOperandNode ||
this is BinaryOrEnterRightOperandNode ||
this is BinaryAndExitLeftOperandNode ||
this is BinaryAndEnterRightOperandNode ||
this is WhenSyntheticElseBranchNode ||
this is WhenBranchResultEnterNode ||
this is WhenBranchResultExitNode
val allowType = this is LoopEnterNode ||
this is LoopBlockEnterNode ||
this is TryExpressionEnterNode
return !allowType && (skipType || sourceKindsToSkip.contains(this.fir.source?.kind))
}
private fun FirElement.collectInnerNodes(nodes: MutableSet<FirElement>) {
acceptChildren(CollectNodesVisitor(nodes))
}
private class CollectNodesVisitor(private val nodes: MutableSet<FirElement>) : FirVisitorVoid() {
override fun visitElement(element: FirElement) {
nodes.add(element)
element.acceptChildren(this)
}
}
}

View File

@@ -67,6 +67,7 @@ object UnusedChecker : FirControlFlowChecker() {
override fun visitVariableDeclarationNode(node: VariableDeclarationNode) {
val variableSymbol = node.fir.symbol
if (node.fir.source == null) return
if (variableSymbol.isLoopIterator) return
val dataPerNode = data[node] ?: return
for (dataPerLabel in dataPerNode.values) {

View File

@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
import org.jetbrains.kotlin.fir.languageVersionSettings
abstract class DiagnosticReporter {
abstract fun report(diagnostic: FirDiagnostic?, context: CheckerContext)
@@ -75,6 +76,74 @@ fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
source?.let { report(factory.on(it, a, b, c, d, positioningStrategy), context) }
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun DiagnosticReporter.reportOn(
source: FirSourceElement?,
factory: FirDiagnosticFactoryForDeprecation0,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any> DiagnosticReporter.reportOn(
source: FirSourceElement?,
factory: FirDiagnosticFactoryForDeprecation1<A>,
a: A,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any> DiagnosticReporter.reportOn(
source: FirSourceElement?,
factory: FirDiagnosticFactoryForDeprecation2<A, B>,
a: A,
b: B,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, b, context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any, C : Any> DiagnosticReporter.reportOn(
source: FirSourceElement?,
factory: FirDiagnosticFactoryForDeprecation3<A, B, C>,
a: A,
b: B,
c: C,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, b, c, context, positioningStrategy)
}
@OptIn(InternalDiagnosticFactoryMethod::class)
fun <A : Any, B : Any, C : Any, D : Any> DiagnosticReporter.reportOn(
source: FirSourceElement?,
factory: FirDiagnosticFactoryForDeprecation4<A, B, C, D>,
a: A,
b: B,
c: C,
d: D,
context: CheckerContext,
positioningStrategy: SourceElementPositioningStrategy? = null
) {
reportOn(source, factory.chooseFactory(context), a, b, c, d, context, positioningStrategy)
}
fun <F : AbstractFirDiagnosticFactory> FirDiagnosticFactoryForDeprecation<F>.chooseFactory(context: CheckerContext): F {
return if (context.session.languageVersionSettings.supportsFeature(deprecatingFeature)) {
errorFactory
} else {
warningFactory
}
}
inline fun withSuppressedDiagnostics(
element: FirElement,
context: CheckerContext,

View File

@@ -107,10 +107,12 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CREATING_AN_INSTA
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_GENERIC_UPPER_BOUND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_INHERITANCE_HIERARCHY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DANGEROUS_CHARACTERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_NOT_PROPERTY_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_OVERRIDE_CONFLICT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_VARARG_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DATA_CLASS_WITHOUT_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DECLARATION_CANT_BE_INLINED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_INSIDE_INLINE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATED_PROPERTY_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DELEGATE_SPECIAL_FUNCTION_AMBIGUITY
@@ -188,8 +190,12 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.GENERIC_THROWABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.HAS_NEXT_FUNCTION_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_CONST_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_INLINE_PARAMETER_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_KOTLIN_VERSION_STRING_VALUE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_SELECTOR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_SUSPEND_FUNCTION_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_SUSPEND_PROPERTY_ACCESS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_UNDERSCORE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.IMPLEMENTATION_BY_DELEGATION_IN_EXPECT_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_CANDIDATE
@@ -220,10 +226,14 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_CONS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_HAS_INAPPLICABLE_PARAMETER_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_NOT_FINAL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_CLASS_NOT_TOP_LEVEL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_PROPERTY_WITH_BACKING_FIELD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_INSIDE_INLINE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INNER_CLASS_OF_GENERIC_THROWABLE_SUBCLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INTERFACE_WITH_SUPERCLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_CHARACTERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_IF_AS_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVALID_TYPE_OF_ANNOTATION_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INVISIBLE_REFERENCE
@@ -242,6 +252,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_LAMBDA_EXPRE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISPLACED_TYPE_PARAMETER_CONSTRAINTS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
@@ -256,12 +267,16 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_ABSTRACT_FUNC
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_EXHAUSTIVE_WHEN_STATEMENT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_IN_FINAL_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_IN_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_INTERNAL_PUBLISHED_API
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_LOCAL_SUSPENSION_POINT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_MEMBER_FUNCTION_NO_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_ENUM
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_VARARG_SPREAD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOTHING_TO_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOTHING_TO_OVERRIDE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_AN_ANNOTATION_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_LOOP_LABEL
@@ -270,6 +285,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_NULL_ASSERTIO
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ACTUAL_FOR_EXPECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_YET_SUPPORTED_IN_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_COMPANION_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ELSE_IN_WHEN
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_GET_METHOD
@@ -278,6 +294,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_RETURN_IN_FUNC
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_SET_METHOD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_THIS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_VALUE_FOR_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_INLINE_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_SUPERTYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_IN_CLASS_LITERAL_LHS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_OF_ANNOTATION_MEMBER
@@ -286,6 +303,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPERATOR_RENAMED_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OTHER_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDE_BY_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_CANNOT_BE_IMPORTED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PRIMARY_CONSTRUCTOR_DELEGATION_CALL_EXPECTED
@@ -315,6 +333,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDECLARATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_ANNOTATION_TARGET
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_CALL_OF_CONVERSION_METHOD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_EXPLICIT_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODALITY_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_OPEN_IN_INTERFACE
@@ -325,12 +344,15 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_SINGLE_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REDUNDANT_VISIBILITY_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REIFIED_TYPE_FORBIDDEN_SUBSTITUTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REIFIED_TYPE_IN_CATCH_CLAUSE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REIFIED_TYPE_PARAMETER_IN_OVERRIDE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REIFIED_TYPE_PARAMETER_NO_INLINE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REPEATED_BOUND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.REPEATED_MODIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RESERVED_MEMBER_INSIDE_INLINE_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RESOLUTION_TO_CLASSIFIER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RESULT_TYPE_MISMATCH
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_FOR_BUILT_IN_SUSPEND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.RETURN_TYPE_MISMATCH
@@ -371,13 +393,14 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_I
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETERS_NOT_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS_REIFIED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS_REIFIED_ARRAY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS_REIFIED_ARRAY_WARNING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_IN_CATCH_CLAUSE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_IS_NOT_AN_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_ON_LHS_OF_DOT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_VARIANCE_CONFLICT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_VARIANCE_CONFLICT_IN_EXPANDED_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNDERSCORE_IS_RESERVED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNEXPECTED_SAFE_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_ENUM_COMPANION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_ENUM_ENTRY
@@ -386,6 +409,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_VAR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNNECESSARY_LATEINIT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNNECESSARY_NOT_NULL_ASSERTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNNECESSARY_SAFE_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNREACHABLE_CODE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_LABEL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_REFERENCE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_CALL
@@ -414,7 +438,6 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_LOO
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VAL_WITH_SETTER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARARG_OUTSIDE_PARENTHESES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.VARIABLE_EXPECTED
@@ -806,11 +829,6 @@ class FirDefaultErrorMessages {
"Cannot use ''{0}'' as reified type parameter, since the array type parameter is not reified.",
SYMBOL
)
map.put(
TYPE_PARAMETER_AS_REIFIED_ARRAY_WARNING,
"Cannot use ''{0}'' as reified type parameter, since the array type parameter is not reified.",
SYMBOL
)
map.put(
REIFIED_TYPE_FORBIDDEN_SUBSTITUTION,
"Cannot use ''{0}'' as reified type parameter",
@@ -919,6 +937,17 @@ class FirDefaultErrorMessages {
map.put(INLINE_CLASS_CANNOT_IMPLEMENT_INTERFACE_BY_DELEGATION, "Inline class cannot implement an interface by delegation")
map.put(INLINE_CLASS_CANNOT_EXTEND_CLASSES, "Inline class cannot extend classes")
map.put(INLINE_CLASS_CANNOT_BE_RECURSIVE, "Inline class cannot be recursive")
map.put(DECLARATION_CANT_BE_INLINED, "'inline' modifier is not allowed on virtual members. Only private or final members can be inlined")
map.put(OVERRIDE_BY_INLINE, "Override by an inline function")
map.put(REIFIED_TYPE_PARAMETER_IN_OVERRIDE, "Override by a function with reified type parameter")
map.put(INLINE_PROPERTY_WITH_BACKING_FIELD, "Inline property cannot have backing field")
map.put(NON_INTERNAL_PUBLISHED_API, "@PublishedApi annotation is only applicable for internal declaration")
map.put(
INVALID_DEFAULT_FUNCTIONAL_PARAMETER_FOR_INLINE,
"Invalid default value for inline parameter: ''{0}''. Only lambdas, anonymous functions, and callable references are supported",
FIR,
DECLARATION_NAME
)
map.put(RESERVED_MEMBER_INSIDE_INLINE_CLASS, "Member with the name ''{0}'' is reserved for future releases", TO_STRING)
map.put(
SECONDARY_CONSTRUCTOR_WITH_BODY_INSIDE_INLINE_CLASS,
@@ -1253,8 +1282,7 @@ class FirDefaultErrorMessages {
map.put(UNINITIALIZED_ENUM_ENTRY, "Enum entry ''{0}'' is uninitialized here", VARIABLE_NAME)
map.put(UNINITIALIZED_ENUM_COMPANION, "Companion object of enum class ''{0}'' is uninitialized here", SYMBOL)
map.put(VAL_REASSIGNMENT, "Val cannot be reassigned", VARIABLE_NAME)
map.put(VAL_REASSIGNMENT_VIA_BACKING_FIELD, "Reassignment of read-only property via backing field is deprecated", VARIABLE_NAME)
map.put(VAL_REASSIGNMENT_VIA_BACKING_FIELD_ERROR, "Reassignment of read-only property via backing field", VARIABLE_NAME)
map.put(VAL_REASSIGNMENT_VIA_BACKING_FIELD, "Reassignment of read-only property via backing field", VARIABLE_NAME)
map.put(
CAPTURED_VAL_INITIALIZATION,
"Captured values initialization is forbidden due to possible reassignment",
@@ -1279,6 +1307,7 @@ class FirDefaultErrorMessages {
)
map.put(LEAKED_IN_PLACE_LAMBDA, "Leaked in-place lambda: {2}", SYMBOL)
map.put(FirErrors.WRONG_IMPLIES_CONDITION, "Wrong implies condition")
map.put(UNREACHABLE_CODE, "Unreachable code", NOT_RENDERED, NOT_RENDERED)
// Nullability
map.put(
@@ -1378,6 +1407,28 @@ class FirDefaultErrorMessages {
RENDER_TYPE,
RENDER_TYPE,
)
map.put(
UNDERSCORE_IS_RESERVED,
"Names _, __, ___, ..., are reserved in Kotlin"
)
map.put(
UNDERSCORE_USAGE_WITHOUT_BACKTICKS,
"Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)"
)
map.put(
RESOLVED_TO_UNDERSCORE_NAMED_CATCH_PARAMETER,
"Referencing to an underscore-named parameter is deprecated. It will be an error in a future release."
)
map.put(
INVALID_CHARACTERS,
"Name {0}",
STRING
)
map.put(
DANGEROUS_CHARACTERS,
"Name contains characters which can cause problems on Windows: {0}",
STRING
)
map.put(
EQUALITY_NOT_APPLICABLE,
"Operator ''{0}'' cannot be applied to ''{1}'' and ''{2}''",
@@ -1453,8 +1504,32 @@ class FirDefaultErrorMessages {
SYMBOL,
SYMBOL
)
map.put(NOT_YET_SUPPORTED_IN_INLINE, "{0} are not yet supported in inline functions", STRING)
map.put(
NOTHING_TO_INLINE,
"Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types"
)
map.put(
NULLABLE_INLINE_PARAMETER,
"Inline-parameter ''{0}'' of ''{1}'' must not be nullable. Add ''noinline'' modifier to the parameter declaration or make its type not nullable",
SYMBOL,
SYMBOL
)
map.put(SUPER_CALL_FROM_PUBLIC_INLINE, "Accessing super members from public-API inline function is deprecated", SYMBOL)
map.put(ILLEGAL_INLINE_PARAMETER_MODIFIER, "Modifier is allowed only for function parameters of an inline function")
map.put(
INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED,
"Suspend inline lambda parameters of non-suspend function type are not supported. Add 'noinline' or 'crossinline' modifier."
)
map.put(
REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE,
"Redundant 'suspend' modifier: lambda parameters of suspend function type uses existing continuation."
)
//imports
map.put(
CANNOT_ALL_UNDER_IMPORT_FROM_SINGLETON,
@@ -1474,6 +1549,32 @@ class FirDefaultErrorMessages {
)
map.put(OPERATOR_RENAMED_ON_IMPORT, "Operator renamed to a different operator on import")
// Suspend
map.put(
ILLEGAL_SUSPEND_FUNCTION_CALL,
"Suspend function ''{0}'' should be called only from a coroutine or another suspend function",
SYMBOL
)
map.put(
ILLEGAL_SUSPEND_PROPERTY_ACCESS,
"Suspend property ''{0}'' should be accessed only from a coroutine or suspend function",
SYMBOL
)
map.put(NON_LOCAL_SUSPENSION_POINT, "Suspension functions can be called only within coroutine body")
map.put(
ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL,
"Restricted suspending functions can only invoke member or extension suspending functions on their restricted coroutine scope"
)
map.put(
NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND,
"''suspend'' function can only be called in a form of modifier of a lambda: suspend { ... }"
)
map.put(
MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND,
"Calls having a form of ''suspend {}'' are deprecated because ''suspend'' in the context will have a meaning of a modifier. Add empty argument list to the call: ''suspend() { ... }''"
)
map.put(RETURN_FOR_BUILT_IN_SUSPEND, "Using implicit label for this lambda is prohibited")
// Extended checkers group
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
map.put(REDUNDANT_MODALITY_MODIFIER, "Redundant modality modifier")

View File

@@ -2,6 +2,7 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.FirLightSourceElement
import org.jetbrains.kotlin.fir.FirPsiSourceElement
@@ -200,3 +201,41 @@ class FirDiagnosticFactory4<A, B, C, D>(
private fun incorrectElement(element: FirSourceElement): Nothing {
throw IllegalArgumentException("Unknown element type: ${element::class}")
}
// ------------------------------ factories for deprecation ------------------------------
sealed class FirDiagnosticFactoryForDeprecation<F : AbstractFirDiagnosticFactory>(
val deprecatingFeature: LanguageFeature,
val warningFactory: F,
val errorFactory: F
)
class FirDiagnosticFactoryForDeprecation0(
featureForError: LanguageFeature,
warningFactory: FirDiagnosticFactory0,
errorFactory: FirDiagnosticFactory0
) : FirDiagnosticFactoryForDeprecation<FirDiagnosticFactory0>(featureForError, warningFactory, errorFactory)
class FirDiagnosticFactoryForDeprecation1<A>(
featureForError: LanguageFeature,
warningFactory: FirDiagnosticFactory1<A>,
errorFactory: FirDiagnosticFactory1<A>
) : FirDiagnosticFactoryForDeprecation<FirDiagnosticFactory1<A>>(featureForError, warningFactory, errorFactory)
class FirDiagnosticFactoryForDeprecation2<A, B>(
featureForError: LanguageFeature,
warningFactory: FirDiagnosticFactory2<A, B>,
errorFactory: FirDiagnosticFactory2<A, B>
) : FirDiagnosticFactoryForDeprecation<FirDiagnosticFactory2<A, B>>(featureForError, warningFactory, errorFactory)
class FirDiagnosticFactoryForDeprecation3<A, B, C>(
featureForError: LanguageFeature,
warningFactory: FirDiagnosticFactory3<A, B, C>,
errorFactory: FirDiagnosticFactory3<A, B, C>
) : FirDiagnosticFactoryForDeprecation<FirDiagnosticFactory3<A, B, C>>(featureForError, warningFactory, errorFactory)
class FirDiagnosticFactoryForDeprecation4<A, B, C, D>(
featureForError: LanguageFeature,
warningFactory: FirDiagnosticFactory4<A, B, C, D>,
errorFactory: FirDiagnosticFactory4<A, B, C, D>
) : FirDiagnosticFactoryForDeprecation<FirDiagnosticFactory4<A, B, C, D>>(featureForError, warningFactory, errorFactory)

View File

@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.Severity
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KClass
@@ -35,6 +36,12 @@ inline fun <reified P : PsiElement, A, B, C> warning3(
return DiagnosticFactory3DelegateProvider(Severity.WARNING, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A, B, C, D> warning4(
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory4DelegateProvider<A, B, C, D> {
return DiagnosticFactory4DelegateProvider(Severity.WARNING, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement> error0(
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DiagnosticFactory0DelegateProvider {
@@ -65,6 +72,41 @@ inline fun <reified P : PsiElement, A, B, C, D> error4(
return DiagnosticFactory4DelegateProvider(Severity.ERROR, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement> deprecationError0(
featureForError: LanguageFeature,
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DeprecationDiagnosticFactory0DelegateProvider {
return DeprecationDiagnosticFactory0DelegateProvider(featureForError, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A> deprecationError1(
featureForError: LanguageFeature,
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DeprecationDiagnosticFactory1DelegateProvider<A> {
return DeprecationDiagnosticFactory1DelegateProvider(featureForError, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A, B> deprecationError2(
featureForError: LanguageFeature,
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DeprecationDiagnosticFactory2DelegateProvider<A, B> {
return DeprecationDiagnosticFactory2DelegateProvider(featureForError, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A, B, C> deprecationError3(
featureForError: LanguageFeature,
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DeprecationDiagnosticFactory3DelegateProvider<A, B, C> {
return DeprecationDiagnosticFactory3DelegateProvider(featureForError, positioningStrategy, P::class)
}
inline fun <reified P : PsiElement, A, B, C, D> deprecationError4(
featureForError: LanguageFeature,
positioningStrategy: SourceElementPositioningStrategy = SourceElementPositioningStrategy.DEFAULT
): DeprecationDiagnosticFactory4DelegateProvider<A, B, C, D> {
return DeprecationDiagnosticFactory4DelegateProvider(featureForError, positioningStrategy, P::class)
}
// ------------------------------ Providers ------------------------------
class DiagnosticFactory0DelegateProvider(
@@ -117,6 +159,69 @@ class DiagnosticFactory4DelegateProvider<A, B, C, D>(
}
}
private const val WARNING = "_WARNING"
private const val ERROR = "_ERROR"
class DeprecationDiagnosticFactory0DelegateProvider(
private val featureForError: LanguageFeature,
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactoryForDeprecation0> {
val errorFactory = FirDiagnosticFactory0("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = FirDiagnosticFactory0("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(FirDiagnosticFactoryForDeprecation0(featureForError, warningFactory, errorFactory))
}
}
class DeprecationDiagnosticFactory1DelegateProvider<A>(
private val featureForError: LanguageFeature,
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactoryForDeprecation1<A>> {
val errorFactory = FirDiagnosticFactory1<A>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = FirDiagnosticFactory1<A>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(FirDiagnosticFactoryForDeprecation1(featureForError, warningFactory, errorFactory))
}
}
class DeprecationDiagnosticFactory2DelegateProvider<A, B>(
private val featureForError: LanguageFeature,
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactoryForDeprecation2<A, B>> {
val errorFactory = FirDiagnosticFactory2<A, B>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = FirDiagnosticFactory2<A, B>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(FirDiagnosticFactoryForDeprecation2(featureForError, warningFactory, errorFactory))
}
}
class DeprecationDiagnosticFactory3DelegateProvider<A, B, C>(
private val featureForError: LanguageFeature,
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactoryForDeprecation3<A, B, C>> {
val errorFactory = FirDiagnosticFactory3<A, B, C>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = FirDiagnosticFactory3<A, B, C>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(FirDiagnosticFactoryForDeprecation3(featureForError, warningFactory, errorFactory))
}
}
class DeprecationDiagnosticFactory4DelegateProvider<A, B, C, D>(
private val featureForError: LanguageFeature,
private val positioningStrategy: SourceElementPositioningStrategy,
private val psiType: KClass<*>
) {
operator fun provideDelegate(thisRef: Any?, prop: KProperty<*>): ReadOnlyProperty<Any?, FirDiagnosticFactoryForDeprecation4<A, B, C, D>> {
val errorFactory = FirDiagnosticFactory4<A, B, C, D>("${prop.name}$ERROR", Severity.ERROR, positioningStrategy, psiType)
val warningFactory = FirDiagnosticFactory4<A, B, C, D>("${prop.name}$WARNING", Severity.WARNING, positioningStrategy, psiType)
return DummyDelegate(FirDiagnosticFactoryForDeprecation4(featureForError, warningFactory, errorFactory))
}
}
private class DummyDelegate<T>(val value: T) : ReadOnlyProperty<Any?, T> {
override fun getValue(thisRef: Any?, property: KProperty<*>): T {

View File

@@ -54,7 +54,68 @@ class FirDiagnosticFactoryToRendererMap(val name: String) {
put(factory, FirDiagnosticWithParameters4Renderer(message, rendererA, rendererB, rendererC, rendererD))
}
fun put(factory: FirDiagnosticFactoryForDeprecation0, message: String) {
put(factory.errorFactory, SimpleFirDiagnosticRenderer(message))
put(factory.warningFactory, SimpleFirDiagnosticRenderer(factory.warningMessage(message)))
}
fun <A> put(
factory: FirDiagnosticFactoryForDeprecation1<A>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?
) {
put(factory.errorFactory, FirDiagnosticWithParameters1Renderer(message, rendererA))
put(factory.warningFactory, FirDiagnosticWithParameters1Renderer(factory.warningMessage(message), rendererA))
}
fun <A, B> put(
factory: FirDiagnosticFactoryForDeprecation2<A, B>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?
) {
put(factory.errorFactory, FirDiagnosticWithParameters2Renderer(message, rendererA, rendererB))
put(factory.warningFactory, FirDiagnosticWithParameters2Renderer(factory.warningMessage(message), rendererA, rendererB))
}
fun <A, B, C> put(
factory: FirDiagnosticFactoryForDeprecation3<A, B, C>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?,
rendererC: DiagnosticParameterRenderer<C>?
) {
put(factory.errorFactory, FirDiagnosticWithParameters3Renderer(message, rendererA, rendererB, rendererC))
put(factory.warningFactory, FirDiagnosticWithParameters3Renderer(factory.warningMessage(message), rendererA, rendererB, rendererC))
}
fun <A, B, C, D> put(
factory: FirDiagnosticFactoryForDeprecation4<A, B, C, D>,
message: String,
rendererA: DiagnosticParameterRenderer<A>?,
rendererB: DiagnosticParameterRenderer<B>?,
rendererC: DiagnosticParameterRenderer<C>?,
rendererD: DiagnosticParameterRenderer<D>?
) {
put(factory.errorFactory, FirDiagnosticWithParameters4Renderer(message, rendererA, rendererB, rendererC, rendererD))
put(factory.warningFactory, FirDiagnosticWithParameters4Renderer(factory.warningMessage(message), rendererA, rendererB, rendererC, rendererD))
}
private fun put(factory: AbstractFirDiagnosticFactory, renderer: FirDiagnosticRenderer) {
renderersMap[factory] = renderer
}
private fun FirDiagnosticFactoryForDeprecation<*>.warningMessage(errorMessage: String): String {
return buildString {
append(errorMessage)
append(". This will become an error")
val sinceVersion = deprecatingFeature.sinceVersion
if (sinceVersion != null) {
append(" in Kotlin ")
append(sinceVersion.versionString)
} else {
append(" in a future release")
}
}
}
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.diagnostics
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.cfg.UnreachableCode
import org.jetbrains.kotlin.diagnostics.PositioningStrategy
import org.jetbrains.kotlin.fir.FirPsiSourceElement
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.psi.KtElement
abstract class FirPsiPositioningStrategy<in E : PsiElement> : PositioningStrategy<E>(),
FirDiagnosticPositioningStrategy<FirPsiSourceElement>
object FirPsiPositioningStrategies {
val UNREACHABLE_CODE = object : FirPsiPositioningStrategy<PsiElement>() {
override fun markFirDiagnostic(element: FirPsiSourceElement, diagnostic: FirDiagnostic): List<TextRange> {
//todo it is better to implement arguments extraction in FirDiagnosticFactory, but kotlin struggle with checking types in it atm
@Suppress("UNCHECKED_CAST")
val typed = diagnostic as FirDiagnosticWithParameters2<Set<FirSourceElement>, Set<FirSourceElement>>
return UnreachableCode.getUnreachableTextRanges(
element.psi as KtElement,
typed.a.mapNotNull { it.psi as? KtElement }.toSet(),
typed.b.mapNotNull { it.psi as? KtElement }.toSet()
)
}
}
}

View File

@@ -358,6 +358,9 @@ object LightTreePositioningStrategies {
val DATA_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.DATA_KEYWORD))
val INLINE_PARAMETER_MODIFIER: LightTreePositioningStrategy =
ModifierSetBasedLightTreePositioningStrategy(TokenSet.create(KtTokens.NOINLINE_KEYWORD, KtTokens.CROSSINLINE_KEYWORD))
val OPERATOR: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
@@ -708,27 +711,20 @@ object LightTreePositioningStrategies {
}
}
val RESERVED_UNDERSCORE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
val NAME_IDENTIFIER: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
if (node.tokenType == KtNodeTypes.RETURN) {
val parent = tree.getParent(node)
if (parent != null) {
val label = tree.findDescendantByType(parent, KtNodeTypes.LABEL)
if (label != null) {
return markElement(label, startOffset, endOffset - 1, tree, node)
}
}
val nameIdentifier = tree.nameIdentifier(node)
if (nameIdentifier != null) {
return markElement(nameIdentifier, startOffset, endOffset, tree, node)
}
if (node.tokenType == KtNodeTypes.LABEL_QUALIFIER) {
return super.mark(node, startOffset, endOffset - 1, tree)
}
val descendants =
tree.collectDescendantsOfType(node, KtTokens.IDENTIFIER) { descendant -> descendant.toString().all { it == '_' } }
if (descendants.isNotEmpty())
return descendants.map { markSingleElement(it, it, startOffset, endOffset, tree, node) }
return super.mark(node, startOffset, endOffset, tree)
}
}
@@ -840,6 +836,53 @@ object LightTreePositioningStrategies {
private fun lastSymbol(range: TextRange): TextRange =
if (range.isEmpty) range else TextRange.create(range.endOffset - 1, range.endOffset)
}
val UNREACHABLE_CODE: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun markFirDiagnostic(element: FirSourceElement, diagnostic: FirDiagnostic): List<TextRange> {
@Suppress("UNCHECKED_CAST")
val typed = diagnostic as FirDiagnosticWithParameters2<Set<FirSourceElement>, Set<FirSourceElement>>
with(UnreachableCodeLightTreeHelper(element.treeStructure)) {
val reachable = typed.a.map { it.lighterASTNode }.toSet()
val unreachable = typed.b.map { it.lighterASTNode }.toSet()
if (!element.lighterASTNode.hasChildrenInSet(reachable)) {
return super.markFirDiagnostic(element, diagnostic)
}
val nodesToMark = element.lighterASTNode.getLeavesOrReachableChildren(reachable, unreachable)
.removeReachableElementsWithMeaninglessSiblings(reachable)
if (nodesToMark.isEmpty()) {
return super.markFirDiagnostic(element, diagnostic)
}
val ranges = nodesToMark.flatMap {
markElement(it, element.startOffset, element.endOffset, element.treeStructure, element.lighterASTNode)
}
return ranges.mergeAdjacentTextRanges()
}
}
}
val NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT: LightTreePositioningStrategy = object : LightTreePositioningStrategy() {
override fun mark(
node: LighterASTNode,
startOffset: Int,
endOffset: Int,
tree: FlyweightCapableTreeStructure<LighterASTNode>
): List<TextRange> {
val nodeToMark = when (node.tokenType) {
KtNodeTypes.CLASS ->
tree.findChildByType(node, KtTokens.CLASS_KEYWORD)
KtNodeTypes.OBJECT_DECLARATION ->
tree.findChildByType(node, KtTokens.OBJECT_KEYWORD)
KtNodeTypes.FUN ->
tree.inlineModifier(node) ?: tree.findChildByType(node, KtTokens.FUN_KEYWORD)
else -> node
}
return markElement(nodeToMark ?: node, startOffset, endOffset, tree, node)
}
}
}
fun FirSourceElement.hasValOrVar(): Boolean =
@@ -962,6 +1005,9 @@ internal fun FlyweightCapableTreeStructure<LighterASTNode>.modalityModifier(decl
internal fun FlyweightCapableTreeStructure<LighterASTNode>.overrideModifier(declaration: LighterASTNode): LighterASTNode? =
modifierList(declaration)?.let { findChildByType(it, KtTokens.OVERRIDE_KEYWORD) }
internal fun FlyweightCapableTreeStructure<LighterASTNode>.inlineModifier(declaration: LighterASTNode): LighterASTNode? =
modifierList(declaration)?.let { findChildByType(it, KtTokens.INLINE_KEYWORD) }
internal fun FlyweightCapableTreeStructure<LighterASTNode>.typeParametersList(declaration: LighterASTNode): LighterASTNode? =
findChildByType(declaration, KtNodeTypes.TYPE_PARAMETER_LIST)
@@ -1107,6 +1153,29 @@ fun FlyweightCapableTreeStructure<LighterASTNode>.collectDescendantsOfType(
return result
}
fun FlyweightCapableTreeStructure<LighterASTNode>.traverseDescendants(
node: LighterASTNode,
acceptor: (LighterASTNode) -> Boolean
) {
fun FlyweightCapableTreeStructure<LighterASTNode>.traverse(node: LighterASTNode) {
val childrenRef = Ref<Array<LighterASTNode?>>()
getChildren(node, childrenRef)
val childrenRefGet = childrenRef.get()
if (childrenRefGet != null) {
for (child in childrenRefGet) {
if (child != null) {
if (acceptor(child)) {
traverse(child)
}
}
}
}
}
traverse(node)
}
fun FlyweightCapableTreeStructure<LighterASTNode>.findChildByType(node: LighterASTNode, type: TokenSet): LighterASTNode? {
val childrenRef = Ref<Array<LighterASTNode?>>()
getChildren(node, childrenRef)

View File

@@ -10,12 +10,22 @@ import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.TextRange
import com.intellij.psi.TokenType
import com.intellij.util.diff.FlyweightCapableTreeStructure
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.getChildren
import org.jetbrains.kotlin.lexer.KtSingleValueToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.lexer.KtTokens.WHITE_SPACE
open class LightTreePositioningStrategy {
interface FirDiagnosticPositioningStrategy<E : FirSourceElement> {
fun markFirDiagnostic(element: E, diagnostic: FirDiagnostic): List<TextRange>
}
open class LightTreePositioningStrategy : FirDiagnosticPositioningStrategy<FirSourceElement> {
override fun markFirDiagnostic(element: FirSourceElement, diagnostic: FirDiagnostic): List<TextRange> {
return mark(element.lighterASTNode, element.startOffset, element.endOffset, element.treeStructure)
}
open fun mark(
node: LighterASTNode,
startOffset: Int,
@@ -78,11 +88,12 @@ private val FILLER_TOKENS = setOf(
)
private fun LighterASTNode.nonFillerFirstChildOrSelf(tree: FlyweightCapableTreeStructure<LighterASTNode>): LighterASTNode =
getChildren(tree).firstOrNull { it != null && it.tokenType !in FILLER_TOKENS } ?: this
getChildren(tree).firstOrNull { it != null && !it.isFiller() } ?: this
internal fun LighterASTNode.nonFillerLastChildOrSelf(tree: FlyweightCapableTreeStructure<LighterASTNode>): LighterASTNode =
getChildren(tree).lastOrNull { it != null && it.tokenType !in FILLER_TOKENS } ?: this
getChildren(tree).lastOrNull { it != null && !it.isFiller() } ?: this
internal fun LighterASTNode.isFiller() = tokenType in FILLER_TOKENS
private fun hasSyntaxErrors(node: LighterASTNode, tree: FlyweightCapableTreeStructure<LighterASTNode>): Boolean {
if (node.tokenType == TokenType.ERROR_ELEMENT) return true

View File

@@ -238,9 +238,9 @@ object SourceElementPositioningStrategies {
PositioningStrategies.TYPE_PARAMETERS_LIST
)
val RESERVED_UNDERSCORE = SourceElementPositioningStrategy(
LightTreePositioningStrategies.RESERVED_UNDERSCORE,
PositioningStrategies.RESERVED_UNDERSCORE
val NAME_IDENTIFIER = SourceElementPositioningStrategy(
LightTreePositioningStrategies.NAME_IDENTIFIER,
PositioningStrategies.NAME_IDENTIFIER
)
val QUESTION_MARK_BY_TYPE = SourceElementPositioningStrategy(
@@ -273,7 +273,22 @@ object SourceElementPositioningStrategies {
PositioningStrategies.DECLARATION_WITH_BODY
)
val UNREACHABLE_CODE = SourceElementPositioningStrategy(
LightTreePositioningStrategies.UNREACHABLE_CODE,
FirPsiPositioningStrategies.UNREACHABLE_CODE
)
// TODO
val ACTUAL_DECLARATION_NAME = DEFAULT
val INCOMPATIBLE_DECLARATION = DEFAULT
val NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT = SourceElementPositioningStrategy(
LightTreePositioningStrategies.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT,
PositioningStrategies.NOT_SUPPORTED_IN_INLINE_MOST_RELEVANT
)
val INLINE_PARAMETER_MODIFIER = SourceElementPositioningStrategy(
LightTreePositioningStrategies.INLINE_PARAMETER_MODIFIER,
PositioningStrategies.INLINE_PARAMETER_MODIFIER
)
}

View File

@@ -18,10 +18,14 @@ class SourceElementPositioningStrategy(
fun markDiagnostic(diagnostic: FirDiagnostic): List<TextRange> {
val element = diagnostic.element
if (element is FirPsiSourceElement) {
@Suppress("UNCHECKED_CAST")
return psiStrategy.hackyMark(element.psi)
return if (psiStrategy is FirPsiPositioningStrategy<*>) {
psiStrategy.markFirDiagnostic(element, diagnostic)
} else {
@Suppress("UNCHECKED_CAST")
psiStrategy.hackyMark(element.psi)
}
}
return lightTreeStrategy.mark(element.lighterASTNode, element.startOffset, element.endOffset, element.treeStructure)
return lightTreeStrategy.markFirDiagnostic(element, diagnostic)
}
fun isValid(element: FirSourceElement): Boolean {

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