Compare commits

..

412 Commits

Author SHA1 Message Date
Dmitry Petrov
e80744ee08 JVM_IR KT-47984 minor fixes after review 2021-08-12 13:21:13 +03:00
Dmitry Petrov
a691ddc477 JVM_IR KT-47984 minor avoid using @Deprecated function in tests 2021-08-12 12:58:50 +03:00
Dmitry Petrov
99cdb7a9cc JVM_IR KT-47984 allow only limited list of GETSTATICs in arg loading 2021-08-12 12:58:50 +03:00
Dmitry Petrov
9f9b5174cd JVM_IR KT-47984 minor drop unneeded caching 2021-08-12 12:58:50 +03:00
Dmitry Petrov
27edf2f294 JVM_IR KT-47984 add test for argument reordering 2021-08-12 12:58:50 +03:00
Dmitry Petrov
77c1dd2ddf JVM_IR KT-47984 use stack size calculator from ASM 2021-08-12 12:58:50 +03:00
Dmitry Petrov
3119e04bf8 JVM_IR KT-47984 transform inplace arguments before inlining 2021-08-12 12:58:50 +03:00
Dmitry Petrov
567e6a21ab JVM_IR KT-47984 allow noinline functional inplace args 2021-08-12 12:58:49 +03:00
Dmitry Petrov
a447a7188f JVM_IR KT-47984 don't move inplace arguments with suspension points 2021-08-12 12:58:49 +03:00
Dmitry Petrov
6e6d6fec21 JVM_IR KT-47984 minor cleanup 2021-08-12 12:58:49 +03:00
Dmitry Petrov
b2d271a3ac JVM_IR KT-47984 update LVT entries for transformed instructions 2021-08-12 12:58:48 +03:00
Dmitry Petrov
8d8c4416b2 JVM_IR KT-47984 don't transform calls with non-local jumps in arguments 2021-08-12 12:58:48 +03:00
Dmitry Petrov
1d2599767f JVM_IR KT-47984 inplace arguments inlining for @InlineOnly functions 2021-08-12 12:58:48 +03:00
Dmitry Petrov
64de6cb305 JVM_IR minor cleanup in inliner 2021-08-12 12:58:48 +03:00
Yahor Berdnikau
3acb96e474 Allow running KotlinJavaToolchainTest on any user JDK. 2021-08-12 10:00:23 +02:00
Bingran
c57302abba Only check ExternalDependency when customizing kotlin dependencies
This commit fixes the issue where kgp checks group/version of project
dependencies which is uncompatible with project isolation. With this
change, kgp will only check ExternalDependency which should be enough
for setting up kotlin dependencies.

This change also changes the way we apply cache redirector gradle
files to all projects when setting up test projects. To make it
compatible with project isolation, we should move away from using
project.getAllProjects() function.

^KT-47792 Fixed
Test: existing + SimpleKotlinGradleIT.testProjectIsolation
2021-08-12 09:51:20 +02:00
Andrey Zinovyev
1338675833 [FIR] Fix while's label, when condition has lambda
#KT-48116 Fixed
2021-08-12 10:20:45 +03:00
Alexander Shabalin
06001fc091 [K/N] Tweak fronted warning messages for the new MM 2021-08-11 20:06:19 +00:00
Andrey Zinovyev
d3905fd763 Add dist dependency for tests
Because some tests require stdlib
2021-08-11 21:57:16 +03:00
Andrey Zinovyev
3ec9599bc4 [FIR][CFG] Partial support of postponed Nothing calls
In try blocks, last call won't be completed when building node for it
This is workaround to partially reconstruct nothing stub node for such
calls. Should work for non-local returns in try only.
#KT-48160 Fixed
2021-08-11 21:57:14 +03:00
Ivan Kochurkin
445e5122c1 [FIR] Fix conversion of underscored value parameters in functions
Fix false REDECLARATION
2021-08-11 21:52:46 +03:00
Ilya Kirillov
ebe96ec79a FIR IDE: fix reference resolve with invalid number of type args 2021-08-11 18:09:05 +02:00
Ilya Kirillov
a8f7bf5fbc HL API: cleanup reference resolve testdata 2021-08-11 18:09:05 +02:00
Ilya Kirillov
2e3b576342 FIR IDE: change destructing declaration reference behaviour to match FE1.0 plugin behaviour 2021-08-11 18:09:05 +02:00
Pavel Punegov
aef45f0997 [Native] Exclude on wasm initializers tests.
Tests use exceptions and workers that are not supported in wasm
2021-08-11 13:56:48 +00:00
Pavel Punegov
d7f5015faa [Native] wasm: use JS pow method
Replace usage of C pow() function with JS to fix the issue
with stack overflow caused by invocation of missing pow function
2021-08-11 13:56:47 +00:00
Pavel Punegov
cd487efbe9 [Native][test] Exclude FP parsing tests that require exceptions on WASM 2021-08-11 13:56:47 +00:00
pyos
623b289616 Regenerate foreign annotation test data for FIR 2021-08-11 15:58:02 +03:00
pyos
58110709f3 Get rid of lambdas in AbstractForeignAnnotationsTestBase
Also enable the features from the previous two commits
2021-08-11 15:58:01 +03:00
pyos
28c473074c Permit overriding the FIR test in FirTestDataConsistencyHandler 2021-08-11 15:58:01 +03:00
pyos
cd26ef2bb5 Add FIR version of JspecifyDiagnosticComplianceHandler 2021-08-11 15:58:01 +03:00
Mads Ager
608b88996a [JVM_IR] Fix inlining of callable references to extension methods.
Check directly that the referenced function is an extension
function instead of relying on the annotation on the type.

^ KT-47988 Fixed.
2021-08-11 13:29:11 +02:00
Mikhael Bogdanov
1760befa37 [KAPT] Add experimental JDK 17 support
#KT-47583 Fixed
2021-08-11 10:05:24 +02:00
Igor Chevdar
81ce59cf48 [K/N][IR][codegen] Implemented eager initialization
Properties marked with @EagerInitialization will be initialized at program/worker start
even in lazy initialization mode
2021-08-11 11:53:19 +05:00
Sergey Bogolepov
e159392d22 [K/N] Enable caches for iosArm64 and linuxX64 by default 2021-08-11 06:38:59 +00:00
Nikita Bobko
5455800de4 [imltogradle] Exclude 'kotlin.util.compiler-dependencies' module from generation
This module is used as helper module in JPS project module to make sure that IDEA will download
all required dependencies. There are some dependencies which IDEA cannot determine as used so
we force it to download them (kotlinc.kotlin-dist, kotlinc.kotlin-compiler-testdata)

We don't need this module in Gradle project model

This commit fixes:
```
Could not resolve project :prepare:ide-plugin-dependencies:kotlin-compiler-testdata-for-ide.
Required by:
    project :kotlin-ide.kotlin.util.compiler-dependencies
```
2021-08-11 02:17:52 +02:00
Nikita Bobko
747cc7d55d [imltogradle] Fix other kotlinc libraries which don't follow kotlinc.* naming
e.g. kotlin-reflect
2021-08-11 02:17:51 +02:00
Nikita Bobko
784273ac5b [imltogradle] Add additional check for absence of snapshot version in JpsLikeJarDependency 2021-08-11 02:17:51 +02:00
Nikita Bobko
493fdbd418 Fix kotlin stdlib handling for 212 IDEA in ide-iml-to-gradle-generator 2021-08-11 02:17:51 +02:00
Nikita Bobko
8ad368e990 Update verification-metadata.xml with 212.4746.92 artifacts 2021-08-11 02:17:50 +02:00
Ilya Goncharov
40d19b50c5 [Gradle, JS] Use Gradle's hashers 2021-08-10 18:45:09 +00:00
Ilya Goncharov
bfcd954dd3 [Gradle, JS] Add test on not updating Node.JS if it was downloaded
^KT-47845 fixed
2021-08-10 18:45:09 +00:00
Ilya Goncharov
b8330deefa [Gradle, JS] Consider potential hash of nodejs and yarn
^KT-47845 fixed
2021-08-10 18:45:08 +00:00
Ilya Goncharov
5ec19c2417 [Gradle, JS] Up-to-date checks for Node js and yarn
^KT-47845 fixed
2021-08-10 18:45:08 +00:00
Ilya Kirillov
1a1f6b0c0b Regenerate FirIdeSpecTest 2021-08-10 20:06:36 +02:00
Ilya Kirillov
017448e359 FIR IDE: make KtExpression.getKtType() to return null for non-expressions 2021-08-10 18:58:06 +02:00
Roman Artemev
d3ddeef67f [JS IR] Wrap private top level function with internal accessor stub
In case internal inline function references private top level function
after inline such function (T.L.P.) couldn't be referenced
in klib and IC cache. So create internally visible accessors for P.T.L.
function similar to what JVM backend does.

 - add box test
2021-08-10 19:52:08 +03:00
Roman Artemev
b3dbca7ea6 [JS IC] Fix test runner 2021-08-10 19:52:07 +03:00
Tianyu Geng
06ee84f809 FIR checker: report AMBIGUOUS_SUPER 2021-08-10 19:36:44 +03:00
Ivan Kochurkin
5b9ce7e823 [FIR] Use typeArgumentsList from delegatedTypeRef instead of accessing via tree 2021-08-10 19:36:43 +03:00
Tianyu Geng
280c445783 FIR checker: check super reference
This change touches the following diagnostics to make them behave closer
to FE1.0

* SUPER_NOT_AVAILABLE
* SUPER_IS_NOT_AN_EXPRESSION
* INSTANCE_ACCESS_BEFORE_SUPER_CALL
* NOT_A_SUPERTYPE

Other than tweaking the diagnostics, this change also alters resolution
by consider marking `super` with mismatched type parameter as
errorenous. As a result, the following code no longer resolves.

```
class A: B() {
  fun test() {
    super<String>.length
    //            ^^^^^^ FIR currently resolves this to `String.length`.
    //                   With this change, `length` becomes unresolved
    //                   instead
  }
}
```

Also, now we report `UNRESOLVED_LABEL` on unresolved label on `super`
reference, though FE1.0 reports `UNRESOLVED_REFERENCE`.

All the errors above are reported as ConeDiagnostics and hence some
checkers are deleted.

In addition, it also suppresses more downstream (mostly unresolved)
errors if the receiver has errors. FE1.0 doesn't do it for all the cases
we have here. But it seems nicer to reduce these "redundant" unresolved
errors.
2021-08-10 19:36:43 +03:00
Tianyu Geng
bcf6202863 FIR checker: fix position strategy for UNRESOLVED_LABEL 2021-08-10 19:36:04 +03:00
Tianyu Geng
45d31fdba2 FIR: fix atomic qualified acess sharing the same PSI with callee ref
Consider an atomic reference `i`, it's FIR representation is

- FirQualifiedAccessExpression
  - calleeReference : FirNamedReference

Currently, both of the above FIR elements uses the same PSI element as
the source. Such problems are not present with `this` or `super` because
we manually mark them as `ExplicitThisOrSuperReference`.

This change generalizes the previous `ExplicitThisOrSuperReference` as
`ReferenceInAtomicQualifiedAccess` and fixes it for more cases.
2021-08-10 19:35:19 +03:00
Alexander Udalov
3bc0eaff59 Fix warnings in stdlib samples and test modules 2021-08-10 17:57:50 +02:00
Alexander Udalov
0d1380c232 Fix warnings in generator modules 2021-08-10 17:57:50 +02:00
Ivan Kochurkin
2ca3adbcb2 [FIR] Throw REDECLARATION for duplicated type parameters in declarations 2021-08-10 15:09:27 +00:00
Ivan Kochurkin
c19598c2fc [FIR] Throw REDECLARATION for duplicated enum entries 2021-08-10 15:09:26 +00:00
Ivan Kochurkin
9736cc162b [FIR] Throw REDECLARATION for duplicated value parameters in function
Add new test file
2021-08-10 15:09:26 +00:00
Ivan Kochurkin
fd92b851a2 [FIR] Implement PACKAGE_OR_CLASSIFIER_REDECLARATION
Fix REDECLARATION positioning
2021-08-10 15:09:25 +00:00
Nikolay Krasko
1c678be0d3 Drop 202 bunch support 2021-08-10 15:25:46 +03:00
Dmitriy Dolovov
cfc4e715e4 [IR] Tests for IR linking error reporting
^KT-44626
2021-08-10 14:02:45 +03:00
Dmitriy Dolovov
c1fb40a436 [IR] Enhance error reporting for IR linking issues
^KT-44626

Typical use case:
- There are two KLIB libraries: A and B.
- Library A has two versions: A.v1 (older) and A.v2 (newer).
- A.v2 is ABI-incompatible with A.v1.
- B depends on A and was compiled against A.v1.
- An attempt to build the application with A.v2 and B fails with weird error message. It's unclear for end user what's wrong and what needs to be done to fix the issue.

The fix improves error reporting for the following particular cases:
- A symbol that is gone (KT-41378)
- A class that became a typealias (KT-47285, KT-46697)
- A typealias that became a class (KT-46340)
2021-08-10 14:02:40 +03:00
Dmitriy Dolovov
672b972b38 [Native] Add '-Xexternal-dependencies' CLI parameter to pass external deps
^KT-44626
2021-08-10 14:02:35 +03:00
Dmitriy Dolovov
ac387b1f26 [Gradle, Native] Pass external dependencies to Kotlin/Native link tasks
^KT-44626
2021-08-10 14:02:27 +03:00
Mikhail Glukhikh
2c31d2e67d FirTestDataConsistencyHandler: return back FIR files auto-generation 2021-08-10 13:19:28 +03:00
Mikhail Glukhikh
8c51c3c5c3 FirTestDataConsistencyHandler: fix behavior on Windows (partial revert) 2021-08-10 13:19:27 +03:00
Mikhail Glukhikh
512a851c65 Minor fix of test data for consistency with FIR 2021-08-10 13:19:26 +03:00
Mikhail Glukhikh
85a2a3255d Add new SENSELESS_COMPARISON in FIR foreign annotation tests 2021-08-10 13:19:26 +03:00
pyos
cdc0f36859 Permit silencing FIR tests with results depending on configuration 2021-08-10 13:19:25 +03:00
pyos
33251f6d50 Generate foreign annotation test data for FIR 2021-08-10 13:19:23 +03:00
pyos
5873511f64 Generalize AbstractForeignAnnotationsTestBase to FIR 2021-08-10 13:19:22 +03:00
pyos
e2e0358505 Remove "FIR" foreign annotation tests
They do not actually use FIR.
2021-08-10 13:19:21 +03:00
Tianyu Geng
1607a8231a FIR checker: ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS 2021-08-10 13:02:10 +03:00
Tianyu Geng
927723c766 FIR checker: fix JAVA_TYPE_MISMATCH checker
First, the order of arguments is swapped.
Second, projection erasure for argType was too aggressive. We should
instead retain the projections that are under an invariant position.
2021-08-10 13:00:18 +03:00
Tianyu Geng
cc531149e5 Ignore kotlin-ide directory 2021-08-10 13:00:14 +03:00
Hung Nguyen
eb94167ff2 Move RuntimeModuleData from :core:descriptors.runtime to :core:descriptors.jvm
We are working on a feature in the Kotlin Gradle plugin called
`kotlin.incremental.useClasspathSnapshot` to improve incremental
Kotlin compilation.

To allow reuse when writing this feature, this commit moves most of the
code in RuntimeModuleData (in the ':core:descriptors.runtime' project)
to DeserializationComponentsForJava (in the ':core:descriptors.jvm'
project), so that the API can be accessed from the
':kotlin-gradle-plugin' and ':kotlin-build-common' projects where the
feature is written.

Bug: KT-45777
Test: Existing tests should pass (this is a refactoring-only change)
2021-08-10 12:29:45 +03:00
Hung Nguyen
170184dce4 KT-45777: Refactor RuntimeModuleData to support classpath snapshotting
We are working on a feature in the Kotlin Gradle plugin called
`kotlin.incremental.useClasspathSnapshot` to improve incremental
Kotlin compilation.

In this feature, we need to extract ABI information from a .class file.
If the .class file is a Kotlin class, this info can be found in the
class header data. But if the .class file is a Java class, this info is
not readily available.

The RuntimeModuleData class in the ':core:descriptors.runtime' project
can help with that: It uses reflection to generate `ClassDescriptor`s.

However, reflection requires a full classpath to work correctly, whereas
we want to generate a `ClassDescriptor` directly for each class file
(also, reflection is probably slow).

To address that, this commit refactors RuntimeModuleData so that it can
support a generic Kotlin/JavaClassFinder, which can be based on either
reflection or bytecode analysis. The existing code continues to use
reflection while the new feature will use bytecode analysis (e.g., using
the existing BinaryJavaClass).

Bug: KT-45777
Test: Existing tests should pass (this is a refactoring-only change)
2021-08-10 12:29:44 +03:00
Hung Nguyen
206457d9ff KT-45777: Take snapshots and compute changes for Kotlin classes
Reuse the existing IncrementalJvmCache to take snapshots and compute
changes for Kotlin classes.

Java classes will be handled next.

Bug: KT-45777
Test: New ClasspathSnapshotterTest, ClasspathChangesComputerTest
2021-08-10 12:22:58 +03:00
Alexander Shabalin
7e04bb4bf1 [K/N] Refactor unhandled exception handling API
* Do not reset unhandled exception hook
* Add processUnhandledException to perform default unhandled exception
  processing
* Add terminateWithUnhandledException to report the unhandled exception
  and terminate the program
* Use the default unhandled exception processing in entrypoint, interop
  boundaries and in Worker.executeAfter
* Add -Xworker-exception-handling to control exception processing of
  Worker.executeAfter. By default its the old behaviour with the old MM,
  and new behaviour with the new MM.
2021-08-10 08:22:55 +00:00
Ilya Goncharov
766857881a [JS IR] Review remarks
- Use intrinsic on this
- Enqueue invoke for DCE
- Change transform
- Ignore instead of target backend

^KT-46204 fixed
2021-08-10 07:24:51 +00:00
Ilya Goncharov
2f0f88062a [JS IR] Change global map in context to mapping
^KT-46204 fixed
2021-08-10 07:24:50 +00:00
Ilya Goncharov
a28138eb72 [JS IR] Change js function on Kotlin code
^KT-46204 fixed
2021-08-10 07:24:49 +00:00
Ilya Goncharov
b6c3132614 [JS IR] Ignore test for legacy backend
^KT-46204 fixed
2021-08-10 07:24:49 +00:00
Ilya Goncharov
627af332b1 [JS IR] Use PublishedApi for intrinsic
^KT-46204 fixed
2021-08-10 07:24:48 +00:00
Ilya Goncharov
e6af3ff6a8 [JS IR] Rename and doc new intrinsics, add new intrinsic to call suspend fun as supertype
^KT-46204 fixed
2021-08-10 07:24:48 +00:00
Ilya Goncharov
a70fc99130 [JS IR] Add intrinsic to call suspend functions as super type
^KT-46204 fixed
2021-08-10 07:24:47 +00:00
Ilya Goncharov
22d202e657 [JS IR] Add test on type check of suspend functional interfaces
^KT-46204 fixed
2021-08-10 07:24:47 +00:00
Ilya Goncharov
755f847ab9 [JS IR] Use invoke for coroutines in runtime
^KT-46204 fixed
2021-08-10 07:24:46 +00:00
Ilya Goncharov
3c9dcdbbee [JS IR] Generate suspend function as invoke
[JS IR] Fix type check utils to work with array of arities

[JS IR] Store multiple arities for suspend functional interface implementers

^KT-46204 fixed
2021-08-10 07:24:46 +00:00
Ilya Goncharov
8a812996dd [Frontend, JS] Not report error in for inheritance suspend function interface
^KT-46204 fixed
2021-08-10 07:24:45 +00:00
Georgy Bronnikov
1d913a6bf0 JVM_IR: add test for serialization of raw types 2021-08-10 00:37:46 +03:00
Georgy Bronnikov
3b8cb4b00d ModuleTransformerForTwoFilesBoxTests -> SplittingModuleTransformerForBoxTests
Need to include Java files in IR serialization tests, so generalize
TwoFilesBoxTest for more than two files.
2021-08-10 00:37:44 +03:00
Georgy Bronnikov
13cf9329b2 IR: always serialize constant initializers for fields. 2021-08-10 00:37:42 +03:00
Georgy Bronnikov
7e71bd8f1c Add module dependency to fir/checkers/checkers-component-generator
This is a transitive dependency needed when bootstrapping in
-Xserialize-ir mode.
2021-08-10 00:37:41 +03:00
Georgy Bronnikov
307de0be89 IR: always update deserializedSymbols in referenceLocalIrSymbol
The symbol created in deserializeIrSymbolToDeclare might be discarded
when an existing declaration is used in deserialization (as it happens
when deserializing IR bodies for JVM declarations).
2021-08-10 00:37:37 +03:00
Georgy Bronnikov
eccbf38061 IR: use existing type parameters when deserializing IR 2021-08-10 00:37:36 +03:00
Georgy Bronnikov
fb801bdc33 IR: fix mangling of toplevel properties 2021-08-10 00:37:36 +03:00
Georgy Bronnikov
54957ead5c JVM_IR: add test for signatures of flexible types 2021-08-10 00:37:27 +03:00
Georgy Bronnikov
1d2d1f9e8d IR: change mangling for flexible types in DescriptorMangleComputer
This reverts commit 4af2aaedb1.
2021-08-10 00:37:24 +03:00
Alexander Udalov
afacff326d JVM IR: fix smart cast on argument of 'throw'
#KT-48163 Fixed
2021-08-09 22:34:44 +02:00
Ilya Kirillov
cb37a05b79 Restore LC compiler testdata 2021-08-09 20:29:22 +02:00
Jinseong Jeon
e64f7ffb98 FIR LC: populate ctor in anonymous objects
Note that enum entries are modeled as anonymous objects in FIR too.
2021-08-09 20:29:20 +02:00
Jinseong Jeon
75c76e2b57 FIR IDE: resolve implicit ctor delegation calls 2021-08-09 20:29:19 +02:00
Jinseong Jeon
f7f51cf38e FIR IDE: allow implicit ctor call for psi retrieval 2021-08-09 20:29:19 +02:00
Jinseong Jeon
4396482fed FIR IDE: fix nullability of KtType variants 2021-08-09 20:29:19 +02:00
Jinseong Jeon
46a0c4be4b FIR LC: populate property from primary ctor later 2021-08-09 20:29:18 +02:00
Jinseong Jeon
fba480875f FIR LC: populate constructors after member methods 2021-08-09 20:29:18 +02:00
Jinseong Jeon
edc134ef2d FIR IDE: drop stale test results in kt files 2021-08-09 20:29:17 +02:00
Jinseong Jeon
ba8f2e6bf3 FIR LC: introduce FirLightParameterList
LightParameterListBuilder, as a subtype of PsiParameterList, is good
enough for LightMethod's parameter list abstraction. However, it does
not have a parent link, which bothers upward conversion in UAST
(a.k.a. convertParent APIs). So we need an abstraction similar to
KtLightParameterList (in FE 1.0 LC).
2021-08-09 20:29:17 +02:00
Ivan Kochurkin
c1afb6354b [FIR] Restore UPPER_BOUND_VIOLATED and TYPE_VARIANCE_CONFLICT as errors, fix TestStep.kt 2021-08-09 18:19:58 +03:00
Viacheslav Kormushkin
d670743a2f Cocoapods plugin: error reporting in case CocoaPods is not installed on users machine
#KT-47362
2021-08-09 12:54:29 +00:00
Andrey Zinovyev
1b81018b69 [FIR] Fix overloading of renamed jvm methods
#KT-48102 Fixed
2021-08-09 15:22:06 +03:00
Tianyu Geng
cd99c35649 FIR: instantiate type argument to captured type if needed 2021-08-09 14:38:30 +03:00
Tianyu Geng
bcf6582af7 FIR checker: make TypeApproximatorConfiguration.capturedType consistent with others 2021-08-09 14:38:30 +03:00
Tianyu Geng
758859f198 FIR checker: report JAVA_TYPE_MISMATCH 2021-08-09 14:38:29 +03:00
sebastian.sellmair
eec5f99e35 [Gradle] Support 'KONAN_DATA_DIR' in Commonizer tests 2021-08-09 09:48:44 +00:00
sebastian.sellmair
552a012e65 [Gradle] Add missing mavenCentral repository to test projects 2021-08-09 09:48:44 +00:00
sebastian.sellmair
3625c953ae [Gradle] CInteropCommonizerDependent: Implement 'fromAssociateCompilations'
This additional API and changes in CInteropCommonizerDependencies.kt
will make sure, that test source sets will still receive commonization
results, even when the exact targets are not requested by
any of the main source sets.

^KT-48138 Verification Pending
2021-08-09 09:48:43 +00:00
sebastian.sellmair
9a39b1f4d1 [Gradle] Implement integration test to cover ^KT-48138 2021-08-09 09:48:43 +00:00
sebastian.sellmair
c07dcb27df [Gradle] CommonizerIT: Add assertion on commonMain when jvm target is present 2021-08-09 09:48:42 +00:00
sebastian.sellmair
5485a6d6cd [Gradle] CInteropCommonizerDependent: Drop bad condition on compilations
The dropped condition is bad, since source sets like 'commonMain'
might still participate in a 'compileKotlinMetadata' task,
which is not a shared native compilation.

It is absolutely okay to just rely on the return of
'getCommonizerTarget': If a shared commonizer target is returned,
then the source set is guaranteed to be a shared native source set.

^KT-48118 Verification Pending
2021-08-09 09:48:42 +00:00
sebastian.sellmair
b1c5c10233 [Gradle] Implement test KT-48118 c-interops available in commonMain
Integration Test project was taken from:
https://github.com/4qa/kotlin-multiplatform-issues/tree/cinterop-common

The issue seems to be twofold:
1) The old `compileKotlinMetadata` task is still found, even
when compatibilityMetadataVariant is disabled

2) The shared native compilation for commonMain can't be found, because
it is not listing its default source set:
(see: https://youtrack.jetbrains.com/issue/KT-45412)

Covers ^KT-48118
2021-08-09 09:48:42 +00:00
Mikhail Glukhikh
37d25a58e8 Fix .gitignore (intellij directory) 2021-08-09 10:00:24 +03:00
Ilya Matveev
6c7f04ffc6 [K/N][tests] Fix disabling stress_gc_allocations for No-op GC 2021-08-07 06:28:50 +00:00
Nikita Bobko
a97b4ea4ae Fix UnsupportedClassVersionError when running ./gradlew generateIdePluginGradleFiles
This commit fixes:
```
Exception in thread "main" java.lang.UnsupportedClassVersionError: com/intellij/jps/impl/JpsIdePluginManagerImpl has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
```
2021-08-07 00:07:30 +03:00
Nikita Bobko
dac4fe7507 Adapt coop-dev for 212 platform 2021-08-07 00:07:28 +03:00
Alexander Dudinsky
3d81eba32b New HMPP import and highlighting tests
New tests `testHmppLibAndConsumer` and `testMultiModulesHmpp` were added
The first is a test with MPP library and its consumers, it checks import
and also highlighting before and after the library was published
The second is a project which contains three multiplatform modules and
two platform modules and checks import and highlighting.

Original commit: 15582b0353
2021-08-07 00:07:27 +03:00
Alexander Udalov
bc5a79ffcc Minor, add test on repeatable annotations on property getters
#KT-14392
 #KT-36476
2021-08-06 22:47:44 +02:00
Alexander Udalov
209c0fe819 Revert "[Test] Temporary mute some tests because of problems with RepeatedAnnotationLowering"
This reverts commit 3a210f6c81.
2021-08-06 22:47:44 +02:00
Alexander Udalov
f8af127a4e Do not load Java @Repeatable for Kotlin-repeatable annotations
#KT-48131 Fixed
2021-08-06 22:47:36 +02:00
Alexander Udalov
89b3013294 Build: enable Werror for all compileJava tasks 2021-08-06 22:37:00 +02:00
Alexander Udalov
c821aba3bd Fix warnings in native modules 2021-08-06 22:37:00 +02:00
Alexander Udalov
45ffe58b9c Fix warnings in idea-frontend-fir 2021-08-06 22:37:00 +02:00
Alexander Udalov
069e040af9 Fix warnings in kotlin-klib-commonizer 2021-08-06 22:37:00 +02:00
Alexander Udalov
11902c7f8f Fix warnings in daemon-related modules 2021-08-06 22:36:59 +02:00
Alexander Udalov
ca7334acb9 Fix some warnings in Gradle plugin and related modules 2021-08-06 22:36:58 +02:00
Alexander Udalov
376b420d1a Fix warnings in JS/WASM modules 2021-08-06 22:36:22 +02:00
Alexander Udalov
e0643a4185 Build: use -Xskip-runtime-version-check globally in project 2021-08-06 22:36:22 +02:00
Alexander Udalov
1599a049aa Fix warnings in scripting modules 2021-08-06 22:36:22 +02:00
Dmitriy Novozhilov
b9dd73220c [FIR] Update testdata after rebase 2021-08-06 22:57:19 +03:00
Dmitriy Novozhilov
1d491fdce6 [FIR] Don't create union call node for lambda from one when branch and call from condition of another 2021-08-06 22:57:18 +03:00
Tianyu Geng
684ef871ee FIR: unify common special names scattered around the code base 2021-08-06 22:57:17 +03:00
Tianyu Geng
263b876e6e FIR: extends scope of SENSELESS_COMPARISON
FE1.0 only reports SENSELESS_COMPARISON if one of the operand is `null`.
This change makes FIR reports also in case one of the operand has type
`Nothing?`.

In addition, fix handling of type alias in ConeTypeContext#isNullableType
2021-08-06 22:57:17 +03:00
Tianyu Geng
c7272f6986 FIR checker: SENSELESS_(COMPARISON|NULL_IN_WHEN)
Currently DFA does not set "definitely equal to null" for access to variables that got assigned `null`. For example, FIR should mark the following line as SENSELESS_COMPARISON due to `s = null` above.
 d1531f9cdd/compiler/testData/diagnostics/tests/smartCasts/alwaysNull.fir.kt (L6)

The problem is at 7e9f27436a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/FirDataFlowAnalyzer.kt (L1104)

For null assignment, ideally the type should be `Nothing?`. This is
addressed in a followup commit instead.
2021-08-06 22:57:16 +03:00
Tianyu Geng
4726dcce40 FIR DFA: smartcast variable to Nothing? on null assignment
In order to make resolution still work for members not available from
`Nothing`, we track the type without `Nothing?` and use that for
resolution instead.
2021-08-06 22:57:15 +03:00
Tianyu Geng
7e2f15f532 FIR DFA: fix logic clear aliasing
The logic should clear back aliases as well. To ensure all back aliases
don't lose any information, statements on the original variable are
copied over to its aliases.
2021-08-06 22:57:15 +03:00
Tianyu Geng
e495c722c7 FIR DFA: fix handling of equality operation 2021-08-06 22:57:14 +03:00
Tianyu Geng
0026560bd7 FIR: substitute the whole lambda body after builder inference 2021-08-06 22:57:13 +03:00
Tianyu Geng
f737d8002e FIR: allow no else branch for when on Nothing(?) 2021-08-06 22:57:12 +03:00
Tianyu Geng
e242ad955b FIR: tolerate comparison of an intersection of incompatible types
Previously, if user compares an `it<String, Int>` with `String`, the
checker reports it since the flattened types `[String, Int, Int]` are
incompatible. But technically, before flattening, the intersection type
actually contain the other side, so they should really be compatible.
2021-08-06 22:57:11 +03:00
Yahor Berdnikau
b5ea811b9f Migrated BuildCacheIT tests to new DSL.
^KT-45745 In Progress
2021-08-06 20:09:05 +02:00
Yahor Berdnikau
20afb268d1 Allow providing specific kapt options.
^KT-45745 In Progress
2021-08-06 20:09:04 +02:00
Yahor Berdnikau
3d4186bdb1 Allow enabling build cache debug information.
^KT-45745 In Progress
2021-08-06 20:09:04 +02:00
Yahor Berdnikau
e949a0d38d Add assertion checking if task was put into build cache.
^KT-45745 In Progress
2021-08-06 20:09:00 +02:00
Roman Artemev
2574c00dd9 Add index() to LocalSignature for more clear access 2021-08-06 20:49:20 +03:00
Roman Artemev
5a7298808e [JVM KLIB] Fix Type Parameter resolve 2021-08-06 20:49:19 +03:00
Roman Artemev
3dcee8fda8 [KLIB] Optimize deserialization a bit 2021-08-06 20:49:19 +03:00
Roman Artemev
7add820f0d [JS IC] Simplify code a bit 2021-08-06 20:49:17 +03:00
Roman Artemev
398b545801 [JS IC] Rollback hack 2021-08-06 20:49:17 +03:00
Roman Artemev
67f814c99f [JS IC] Don't serialize IrTypeAbbreviation in IC cache 2021-08-06 20:49:15 +03:00
Roman Artemev
d174e8c3d2 small optimization 2021-08-06 20:49:14 +03:00
Roman Artemev
9bfe502afd [JS IC] Fix signature finding in some cases
Found in KFSAD
2021-08-06 20:49:13 +03:00
Roman Artemev
15648da2b4 [PIR] Use simple fast hashCode 2021-08-06 20:49:12 +03:00
Roman Artemev
11f70412e7 [KLIB] Don't resolve delegated symbol where it could be existed 2021-08-06 20:49:12 +03:00
Roman Artemev
297e0a9f43 [JS IC] Improve IC deserializer code a bit 2021-08-06 20:49:11 +03:00
Roman Artemev
6ca87dc43f [KLIB] Drop useless set 2021-08-06 20:49:10 +03:00
Roman Artemev
aeea7147fe [JS IC] Simplify code a bit more 2021-08-06 20:49:09 +03:00
Roman Artemev
28cf9898ef [KLIB] Simplify file symbol resolve 2021-08-06 20:49:08 +03:00
Roman Artemev
6cd0d81561 [JS IC] Drop redundant enqueue 2021-08-06 20:49:07 +03:00
Roman Artemev
b1eeb1fb27 [JS IC] Don't persist temporary copies of inline functions
- drop special `IrValueParameterPublicSymbol`
 - drop special `IrAnonymousInitializerPublicSymbolImpl`
 - drop hacky `useGlobalSignatures`
2021-08-06 20:49:06 +03:00
Roman Artemev
b1251c1716 [JS IC] Drop special IdSignatureSerializer for IC 2021-08-06 20:49:04 +03:00
Roman Artemev
4a601ebf95 [JS IC] Eradicate GlobalScopeLocalDeclaration from code
- Normalize proto names
2021-08-06 20:49:03 +03:00
Roman Artemev
74d8e16d09 [JS IC] Eradicate GlobalFileLocalSignature from code
- Reduce usage of global maps
2021-08-06 20:49:02 +03:00
Roman Artemev
a0449892b2 [JS IC] Simplify signatures, don't use GlobalScopeLocalDeclaration 2021-08-06 20:49:01 +03:00
Roman Artemev
3d3c70141c [JS IC] Properly handle type parameters of Functional interfaces
- drop redundant `IrSymbolTable` and `IrIcModuleDeserializerWithBuiltIns`
2021-08-06 20:48:59 +03:00
Roman Artemev
6aed492703 [JS IR] Set proper visibility for static stub of private members 2021-08-06 20:48:58 +03:00
Yahor Berdnikau
bcf08e3293 Set jvm target validation mode to 'error'. 2021-08-06 17:53:45 +02:00
Yahor Berdnikau
d375c52830 Remove deprecated 'kotlin.useFallbackCompilerSearch' property.
^KT-46719 Fixed
2021-08-06 15:36:46 +00:00
Igor Laevsky
331681b40b WASM: Add different debug levels to the test runner 2021-08-06 17:34:22 +03:00
Igor Laevsky
5db8ec6551 WASM: Don't use intrinsics to specify NaN's 2021-08-06 17:34:21 +03:00
Igor Laevsky
4ffed54f76 WASM: Fix JS runner for standalone compiles 2021-08-06 17:34:20 +03:00
Sergey Bogolepov
18bb287d3b [K/N] Switch from cyclone to apple-a7 for Apple AArch64
This change shouldn't affect behaviour, but rather makes bitcode a bit
more consistent with what Xcode generates.
2021-08-06 14:19:42 +00:00
Sergey Bogolepov
d64cb24643 [K/N] Don't pass -target-cpu to clang
It is not supported by bitcode embedding on Apple platforms.
Instead, we set it in function attributes directly as Clang does.
2021-08-06 14:19:41 +00:00
Dmitriy Novozhilov
3a210f6c81 [Test] Temporary mute some tests because of problems with RepeatedAnnotationLowering
^KT-48131
2021-08-06 16:40:16 +03:00
Dmitriy Novozhilov
cbef031780 Advance bootstrap to 1.6.0-dev-2458 2021-08-06 16:40:07 +03:00
Aleksei.Cherepanov
a4a1d35021 Simplify nested errors
Replace incomprehensible IndexOutOfBoundsException with intelligible exception

#KT-47753 Fixed
2021-08-06 15:08:01 +03:00
Dmitriy Novozhilov
afd9b4935a [FIR] Configure language version for FP test via env properties 2021-08-06 14:24:42 +03:00
Ivan Kylchik
4f15bd4817 Introduce a workaround in interpreter tests to make them pass
There is a problem with ranges and iterators. To work properly
they must be resolved firstly, before operator rangeTo.
2021-08-06 13:33:33 +03:00
Ivan Kylchik
44e1b61e6c Move static cache from Wrapper into non-static container in environment
By this change it is possible to run multiple test in parallel
without running out of memory.
2021-08-06 13:33:32 +03:00
Ivan Kylchik
3932acf843 Fix interpretation of default varargs 2021-08-06 13:33:30 +03:00
Ivan Kylchik
0ce3dd117e Drop unnecessary check for not static initializer in interpreter
Apparently initializers can become static only in lowering
2021-08-06 13:33:30 +03:00
Ivan Kylchik
0af918be4f Use IrFactory to create IrFunction in interpreter 2021-08-06 13:33:29 +03:00
Ivan Kylchik
1002d076b3 Use StandardNames whenever it is possible in Wrapper 2021-08-06 13:33:28 +03:00
Ivan Kylchik
3cf4b8b108 Combine two caches from interpreter environment into single one 2021-08-06 13:33:28 +03:00
Ivan Kylchik
3fc5405d57 Implement simple cache for dynamically created wrapper for defaults 2021-08-06 13:33:27 +03:00
Ivan Kylchik
09c31b0900 Implement simple cache for dynamically created wrapper for lambda 2021-08-06 13:33:25 +03:00
Ivan Kylchik
6482abc602 Add CompileTimeCalculation annotation as helper to interpreter's tests 2021-08-06 13:33:25 +03:00
Ivan Kylchik
524189132b Introduce new property fqName to make it easier to take element's name 2021-08-06 13:33:24 +03:00
Ivan Kylchik
fe74dd2689 Mute failing tests for IrInterpreterAfterPsi2IrTestGenerated
These tests are not passing because of the way how test system works.
To works properly interpreter needs source files. For now they are
passed as additional source files, but this method is not working
for old frontend, some conflicts appear in symbol table. Best way to
fix it is to wait until ir serialization.
2021-08-06 13:33:23 +03:00
Ivan Kylchik
295638b26e Allow to interpret non const properties of compile time object 2021-08-06 13:33:22 +03:00
Ivan Kylchik
1978bfcd85 Rewrite rendering of meta info for CHECK_NOT_NULL in interpreter's test
This way it is possible to unify rendering of elements built by psi2ir
and fir2ir.
2021-08-06 13:33:22 +03:00
Ivan Kylchik
a9abf3b9b6 Drop redundant frames after some of exceptions in interpreter
Drop only last frame because it is pointing on function itself.
2021-08-06 13:33:21 +03:00
Ivan Kylchik
334d518aba Change the way of getting name and ordinal for enum entry in interpreter
For now IrProperty doesn't have corresponding overridden symbol, so
it must be taken from getter.
2021-08-06 13:33:20 +03:00
Ivan Kylchik
f815f63fc5 Replace UNDEFINED_OFFSET with SYNTHETIC_OFFSET in IrTreeBuildUtils
This change is needed to avoid exception in `getLineNumber` method.
2021-08-06 13:33:20 +03:00
Ivan Kylchik
0c5fca31ec Support early return from constructor interpretation 2021-08-06 13:33:19 +03:00
Ivan Kylchik
96cc74a752 Fix enum interpretation in case when primary constructor is missing 2021-08-06 13:33:18 +03:00
Ivan Kylchik
668bb4fd71 Fix equals check in interpreter in case when object is wrapped as Proxy 2021-08-06 13:33:18 +03:00
Ivan Kylchik
b9decc3b30 Support type check for deep nested arrays in interpreter 2021-08-06 13:33:17 +03:00
Ivan Kylchik
4ad88679fd Unify logic of creation new ir tree nodes in interpreter 2021-08-06 13:33:17 +03:00
Ivan Kylchik
6ce2f8eb14 Drop unnecessary SubFrame creation from interpreter 2021-08-06 13:33:16 +03:00
Ivan Kylchik
10efbeb0c9 Add synthetic function in interpreter for default args evaluation 2021-08-06 13:33:16 +03:00
Ivan Kylchik
7852d01da6 Rewrite interpreter logic around arguments evaluation
For now calculated arguments will be stored on stack instead of memory.
At first this was done because of problems with default arguments, but
in the next commit this problem will be solved.
2021-08-06 13:33:15 +03:00
Ivan Kylchik
d41c6e900a Place variables in interpreter's memory at the beginning
In case than in single SubFrame can appear several variables with
the same symbol, it is important to get the latest one. It is
relevant for local functions.
2021-08-06 13:33:14 +03:00
Ivan Kylchik
e5ca646de4 Move object creation logic into constructor interpretation
This newly created object is not used in arguments interpretation
so there is no need to create it in InstructionsUnfolder. Moreover
this object can interfere with other objects in memory, for example,
when creating outer object from inner.
2021-08-06 13:33:14 +03:00
Ivan Kylchik
1af1a3c84e Support interpretation of Throwable constructor
For now every subclass of Throwable will be represented as
ExceptionState. This way it is easier to store stack trace and handle
`cause` property in exceptions.
2021-08-06 13:33:13 +03:00
Ivan Kylchik
c8cd000563 Simplify work with fake override methods in interpreter 2021-08-06 13:33:12 +03:00
Ivan Kylchik
8972fc5158 Interpret properties and init blocks in order of appearance 2021-08-06 13:33:12 +03:00
Ivan Kylchik
78475a5d9c Support interpretation of toArray for collections 2021-08-06 13:33:11 +03:00
Ivan Kylchik
b10fdb919f Support cast to array with reified argument in interpreter 2021-08-06 13:33:10 +03:00
Ivan Kylchik
cc56acc2c2 Add configuration into IrInterpreterEnvironment
This configuration will contains all necessary setting for interpreter
and will be replenished over time
2021-08-06 13:33:10 +03:00
Ivan Kylchik
b150cc9537 Implement better support for default args in interpreter
Now supported default args:
1. from super class or interface;
2. with field access, declared in interface;
3. with field access, declared in outer class.
2021-08-06 13:33:09 +03:00
Ivan Kylchik
42ea17b151 Support interpretation of dataClassArrayMemberToString method 2021-08-06 13:33:09 +03:00
Ivan Kylchik
15808cb376 Lower priority of captured variables in interpreter 2021-08-06 13:33:08 +03:00
Ivan Kylchik
4f3d47eed3 Remove unused equals and hashCode methods from Primitive class
They were used only when primitive objects were put in the collection
as they were, in Primitive state wrapper
2021-08-06 13:33:07 +03:00
Ivan Kylchik
0716c557fe Allow inner class to has outer super class in interpreter 2021-08-06 13:33:07 +03:00
Ivan Kylchik
574c607f1c Support proper subtype check in interpreter for KFunction 2021-08-06 13:33:06 +03:00
Ivan Kylchik
9638af042d Support proper behavior in interpreter for cast of null value 2021-08-06 13:33:05 +03:00
Ivan Kylchik
c2fc017d96 Move doubleArrayOf test file to proper place in interpreter test data 2021-08-06 13:33:04 +03:00
Ivan Kylchik
b44fd1a6fe Simplify logic of interpreting invoke method for lambdas
For now will be created separate invoke method that will contains
a call to lambda. This way it is clearer and more intuitive
2021-08-06 13:33:04 +03:00
Ivan Kylchik
06a8156376 Change logic of returning object from constructor in interpreter
For now there is no need to place object on stack before evaluation.
The result will be taken from memory and all unnecessary values on
stack will be removed
2021-08-06 13:33:02 +03:00
Ivan Kylchik
3326cbd9c0 Support passing property as argument to array constructor in interpreter 2021-08-06 13:33:02 +03:00
Ivan Kylchik
59fefb6214 Fix property rendering in interpreter 2021-08-06 13:33:01 +03:00
Ivan Kylchik
af67e950c4 Replace all assert calls in interpreter with internal verify
This swap of methods allow us to handle all asserted errors as
critical and not to process them inside interpreter
2021-08-06 13:33:00 +03:00
Ivan Kylchik
23392b73a9 Simplify the interpretation logic of methods defined in super Wrapper 2021-08-06 13:32:58 +03:00
Ivan Kylchik
cf20e64c61 Support basic interpretation of IrGetClass 2021-08-06 13:32:57 +03:00
Ivan Kylchik
6fe8dd1254 Add ir interpreter tests for ir built from psi 2021-08-06 13:32:57 +03:00
Dmitriy Novozhilov
a9882a86c0 [FIR] Consider extension receiver type in conflicting members checker 2021-08-06 13:31:20 +03:00
Victor Petukhov
cd09c8ba51 Report CANNOT_INFER_PARAMETER_TYPE on any error value parameters of a lambda
^KT-48058 Fixed
2021-08-06 13:27:57 +03:00
Victor Petukhov
1966915e92 Create DONT_CARE type only for dependent lambdas (i.e. to be resolved through the type inference later)
^KT-47493 Fixed
2021-08-06 13:27:56 +03:00
sebastian.sellmair
dbdc6176f0 [Gradle] GradleIT: kotlinToolingMetadataAndroid: Add java 8 support
^KT-48019
2021-08-06 09:25:01 +00:00
Andrey Zinovyev
6dd4164f1e [FIR][CFG] Link finally exit to jump target
Instead of try exit node. So try exit is used only for real exits from
try expressions.
2021-08-06 11:49:35 +03:00
Andrey Zinovyev
32426da625 [FIR][CFG] Support multiple levels of finally blocks in jumps
Jump inside try expressions now goes through all finally blocks between
it and the target
2021-08-06 11:49:35 +03:00
Andrey Zinovyev
06b23d5937 [FIR] Improve the control flow graph around try expressions
1. throw goes to catches instead of main exist block
2. return goes via finally (single level only supported atm)
3. collect non-direct return to retrieve all return expressions easier
2021-08-06 11:49:34 +03:00
Yahor Berdnikau
7b6dddf012 Replace usages of IncrementalTaskInputs with InputChanges.
Gradle IncrementalTaskInputs was long time ago deprecated and not
so flexible as a new proposed way - InputChanges.

^KT-47867 Fixed
2021-08-06 08:44:56 +00: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
1878 changed files with 36774 additions and 20218 deletions

1
.bunch
View File

@@ -1,2 +1 @@
203
202

3
.gitignore vendored
View File

@@ -12,7 +12,7 @@
/android-studio/sdk
out/
/tmp
kotlin-ide/
/intellij
workspace.xml
*.versionsBackup
/idea/testData/debugger/tinyApp/classes*
@@ -68,3 +68,4 @@ distTmp/
outTmp/
/test.output
/kotlin-native/dist
kotlin-ide/

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

@@ -25,6 +25,7 @@ import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.build.GeneratedJvmClass
import org.jetbrains.kotlin.incremental.storage.*
import org.jetbrains.kotlin.inline.inlineFunctionsJvmNames
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
@@ -113,7 +114,7 @@ open class IncrementalJvmCache(
}
open fun saveFileToCache(generatedClass: GeneratedJvmClass, changesCollector: ChangesCollector) {
saveClassToCache(KotlinClassInfo(generatedClass.outputClass), generatedClass.sourceFiles, changesCollector)
saveClassToCache(KotlinClassInfo.createFrom(generatedClass.outputClass), generatedClass.sourceFiles, changesCollector)
}
/**
@@ -612,16 +613,6 @@ class KotlinClassInfo private constructor(
val inlineFunctionsMap: LinkedHashMap<String, Long>
) {
constructor(kotlinClass: LocalFileKotlinClass) : this(
kotlinClass.classId,
kotlinClass.classHeader.kind,
kotlinClass.classHeader.data,
kotlinClass.classHeader.strings,
kotlinClass.classHeader.multifileClassName,
getConstantsMap(kotlinClass.fileContents),
getInlineFunctionsMap(kotlinClass.classHeader, kotlinClass.fileContents)
)
val className: JvmClassName by lazy { JvmClassName.byClassId(classId) }
fun scopeFqName(companion: Boolean = false) = when (classKind) {
@@ -630,6 +621,36 @@ class KotlinClassInfo private constructor(
}
else -> className.packageFqName
}
companion object {
fun createFrom(kotlinClass: LocalFileKotlinClass): KotlinClassInfo {
return KotlinClassInfo(
kotlinClass.classId,
kotlinClass.classHeader.kind,
kotlinClass.classHeader.data,
kotlinClass.classHeader.strings,
kotlinClass.classHeader.multifileClassName,
getConstantsMap(kotlinClass.fileContents),
getInlineFunctionsMap(kotlinClass.classHeader, kotlinClass.fileContents)
)
}
/** Creates [KotlinClassInfo] from the given classContents, or returns `null` if the class is not a kotlinc-generated class. */
fun tryCreateFrom(classContents: ByteArray): KotlinClassInfo? {
return FileBasedKotlinClass.create(classContents) { classId, _, classHeader, _ ->
KotlinClassInfo(
classId,
classHeader.kind,
classHeader.data,
classHeader.strings,
classHeader.multifileClassName,
getConstantsMap(classContents),
getInlineFunctionsMap(classHeader, classContents)
)
}
}
}
}
private fun getConstantsMap(bytes: ByteArray): LinkedHashMap<String, Any> {
@@ -694,4 +715,4 @@ private fun getInlineFunctionsMap(header: KotlinClassHeader, bytes: ByteArray):
}, 0)
return result
}
}

View File

@@ -48,13 +48,18 @@ 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()
size = lines.firstOrNull()?.toIntOrNull() ?: throw IOException("$countersFile exists, but it is empty. " +
"Counters file is corrupted")
oldSize = size
}
} catch (e: IOException) {
throw e
} catch (e: Exception) {
throw IOException("Could not read $countersFile", e)
}
@@ -120,13 +125,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")
@@ -443,6 +443,12 @@ allprojects {
project.configureShadowJarSubstitutionInCompileClasspath()
}
tasks.withType<JavaCompile> {
options.compilerArgs.add("-Xlint:deprecation")
options.compilerArgs.add("-Xlint:unchecked")
options.compilerArgs.add("-Werror")
}
val commonCompilerArgs = listOfNotNull(
"-Xopt-in=kotlin.RequiresOptIn",
"-progressive".takeIf { hasProperty("test.progressive.mode") }
@@ -460,6 +466,7 @@ allprojects {
"-Xjvm-default=compatibility",
"-Xno-optimized-callable-references",
"-Xno-kotlin-nothing-value-exception",
"-Xskip-runtime-version-check",
"-Xsuppress-deprecated-jvm-target-warning" // Remove as soon as there are no modules for JDK 1.6 & 1.7
)

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

@@ -89,4 +89,4 @@ val Project.isIdeaActive
get() = providers.systemProperty("idea.active").forUseAtConfigurationTime().isPresent
val Project.intellijCommunityDir: File
get() = rootDir.resolve("kotlin-ide/intellij/community").takeIf { it.isDirectory } ?: rootDir.resolve("kotlin-ide/intellij")
get() = rootDir.resolve("intellij/community").takeIf { it.isDirectory } ?: rootDir.resolve("intellij")

View File

@@ -41,7 +41,6 @@ tasks.withType<KotlinCompile> {
kotlinOptions.apiVersion = "1.4"
kotlinOptions.freeCompilerArgs += listOf(
"-Xskip-prerelease-check",
"-Xskip-runtime-version-check",
"-Xsuppress-version-warnings",
"-Xuse-ir" // Needed as long as languageVersion is less than 1.5.
)

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

@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
@@ -26,7 +26,7 @@ class AccessorForConstructorDescriptor(
containingDeclaration: DeclarationDescriptor,
override val superCallTarget: ClassDescriptor?,
override val accessorKind: AccessorKind
) : AbstractAccessorForFunctionDescriptor(containingDeclaration, Name.special("<init>")),
) : AbstractAccessorForFunctionDescriptor(containingDeclaration, SpecialNames.INIT),
ClassConstructorDescriptor,
AccessorForCallableDescriptor<ConstructorDescriptor> {

View File

@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.sam.JavaSingleAbstractMethodUtils;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.stubs.KotlinFileStub;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -298,7 +299,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
private String getName(ClassDescriptor classDescriptor) {
String base = peekFromStack(nameStack);
Name descriptorName = safeIdentifier(classDescriptor.getName());
Name descriptorName = SpecialNames.safeIdentifier(classDescriptor.getName());
if (DescriptorUtils.isTopLevelDeclaration(classDescriptor)) {
return base.isEmpty() ? descriptorName.asString() : base + '/' + descriptorName;
}

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

@@ -0,0 +1,386 @@
/*
* 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.codegen.inline
import org.jetbrains.kotlin.codegen.optimization.boxing.isMethodInsnWith
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables
import org.jetbrains.kotlin.codegen.optimization.common.updateMaxStack
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.*
class InplaceArgumentsMethodTransformer : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) {
val methodContext = parseMethodOrNull(methodNode)
if (methodContext != null) {
if (methodContext.calls.isEmpty()) return
collectStartToEnd(methodContext)
collectLvtEntryInstructions(methodContext)
collectSuspensionPoints(methodContext)
transformMethod(methodContext)
updateLvtEntriesForMovedInstructions(methodContext)
methodNode.removeUnusedLocalVariables()
methodNode.updateMaxStack()
}
stripMarkers(methodNode)
}
private class MethodContext(
val methodNode: MethodNode,
val calls: List<CallContext>
) {
val startArgToEndArg = HashMap<AbstractInsnNode, AbstractInsnNode>()
val lvtEntryForInstruction = HashMap<AbstractInsnNode, LocalVariableNode>()
val varInstructionMoved = HashMap<AbstractInsnNode, CallContext>()
val suspensionJumpLabels = HashSet<LabelNode>()
}
private class CallContext(
val callStartMarker: AbstractInsnNode,
val callEndMarker: AbstractInsnNode,
val args: List<ArgContext>,
val calls: List<CallContext>,
val endLabel: LabelNode
)
private class ArgContext(
val argStartMarker: AbstractInsnNode,
val argEndMarker: AbstractInsnNode,
val calls: List<CallContext>,
val storeInsn: VarInsnNode
) {
val loadOpcode = storeInsn.opcode - Opcodes.ISTORE + Opcodes.ILOAD
val varIndex = storeInsn.`var`
}
private fun parseMethodOrNull(methodNode: MethodNode): MethodContext? {
// We assume that the method body structure follows this grammar:
// METHOD ::= insn* (CALL insn*)*
// CALL ::= callStartMarker insn* (ARG insn*)* (CALL insn*)* callEndMarker
// ARG ::= argStartMarker insn* (CALL insn*)* argEndMarker storeInsn
val iter = methodNode.instructions.iterator()
val calls = ArrayList<CallContext>()
try {
while (iter.hasNext()) {
val insn = iter.next()
when {
insn.isInplaceCallStartMarker() ->
calls.add(parseCall(methodNode, insn, iter))
insn.isInplaceCallEndMarker() || insn.isInplaceArgumentStartMarker() || insn.isInplaceArgumentEndMarker() ->
throw ParseErrorException()
}
}
} catch (e: ParseErrorException) {
return null
}
return MethodContext(methodNode, calls)
}
private fun parseCall(methodNode: MethodNode, start: AbstractInsnNode, iter: ListIterator<AbstractInsnNode>): CallContext {
// CALL ::= callStartMarker insn* (ARG insn*)* (CALL insn*)* callEndMarker
val args = ArrayList<ArgContext>()
val calls = ArrayList<CallContext>()
while (iter.hasNext()) {
val insn = iter.next()
when {
insn.isInplaceCallStartMarker() ->
calls.add(parseCall(methodNode, insn, iter))
insn.isInplaceCallEndMarker() -> {
val previous = insn.previous
val endLabel =
if (previous.type == AbstractInsnNode.LABEL)
previous as LabelNode
else
LabelNode(Label()).also {
// Make sure each call with inplace arguments has an endLabel
// (we need it to update LVT after transformation).
methodNode.instructions.insertBefore(insn, it)
}
return CallContext(start, insn, args, calls, endLabel)
}
insn.isInplaceArgumentStartMarker() ->
args.add(parseArg(methodNode, insn, iter))
insn.isInplaceArgumentEndMarker() ->
throw ParseErrorException()
}
}
// Reached instruction list end, didn't find inplace-call-end marker
throw ParseErrorException()
}
private fun parseArg(methodNode: MethodNode, start: AbstractInsnNode, iter: ListIterator<AbstractInsnNode>): ArgContext {
// ARG ::= argStartMarker insn* (CALL insn*)* argEndMarker storeInsn
val calls = ArrayList<CallContext>()
while (iter.hasNext()) {
val insn = iter.next()
when {
insn.isInplaceCallStartMarker() ->
calls.add(parseCall(methodNode, insn, iter))
insn.isInplaceArgumentEndMarker() -> {
val next = insn.next
if (next is VarInsnNode && next.opcode in Opcodes.ISTORE..Opcodes.ASTORE) {
iter.next()
return ArgContext(start, insn, calls, next)
} else {
throw ParseErrorException()
}
}
insn.isInplaceCallEndMarker() || insn.isInplaceArgumentStartMarker() ->
throw ParseErrorException()
}
}
// Reached instruction list end, didn't find inplace-argument-end marker
throw ParseErrorException()
}
private class ParseErrorException : RuntimeException() {
override fun fillInStackTrace(): Throwable = this
}
private fun collectStartToEnd(methodContext: MethodContext) {
for (call in methodContext.calls) {
collectStartToEnd(methodContext, call)
}
}
private fun collectStartToEnd(methodContext: MethodContext, callContext: CallContext) {
for (arg in callContext.args) {
collectStartToEnd(methodContext, arg)
}
for (call in callContext.calls) {
collectStartToEnd(methodContext, call)
}
}
private fun collectStartToEnd(methodContext: MethodContext, argContext: ArgContext) {
methodContext.startArgToEndArg[argContext.argStartMarker] = argContext.argEndMarker
for (call in argContext.calls) {
collectStartToEnd(methodContext, call)
}
}
private fun collectLvtEntryInstructions(methodContext: MethodContext) {
val insnList = methodContext.methodNode.instructions
val insnArray = insnList.toArray()
for (lv in methodContext.methodNode.localVariables) {
val lvStartIndex = insnList.indexOf(lv.start)
val lvEndIndex = insnList.indexOf(lv.end)
for (i in lvStartIndex until lvEndIndex) {
val insn = insnArray[i]
if (insn.opcode in Opcodes.ILOAD..Opcodes.ALOAD || insn.opcode in Opcodes.ISTORE..Opcodes.ASTORE) {
if ((insn as VarInsnNode).`var` == lv.index) {
methodContext.lvtEntryForInstruction[insn] = lv
}
} else if (insn.opcode == Opcodes.IINC) {
if ((insn as IincInsnNode).`var` == lv.index) {
methodContext.lvtEntryForInstruction[insn] = lv
}
}
}
}
}
private fun collectSuspensionPoints(methodContext: MethodContext) {
val insnList = methodContext.methodNode.instructions
var insn = insnList.first
while (
!insn.isMethodInsnWith(Opcodes.INVOKESTATIC) {
owner == "kotlin/coroutines/intrinsics/IntrinsicsKt" &&
name == "getCOROUTINE_SUSPENDED" &&
desc == "()Ljava/lang/Object;"
}
) {
insn = insn.next ?: return
}
// Find a first TABLESWITCH and record its jump destinations
while (insn != null) {
if (insn.opcode != Opcodes.TABLESWITCH || insn.previous.opcode != Opcodes.GETFIELD) {
insn = insn.next
continue
}
val getFiendInsn = insn.previous as FieldInsnNode
if (getFiendInsn.name != "label" || getFiendInsn.desc != "I") {
insn = insn.next
continue
}
val tableSwitchInsn = insn as TableSwitchInsnNode
methodContext.suspensionJumpLabels.addAll(tableSwitchInsn.labels)
methodContext.suspensionJumpLabels.add(tableSwitchInsn.dflt)
return
}
}
private fun transformMethod(methodContext: MethodContext) {
for (call in methodContext.calls) {
transformCall(methodContext, call)
}
}
private fun transformCall(methodContext: MethodContext, callContext: CallContext) {
// Transform nested calls
for (arg in callContext.args) {
for (nestedCall in arg.calls) {
transformCall(methodContext, nestedCall)
}
}
for (call in callContext.calls) {
transformCall(methodContext, call)
}
// If an inplace argument contains a non-local jump,
// moving such argument inside inline function body can interfere with stack normalization.
// TODO investigate complex cases
if (callContext.args.any { it.isUnsafeToMove(methodContext) }) {
// Do not transform such call, just strip call and argument markers.
val insnList = methodContext.methodNode.instructions
for (arg in callContext.args) {
insnList.remove(arg.argStartMarker)
insnList.remove(arg.argEndMarker)
}
insnList.remove(callContext.callStartMarker)
insnList.remove(callContext.callEndMarker)
return
}
moveInplaceArgumentsFromStoresToLoads(methodContext, callContext)
}
private fun ArgContext.isUnsafeToMove(methodContext: MethodContext): Boolean {
val argInsns = InsnSequence(this.argStartMarker, this.argEndMarker)
val localLabels = argInsns.filterTo(HashSet()) { it is LabelNode }
return argInsns.any { insn ->
insn in methodContext.suspensionJumpLabels ||
insn.opcode == Opcodes.GOTO && (insn as JumpInsnNode).label !in localLabels
}
}
private fun moveInplaceArgumentsFromStoresToLoads(methodContext: MethodContext, callContext: CallContext) {
// Transform call
val insnList = methodContext.methodNode.instructions
val args = callContext.args.associateBy { it.varIndex }
var argsProcessed = 0
var insn: AbstractInsnNode = callContext.callStartMarker
while (insn != callContext.callEndMarker) {
when {
insn.isInplaceArgumentStartMarker() -> {
// Skip argument body
insn = methodContext.startArgToEndArg[insn]!!
}
insn.opcode in Opcodes.ILOAD..Opcodes.ALOAD -> {
// Load instruction
val loadInsn = insn as VarInsnNode
val varIndex = loadInsn.`var`
val arg = args[varIndex]
if (arg == null || arg.loadOpcode != insn.opcode) {
// Not an argument load
insn = insn.next
} else {
// For each argument within this call we have
// <inplaceArgStartMarker>
// <argumentBody>
// <inplaceArgEndMarker>
// store [arg]
// ...
// load [arg]
// Replace 'load [arg]' with '<argumentBody>', drop 'store [arg]' and argument markers.
var argInsn = arg.argStartMarker.next
while (argInsn != arg.argEndMarker) {
// If a LOAD/STORE/IINC instruction was moved,
// record it so that we can update corresponding LVT entry if needed.
// NB it's better to do so after all transformations, so that we don't recalculate node indices.
if (argInsn.opcode in Opcodes.ILOAD..Opcodes.ALOAD ||
argInsn.opcode in Opcodes.ISTORE..Opcodes.ASTORE ||
argInsn.opcode == Opcodes.IINC
) {
methodContext.varInstructionMoved[argInsn] = callContext
}
val argInsnNext = argInsn.next
insnList.remove(argInsn)
insnList.insertBefore(loadInsn, argInsn)
argInsn = argInsnNext
}
// Remove argument load and corresponding argument store instructions
insnList.remove(arg.storeInsn)
insn = loadInsn.next
insnList.remove(loadInsn)
// Replace subsequent argument loads with DUP instructions of appropriate size
while (insn.opcode == loadInsn.opcode && (insn as VarInsnNode).`var` == varIndex) {
if (insn.opcode == Opcodes.LLOAD || insn.opcode == Opcodes.DLOAD) {
insnList.insertBefore(insn, InsnNode(Opcodes.DUP2))
} else {
insnList.insertBefore(insn, InsnNode(Opcodes.DUP))
}
val next = insn.next
insnList.remove(insn)
insn = next
}
// Remove argument markers
insnList.remove(arg.argStartMarker)
insnList.remove(arg.argEndMarker)
// If there are no more inplace arguments left to process, we are done
++argsProcessed
if (argsProcessed >= callContext.args.size)
break
}
}
else ->
insn = insn.next
}
}
// Remove call start and call end markers
insnList.remove(callContext.callStartMarker)
insnList.remove(callContext.callEndMarker)
}
private fun updateLvtEntriesForMovedInstructions(methodContext: MethodContext) {
val insnList = methodContext.methodNode.instructions
for ((insn, callContext) in methodContext.varInstructionMoved.entries) {
// Extend local variable interval to call end label if needed
val lv = methodContext.lvtEntryForInstruction[insn] ?: continue
val lvEndIndex = insnList.indexOf(lv.end)
val endLabelIndex = insnList.indexOf(callContext.endLabel)
if (endLabelIndex > lvEndIndex) {
lv.end = callContext.endLabel
}
}
}
private fun stripMarkers(methodNode: MethodNode) {
var insn = methodNode.instructions.first
while (insn != null) {
if (insn.isInplaceCallStartMarker() ||
insn.isInplaceCallEndMarker() ||
insn.isInplaceArgumentStartMarker() ||
insn.isInplaceArgumentEndMarker()
) {
val next = insn.next
methodNode.instructions.remove(insn)
insn = next
continue
}
insn = insn.next
}
}
}

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
@@ -737,6 +733,7 @@ class MethodInliner(
private fun preprocessNodeBeforeInline(node: MethodNode, returnLabels: Map<String, Label?>) {
try {
InplaceArgumentsMethodTransformer().transform("fake", node)
FixStackWithLabelNormalizationMethodTransformer().transform("fake", node)
} catch (e: Throwable) {
throw wrapException(e, node, "couldn't inline method call")
@@ -747,6 +744,8 @@ class MethodInliner(
ApiVersionCallsPreprocessingMethodTransformer(targetApiVersion).transform("fake", node)
}
removeFakeVariablesInitializationIfPresent(node)
val frames = FastStackAnalyzer("<fake>", node, FixStackInterpreter()).analyze()
val localReturnsNormalizer = LocalReturnsNormalizer()
@@ -769,6 +768,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

@@ -0,0 +1,223 @@
/*
* 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.codegen.inline
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isParameterCheckedForNull
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.*
fun canInlineArgumentsInPlace(methodNode: MethodNode): Boolean {
// Usual inline functions are inlined in the following way:
// <evaluate argument #1>
// <store argument to an argument variable V1>
// ...
// <evaluate argument #N>
// <store argument to an argument variable VN>
// <inline function method body with parameter variables Pi remapped to argument variables Vi>
// If an argument #k is already stored in a local variable W, this variable W is reused.
// When inlining arguments in-place, we instead replace corresponding variable load instructions in the inline function method body
// with bytecode for evaluating a given argument.
// We can do so if such transformation keeps the evaluation order intact, possibly disregarding class initialization.
//
// This is true for many simple @InlineOnly functions from Kotlin standard library.
// For example, bytecode for 'inline fun println(message: Any?)' is:
// GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
// ALOAD 0
// INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V
// Basic inlining for 'println("Hello, world!")' would produce (skipping labels and line numbers):
// // evaluate arguments, storing them to local variables
// LDC "Hello, world!"
// ASTORE 0
// GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
// ALOAD 0
// INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V
// With argument "Hello, world!" inlined in-place it would be:
// GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
// LDC "Hello, world!"
// INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/Object;)V
// Such inlining is possible because we consider it OK to reorder 'GETSTATIC java/lang/System.out : Ljava/io/PrintStream;' instruction
// with any argument evaluation instructions ('LDC "Hello, world!"' in this case).
val tcbStartLabels = methodNode.tryCatchBlocks.mapTo(HashSet()) { it.start }
val methodParameterTypes = Type.getArgumentTypes(methodNode.desc)
val jvmArgumentTypes = ArrayList<Type>(methodParameterTypes.size + 1)
if (methodNode.access and Opcodes.ACC_STATIC == 0) {
// Here we don't care much about the exact 'this' type,
// it's only important to remember that variable slot #0 holds an object reference.
jvmArgumentTypes.add(AsmTypes.OBJECT_TYPE)
}
jvmArgumentTypes.addAll(methodParameterTypes)
val argumentVarEnd = jvmArgumentTypes.sumOf { it.size }
var expectedArgumentVar = 0
var lastArgIndex = 0
var insn = methodNode.instructions.first
// During arguments evaluation, make sure that all arguments are loaded in expected order
// and there are no unexpected side effects in-between.
while (insn != null && expectedArgumentVar < argumentVarEnd) {
// Entering a try-catch block before all arguments are loaded breaks evaluation order.
if (insn in tcbStartLabels)
return false
// Some instructions break evaluation order.
if (insn.isProhibitedDuringArgumentsEvaluation())
return false
// Allow a limited list of 'GETSTATIC <owner> <name> <desc>' instructions.
if (insn.opcode == Opcodes.GETSTATIC) {
val fieldInsn = insn as FieldInsnNode
val fieldSignature = FieldSignature(fieldInsn.owner, fieldInsn.name, fieldInsn.desc)
if (fieldSignature !in whitelistedStaticFields)
return false
}
// Writing to or incrementing an argument variable forbids in-place argument inlining.
if (insn.opcode in Opcodes.ISTORE..Opcodes.ASTORE && (insn as VarInsnNode).`var` < argumentVarEnd)
return false
if (insn.opcode == Opcodes.IINC && (insn as IincInsnNode).`var` < argumentVarEnd)
return false
// Analyze variable loads.
if (insn.opcode in Opcodes.ILOAD..Opcodes.ALOAD) {
// Skip parameter null check: 'aload x; ldc "..."; invokestatic <check>'
if (insn.opcode == Opcodes.ALOAD && insn.isParameterCheckedForNull()) {
// Go directly to the instruction after 'invokestatic <check>'
insn = insn.next.next.next
continue
}
val varInsn = insn as VarInsnNode
val varIndex = (varInsn).`var`
if (varIndex == expectedArgumentVar) {
// Expected argument variable loaded.
expectedArgumentVar += jvmArgumentTypes[lastArgIndex].size
++lastArgIndex
// Skip a sequence of load instructions referring to the same argument variable
// (such sequence is present in functions like 'Array.copyOf' and can be replaced with DUP instructions).
do {
insn = insn.next
} while (insn != null && insn.opcode == varInsn.opcode && (insn as VarInsnNode).`var` == varIndex)
continue
} else if (varIndex < argumentVarEnd) {
// Loaded an argument variable, but not an expected one => broken evaluation order
return false
} else {
// It's OK to load any non-argument variable during argument evaluation.
insn = insn.next
continue
}
}
// Anything else is fine.
insn = insn.next
}
// Method body is over, but not all arguments were loaded on stack.
if (expectedArgumentVar < argumentVarEnd)
return false
// After arguments evaluation make sure that argument variables are no longer accessed
// (we are not going to store anything to those variables anyway).
while (insn != null) {
if (insn.opcode in Opcodes.ILOAD..Opcodes.ALOAD || insn.opcode in Opcodes.ISTORE..Opcodes.ASTORE) {
if ((insn as VarInsnNode).`var` < argumentVarEnd)
return false
} else if (insn.opcode == Opcodes.IINC) {
if ((insn as IincInsnNode).`var` < argumentVarEnd)
return false
}
insn = insn.next
}
// Didn't encounter anything suspicious.
return true
}
internal data class FieldSignature(
val owner: String,
val name: String,
val desc: String
)
private val whitelistedStaticFields: Set<FieldSignature> =
hashSetOf(
FieldSignature("java/lang/System", "out", "Ljava/io/PrintStream;"),
FieldSignature("kotlin/Result", "Companion", "Lkotlin/Result\$Companion;"),
FieldSignature("kotlin/_Assertions", "ENABLED", "Z")
)
private fun AbstractInsnNode.isProhibitedDuringArgumentsEvaluation() =
opcode in opcodeProhibitedDuringArgumentsEvaluation.indices &&
opcodeProhibitedDuringArgumentsEvaluation[opcode]
private val opcodeProhibitedDuringArgumentsEvaluation = BooleanArray(256).also { a ->
// Any kind of jump during arguments evaluation is a hazard.
// This includes all conditional jump instructions, switch instructions, return and throw instructions.
// Very conservative, but enough for practical cases.
for (i in Opcodes.IFEQ..Opcodes.RETURN) a[i] = true
a[Opcodes.IFNULL] = true
a[Opcodes.IFNONNULL] = true
a[Opcodes.ATHROW] = true
// Instruction with non-trivial side effects is a hazard.
// NB GETSTATIC is taken care of separately.
a[Opcodes.PUTSTATIC] = true
a[Opcodes.PUTFIELD] = true
a[Opcodes.INVOKEVIRTUAL] = true
a[Opcodes.INVOKESPECIAL] = true
a[Opcodes.INVOKESTATIC] = true
a[Opcodes.INVOKEINTERFACE] = true
a[Opcodes.INVOKEDYNAMIC] = true
a[Opcodes.MONITORENTER] = true
a[Opcodes.MONITOREXIT] = true
// Integer division instructions can throw exception
a[Opcodes.IDIV] = true
a[Opcodes.LDIV] = true
a[Opcodes.IREM] = true
a[Opcodes.LREM] = true
// CHECKCAST can throw exception
a[Opcodes.CHECKCAST] = true
// Array creation can throw exception (in case of negative array size)
a[Opcodes.NEWARRAY] = true
a[Opcodes.ANEWARRAY] = true
a[Opcodes.MULTIANEWARRAY] = true
// Array access instructions can throw exception
for (i in Opcodes.IALOAD..Opcodes.SALOAD) a[i] = true
for (i in Opcodes.IASTORE..Opcodes.SASTORE) a[i] = true
}
private const val MARKER_INPLACE_CALL_START = "<INPLACE-CALL-START>"
private const val MARKER_INPLACE_ARGUMENT_START = "<INPLACE-ARGUMENT-START>"
private const val MARKER_INPLACE_ARGUMENT_END = "<INPLACE-ARGUMENT-END>"
private const val MARKER_INPLACE_CALL_END = "<INPLACE-CALL-END>"
private fun InstructionAdapter.addMarker(name: String) {
visitMethodInsn(Opcodes.INVOKESTATIC, INLINE_MARKER_CLASS_NAME, name, "()V", false)
}
fun InstructionAdapter.addInplaceCallStartMarker() = addMarker(MARKER_INPLACE_CALL_START)
fun InstructionAdapter.addInplaceCallEndMarker() = addMarker(MARKER_INPLACE_CALL_END)
fun InstructionAdapter.addInplaceArgumentStartMarker() = addMarker(MARKER_INPLACE_ARGUMENT_START)
fun InstructionAdapter.addInplaceArgumentEndMarker() = addMarker(MARKER_INPLACE_ARGUMENT_END)
internal fun AbstractInsnNode.isInplaceCallStartMarker() = isInlineMarker(this, MARKER_INPLACE_CALL_START)
internal fun AbstractInsnNode.isInplaceCallEndMarker() = isInlineMarker(this, MARKER_INPLACE_CALL_END)
internal fun AbstractInsnNode.isInplaceArgumentStartMarker() = isInlineMarker(this, MARKER_INPLACE_ARGUMENT_START)
internal fun AbstractInsnNode.isInplaceArgumentEndMarker() = isInlineMarker(this, MARKER_INPLACE_ARGUMENT_END)

View File

@@ -60,7 +60,7 @@ const val INLINE_FUN_VAR_SUFFIX = "\$iv"
internal const val FIRST_FUN_LABEL = "$$$$\$ROOT$$$$$"
internal const val SPECIAL_TRANSFORMATION_NAME = "\$special"
const val INLINE_TRANSFORMATION_SUFFIX = "\$inlined"
internal const val INLINE_CALL_TRANSFORMATION_SUFFIX = "$" + INLINE_TRANSFORMATION_SUFFIX
internal const val INLINE_CALL_TRANSFORMATION_SUFFIX = "$$INLINE_TRANSFORMATION_SUFFIX"
internal const val INLINE_FUN_THIS_0_SUFFIX = "\$inline_fun"
internal const val DEFAULT_LAMBDA_FAKE_CALL = "$$\$DEFAULT_LAMBDA_FAKE_CALL$$$"
internal const val CAPTURED_FIELD_FOLD_PREFIX = "$$$"
@@ -68,11 +68,10 @@ internal const val CAPTURED_FIELD_FOLD_PREFIX = "$$$"
private const val NON_LOCAL_RETURN = "$$$$\$NON_LOCAL_RETURN$$$$$"
const val CAPTURED_FIELD_PREFIX = "$"
private const val NON_CAPTURED_FIELD_PREFIX = "$$"
private const val INLINE_MARKER_CLASS_NAME = "kotlin/jvm/internal/InlineMarker"
internal const val INLINE_MARKER_CLASS_NAME = "kotlin/jvm/internal/InlineMarker"
private const val INLINE_MARKER_BEFORE_METHOD_NAME = "beforeInlineCall"
private const val INLINE_MARKER_AFTER_METHOD_NAME = "afterInlineCall"
private const val INLINE_MARKER_FINALLY_START = "finallyStart"
private const val INLINE_MARKER_FINALLY_END = "finallyEnd"
private const val INLINE_MARKER_BEFORE_SUSPEND_ID = 0
private const val INLINE_MARKER_AFTER_SUSPEND_ID = 1
@@ -302,7 +301,7 @@ internal fun firstLabelInChain(node: LabelNode): LabelNode {
internal fun areLabelsBeforeSameInsn(first: LabelNode, second: LabelNode): Boolean =
firstLabelInChain(first) == firstLabelInChain(second)
internal val MethodNode?.nodeText: String
val MethodNode?.nodeText: String
get() {
if (this == null) {
return "Not generated"
@@ -535,17 +534,15 @@ internal fun isInlineMarker(insn: AbstractInsnNode): Boolean {
return isInlineMarker(insn, null)
}
private fun isInlineMarker(insn: AbstractInsnNode, name: String?): Boolean {
if (insn !is MethodInsnNode) {
return false
}
internal fun isInlineMarker(insn: AbstractInsnNode, name: String?): Boolean {
if (insn.opcode != Opcodes.INVOKESTATIC) return false
return insn.getOpcode() == Opcodes.INVOKESTATIC &&
insn.owner == INLINE_MARKER_CLASS_NAME &&
val methodInsn = insn as MethodInsnNode
return methodInsn.owner == INLINE_MARKER_CLASS_NAME &&
if (name != null)
insn.name == name
methodInsn.name == name
else
insn.name == INLINE_MARKER_BEFORE_METHOD_NAME || insn.name == INLINE_MARKER_AFTER_METHOD_NAME
methodInsn.name == INLINE_MARKER_BEFORE_METHOD_NAME || methodInsn.name == INLINE_MARKER_AFTER_METHOD_NAME
}
internal fun isBeforeInlineMarker(insn: AbstractInsnNode): Boolean {

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.codegen.optimization
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
import org.jetbrains.kotlin.codegen.inline.InplaceArgumentsMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.boxing.PopBackwardPropagationTransformer
import org.jetbrains.kotlin.codegen.optimization.boxing.RedundantBoxingMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.boxing.StackPeepholeOptimizationsTransformer
@@ -40,6 +41,7 @@ class OptimizationMethodVisitor(
UninitializedStoresMethodTransformer(generationState.constructorCallNormalizationMode)
val normalizationMethodTransformer = CompositeMethodTransformer(
InplaceArgumentsMethodTransformer(),
FixStackWithLabelNormalizationMethodTransformer(),
MethodVerifier("AFTER mandatory stack transformations", generationState)
)

View File

@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.codegen.optimization.removeNodeGetNext
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.*
@@ -36,7 +35,7 @@ val AbstractInsnNode.isMeaningful: Boolean
val AbstractInsnNode.isBranchOrCall: Boolean
get() =
when(this.type) {
when (this.type) {
AbstractInsnNode.JUMP_INSN,
AbstractInsnNode.TABLESWITCH_INSN,
AbstractInsnNode.LOOKUPSWITCH_INSN,
@@ -85,13 +84,17 @@ fun MethodNode.prepareForEmitting() {
current = prev
}
updateMaxStack()
}
fun MethodNode.updateMaxStack() {
maxStack = -1
accept(
MaxStackFrameSizeAndLocalsCalculator(
Opcodes.API_VERSION, access, desc,
object : MethodVisitor(Opcodes.API_VERSION) {
API_VERSION, access, desc,
object : MethodVisitor(API_VERSION) {
override fun visitMaxs(maxStack: Int, maxLocals: Int) {
this@prepareForEmitting.maxStack = maxStack
this@updateMaxStack.maxStack = maxStack
}
})
)
@@ -100,10 +103,10 @@ fun MethodNode.prepareForEmitting() {
fun MethodNode.stripOptimizationMarkers() {
var insn = instructions.first
while (insn != null) {
if (isOptimizationMarker(insn)) {
insn = instructions.removeNodeGetNext(insn)
insn = if (isOptimizationMarker(insn)) {
instructions.removeNodeGetNext(insn)
} else {
insn = insn.next
insn.next
}
}
}
@@ -123,7 +126,7 @@ fun MethodNode.removeUnusedLocalVariables() {
// Arguments are always used whether or not they are in the local variable table
// or used by instructions.
var argumentIndex = 0
val isStatic = (access and Opcodes.ACC_STATIC) != 0
val isStatic = (access and ACC_STATIC) != 0
if (!isStatic) {
used[argumentIndex++] = true
}
@@ -230,8 +233,8 @@ val AbstractInsnNode.intConstant: Int?
fun insnListOf(vararg insns: AbstractInsnNode) = InsnList().apply { insns.forEach { add(it) } }
fun AbstractInsnNode.isStoreOperation(): Boolean = opcode in Opcodes.ISTORE..Opcodes.ASTORE
fun AbstractInsnNode.isLoadOperation(): Boolean = opcode in Opcodes.ILOAD..Opcodes.ALOAD
fun AbstractInsnNode.isStoreOperation(): Boolean = opcode in ISTORE..ASTORE
fun AbstractInsnNode.isLoadOperation(): Boolean = opcode in ILOAD..ALOAD
val AbstractInsnNode?.debugText
get() =

View File

@@ -441,7 +441,7 @@ fun MethodNode.usesLocalExceptParameterNullCheck(index: Int): Boolean =
it is VarInsnNode && it.opcode == Opcodes.ALOAD && it.`var` == index && !it.isParameterCheckedForNull()
}
internal fun AbstractInsnNode.isParameterCheckedForNull(): Boolean =
fun AbstractInsnNode.isParameterCheckedForNull(): Boolean =
next?.takeIf { it.opcode == Opcodes.LDC }?.next?.isCheckParameterIsNotNull() == true
internal fun AbstractInsnNode.isCheckParameterIsNotNull() =

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

@@ -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

@@ -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

@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.daemon.client.experimental
import io.ktor.network.sockets.Socket
import io.ktor.network.sockets.*
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
@@ -438,6 +438,7 @@ class KotlinCompilerClient : KotlinCompilerDaemonClient {
.thenBy(FileAgeComparator()) { it.runFile }
val optsCopy = daemonJVMOptions.copy()
// if required options fit into fattest running daemon - return the daemon and required options with memory params set to actual ones in the daemon
@Suppress("DEPRECATION") // TODO: replace with maxWithOrNull as soon as minimal version of Gradle that we support has Kotlin 1.4+.
aliveWithMetadata.maxWith(comparator)
?.takeIf { daemonJVMOptions memorywiseFitsInto it.jvmOptions }
?.let {

View File

@@ -359,6 +359,7 @@ object KotlinCompilerClient {
.thenBy(FileAgeComparator()) { it.runFile }
val optsCopy = daemonJVMOptions.copy()
// if required options fit into fattest running daemon - return the daemon and required options with memory params set to actual ones in the daemon
@Suppress("DEPRECATION") // TODO: replace with maxWithOrNull as soon as minimal version of Gradle that we support has Kotlin 1.4+.
return aliveWithMetadata.maxWith(comparator)?.takeIf { daemonJVMOptions memorywiseFitsInto it.jvmOptions }?.let {
Pair(it.daemon, optsCopy.updateMemoryUpperBounds(it.jvmOptions))
}

View File

@@ -1,9 +1,9 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
* 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.
*/
@file:OptIn(ExperimentalPathApi::class)
@file:OptIn(ExperimentalPathApi::class, DelicateCoroutinesApi::class)
package org.jetbrains.kotlin.daemon.experimental.integration

View File

@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.daemon.experimental.unit
import io.ktor.network.sockets.aSocket
import io.ktor.util.*
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.runBlocking
@@ -31,6 +32,7 @@ class TestServer(val serverPort: Int = 6999) {
private val serverSocket = aSocket(selectorMgr).tcp().bind(InetSocketAddress(serverPort))
private val log = Logger.getLogger("TestServer")
@OptIn(DelicateCoroutinesApi::class)
fun awaitClient() = GlobalScope.async {
log.info("accepting clientSocket...")
val client = serverSocket.accept()
@@ -61,7 +63,7 @@ class ClientSerializationTest : KotlinIntegrationTestBase() {
}
}
log.info("printed")
var client2: T? = null
var client2: T?
var connected = false
runBlocking {
val clientAwait = testServer.awaitClient()

View File

@@ -621,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");
@@ -2696,6 +2701,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/overrides/protobufExt.kt");
}
@TestMetadata("sameValueParametersDifferentReceiver.kt")
public void testSameValueParametersDifferentReceiver() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/overrides/sameValueParametersDifferentReceiver.kt");
}
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/overrides/simple.kt");
@@ -3059,6 +3069,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/equalsAndIdentity.kt");
}
@TestMetadata("incorrectSmartcastToNothing.kt")
public void testIncorrectSmartcastToNothing() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/incorrectSmartcastToNothing.kt");
}
@TestMetadata("kt10240.kt")
public void testKt10240() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/kt10240.kt");

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

@@ -7,7 +7,7 @@ FILE: typeAliasWithNotNullBound.kt
}
public final typealias MyAlias = R|Inv<out kotlin/CharSequence>|
public final fun foo(p: R|MyAlias|): R|kotlin/Unit| {
R|/bar|<R|kotlin/CharSequence|>(R|<local>/p|).R|kotlin/CharSequence.length|
R|/bar|<R|CapturedType(out kotlin/CharSequence)|>(R|<local>/p|).R|kotlin/CharSequence.length|
}
public final fun <T : R|kotlin/Any|> bar(x: R|Inv<T>|): R|T| {
^bar R|kotlin/TODO|()

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

@@ -8,17 +8,17 @@ fun test() {}
fun test(z: Int, c: Char) {}
<!REDECLARATION!>open class A {
open class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
open fun rest(s: String) {}
open val u = 20
}<!>
}
<!REDECLARATION!>class A {
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>A<!> {
}<!>
}
<!REDECLARATION!>class B : <!FINAL_SUPERTYPE, SUPERTYPE_NOT_INITIALIZED!>A<!> {
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : <!FINAL_SUPERTYPE, SUPERTYPE_NOT_INITIALIZED!>A<!> {
<!CONFLICTING_OVERLOADS!><!NOTHING_TO_OVERRIDE!>override<!> fun rest(s: String)<!> {}
<!CONFLICTING_OVERLOADS!>fun rest(s: String)<!> {}
@@ -26,17 +26,17 @@ fun test(z: Int, c: Char) {}
fun rest(l: Long) {}
<!NOTHING_TO_OVERRIDE!>override<!> val u = 310
}<!>
}
<!REDECLARATION!>interface B<!>
interface <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!>
<!REDECLARATION!>enum class B<!>
enum class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!>
<!REDECLARATION!>val u = 10<!>
<!REDECLARATION!>val u = 20<!>
val <!REDECLARATION!>u<!> = 10
val <!REDECLARATION!>u<!> = 20
<!REDECLARATION!>typealias TA = A<!>
<!REDECLARATION!>typealias TA = B<!>
typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = A
typealias <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>TA<!> = B
typealias BA = A
@@ -52,7 +52,7 @@ fun lol(a: Array<Boolean>) {}
class M {
companion <!REDECLARATION!>object<!> {}
<!REDECLARATION!>val Companion = object : Any {}<!>
val <!REDECLARATION!>Companion<!> = object : Any {}
}
fun B.foo() {}

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

@@ -37,7 +37,7 @@ class F(var a: Int, b: Int, closure: () -> Unit, instance: F?) {
val a = 10
<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>
test(<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>)
<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.<!UNRESOLVED_REFERENCE!>a<!> = 20
<!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>.a = 20
}, <!INSTANCE_ACCESS_BEFORE_SUPER_CALL!>this<!>) {
this.a = 30
}

View File

@@ -14,7 +14,7 @@ FILE: notASupertype.kt
}
public final fun g(): R|kotlin/Unit| {
this@R|/B|.super<R|kotlin/String|>.<Unresolved name: f>#()
this@R|/B|.super<<ERROR TYPE REF: Not a super type>>.<Unresolved name: f>#()
this@R|/B|.super<R|A|>.R|/A.f|()
}

View File

@@ -4,7 +4,7 @@ open class A {
class B : <!SUPERTYPE_NOT_INITIALIZED!>A<!> {
fun g() {
<!NOT_A_SUPERTYPE!>super<String><!>.<!UNRESOLVED_REFERENCE!>f<!>()
super<<!NOT_A_SUPERTYPE!>String<!>>.f()
super<A>.f()
}
}

View File

@@ -2,7 +2,7 @@
sealed class A
<!REDECLARATION!>class B : A()<!>
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> : A()
interface C : <!INTERFACE_WITH_SUPERCLASS!>A<!>
@@ -30,7 +30,7 @@ sealed class P {
class K : P()
<!REDECLARATION!>object B<!> {
object <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>B<!> {
class I : P()
}

View File

@@ -1,12 +1,12 @@
FILE: superNotAvailable.kt
public final fun R|kotlin/String|.f(): R|kotlin/Unit| {
super<<ERROR TYPE REF: No super type>>@f#.<Unresolved name: compareTo>#(String())
super<<ERROR TYPE REF: No super type>>.<Unresolved name: compareTo>#(String())
<Super not available>#.<Unresolved name: compareTo>#(String())
<Super not available>#.<Unresolved name: compareTo>#(String())
}
public final fun foo(): R|kotlin/Unit| {
super<<ERROR TYPE REF: No super type>>
super<<ERROR TYPE REF: No super type>>.<Unresolved name: foo>#()
super<R|kotlin/Nothing|>.<Unresolved name: foo>#()
<Super not allowed>#
<Super not available>#.<Unresolved name: foo>#()
<Super not available>#.<Unresolved name: foo>#()
}
public final class A : R|kotlin/Any| {
public constructor(): R|A| {

View File

@@ -1,12 +1,12 @@
fun String.f() {
<!SUPER_NOT_AVAILABLE!>super@f<!>.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
<!SUPER_NOT_AVAILABLE!>super<!>.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
<!SUPER_NOT_AVAILABLE!>super@f<!>.compareTo("")
<!SUPER_NOT_AVAILABLE!>super<!>.compareTo("")
}
fun foo() {
<!SUPER_NOT_AVAILABLE!>super<!>
<!SUPER_NOT_AVAILABLE!>super<!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!SUPER_NOT_AVAILABLE!>super<Nothing><!>.<!UNRESOLVED_REFERENCE!>foo<!>()
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>
<!SUPER_NOT_AVAILABLE!>super<!>.foo()
<!SUPER_NOT_AVAILABLE!>super<Nothing><!>.foo()
}
class A {

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

@@ -2,7 +2,7 @@
fun x() {}
operator fun Int.invoke(): Foo = <!UNRESOLVED_LABEL!>this@Foo<!>
operator fun Int.invoke(): Foo = this<!UNRESOLVED_LABEL!>@Foo<!>
class Foo {

View File

@@ -1,6 +1,6 @@
<!REDECLARATION!>object A<!>
object <!REDECLARATION!>A<!>
<!REDECLARATION!>val A = 10<!>
val <!REDECLARATION!>A<!> = 10
fun foo() = A

View File

@@ -137,7 +137,7 @@ fun main(args: Array<String?>) {
<!ASSIGNED_VALUE_IS_NEVER_READ!>a<!> = args[0]
} else {
a = args.toString()
if (a != null && a.equals("cde")) return
if (<!SENSELESS_COMPARISON!>a != null<!> && a.equals("cde")) return
}
}

View File

@@ -2,15 +2,15 @@
@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class Ann
<!REDECLARATION!>var x: Int
var <!REDECLARATION!>x<!>: Int
get() = 1
set(@Ann private x) { }<!>
set(@Ann private x) { }
<!REDECLARATION!>var x: String = ""
var <!REDECLARATION!>x<!>: String = ""
set(param: <!REDUNDANT_SETTER_PARAMETER_TYPE!>String<!>) {
field = "$param "
}<!>
}
class My {
var y: Int = 1
@@ -25,4 +25,4 @@ class My {
set(param) {
field = !param
}
}
}

View File

@@ -6,15 +6,15 @@ fun f() {
LocalClass().foo = 1
}
internal inline fun internal() {
internal <!NOTHING_TO_INLINE!>inline<!> fun internal() {
f()
}
<!REDECLARATION!>class C {
class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!> {
internal val z = object {
fun foo() = 13
}
}<!>
}
class Foo2<
T1,
@@ -26,12 +26,12 @@ class Foo2<
internal inner class B<T,T2,>
}
<!REDECLARATION!><!REDUNDANT_VISIBILITY_MODIFIER!>public<!> class C {
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> class <!PACKAGE_OR_CLASSIFIER_REDECLARATION!>C<!> {
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> val foo: Int = 0
<!REDUNDANT_VISIBILITY_MODIFIER!>public<!> fun bar() {}
}<!>
}
open class D {
protected open fun willRemainProtected() {

View File

@@ -15,7 +15,7 @@ open class B {
override fun foo() {
super.foo()
super.<!UNRESOLVED_REFERENCE!>bar<!>() // should be ambiguity (NB: really we should have overridden bar in C)
<!AMBIGUOUS_SUPER!>super<!>.bar() // should be ambiguity (NB: really we should have overridden bar in C)
super.baz() // Ok
baz() // Ok

View File

@@ -4,5 +4,5 @@ FILE: main.kt
public final fun <D : R|A|> foo(b: R|B<D>|): R|kotlin/Unit| {
}
public final fun main(b: R|B<*>|): R|kotlin/Unit| {
R|/foo|<R|ft<A, A?>|>(R|<local>/b|)
R|/foo|<R|CapturedType(*)|>(R|<local>/b|)
}

View File

@@ -5,7 +5,7 @@ FILE: kt40131.kt
}
public final val <T : R|kotlin/reflect/KClass<*>|> R|T|.myJava1: R|java/lang/Class<*>|
public get(): R|java/lang/Class<*>| {
^ this@R|/myJava1|.R|/javaImpl|<R|kotlin/Any|>
^ this@R|/myJava1|.R|/javaImpl|<R|CapturedType(*)|>
}
public final val <E : R|kotlin/Any|, T : R|kotlin/reflect/KClass<E>|> R|T|.myJava2: R|java/lang/Class<E>|
public get(): R|java/lang/Class<E>| {

View File

@@ -15,19 +15,19 @@ FILE: receiverWithCapturedType.kt
^updateD R|<local>/d|
}
public final fun test_1_1(resolvedCall: R|ResolvedCall<out CallableDescriptor>|): R|kotlin/Unit| {
R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CallableDescriptor|>()
R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CapturedType(out CallableDescriptor)|>()
}
public final fun test_1_2(resolvedCall: R|ResolvedCall<in CallableDescriptor>|): R|kotlin/Unit| {
R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CallableDescriptor|>()
R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CapturedType(in CallableDescriptor)|>()
}
public final fun test_1_3(resolvedCall: R|ResolvedCall<CallableDescriptor>|): R|kotlin/Unit| {
R|<local>/resolvedCall|.R|/getParameterForArgument|<R|CallableDescriptor|>()
}
public final fun test_2_1(resolvedCall: R|ResolvedCall<out CallableDescriptor>|, d: R|CallableDescriptor|): R|kotlin/Unit| {
lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.<Inapplicable(INAPPLICABLE): /updateD>#<R|CallableDescriptor|>(R|<local>/d|)
lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.<Inapplicable(INAPPLICABLE): /updateD>#<R|CapturedType(out CallableDescriptor)|>(R|<local>/d|)
}
public final fun test_2_2(resolvedCall: R|ResolvedCall<in CallableDescriptor>|, d: R|CallableDescriptor|): R|kotlin/Unit| {
lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.R|/updateD|<R|CallableDescriptor|>(R|<local>/d|)
lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.R|/updateD|<R|CapturedType(in CallableDescriptor)|>(R|<local>/d|)
}
public final fun test_2_3(resolvedCall: R|ResolvedCall<CallableDescriptor>|, d: R|CallableDescriptor|): R|kotlin/Unit| {
lval x: R|CallableDescriptor| = R|<local>/resolvedCall|.R|/updateD|<R|CallableDescriptor|>(R|<local>/d|)

View File

@@ -19,10 +19,10 @@ FILE: simpleCapturedTypes.kt
^ this@R|/idP|
}
private final fun getSetterInfos(kc: R|KC<out Ann>|): R|kotlin/Unit| {
R|/id|<R|Ann|>(R|<local>/kc|).R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
R|<local>/kc|.R|/idR|<R|Ann|>().R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
R|<local>/kc|.R|/idP|<R|Ann|>.R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
lval x1: R|KC<out Ann>| = R|/id|<R|Ann|>(R|<local>/kc|)
lval x2: R|KC<out Ann>| = R|<local>/kc|.R|/idR|<R|Ann|>()
lval x3: R|KC<out Ann>| = R|<local>/kc|.R|/idP|<R|Ann|>
R|/id|<R|CapturedType(out Ann)|>(R|<local>/kc|).R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
R|<local>/kc|.R|/idR|<R|CapturedType(out Ann)|>().R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
R|<local>/kc|.R|/idP|<R|CapturedType(out Ann)|>.R|SubstitutionOverride</KC.x: R|CapturedType(out Ann)|>|.R|/Ann.foo|()
lval x1: R|KC<out Ann>| = R|/id|<R|CapturedType(out Ann)|>(R|<local>/kc|)
lval x2: R|KC<out Ann>| = R|<local>/kc|.R|/idR|<R|CapturedType(out Ann)|>()
lval x3: R|KC<out Ann>| = R|<local>/kc|.R|/idP|<R|CapturedType(out Ann)|>
}

View File

@@ -0,0 +1,21 @@
FILE: sameValueParametersDifferentReceiver.kt
public open class A : R|kotlin/Any| {
public constructor(): R|A| {
super<R|kotlin/Any|>()
}
public final fun R|kotlin/String|.foo(from: R|kotlin/String|, to: R|kotlin/String|): R|kotlin/Int| {
^foo Int(1)
}
public final fun <T> R|T|.foo(from: R|kotlin/String|, to: R|kotlin/String|): R|kotlin/Int| {
^foo Int(1)
}
}
public final class B : R|A| {
public constructor(): R|B| {
super<R|A|>()
}
}

View File

@@ -0,0 +1,11 @@
open class A {
fun String.foo(from: String, to: String): Int {
return 1
}
fun <T> T.foo(from: String, to: String): Int {
return 1
}
}
class B : A()

View File

@@ -40,8 +40,8 @@ FILE: referenceToExtension.kt
}
public final fun test_2(): R|kotlin/Unit| {
lval extensionValRef: R|kotlin/reflect/KProperty1<GenericTest.B<*>, GenericTest.A<CapturedType(*)>>| = Q|GenericTest.B|::R|/GenericTest.extensionVal<kotlin/Any?>|
lval extensionFunRef: R|@ExtensionFunctionType kotlin/reflect/KFunction1<GenericTest.B<*>, GenericTest.A<CapturedType(*)>>| = Q|GenericTest.B|::R|/GenericTest.extensionFun<kotlin/Any?>|
lval extensionValRef: R|kotlin/reflect/KProperty1<GenericTest.B<*>, GenericTest.A<CapturedType(*)>>| = Q|GenericTest.B|::R|/GenericTest.extensionVal<CapturedType(*)>|
lval extensionFunRef: R|@ExtensionFunctionType kotlin/reflect/KFunction1<GenericTest.B<*>, GenericTest.A<CapturedType(*)>>| = Q|GenericTest.B|::R|/GenericTest.extensionFun<CapturedType(*)>|
}
}

View File

@@ -702,44 +702,45 @@ digraph boundSmartcastsInBranches_kt {
293 [label="Access variable R|<local>/x|"];
294 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
295 [label="Access variable R|<local>/y|"];
296 [label="Access variable R|kotlin/String.length|"];
297 [label="Access variable R|<local>/z|"];
298 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
299 [label="Exit block"];
296 [label="Stub" style="filled" fillcolor=gray];
297 [label="Access variable R|kotlin/String.length|" style="filled" fillcolor=gray];
298 [label="Access variable R|<local>/z|" style="filled" fillcolor=gray];
299 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#" style="filled" fillcolor=gray];
300 [label="Exit block" style="filled" fillcolor=gray];
}
300 [label="Exit when branch result"];
301 [label="Exit when"];
301 [label="Exit when branch result" style="filled" fillcolor=gray];
302 [label="Exit when"];
}
subgraph cluster_67 {
color=blue
302 [label="Enter when"];
303 [label="Enter when"];
subgraph cluster_68 {
color=blue
303 [label="Enter when branch condition "];
304 [label="Access variable R|<local>/z|"];
305 [label="Const: Null(null)"];
306 [label="Equality operator !="];
307 [label="Exit when branch condition"];
304 [label="Enter when branch condition "];
305 [label="Access variable R|<local>/z|"];
306 [label="Const: Null(null)"];
307 [label="Equality operator !="];
308 [label="Exit when branch condition"];
}
308 [label="Synthetic else branch"];
309 [label="Enter when branch result"];
309 [label="Synthetic else branch"];
310 [label="Enter when branch result"];
subgraph cluster_69 {
color=blue
310 [label="Enter block"];
311 [label="Access variable R|<local>/x|"];
312 [label="Access variable R|kotlin/String.length|"];
313 [label="Access variable R|<local>/y|"];
314 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
315 [label="Access variable R|<local>/z|"];
316 [label="Access variable R|kotlin/String.length|"];
317 [label="Exit block"];
311 [label="Enter block"];
312 [label="Access variable R|<local>/x|"];
313 [label="Access variable R|kotlin/String.length|"];
314 [label="Access variable R|<local>/y|"];
315 [label="Access variable <Inapplicable(UNSAFE_CALL): kotlin/String.length>#"];
316 [label="Access variable R|<local>/z|"];
317 [label="Access variable R|kotlin/String.length|"];
318 [label="Exit block"];
}
318 [label="Exit when branch result"];
319 [label="Exit when"];
319 [label="Exit when branch result"];
320 [label="Exit when"];
}
320 [label="Exit block"];
321 [label="Exit block"];
}
321 [label="Exit function test_7" style="filled" fillcolor=red];
322 [label="Exit function test_7" style="filled" fillcolor=red];
}
202 -> {203};
203 -> {204};
@@ -829,26 +830,27 @@ digraph boundSmartcastsInBranches_kt {
287 -> {288};
288 -> {289};
289 -> {291 290};
290 -> {301};
290 -> {302};
291 -> {292};
292 -> {293};
293 -> {294};
294 -> {295};
295 -> {296};
296 -> {297};
297 -> {298};
298 -> {299};
299 -> {300};
300 -> {301};
301 -> {302};
295 -> {322} [label=onUncaughtException];
295 -> {296} [style=dotted];
296 -> {297} [style=dotted];
297 -> {298} [style=dotted];
298 -> {299} [style=dotted];
299 -> {300} [style=dotted];
300 -> {301} [style=dotted];
301 -> {302} [style=dotted];
302 -> {303};
303 -> {304};
304 -> {305};
305 -> {306};
306 -> {307};
307 -> {309 308};
308 -> {319};
309 -> {310};
307 -> {308};
308 -> {310 309};
309 -> {320};
310 -> {311};
311 -> {312};
312 -> {313};
@@ -860,5 +862,6 @@ digraph boundSmartcastsInBranches_kt {
318 -> {319};
319 -> {320};
320 -> {321};
321 -> {322};
}

View File

@@ -107,7 +107,7 @@ fun test_7() {
y<!UNSAFE_CALL!>.<!>length // Bad
z.length // OK
}
if (y != null) {
if (<!SENSELESS_COMPARISON!>y != null<!>) {
x<!UNSAFE_CALL!>.<!>length // Bad
y.length // OK
z<!UNSAFE_CALL!>.<!>length // Bad

View File

@@ -0,0 +1,144 @@
digraph incorrectSmartcastToNothing_kt {
graph [nodesep=3]
node [shape=box penwidth=2]
edge [penwidth=2]
subgraph cluster_0 {
color=red
0 [label="Enter property" style="filled" fillcolor=red];
1 [label="Const: String(foo)"];
2 [label="Function call: R|java/io/File.File|(...)"];
3 [label="Exit property" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
subgraph cluster_1 {
color=red
4 [label="Enter function test" style="filled" fillcolor=red];
subgraph cluster_2 {
color=blue
5 [label="Enter block"];
subgraph cluster_3 {
color=blue
6 [label="Enter when"];
subgraph cluster_4 {
color=blue
7 [label="Enter when branch condition "];
8 [label="Access variable R|<local>/cacheExtSetting|"];
9 [label="Const: Null(null)"];
10 [label="Equality operator =="];
11 [label="Exit when branch condition"];
}
subgraph cluster_5 {
color=blue
12 [label="Enter when branch condition "];
13 [label="Access variable R|<local>/cacheExtSetting|"];
14 [label="Function call: R|<local>/cacheExtSetting|.R|kotlin/text/isBlank|()"];
15 [label="Exit when branch condition"];
}
subgraph cluster_6 {
color=blue
16 [label="Enter when branch condition else"];
17 [label="Exit when branch condition"];
}
18 [label="Enter when branch result"];
subgraph cluster_7 {
color=blue
19 [label="Enter block"];
20 [label="Access variable R|<local>/cacheExtSetting|"];
21 [label="Function call: R|java/io/File.File|(...)"];
22 [label="Exit block"];
}
23 [label="Exit when branch result"];
24 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
25 [label="Enter block"];
26 [label="Const: Null(null)"];
27 [label="Exit block"];
}
28 [label="Exit when branch result"];
29 [label="Enter when branch result"];
subgraph cluster_9 {
color=blue
30 [label="Enter block"];
31 [label="Access variable R|/cache|"];
32 [label="Enter safe call"];
33 [label="Postponed enter to lambda"];
subgraph cluster_10 {
color=blue
43 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_11 {
color=blue
44 [label="Enter block"];
45 [label="Access variable R|<local>/it|"];
46 [label="Const: String(main.kts.compiled.cache)"];
47 [label="Function call: R|java/io/File.File|(...)"];
48 [label="Exit block"];
}
49 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
34 [label="Postponed exit from lambda"];
35 [label="Function call: $subj$.R|kotlin/let|<R|java/io/File|, R|java/io/File|>(...)"];
36 [label="Exit safe call"];
37 [label="Exit block"];
}
38 [label="Exit when branch result"];
39 [label="Exit when"];
}
40 [label="Variable declaration: lval cacheBaseDir: R|java/io/File?|"];
41 [label="Exit block"];
}
42 [label="Exit function test" style="filled" fillcolor=red];
}
4 -> {5};
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {29 12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {24 16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {39};
24 -> {25};
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {39};
29 -> {30};
30 -> {31};
31 -> {32 36};
32 -> {33};
33 -> {43};
33 -> {34} [color=red];
33 -> {43} [style=dashed];
34 -> {35};
35 -> {36};
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {40};
40 -> {41};
41 -> {42};
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {34} [color=green];
}

View File

@@ -0,0 +1,20 @@
FILE: incorrectSmartcastToNothing.kt
public final val cache: R|java/io/File?| = R|java/io/File.File|(String(foo))
public get(): R|java/io/File?|
public final fun test(cacheExtSetting: R|kotlin/String?|): R|kotlin/Unit| {
lval cacheBaseDir: R|java/io/File?| = when () {
==(R|<local>/cacheExtSetting|, Null(null)) -> {
R|/cache|?.{ $subj$.R|kotlin/let|<R|java/io/File|, R|java/io/File|>(<L> = let@fun <anonymous>(it: R|java/io/File|): R|java/io/File| <inline=Inline, kind=EXACTLY_ONCE> {
^ R|java/io/File.File|(R|<local>/it|, String(main.kts.compiled.cache))
}
) }
}
R|<local>/cacheExtSetting|.R|kotlin/text/isBlank|() -> {
Null(null)
}
else -> {
R|java/io/File.File|(R|<local>/cacheExtSetting|)
}
}
}

View File

@@ -0,0 +1,15 @@
// WITH_STDLIB
// FULL_JDK
// DUMP_CFG
import java.io.File
val cache: File? = File("foo")
fun test(cacheExtSetting: String?) {
val cacheBaseDir = when {
cacheExtSetting == null -> cache?.let { File(it, "main.kts.compiled.cache") }
cacheExtSetting.isBlank() -> null
else -> File(cacheExtSetting)
}
}

View File

@@ -14,7 +14,7 @@ var Any?.isNotNull: Boolean
set(value) {
contract {
returns() implies (this@isNotNull != null)
<!ERROR_IN_CONTRACT_DESCRIPTION!>require(this != null)<!>
<!ERROR_IN_CONTRACT_DESCRIPTION!>require(<!SENSELESS_COMPARISON!>this != null<!>)<!>
}
}

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

@@ -7,7 +7,7 @@ FILE: test.kt
super<R|kotlin/Any|>()
}
private final val klass: R|java/lang/Class<out MyTest>| = <getClass>(this@R|/MyTest|).R|kotlin/jvm/java|<R|MyTest|>
private final val klass: R|java/lang/Class<out MyTest>| = <getClass>(this@R|/MyTest|).R|kotlin/jvm/java|<R|CapturedType(out MyTest)|>
private get(): R|java/lang/Class<out MyTest>|
private final val logger: R|ft<Logger, Logger?>| = Q|Logger|.R|/Logger.getInstance|(this@R|/MyTest|.R|/MyTest.klass|)

View File

@@ -1,4 +1,4 @@
FILE: capturedFlexible.kt
public final fun foo(z: R|java/util/zip/ZipFile|): R|kotlin/Unit| {
R|<local>/z|.R|java/util/zip/ZipFile.entries|().R|kotlin/sequences/asSequence|<R|ft<java/util/zip/ZipEntry, java/util/zip/ZipEntry?>|>()
R|<local>/z|.R|java/util/zip/ZipFile.entries|().R|kotlin/sequences/asSequence|<R|CapturedType(out ft<java/util/zip/ZipEntry, java/util/zip/ZipEntry?>)|>()
}

View File

@@ -13,7 +13,7 @@ fun test() {
val Any.bar get() = "456"
val String.bar get() = "987"
<!REDECLARATION!>val t = "".bar<!>
val <!REDECLARATION!>t<!> = "".bar
val p = Pair(0, "")
@@ -21,4 +21,4 @@ open class Base<T>(val x: T)
class Derived : Base<Int>(10)
val xx = Derived().x + 1
<!REDECLARATION!>val t = throw AssertionError("")<!>
val <!REDECLARATION!>t<!> = throw AssertionError("")

View File

@@ -731,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 {
@@ -3053,6 +3059,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/overrides/protobufExt.kt");
}
@Test
@TestMetadata("sameValueParametersDifferentReceiver.kt")
public void testSameValueParametersDifferentReceiver() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/overrides/sameValueParametersDifferentReceiver.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
@@ -3455,6 +3467,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/equalsAndIdentity.kt");
}
@Test
@TestMetadata("incorrectSmartcastToNothing.kt")
public void testIncorrectSmartcastToNothing() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/incorrectSmartcastToNothing.kt");
}
@Test
@TestMetadata("kt10240.kt")
public void testKt10240() throws Exception {
@@ -5006,6 +5024,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")

View File

@@ -731,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 {
@@ -3053,6 +3059,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/overrides/protobufExt.kt");
}
@Test
@TestMetadata("sameValueParametersDifferentReceiver.kt")
public void testSameValueParametersDifferentReceiver() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/overrides/sameValueParametersDifferentReceiver.kt");
}
@Test
@TestMetadata("simple.kt")
public void testSimple() throws Exception {
@@ -3455,6 +3467,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/equalsAndIdentity.kt");
}
@Test
@TestMetadata("incorrectSmartcastToNothing.kt")
public void testIncorrectSmartcastToNothing() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolve/smartcasts/incorrectSmartcastToNothing.kt");
}
@Test
@TestMetadata("kt10240.kt")
public void testKt10240() throws Exception {
@@ -5006,6 +5024,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")

View File

@@ -5908,6 +5908,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/definiteReturn/kt4034.kt");
}
@Test
@TestMetadata("lambdaInTryFalsePositive.kt")
public void testLambdaInTryFalsePositive() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/definiteReturn/lambdaInTryFalsePositive.kt");
}
@Test
@TestMetadata("ReturnFromFunctionInObject.kt")
public void testReturnFromFunctionInObject() throws Exception {
@@ -6013,6 +6019,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/controlStructures"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("breakToLabel.kt")
public void testBreakToLabel() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlStructures/breakToLabel.kt");
}
@Test
@TestMetadata("catchGenerics.kt")
public void testCatchGenerics() throws Exception {
@@ -7495,6 +7507,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt");
}
@Test
@TestMetadata("mappedFunctionNotImplemented.kt")
public void testMappedFunctionNotImplemented() throws Exception {
runTest("compiler/testData/diagnostics/tests/declarationChecks/mappedFunctionNotImplemented.kt");
}
@Test
@TestMetadata("mulitpleVarargParameters.kt")
public void testMulitpleVarargParameters() throws Exception {
@@ -10705,6 +10723,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt4529.kt");
}
@Test
@TestMetadata("kt47493.kt")
public void testKt47493() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt47493.kt");
}
@Test
@TestMetadata("kt6541_extensionForExtensionFunction.kt")
public void testKt6541_extensionForExtensionFunction() throws Exception {
@@ -15234,6 +15258,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 {
@@ -21646,12 +21676,30 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("deepTypeHierarchy.kt")
public void testDeepTypeHierarchy() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/deepTypeHierarchy.kt");
}
@Test
@TestMetadata("inferenceFrom.kt")
public void testInferenceFrom() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/inferenceFrom.kt");
}
@Test
@TestMetadata("javaOutProjection.kt")
public void testJavaOutProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.kt");
}
@Test
@TestMetadata("kotlinOutProjection.kt")
public void testKotlinOutProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.kt");
}
@Test
@TestMetadata("listSuperType.kt")
public void testListSuperType() throws Exception {
@@ -22330,6 +22378,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
@TestMetadata("compiler/testData/diagnostics/tests/properties")
@TestDataPath("$PROJECT_ROOT")
public class Properties {
@Test
@TestMetadata("abstarctPropertyInPrimaryConstructor.kt")
public void testAbstarctPropertyInPrimaryConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/properties/abstarctPropertyInPrimaryConstructor.kt");
}
@Test
public void testAllFilesPresentInProperties() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/properties"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
@@ -22763,6 +22817,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredTypeParameters.kt");
}
@Test
@TestMetadata("RedeclaredValueParameters.kt")
public void testRedeclaredValueParameters() throws Exception {
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredValueParameters.kt");
}
@Test
@TestMetadata("RedeclaringPrivateToFile.kt")
public void testRedeclaringPrivateToFile() throws Exception {
@@ -28205,6 +28265,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/smartCasts/variables/accessorAndFunction.kt");
}
@Test
@TestMetadata("aliasing.kt")
public void testAliasing() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/variables/aliasing.kt");
}
@Test
public void testAllFilesPresentInVariables() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/smartCasts/variables"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
@@ -31915,6 +31981,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 {
@@ -32071,6 +32143,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/when/whenAndLambdaWithExpectedType.kt");
}
@Test
@TestMetadata("whenOnNothing.kt")
public void testWhenOnNothing() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/whenOnNothing.kt");
}
@Test
@TestMetadata("WhenTypeDisjunctions.kt")
public void testWhenTypeDisjunctions() throws Exception {

View File

@@ -5908,6 +5908,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/definiteReturn/kt4034.kt");
}
@Test
@TestMetadata("lambdaInTryFalsePositive.kt")
public void testLambdaInTryFalsePositive() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlFlowAnalysis/definiteReturn/lambdaInTryFalsePositive.kt");
}
@Test
@TestMetadata("ReturnFromFunctionInObject.kt")
public void testReturnFromFunctionInObject() throws Exception {
@@ -6013,6 +6019,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/controlStructures"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("breakToLabel.kt")
public void testBreakToLabel() throws Exception {
runTest("compiler/testData/diagnostics/tests/controlStructures/breakToLabel.kt");
}
@Test
@TestMetadata("catchGenerics.kt")
public void testCatchGenerics() throws Exception {
@@ -7495,6 +7507,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/declarationChecks/localVariablesWithTypeParameters_1_4.kt");
}
@Test
@TestMetadata("mappedFunctionNotImplemented.kt")
public void testMappedFunctionNotImplemented() throws Exception {
runTest("compiler/testData/diagnostics/tests/declarationChecks/mappedFunctionNotImplemented.kt");
}
@Test
@TestMetadata("mulitpleVarargParameters.kt")
public void testMulitpleVarargParameters() throws Exception {
@@ -10705,6 +10723,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt4529.kt");
}
@Test
@TestMetadata("kt47493.kt")
public void testKt47493() throws Exception {
runTest("compiler/testData/diagnostics/tests/functionLiterals/kt47493.kt");
}
@Test
@TestMetadata("kt6541_extensionForExtensionFunction.kt")
public void testKt6541_extensionForExtensionFunction() throws Exception {
@@ -15234,6 +15258,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 {
@@ -21646,12 +21676,30 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("deepTypeHierarchy.kt")
public void testDeepTypeHierarchy() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/deepTypeHierarchy.kt");
}
@Test
@TestMetadata("inferenceFrom.kt")
public void testInferenceFrom() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/inferenceFrom.kt");
}
@Test
@TestMetadata("javaOutProjection.kt")
public void testJavaOutProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/javaOutProjection.kt");
}
@Test
@TestMetadata("kotlinOutProjection.kt")
public void testKotlinOutProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/platformTypes/genericVarianceViolation/kotlinOutProjection.kt");
}
@Test
@TestMetadata("listSuperType.kt")
public void testListSuperType() throws Exception {
@@ -22330,6 +22378,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
@TestMetadata("compiler/testData/diagnostics/tests/properties")
@TestDataPath("$PROJECT_ROOT")
public class Properties {
@Test
@TestMetadata("abstarctPropertyInPrimaryConstructor.kt")
public void testAbstarctPropertyInPrimaryConstructor() throws Exception {
runTest("compiler/testData/diagnostics/tests/properties/abstarctPropertyInPrimaryConstructor.kt");
}
@Test
public void testAllFilesPresentInProperties() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/properties"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
@@ -22763,6 +22817,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredTypeParameters.kt");
}
@Test
@TestMetadata("RedeclaredValueParameters.kt")
public void testRedeclaredValueParameters() throws Exception {
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclaredValueParameters.kt");
}
@Test
@TestMetadata("RedeclaringPrivateToFile.kt")
public void testRedeclaringPrivateToFile() throws Exception {
@@ -28205,6 +28265,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/smartCasts/variables/accessorAndFunction.kt");
}
@Test
@TestMetadata("aliasing.kt")
public void testAliasing() throws Exception {
runTest("compiler/testData/diagnostics/tests/smartCasts/variables/aliasing.kt");
}
@Test
public void testAllFilesPresentInVariables() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/smartCasts/variables"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
@@ -31915,6 +31981,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 {
@@ -32071,6 +32143,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/when/whenAndLambdaWithExpectedType.kt");
}
@Test
@TestMetadata("whenOnNothing.kt")
public void testWhenOnNothing() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/whenOnNothing.kt");
}
@Test
@TestMetadata("WhenTypeDisjunctions.kt")
public void testWhenTypeDisjunctions() throws Exception {

View File

@@ -5,6 +5,7 @@ plugins {
}
dependencies {
implementation(project(":generators"))
implementation(project(":compiler:fir:tree"))
implementation(project(":compiler:fir:tree:tree-generator"))
implementation(project(":compiler:resolution.common"))

View File

@@ -14,16 +14,16 @@ 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.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.lexer.KtKeywordToken
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
@@ -87,11 +87,6 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning<KtParameter>(PositioningStrategy.VAL_OR_VAR_NODE) {
parameter<KtKeywordToken>("valOrVar")
}
val INVISIBLE_SETTER by error<PsiElement>(PositioningStrategy.ASSIGNMENT_LHS) {
parameter<FirPropertySymbol>("property")
parameter<Visibility>("visibility")
parameter<CallableId>("callableId")
}
}
val UNRESOLVED by object : DiagnosticGroup("Unresolved") {
@@ -101,7 +96,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val UNRESOLVED_REFERENCE by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
parameter<String>("reference")
}
val UNRESOLVED_LABEL by error<PsiElement>()
val UNRESOLVED_LABEL by error<PsiElement>(PositioningStrategy.LABEL)
val DESERIALIZATION_ERROR by error<PsiElement>()
val ERROR_FROM_JAVA_RESOLUTION by error<PsiElement>()
val MISSING_STDLIB_CLASS by error<PsiElement>()
@@ -146,6 +141,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val SUPERTYPES by object : DiagnosticGroup("Supertypes") {
val NOT_A_SUPERTYPE by error<PsiElement>()
val TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER by warning<KtElement>()
val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error<PsiElement>()
val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error<KtTypeReference> {
parameter<Symbol>("otherSuperType")
@@ -182,6 +178,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<FirRegularClassSymbol>("type")
parameter<Collection<ConeKotlinType>>("bounds")
}
val AMBIGUOUS_SUPER by error<KtSuperExpression>()
}
val CONSTRUCTOR_PROBLEMS by object : DiagnosticGroup("Constructor problems") {
@@ -235,8 +232,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")
}
@@ -497,11 +494,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")
}
@@ -670,11 +663,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")
}
@@ -724,7 +716,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val CONFLICTING_OVERLOADS by error<PsiElement>(PositioningStrategy.DECLARATION_SIGNATURE_OR_DEFAULT) {
parameter<Collection<Symbol>>("conflictingOverloads")
}
val REDECLARATION by error<PsiElement> {
val REDECLARATION by error<KtNamedDeclaration>(PositioningStrategy.NAME_IDENTIFIER) {
parameter<Collection<Symbol>>("conflictingDeclarations")
}
val PACKAGE_OR_CLASSIFIER_REDECLARATION by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME) {
parameter<Collection<Symbol>>("conflictingDeclarations")
}
val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE by error<PsiElement>()
@@ -836,6 +831,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
parameter<ConeKotlinType>("actualType")
}
val ACCESSOR_FOR_DELEGATED_PROPERTY by error<KtPropertyAccessor>()
val ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS by error<KtModifierListOwner>(PositioningStrategy.ABSTRACT_MODIFIER)
}
val MPP_PROJECTS by object : DiagnosticGroup("Multi-platform projects") {
@@ -928,10 +924,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> {
@@ -957,6 +950,15 @@ 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 SENSELESS_COMPARISON by warning<KtExpression> {
parameter<FirExpression>("expression")
parameter<Boolean>("compareResult")
}
val SENSELESS_NULL_IN_WHEN by warning<KtElement>()
}
val NULLABILITY by object : DiagnosticGroup("Nullability") {
@@ -1138,6 +1140,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")
}
@@ -1170,6 +1183,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") {
@@ -1203,6 +1237,13 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
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>()
}
val JVM by object : DiagnosticGroup("jvm") {
val JAVA_TYPE_MISMATCH by error<KtExpression> {
parameter<ConeKotlinType>("expectedType")
parameter<ConeKotlinType>("actualType")
}
}
}
private val exposedVisibilityDiagnosticInit: DiagnosticBuilder.() -> Unit = {
@@ -1213,13 +1254,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,
@@ -77,9 +95,13 @@ 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,
ABSTRACT_MODIFIER,
LABEL,
;
val expressionToCreate get() = "SourceElementPositioningStrategies.${strategy ?: name}"

View File

@@ -0,0 +1,17 @@
/*
* 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.jvm.checkers
import org.jetbrains.kotlin.fir.analysis.checkers.expression.ExpressionCheckers
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker
import org.jetbrains.kotlin.fir.analysis.jvm.checkers.expression.FirJavaGenericVarianceViolationTypeChecker
object JvmExpressionCheckers : ExpressionCheckers() {
override val functionCallCheckers: Set<FirFunctionCallChecker>
get() = setOf(
FirJavaGenericVarianceViolationTypeChecker,
)
}

View File

@@ -0,0 +1,188 @@
/*
* 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.jvm.checkers.expression
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker
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.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.argumentMapping
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
import org.jetbrains.kotlin.fir.originalOrSelf
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.model.typeConstructor
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
/**
* Checks compatibility of variance of type argument for Java collections.
*
* Java collection interfaces all include methods mutating the collection. Hence, they naturally map to mutable versions of Kotlin
* collections. But Kotlin provides immutable collections and it's good practice to enforce immutability when possible. Hence, to make it
* easier to use immutable collections in Kotlin, Java collection types are instead mapped to flexible type with mutable collection as the
* lower type and immutable collection as upper type. However, flexible types make type checking unsound. Hence we have this check that
* catches a common mistake allowed by flexible type.
*
* Consider a Java method accepting type `List<Object>`, which is mapped to `MutableList<Any?>..List<(out) Any?>`. If one passes a mutable
* list of some more concrete type than `Any` (ArrayList<String>, LinkedList<Int>, etc.) to this Java method, then any writes to this
* mutable collection could cause `ClassCastException`s if the same mutable list is read elsewhere. It's the purpose of this checker to
* reject such code.
*
* On the other hand, if one passes an immutable list of some more concrete type, then any writes to it on the Java side would cause
* `UnsupportedOperationException`, which is expected and the price we pay in order to make immutable collection easier to use. This checker
* doesn't do anything to prevent this from happening.
*/
object FirJavaGenericVarianceViolationTypeChecker : FirFunctionCallChecker() {
private val javaOrigin = setOf(FirDeclarationOrigin.Java, FirDeclarationOrigin.Enhancement)
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
val calleeFunction = expression.calleeReference.toResolvedCallableSymbol() as? FirFunctionSymbol<*> ?: return
if (calleeFunction.originalOrSelf().origin !in javaOrigin) {
return
}
val argumentMapping = expression.argumentMapping ?: return
val typeArgumentMap = mutableMapOf<FirTypeParameterSymbol, ConeKotlinType>()
for (i in 0 until expression.typeArguments.size) {
val type = expression.typeArguments[i].safeAs<FirTypeProjectionWithVariance>()?.typeRef?.coneTypeSafe<ConeKotlinType>()
if (type != null) {
typeArgumentMap[calleeFunction.typeParameterSymbols[i]] = type
}
}
val typeParameterSubstitutor = substitutorByMap(typeArgumentMap, context.session)
for ((arg, param) in argumentMapping) {
val expectedType = typeParameterSubstitutor.substituteOrSelf(param.returnTypeRef.coneType)
// optimization: if no arguments or flexibility, everything is OK
if (expectedType !is ConeFlexibleType || expectedType.typeArguments.isEmpty()) continue
// Anything is acceptable for raw types
if (expectedType is ConeRawType) continue
val argType = arg.typeRef.coneType
val lowerBound = expectedType.lowerBound
val upperBound = expectedType.upperBound
val typeCtx = context.session.inferenceComponents.ctx
val lowerConstructor = lowerBound.typeConstructor(typeCtx)
val upperConstructor = upperBound.typeConstructor(typeCtx)
// Use site variance projection is always the same for flexible types. So there is no need to check if declaration site is the
// same.
if (lowerConstructor == upperConstructor) continue
// If the base class of the argument type is not equal or a sub class of the lower bound, then we simply allow it so that
// Kotlin immutable collections can be used in place of Java collection types.
if (!typeCtx.isTypeConstructorEqualOrSubClassOf(argType, lowerBound)) continue
// In general, out type projection makes a mutable collection "readonly". A priori such a projected type is not a subtype of a
// non-projected type because projection has "removed" the ability to write to this collection. But for the purpose of this
// checker, we don't care about the readability/writability of collections.
//
// More importantly, removing such out projection is a
// shortcut to make this type comparable with the expected type by the function (after removing type capturing below). Consider
// the code below (here we use kotlin code in the example, but the same idea applies to calls to Java methods as well)
//
// ```
// fun get(): MutableList<out String> = ...
// fun <T> take(l: MutableList<T>) = ...
// fun test() {
// take(get())
// }
// ```
//
// The type of `get()` is `MutableList<out String>`. After type parameter instantiation, `take` takes a
// `MutableList<Captured<out String>>`. Obviously, a `MutableList<out String>` is not a subtype of `MutableList<Captured<out
// String>>` because we have lost the identity of the captured type at this point: we no longer know that the captured type is
// actually created because of type projection from `get`. Hence, to workaround this problem, we simply remove all the out
// projection and type capturing and compare the types after such erasure. This way, we won't incorrectly reject any valid code
// though we may accept some invalid code. But in presence of the unsound flexible types, we are allowing invalid code already.
val argTypeWithoutOutProjection = argType.removeOutProjection(true)
val lowerBoundWithoutCapturing = context.session.inferenceComponents.approximator.approximateToSuperType(
lowerBound,
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
) ?: lowerBound
if (!AbstractTypeChecker.isSubtypeOf(
typeCtx,
argTypeWithoutOutProjection,
lowerBoundWithoutCapturing.withNullability(ConeNullability.NULLABLE, typeCtx)
)
) {
reporter.reportOn(arg.source, FirErrors.JAVA_TYPE_MISMATCH, expectedType, argType, context)
}
}
}
private fun ConeKotlinType.removeOutProjection(positive: Boolean): ConeKotlinType {
return when (this) {
is ConeFlexibleType -> ConeFlexibleType(lowerBound.removeOutProjection(positive), upperBound.removeOutProjection(positive))
is ConeCapturedType -> ConeCapturedType(
captureStatus,
lowerType?.removeOutProjection(positive),
nullability,
constructor.apply {
ConeCapturedTypeConstructor(
projection.removeOutProjection(positive),
supertypes?.map { it.removeOutProjection(positive) },
typeParameterMarker
)
},
attributes,
isProjectionNotNull
)
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.removeOutProjection(positive))
is ConeIntersectionType -> ConeIntersectionType(
intersectedTypes.map { it.removeOutProjection(positive) },
alternativeType?.removeOutProjection(positive)
)
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(
lookupTag,
typeArguments.map { it.removeOutProjection(positive) }.toTypedArray(),
isNullable,
attributes
)
else -> this
}
}
private fun ConeTypeProjection.removeOutProjection(positive: Boolean): ConeTypeProjection {
return when (this) {
is ConeKotlinTypeProjectionOut -> if (positive) type else this
is ConeKotlinTypeProjectionIn -> ConeKotlinTypeProjectionIn(type.removeOutProjection(!positive))
// Don't remove nested projections for types at invariant position.
is ConeKotlinTypeConflictingProjection,
is ConeKotlinType,
is ConeStarProjection -> this
}
}
private fun ConeInferenceContext.isTypeConstructorEqualOrSubClassOf(subType: ConeKotlinType, superType: ConeKotlinType): Boolean {
return isTypeConstructorEqualOrSubClassOf(subType.typeConstructor(), superType.typeConstructor())
}
private fun ConeInferenceContext.isTypeConstructorEqualOrSubClassOf(
subTypeConstructor: TypeConstructorMarker,
superTypeConstructor: TypeConstructorMarker
): Boolean {
if (subTypeConstructor == superTypeConstructor) return true
for (immediateSuperType in subTypeConstructor.supertypes()) {
val immediateSuperTypeConstructor = immediateSuperType.typeConstructor()
if (superTypeConstructor == immediateSuperTypeConstructor) return true
if (this@isTypeConstructorEqualOrSubClassOf.isTypeConstructorEqualOrSubClassOf(immediateSuperTypeConstructor, superTypeConstructor)) return true
}
return false
}
}

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
@@ -32,7 +38,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.lexer.KtKeywordToken
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtAnnotationEntry
@@ -66,6 +71,7 @@ import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPropertyAccessor
import org.jetbrains.kotlin.psi.KtReturnExpression
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.KtSuperExpression
import org.jetbrains.kotlin.psi.KtTypeAlias
import org.jetbrains.kotlin.psi.KtTypeParameter
import org.jetbrains.kotlin.psi.KtTypeProjection
@@ -118,12 +124,11 @@ object FirErrors {
val VAL_OR_VAR_ON_FUN_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
val VAL_OR_VAR_ON_CATCH_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
val VAL_OR_VAR_ON_SECONDARY_CONSTRUCTOR_PARAMETER by warning1<KtParameter, KtKeywordToken>(SourceElementPositioningStrategies.VAL_OR_VAR_NODE)
val INVISIBLE_SETTER by error3<PsiElement, FirPropertySymbol, Visibility, CallableId>(SourceElementPositioningStrategies.ASSIGNMENT_LHS)
// Unresolved
val INVISIBLE_REFERENCE by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)
val UNRESOLVED_REFERENCE by error1<PsiElement, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val UNRESOLVED_LABEL by error0<PsiElement>()
val UNRESOLVED_LABEL by error0<PsiElement>(SourceElementPositioningStrategies.LABEL)
val DESERIALIZATION_ERROR by error0<PsiElement>()
val ERROR_FROM_JAVA_RESOLUTION by error0<PsiElement>()
val MISSING_STDLIB_CLASS by error0<PsiElement>()
@@ -147,6 +152,7 @@ object FirErrors {
// Supertypes
val NOT_A_SUPERTYPE by error0<PsiElement>()
val TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER by warning0<KtElement>()
val SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE by error0<PsiElement>()
val QUALIFIED_SUPERTYPE_EXTENDED_BY_OTHER_SUPERTYPE by error1<KtTypeReference, FirBasedSymbol<*>>()
val SUPERTYPE_INITIALIZED_IN_INTERFACE by error0<KtTypeReference>()
@@ -167,6 +173,7 @@ object FirErrors {
val PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE by error0<KtModifierListOwner>(SourceElementPositioningStrategies.VARIANCE_MODIFIER)
val INCONSISTENT_TYPE_PARAMETER_VALUES by error3<KtClass, FirTypeParameterSymbol, FirRegularClassSymbol, Collection<ConeKotlinType>>(SourceElementPositioningStrategies.SUPERTYPES_LIST)
val INCONSISTENT_TYPE_PARAMETER_BOUNDS by error3<PsiElement, FirTypeParameterSymbol, FirRegularClassSymbol, Collection<ConeKotlinType>>()
val AMBIGUOUS_SUPER by error0<KtSuperExpression>()
// Constructor problems
val CONSTRUCTOR_IN_OBJECT by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
@@ -209,8 +216,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>()
@@ -326,8 +333,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>()
@@ -375,8 +381,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)
@@ -392,7 +397,8 @@ object FirErrors {
// Redeclarations
val MANY_COMPANION_OBJECTS by error0<KtObjectDeclaration>(SourceElementPositioningStrategies.COMPANION_OBJECT)
val CONFLICTING_OVERLOADS by error1<PsiElement, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT)
val REDECLARATION by error1<PsiElement, Collection<FirBasedSymbol<*>>>()
val REDECLARATION by error1<KtNamedDeclaration, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.NAME_IDENTIFIER)
val PACKAGE_OR_CLASSIFIER_REDECLARATION by error1<KtNamedDeclaration, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
val METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE by error0<PsiElement>()
// Invalid local declarations
@@ -455,6 +461,7 @@ object FirErrors {
val WRONG_SETTER_RETURN_TYPE by error0<KtTypeReference>()
val WRONG_GETTER_RETURN_TYPE by error2<KtTypeReference, ConeKotlinType, ConeKotlinType>()
val ACCESSOR_FOR_DELEGATED_PROPERTY by error0<KtPropertyAccessor>()
val ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS by error0<KtModifierListOwner>(SourceElementPositioningStrategies.ABSTRACT_MODIFIER)
// Multi-platform projects
val EXPECTED_DECLARATION_WITH_BODY by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
@@ -495,8 +502,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)
@@ -505,6 +511,9 @@ 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)
val SENSELESS_COMPARISON by warning2<KtExpression, FirExpression, Boolean>()
val SENSELESS_NULL_IN_WHEN by warning0<KtElement>()
// Nullability
val UNSAFE_CALL by error2<PsiElement, ConeKotlinType, FirExpression?>(SourceElementPositioningStrategies.DOT_BY_QUALIFIED)
@@ -596,6 +605,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)
@@ -603,6 +615,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)
@@ -620,4 +641,7 @@ object FirErrors {
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>()
// jvm
val JAVA_TYPE_MISMATCH by error2<KtExpression, ConeKotlinType, ConeKotlinType>()
}

View File

@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.fir.declarations.utils.isLateInit
import org.jetbrains.kotlin.fir.declarations.utils.referredPropertySymbol
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.expressions.FirVariableAssignment
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.*
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol

View File

@@ -56,6 +56,8 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirPropertyTypeParametersChecker,
FirInitializerTypeMismatchChecker,
FirDelegatedPropertyChecker,
FirInlinePropertyChecker,
FirPropertyFromParameterChecker,
)
override val classCheckers: Set<FirClassChecker>
@@ -129,6 +131,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
override val annotatedDeclarationCheckers: Set<FirAnnotatedDeclarationChecker>
get() = setOf(
FirAnnotationChecker,
FirPublishedApiChecker,
)
override val typeAliasCheckers: Set<FirTypeAliasChecker>

View File

@@ -29,8 +29,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
override val qualifiedAccessExpressionCheckers: Set<FirQualifiedAccessExpressionChecker>
get() = setOf(
FirCallableReferenceChecker,
FirSuperNotAvailableChecker,
FirNotASupertypeChecker,
FirSuperReferenceChecker,
FirSuperclassNotAccessibleFromInterfaceChecker,
FirAbstractSuperCallChecker,
FirQualifiedSupertypeExtendedByOtherSupertypeChecker,
@@ -60,7 +59,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
override val variableAssignmentCheckers: Set<FirVariableAssignmentChecker>
get() = setOf(
FirReassignmentAndInvisibleSetterChecker,
FirValReassignmentChecker,
FirAssignmentTypeMismatchChecker
)

View File

@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.analysis.checkers
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.isPrimitiveType
import org.jetbrains.kotlin.fir.languageVersionSettings
@@ -63,7 +62,23 @@ internal object ConeTypeCompatibilityChecker {
HARD_INCOMPATIBLE,
}
fun Collection<ConeKotlinType>.areCompatible(ctx: ConeInferenceContext): Compatibility {
fun ConeInferenceContext.isCompatible(a: ConeKotlinType, b: ConeKotlinType): Compatibility {
val aUnwrap = unwrap(a)
val bUnwrap = unwrap(b)
if (aUnwrap.containsAll(bUnwrap) || bUnwrap.containsAll(aUnwrap)) {
return Compatibility.COMPATIBLE
}
val intersectionType = intersectTypesOrNull(listOf(a, b)) as? ConeIntersectionType ?: return Compatibility.COMPATIBLE
return intersectionType.intersectedTypes.areCompatible(this)
}
private fun unwrap(type: ConeKotlinType): Collection<ConeKotlinType> = when (type) {
is ConeIntersectionType -> type.intersectedTypes
else -> listOf(type)
}
private fun Collection<ConeKotlinType>.areCompatible(ctx: ConeInferenceContext): Compatibility {
// If all types are nullable, then `null` makes the given types compatible.
if (all { with(ctx) { it.isNullableType() } }) return Compatibility.COMPATIBLE

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

@@ -142,7 +142,7 @@ interface FirDeclarationPresenter {
appendRepresentation(it.returnTypeRef)
}
fun represent(it: FirProperty) = buildString {
fun represent(it: FirVariable) = buildString {
append('[')
it.receiverTypeRef?.let {
appendRepresentation(it)
@@ -241,7 +241,7 @@ open class FirDeclarationInspector(
declaration is FirSimpleFunction -> collectFunction(presenter.represent(declaration), declaration)
declaration is FirRegularClass -> collectNonFunctionDeclaration(presenter.represent(declaration), declaration)
declaration is FirTypeAlias -> collectNonFunctionDeclaration(presenter.represent(declaration), declaration)
declaration is FirProperty -> collectNonFunctionDeclaration(presenter.represent(declaration), declaration)
declaration is FirVariable -> collectNonFunctionDeclaration(presenter.represent(declaration), declaration)
}
}

View File

@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.FirRealSourceElementKind
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
@@ -18,7 +19,7 @@ fun checkUnderscoreDiagnostics(
reporter: DiagnosticReporter,
isExpression: Boolean
) {
if (source != null && source.kind !is FirFakeSourceElementKind) {
if (source != null && (source.kind is FirRealSourceElementKind || source.kind is FirFakeSourceElementKind.ReferenceInAtomicQualifiedAccess)) {
with(SourceNavigator.forSource(source)) {
if (source.getRawIdentifier()?.isUnderscore == true) {
reporter.reportOn(

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

@@ -13,7 +13,9 @@ 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.declarations.impl.FirOuterClassTypeParameterRef
import org.jetbrains.kotlin.fir.resolve.firProvider
import org.jetbrains.kotlin.fir.resolve.getOuterClass
import org.jetbrains.kotlin.fir.scopes.PACKAGE_MEMBER
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
@@ -21,6 +23,7 @@ import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
import org.jetbrains.kotlin.fir.util.ListMultimap
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
@@ -197,7 +200,8 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
}
}
}
else -> {}
else -> {
}
}
if (declarationName != null) {
session.lookupTracker?.recordLookup(
@@ -213,17 +217,89 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
when (declaration) {
is FirFile -> checkFile(declaration, inspector, context)
is FirRegularClass -> checkRegularClass(declaration, inspector)
else -> return
else -> {
}
}
inspector.declarationConflictingSymbols.forEach { (declaration, symbols) ->
when {
symbols.isEmpty() -> {}
declaration is FirSimpleFunction || declaration is FirConstructor -> {
reporter.reportOn(declaration.source, FirErrors.CONFLICTING_OVERLOADS, symbols, context)
inspector.declarationConflictingSymbols.forEach { (conflictingDeclaration, symbols) ->
val source = conflictingDeclaration.source
if (source != null && symbols.isNotEmpty()) {
when (conflictingDeclaration) {
is FirSimpleFunction,
is FirConstructor -> {
reporter.reportOn(source, FirErrors.CONFLICTING_OVERLOADS, symbols, context)
}
else -> {
val factory = if (conflictingDeclaration is FirClassLikeDeclaration &&
getOuterClass(conflictingDeclaration, context.session) == null &&
symbols.any { it is FirClassLikeSymbol<*> }
) {
FirErrors.PACKAGE_OR_CLASSIFIER_REDECLARATION
} else {
FirErrors.REDECLARATION
}
reporter.reportOn(source, factory, symbols, context)
}
}
}
}
if (declaration.source?.kind !is FirFakeSourceElementKind) {
when (declaration) {
is FirMemberDeclaration -> {
if (declaration is FirFunction) {
checkConflictingParameters(declaration.valueParameters, context, reporter)
}
checkConflictingParameters(declaration.typeParameters, context, reporter)
}
is FirTypeParametersOwner -> {
checkConflictingParameters(declaration.typeParameters, context, reporter)
}
else -> {
reporter.reportOn(declaration.source, FirErrors.REDECLARATION, symbols, context)
}
}
}
}
private fun checkConflictingParameters(parameters: List<FirElement>, context: CheckerContext, reporter: DiagnosticReporter) {
if (parameters.size <= 1) return
val multimap = ListMultimap<Name, FirBasedSymbol<*>>()
for (parameter in parameters) {
val name: Name
val symbol: FirBasedSymbol<*>
when (parameter) {
is FirValueParameter -> {
symbol = parameter.symbol
name = parameter.name
}
is FirOuterClassTypeParameterRef -> {
continue
}
is FirTypeParameterRef -> {
symbol = parameter.symbol
name = symbol.name
}
is FirTypeParameter -> {
symbol = parameter.symbol
name = parameter.name
}
else -> throw AssertionError("Invalid parameter type")
}
if (!name.isSpecial) {
multimap.put(name, symbol)
}
}
for (key in multimap.keys) {
val conflictingParameters = multimap[key]
if (conflictingParameters.size > 1) {
for (parameter in conflictingParameters) {
reporter.reportOn(
parameter.source,
FirErrors.REDECLARATION,
conflictingParameters,
context
)
}
}
}

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