Compare commits

...

918 Commits

Author SHA1 Message Date
Sergey Bogolepov
a7fd140329 [K/N] Separate compilation POC 2021-08-09 10:28:17 +07:00
Sergey Bogolepov
4bfa5ad532 wip 2021-08-07 11:47:02 +07:00
Sergey Bogolepov
b694fcdac6 wip 2021-08-07 11:46:47 +07:00
Sergey Bogolepov
b991d3cd4c wip 2021-08-07 11:46:37 +07:00
Sergey Bogolepov
f95c1a0996 [K/N] Rename lldLocation to linker
Actually, there is nothing LLD-specific in this property now,
so let's rename it to avoid confusion.
2021-08-07 11:45:55 +07:00
Sergey Bogolepov
216e306e58 [K/N] Invoke MinGW linker directly
There is an overhead of invoking linker via `clang -fuse-ld`. It became
significant in LLVM 11.1.0. Let's avoid it by invoking LLD directly.
2021-08-07 11:45:54 +07:00
Sergey Bogolepov
1b6ff4d8bd wip 2021-08-07 11:20:11 +07:00
Sergey Bogolepov
65358742dd Working with compiler caches 2021-08-07 11:20:11 +07:00
Sergey Bogolepov
e05c139668 brr 2021-08-07 11:20:11 +07:00
Sergey Bogolepov
d7283d2983 brr 2021-08-07 11:20:10 +07:00
Jinseong Jeon
59ad7e0e04 FIR IDE: create call target for super reference 2021-08-04 15:10:04 +02:00
Jinseong Jeon
c597ee0e34 FIR IDE: fix kotlin origin of annotation call 2021-08-04 15:10:03 +02:00
Jinseong Jeon
c559adc0fb FIR IDE: render list of symbols with indentation
Also, render `psi` of annotation call
(to showcase they're always null for now)
2021-08-04 15:10:02 +02:00
Jinseong Jeon
5b40f291bd FIR IDE: resolve KtTypeReference from super type entry to KtType
which will be mapped to delegated constructor call where we can still
find the referred type.
2021-08-04 15:09:58 +02:00
Jinseong Jeon
d4e1ecd9d3 FIR IDE: fix scope processing for enum entry with members 2021-08-04 15:09:57 +02:00
Stanislav Erokhin
748a2d2e7c [MPP] Performance optimization in expect/actual checker
Previously, the checker executed for every declaration i.e. every
declaration was considered as expect declaration. Because of that in
some cases this checker could eat 6% of compilation time.
After this commit only declarations marked with expect or actual
are checked. To achieve that, logic, that do reporting about missing
actual modifier was moved to the Actual part.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  When this flag is enabled:

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

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

  With this flag is enabled:

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

* Add consistency checks for new VS old flags

Issue #KT-40245
2021-07-29 19:12:53 +03:00
Pavel Kirpichenkov
352c624601 Provide built-ins module name in IrLinker for debugger 2021-07-29 19:04:25 +03:00
Dmitriy Novozhilov
046730c62c [Test] Integrate AbstractCompileTimeConstantEvaluatorTest to AbstractDiagnosticTest
^KT-47898
2021-07-29 15:25:53 +03:00
pyos
c401582770 FE: do not wrap types with enhancements if they're the same 2021-07-29 14:52:51 +03:00
pyos
8c524c2f89 FE: do not attach enhancements to parts of enhanced flexible types 2021-07-29 14:52:51 +03:00
pyos
6cb6abee98 FE: do not create multiple layers of enhancements for warnings 2021-07-29 14:52:51 +03:00
Victor Petukhov
5684b6977a Do preparation of enhancement as well (for types with enhancement), during subtype checks
^KT-47899 Fixed
2021-07-29 14:23:56 +03:00
Victor Petukhov
c5d783596d Check type parameter bounds by java nullability annotations not only in basic resolution context
^KT-47920 Fixed
2021-07-29 14:23:55 +03:00
Victor Petukhov
20d50cfee7 Prevent leaking of type parameter erasion results cache into static scope 2021-07-29 14:23:55 +03:00
Victor Petukhov
6706ee87ad Introduce TypeParameterUpperBoundEraser to memorize results of type parameters erasion computation
^KT-47785 Fixed
2021-07-29 14:23:54 +03:00
Victor Petukhov
f9cb0d61a8 Don't apply Java defaulting nullability annotations rules to unbounded wildcards
^KT-47396 Fixed
2021-07-29 14:23:53 +03:00
Victor Petukhov
99491014e4 Prefer flexible nullability by Java annotations to nullable one if the corresponding type parameter has nullable bound
^KT-47422 Fixed
2021-07-29 14:23:52 +03:00
Dmitriy Novozhilov
2c9857b880 Assume LV 1.6 ready for preview
^KTIJ-19253 Fixed
2021-07-29 13:28:15 +03:00
Dmitriy Dolovov
59dcef81f7 [K/N][Gradle] Make sure K/N Gradle plugin don't fail when K/N distribution directory has no platform libs 2021-07-29 12:56:55 +03:00
Dmitriy Dolovov
66c9d658e4 [K/N] Keep the Kotlin/Native compiler version inside of the K/N distribution
Restore the behavior that was accidentally disabled.
2021-07-29 12:56:50 +03:00
Dmitriy Dolovov
b505486063 K/N, Minor: Drop unused exception class: KonanIrDeserializationException 2021-07-29 12:56:45 +03:00
Dmitriy Dolovov
50d150ace5 K/N: Avoid reporting excessive "error: compilation failed: null" message
This could happen if the source of the exception is inside of KotlinIrLinker/KonanIrLinker or IR deserializers.
2021-07-29 12:56:40 +03:00
Ilya Matveev
3e823d62a9 [K/N][kotlin.test] Make GeneratedSuites public
Issue #KT-47915 fixed
2021-07-29 08:44:32 +00:00
Ivan Kochurkin
d4e1cded59 [FIR] Implement RESOLUTION_TO_CLASSIFIER 2021-07-28 23:18:38 +03:00
Ivan Kochurkin
2574dc907c [FIR] Implement FUNCTION_EXPECTED 2021-07-28 23:17:31 +03:00
Ivan Kochurkin
263e40e753 [FIR] Implement NO_RECEIVER_ALLOWED 2021-07-28 22:52:06 +03:00
Dmitry Savvinov
45a384bb77 Exclude stdlib-common from non-JVM targets as well
This is a continuation of KT-46936. This commit removes stdlib-common
from platform-specific source sets of JS/Native targets, as well as
Android and 'jvm { withJava() }'

The tests are made on kotlin-ide side, see the KT-46936 for attached
commits.

^KT-46936
^KT-47695 Fixed
^KT-47604 Fixed
2021-07-28 20:02:13 +03:00
Dmitry Petrov
ce79fc77c9 JVM minor cleanup in bytecode analyzers 2021-07-28 19:53:39 +03:00
Hung Nguyen
f95c50064c KT-45777: Refactor IncrementalJvmCache to support classpath snapshotting
Extract minimal required information into the new `KotlinClassInfo`
class. This info will be part of the classpath snapshot of the
`KotlinCompile` task in an upcoming change.

Bug: KT-45777
Test: Existing tests should pass (this is a refactoring-only change)
2021-07-28 19:32:10 +03:00
Pavel Kirpichenkov
19467861c9 [MPP] Fix false positive expect-actual mismatch
Use type refiner to correctly expand actual type alias - expect
class chains, produced by the commonizer. In a case when type
refiner doesn't exist for module create a one-shot thread local
instance. This might happen with modules without source code
in project (coming from build system model).

^KT-46691 Fixed
2021-07-28 18:57:08 +03:00
Pavel Kirpichenkov
2d91917ac7 [MPP] Make type refinement capability aware of HMPP state
Introduce intermediate state for cases when module doens't
have a type refiner even though HMPP is enabled.

KT-46691
2021-07-28 18:57:07 +03:00
Pavel Kirpichenkov
566640aa6d [MPP] Move KotlinTypeRefinerImpl (frontend -> descriptors)
ExpectedActualResolver in certain cases needs an ability
to create a standalone refiner instance, see the following
commits. A direct module dependency (resolution -> frontend)
can't be added, the opposite one already exists which leads
to a dependency cycle. Both modules depend on core.descriptors
module where KotlinTypeRefiner resides.

KT-46691
2021-07-28 18:57:07 +03:00
Pavel Kirpichenkov
1f3004a667 [MPP] Support multiple levels of actual type alias expansions
Commonizer might transform typealias chains into several
expect classes with actual type aliases. In this case
refining a common type once is not enough as the result
will be another expect type from type alias expansion.

KT-46691
2021-07-28 18:57:05 +03:00
Andrey Zinovyev
d84cc4333c [FIR] Add INITIALIZATION_BEFORE_DECLARATION diagnostic 2021-07-28 16:56:54 +03:00
Andrey Zinovyev
b706e776ad [FIR] Add VARIABLE_WITH_NO_TYPE_NO_INITIALIZER diagnostic 2021-07-28 16:56:53 +03:00
Svyatoslav Scherbina
a63f218dd3 Stop using ModuleDescriptor.name for top-level ObjCExport name prefix
^KT-47809 Fixed

Do similar for C export.
2021-07-28 12:46:11 +00:00
Alexander Shabalin
48a2b23b3a Add a separate compiler switch for runtime asserts 2021-07-28 07:43:08 +00:00
Alexander Likhachev
c3515cc338 [Gradle] Use compiler argument -opt-in instead of '-Xopt-in'
#KT-35832 Fixed
2021-07-28 05:58:58 +00:00
Alexander Likhachev
10f9c217fd [Gradle] Advance K/N version to 1.6.0-dev-1728 2021-07-28 05:58:58 +00:00
Dmitry Petrov
4267852030 JVM cleanup bytecode analyzers 2021-07-28 08:04:55 +03:00
pyos
e9b177352c JVM_IR: do not inline reads of constructor arguments into accessors 2021-07-28 02:16:01 +02:00
Vasily Levchenko
2baf344f5f [kotlin gradle plugin] enable to work with embedded k/n compiler. 2021-07-27 19:44:31 +00:00
Vasily Levchenko
1eb951749d [build][kotlin-native] native compiler embeddable 2021-07-27 19:44:31 +00:00
Viacheslav Kormushkin
fa2e787f76 CocoaPods Gradle plugin: Support incremental task execution when switching between Xcode and terminal
#KT-37511
2021-07-27 16:08:32 +00:00
Ilya Kirillov
91ecaa32e3 HL API: render local fqNames in reference resolve tests 2021-07-27 17:58:47 +03:00
Ilya Kirillov
77fcb12af8 Fix project leaking in tests
The project was leaking via MockApplication -> LowMemoryWatcherManager -> List<Project>
It happened due to unregistered disposable provided to the MockApplication
2021-07-27 17:58:47 +03:00
Ilya Kirillov
f19dfd9d2a HL API: restore SymbolByReferenceTest
Now it is possible as references are working in HL API tests now
2021-07-27 17:58:46 +03:00
Ilya Kirillov
c678d4b506 HL API: generate reference resolve tests
The testdata is taken from corresponding IDE reference resolve tests
2021-07-27 17:58:45 +03:00
Ilya Kirillov
7ba8e7d1d3 LL API: fix KtPackageProvider package existent checks for tests
Before it was not able to check nested packages for existence

Also, implement unimplemented getKotlinSubPackageFqNames
2021-07-27 17:58:45 +03:00
Ilya Kirillov
4fe240d1b4 HL API: fix KtUserType kt -> fir mapping for non-IDEA usages
createType(KtTypeElement) requires some access to IJ services which are unavailable to IJ core
2021-07-27 17:58:44 +03:00
Ilya Kirillov
970d7b5a78 HL API: implement tests for reference resolve 2021-07-27 17:58:43 +03:00
Ilya Kirillov
55489b6249 FIR IDE: fix containing KtFirSymbolContainingDeclarationProvider for implicit constructors 2021-07-27 17:58:42 +03:00
Ilya Kirillov
eb69153fbc HL API: fix renderer for package symbols 2021-07-27 17:58:40 +03:00
Mikhail Glukhikh
84bd347841 Make EXPERIMENTAL_API_USAGE_ERR warning till 1.6 for signature type case 2021-07-27 14:58:56 +03:00
Mikhail Glukhikh
810def829c Make EXPERIMENTAL_ANNOTATION_ON_OVERRIDE warning till 1.6 2021-07-27 14:58:55 +03:00
Mikhail Glukhikh
bb38eaae61 Postpone OptIn release to version 1.7 2021-07-27 14:56:54 +03:00
Alexander Udalov
0a9498f7e2 Build: suppress deprecated JVM target warning globally
There seems to be no point in configuring the compiler argument per
project. This argument will be deleted soon anyway, when we remove
support for JDK 1.6 & 1.7.

Also remove `disableDeprecatedJvmTargetWarning`. It didn't have any
effect in all modules where it was applied because these modules
reassign `freeCompilerArgs` anyway, with
`-Xsuppress-deprecated-jvm-target-warning` in it.
2021-07-27 13:35:39 +02:00
Alexander Udalov
91c39ed01c Build: remove obsolete compiler arguments
These compiler arguments enable features which are enabled by default in
the current Kotlin anyway.

The only exception is in :compiler:cli which uses an old language
version.
2021-07-27 13:35:38 +02:00
Steffi Stumpos
707e1c7f8d [Test] Add service to provide additional classpath to box tests 2021-07-27 14:05:51 +03:00
Yahor Berdnikau
a55eacd8db Migrate Gradle daemon memory leak tests to JUnit5.
^KT-45745 In Progress
2021-07-27 11:43:32 +03:00
Pavel Kunyavskiy
be0a0a7784 [K/N] Support escape analysis with new mm 2021-07-27 08:22:02 +00:00
Igor Yakovlev
f671061328 [FIR IDE] Add check resolved type for phase less than Types 2021-07-26 23:08:54 +02:00
Igor Yakovlev
02f2f6c148 [FIR IDE] Code review minor changes 2021-07-26 23:08:54 +02:00
Igor Yakovlev
4eb534e39b [FIR IDE] Remove withFirWithPossibleResolve inside function 2021-07-26 23:08:54 +02:00
Igor Yakovlev
563f8c8541 [FIR IDE] Split names of withRef function to phase and type versions 2021-07-26 23:08:54 +02:00
Igor Yakovlev
66fa624ab7 [FIR IDE] Fix IDE return type calculators 2021-07-26 23:08:54 +02:00
Igor Yakovlev
4711577b17 [FIR IDE] Add containing file workaround for FirLightAnonymousClassForSymbol 2021-07-26 23:08:54 +02:00
Igor Yakovlev
a4426cd40d [FIR IDE] Fix invalid partial resolve of file annotations 2021-07-26 23:08:54 +02:00
Igor Yakovlev
e1c8f302a4 [FIR IDE] Make fir resolve phase volatile and remove locks 2021-07-26 23:08:54 +02:00
Igor Yakovlev
78e249c2d5 [FIR IDE] Fix creating fir light classes for NotUnderContentRootModuleInfo module content 2021-07-26 23:08:53 +02:00
Igor Yakovlev
ab2aaec4fe [FIR IDE] Ensure resolve for status transformer 2021-07-26 23:08:53 +02:00
Igor Yakovlev
4e870b6796 [FIR IDE] Fix invalid resolve for fir synthetic properties and accessors 2021-07-26 23:08:53 +02:00
Igor Yakovlev
6700179ee4 [FIR IDE] Add LibraryModuleSourceInfoBase and filter out light classes for sources from libraries 2021-07-26 23:08:53 +02:00
Igor Yakovlev
a0418c3146 [STUBS] Fix invalid classId calculation for KtObjectLiteralExpression 2021-07-26 23:08:53 +02:00
Igor Yakovlev
6869fbbfe5 [FIR IDE] Insert ensure resolve into checkers and scopes 2021-07-26 23:08:53 +02:00
Igor Yakovlev
2fd6c55fc8 [FIR IDE] Replace FIR phase update to FIR IDE 2021-07-26 23:08:53 +02:00
Ilya Chernikov
df9a3c0300 Restore scripting-ide-services testing, fix coroutines dependency 2021-07-26 21:16:50 +03:00
Ivan Kochurkin
173813f7cf [FIR] Implement REIFIED_TYPE_FORBIDDEN_SUBSTITUTION 2021-07-26 21:13:25 +03:00
Ivan Kochurkin
bade6cb611 [FIR] Improve TYPE_PARAMETER_AS_REIFIED detecting, implement TYPE_PARAMETER_AS_REIFIED_ARRAY, TYPE_PARAMETER_AS_REIFIED_ARRAY_WARNING 2021-07-26 21:13:25 +03:00
Ivan Kochurkin
2333b1bcf6 [FIR] Implement BREAK_OR_CONTINUE_JUMPS_ACROSS_FUNCTION_BOUNDARY 2021-07-26 21:13:23 +03:00
Alexander Udalov
cbdd0f579a Regenerate Gradle options 2021-07-26 19:36:53 +02:00
Alexander Udalov
0083ef053b Remove Gradle option annotation for -Xbuiltins-from-sources
This is an internal compiler argument for FIR which doesn't seem
valuable enough to be exposed in Gradle, because it'd require to perform
some kind of deprecation if it's changed or removed. It'll still be
possible to use it via `freeCompilerArgs += "-Xbuiltins-from-sources"`.

Note that generated Gradle options are not changed because the generator
was not rerun after adding this compiler argument. (And the test that
checks that the generator was run is failing right now.)
2021-07-26 19:36:53 +02:00
Alexander Udalov
fe18e3fa31 Do not use uninterruptible file channels in FileChannelUtil
To avoid illegal access errors from incremental compilation on JDK 16+.

 #KT-45689 Fixed
 #KT-47152 Fixed
2021-07-26 19:27:09 +02:00
Alexander Udalov
2ca241c82c Copy FileChannelUtil from intellij-core
#KT-45689
 #KT-47152
2021-07-26 19:27:09 +02:00
Alexander Udalov
698c0bb2a9 Replace --illegal-access workaround with --add-exports
--illegal-access=permit doesn't work since JDK 17.

 #KT-47152 Fixed
2021-07-26 19:27:09 +02:00
Nikolay Lunyak
a44048e713 Add withBindThis to field configuration 2021-07-26 16:12:16 +00:00
Aleksei.Cherepanov
4003cd2832 Fix backward compatibility of portable caches for 212 idea
Write zero to deletedCount value of counters map instead of removing it in context of LookupStorage performance improving
2021-07-26 18:58:12 +03:00
Alexander Shabalin
a24eab9745 Fix STMS tests 2021-07-26 15:09:59 +00:00
Alexander Udalov
5526281c54 Minor, refactor diagnostic tests on repeatable annotations 2021-07-26 14:33:32 +02:00
Alexander Udalov
56866e6927 JVM IR: move java.lang.annotation symbols to JvmSymbols.javaAnnotations
Since a separate instance of AdditionalClassAnnotationLowering is
created for each source file, symbols for these classes were created as
many times as there were source files in the module.

Also inline some variables in the process and move around some methods.
2021-07-26 14:33:32 +02:00
Alexander Udalov
50f7594d9e Minor, move RepeatableAnnotationChecker to separate file 2021-07-26 14:33:31 +02:00
Alexander Udalov
104188c035 Render annotation arguments in bytecodeListing tests 2021-07-26 14:33:30 +02:00
Yahor Berdnikau
7958307d28 Allow to override build options for particular builds.
^KT-45745 In Progress
2021-07-26 14:27:47 +02:00
Yahor Berdnikau
25192cd639 Fix project options are ignored for builds.
Fix 'forceOutput' and 'enableGradleDebug' project level options are not
taken into account when running particular build.

^KT-45745 In Progress
2021-07-26 14:27:47 +02:00
Yahor Berdnikau
a49b36f6b1 Add additional output assertions.
- check if output contains string exactly times
- check if output does not contain Kotlin warnings
- check expected incremental compilation

^KT-45745 In Progress
2021-07-26 14:27:47 +02:00
Yahor Berdnikau
c816d6f2e5 Modify file exists assertion.
Additionally allow to check if file exists in any location, even outside
of the project.

^KT-45745 In Progress
2021-07-26 14:27:47 +02:00
Yahor Berdnikau
18d74e62a6 Add additional shortcuts for common project files.
^KT-45745 In Progress
2021-07-26 14:27:47 +02:00
Yahor Berdnikau
35677f4727 Add random hash to the tempDir project dir.
This will allow to create several similar projects from one resource
project in a single test.

^KT-45745 In Progress
2021-07-26 14:27:46 +02:00
Andrey Zinovyev
8a0941a85a [FIR] Report deprecations in qualified expressions 2021-07-26 14:50:54 +03:00
Mikhail Glukhikh
98bd6f5d3e Fix "implicit type" exception in FIR OptIn checker 2021-07-26 10:13:13 +03:00
Mikhail Glukhikh
2a6355b64c FIR: use coneType instead of coneTypeSafe in OptIn checkers 2021-07-23 23:59:01 +03:00
Mikhail Glukhikh
73539cf342 FIR: use symbols as base for OptIn-checkers 2021-07-23 23:59:00 +03:00
Mikhail Glukhikh
cb847b945d FIR: use getAnnotationByClassId instead of getAnnotationByFqName 2021-07-23 23:58:59 +03:00
Mikhail Glukhikh
7cbea12c8a FIR: store all annotationContainers in checker context 2021-07-23 23:58:58 +03:00
Mikhail Glukhikh
d020948933 FIR: support EXPERIMENTAL_MARKER_CAN_ONLY_BE_USED_AS_ANNOTATION... 2021-07-23 23:58:57 +03:00
Mikhail Glukhikh
543ce06d85 FIR OptIn: temporarily replace error USAGE with warning
This commit is required for FP test to pass,
because FP test does not see module -Xopt-in=... flags.
2021-07-23 23:58:56 +03:00
Mikhail Glukhikh
82f268d611 FIR: add EXPERIMENTAL_API_USAGE reporting 2021-07-23 23:58:55 +03:00
Mikhail Glukhikh
3235b09a92 FIR: introduce MutableCheckerContext to save performance 2021-07-23 23:48:19 +03:00
Denis.Zharkov
b547870d71 Use unsigned version of short numbers in ZipImplementation
Because some two-byte represented numbers (like amount of files in the zip)
exceed 32767 (but less than 65534)
2021-07-23 21:38:46 +03:00
Denis.Zharkov
ea5157cadc Change type of KotlinCoreEnvironment::projectEnvironment type 2021-07-23 21:38:45 +03:00
Denis.Zharkov
d6adac8dd0 Move FastJarFileSystem to ProjectEnvironment and link to the root disposable 2021-07-23 21:38:45 +03:00
Denis.Zharkov
3afed7f972 Fallback to CoreJarFileSystem when JDK doesn't support buffers unmapping 2021-07-23 21:38:43 +03:00
Denis.Zharkov
c6525974d0 Move handlers cache from static field to the instance of FastJarFileSystem 2021-07-23 21:38:43 +03:00
Denis.Zharkov
03e5dc6117 Force unmapping MappedByteBuffer
Otherwise, on Windows daemon might hold mapped regions for some time
(until those objects are collection) and during the time those file become
locked (it's impossible to modify or remove them)

Reflection/Unsafe of course is not a cool thing to use, but JDK still
(already for 18 years) doesn't have public API for this

See https://bugs.java.com/bugdatabase/view_bug.do?bug_id=4724038
And https://stackoverflow.com/questions/2972986/how-to-unmap-a-file-from-memory-mapped-using-filechannel-in-java
2021-07-23 21:38:42 +03:00
Denis.Zharkov
4e11c670c6 Clear cleanFileAccessorsCache for FastJarFileSystem 2021-07-23 21:38:41 +03:00
Denis.Zharkov
7ca2a83f08 Use native endian mode from MappedByteBuffer 2021-07-23 21:38:40 +03:00
Denis.Zharkov
33cf058b55 Use MappedBuffer for FastJarFileSystem implementation 2021-07-23 21:38:40 +03:00
Denis.Zharkov
8f06e59d3b Implement new faster version of Jar virtual file system
It's only enabled by default in FIR and might be turned on with a CLI flag

The main idea is that default FarFS re-read ZIP file list each time when
class file is requested that is quite slow.
We read it once and them reading bytes from the known offset.

Also, unlike the default version we don't perform attributes check on each access
On the one hand, it works faster on the other it might not notice that one
of the JAR has been changed during compilation process
But looks like it's not supposed to be a frequent even during
compilation of a single module
2021-07-23 21:38:38 +03:00
Dmitriy Novozhilov
559e7d223a [FIR] Add friends path from Module in CLI compiler 2021-07-23 17:28:42 +03:00
Dmitriy Novozhilov
d9d2a9cc31 Move BuildSessionLoggerTest to :kotlin-gradle-plugin tests
There was a problem that :kotlin-gradle-statistics:test can not be
  properly imported and kotlin stdlib wasn't accessible in it. I didn't
  find a way to fix it in :kotlin-gradle-statistics module, so I just
  moved tests from it to others gradle plugin tests
2021-07-23 17:15:55 +03:00
Anton Bannykh
a7549be95e JS IR IC: report cache validataion duration when up-to-date 2021-07-23 17:10:07 +03:00
Anton Bannykh
4cee44cd6e JS IR IC: add a flag for DCE hack
The deserialized PIR does not support declaration mutation.
Until that's fixed the associatedObject removal optimization
has to be disabled.
2021-07-23 17:10:07 +03:00
Anton Bannykh
508d3bd9c0 JS IR IC: IC data may reference additional original declarations
Function types, which are created on the fly from lowerings are one such example.
2021-07-23 17:10:06 +03:00
Anton Bannykh
fa21132704 JS IR IC: fix order storage
Some classes don't survive till the end. Their declaration lists
need to be stored nevertheless.
2021-07-23 17:10:06 +03:00
Anton Bannykh
c6ab195a87 JS IR IC: invalid loops references exist after lowerings 2021-07-23 17:10:04 +03:00
Anton Bannykh
0130d18ea9 JS IR IC: deserialization fix 2021-07-23 17:10:03 +03:00
Anton Bannykh
058ca16af7 JC IR IC: correct signatures for function types created during lowerings 2021-07-23 17:10:02 +03:00
Anton Bannykh
8553c6ef58 JS IR IC: pass through more compiler flags 2021-07-23 17:10:02 +03:00
Yahor Berdnikau
5dc6e1b473 Fix no duplicate strategy was set for compilation with 'withJava()'.
In such case Kotlin jvm compilation has additionally java resource dir
that points to the same location. So ProcessResources task copies same
file twice. Fixed by setting ignore duplicates strategy.

^KT-46978 Fixed
2021-07-23 14:03:57 +00:00
Nikolay Krasko
83023c2073 Remove 202 platform support in build scripts 2021-07-23 16:58:28 +03:00
Nikolay Krasko
ec99585eb9 Remove explicit registration of classFileDecompiler EP and core.xml 2021-07-23 16:58:27 +03:00
Nikolay Krasko
1b3046a61b Cleanup 202 bunch files
Leave 202 in .bunch file to give some time for updating build server
2021-07-23 16:58:26 +03:00
Nikolay Krasko
000a437315 Update .bunch file after 202 -> 203 switch 2021-07-23 16:58:25 +03:00
Nikolay Krasko
bba0dfb469 Cleanup as42 bunch files
We don't build AS42 plugin from main kotlin repo anymore.
2021-07-23 16:58:24 +03:00
Dmitry Petrov
34f5b85ae5 IR KT-47840 fix-point solution for closure conversion 2021-07-23 14:58:23 +03:00
Jinseong Jeon
e9f2d574d5 FIR IDE: simplify HL APIs for PsiType
The idea is to convert `KtType` to `PsiType`, along with the given
`PsiElement` context, instead of providing individual API to convert
different psi source to `PsiType`. To that end, we need to
migrate/rewrite some APIs/implementations that retrieve `KtType` from
different source of `PsiElement`.
2021-07-23 13:28:14 +02:00
Jinseong Jeon
f02f3c76ae FIR IDE: API to resolve KtTypeReference to KtType 2021-07-23 13:28:11 +02:00
Jinseong Jeon
5358d4f07c FIR IDE: construct function type from a function as PsiType 2021-07-23 13:28:05 +02:00
Jinseong Jeon
f19a501cc7 FIR IDE: common super type of given KtExpression's 2021-07-23 13:27:59 +02:00
Jinseong Jeon
5690b4d8c2 FIR IDE: get the return type of KtDeclaration as PsiType 2021-07-23 13:27:57 +02:00
Konstantin Tskhovrebov
de4c2d35ab Assemble fat framework if Xcode requires several architectures.
#KT-47653
2021-07-23 11:00:35 +00:00
Konstantin Tskhovrebov
68a3c5f378 Use 'ARCHS' Xcode env for assembleAppleFramework task registration.
#KT-47653
2021-07-23 11:00:34 +00:00
Konstantin Tskhovrebov
414e735a67 Move native target definition by sdk and arch from Cocoapods to MPP plugin.
#KT-47653
2021-07-23 11:00:34 +00:00
Dmitriy Novozhilov
9b00776dba [FIR] Create CFG node for ::class calls 2021-07-23 12:20:39 +03:00
Yahor Berdnikau
c5ce52eef5 Configure Android SDK in new test dsl. 2021-07-23 08:11:03 +00:00
Yahor Berdnikau
1e758c6767 Toolchain takes into account kotlin options set via Android extension.
This extension updates not common task kotlin options, but special
field in the task. Toolchain will also check this field to decide
whether it should set 'jvmTarget' or not.

^KT-47754 Fixed
2021-07-23 08:11:02 +00:00
Yahor Berdnikau
e3b219b68f Don't produce warning when '-no-jdk' option is present.
Toolchain in such case should avoid setting '-jdk-home' option.

^KT-46626 In Progress
2021-07-23 08:11:02 +00:00
Mads Ager
c0f5d09759 Copy locals in addition to instructions when inlining finally blocks
^KT-46448 Fixed
2021-07-23 09:11:48 +02:00
pyos
d00fba3718 FE: avoid stack overflow on star projection of enhanced type parameter
#KT-47846 Fixed
2021-07-23 10:03:57 +03:00
Sergey Bogolepov
ed44497a9b [K/N] Prepare CallsChecker for LLVM 11.1.0
LLVM 11.1.0 adds a bit more "good" external functions and intrinsics.
2021-07-23 04:52:16 +00:00
Sergey Bogolepov
bce1075fc4 [K/N] Prepare MinGW linker for LLVM 11
Explicitly set sysroot, target and linker when linking MinGW binary
because it won't be the default target after LLVM update.
2021-07-23 04:51:52 +00:00
Sergey Bogolepov
272284680e [K/N] Prepare Windows runtime tests for LLVM update
In the upcoming LLVM update the default target for windows will be
x86_64-pc-windows-msvc and it will break runtime tests. To mitigate this
problem we explicitly set compilation target to x86_64-pc-windows-gnu
as we do in BitcodeCompiler.
2021-07-23 04:46:13 +00:00
Roman Artemev
f768d5b453 [JS TEST] Refactor test runner a bit
Build IC cache for library right after its compilation
2021-07-22 21:56:57 +03:00
Roman Artemev
0310f7cb0b [JS IC] Lot of fixes after rebase 2021-07-22 21:56:57 +03:00
Roman Artemev
8782399ffb [JS IC] Make sure already bound symbol is not being enqueued 2021-07-22 21:56:56 +03:00
Roman Artemev
334e34b70b [JS PIR] Fix inliner. Do not mutate existed statement list
Such list could be part of PIR structures
2021-07-22 21:56:56 +03:00
Anton Bannykh
20088994c1 JS IC: IC lowerings prototype 2021-07-22 21:56:55 +03:00
Anton Bannykh
525c5b886f JS IR gradle plugin: don't run IC for the main module 2021-07-22 21:56:53 +03:00
Anton Bannykh
e03cb372b7 KLIB: don't fail on invalid loops
Temporarily disable assert because this happens in lowered IR
2021-07-22 21:56:52 +03:00
Anton Bannykh
48ce8c049d JS IC: temporarily disable isPublic assert 2021-07-22 21:56:52 +03:00
Anton Bannykh
3833c833ef KLIB: changes in the .proto and linker required for the JS IC
The original behaviour is preserved. All changes should be behind the flags.
2021-07-22 21:56:51 +03:00
Anton Bannykh
002f4210f7 IR: pass information about the declaration being lowered to the infrastructure 2021-07-22 21:56:51 +03:00
Anton Bannykh
5ee865437d JS IC: expose currentDeclaration from StageController 2021-07-22 21:56:50 +03:00
Anton Bannykh
ba541bd53b IR: allow SymbolTable descendants 2021-07-22 21:56:50 +03:00
Anton Bannykh
e0570d98b2 IR: cache IdSignature hashCode for better performance in maps 2021-07-22 21:56:49 +03:00
Anton Bannykh
76f0684d7c IR: .isBound API for F/O declarations
Fake override functions and properties may not be bound to symbols.
This API allows to know if such declaration is actually bound
2021-07-22 21:56:47 +03:00
Dmitry Petrov
6c734289be JVM skip methods without NEW insns in UninitializedStoresProcessor 2021-07-22 21:29:41 +03:00
Dmitry Petrov
eff7c375ce Minor HackedFixStackMethodAnalyzerBase -> FastStackAnalyzer 2021-07-22 21:29:41 +03:00
Dmitry Petrov
aef9701661 JVM use new stack state analyzer in non-local returns preprocessing 2021-07-22 21:29:40 +03:00
Dmitry Petrov
cf2b4dd277 JVM don't use SPBs in FixStack method analyzer (we don't merge) 2021-07-22 21:29:40 +03:00
Dmitry Petrov
ca84aa4f2c JVM don't optimize if there are too many data on exception edges 2021-07-22 21:29:39 +03:00
Dmitry Petrov
c1a5ce6e61 JVM skip redundant boxing optimization in methods without boxing 2021-07-22 21:29:38 +03:00
Tianyu Geng
a8e379a025 FIR: Fix positioning of ENUM_ENTRY_AS_TYPE
The current SELECTOR_BY_QUALIFIED positioning strategy is closely
related what should be done here. But it only works on qualified access
expressions. This change also makes it work for type references.
2021-07-22 20:39:56 +03:00
Tianyu Geng
c648356887 FIR: report ENUM_ENTRY_AS_TYPE and IS_ENUM_TYPE
These two diagnostics are similar: both are reported on type references
to enum entries. But `IS_ENUM_TYPE` is reported if the type ref is an
operand of `is` operator. To pass along this contextual information, a
boolean is added to FirSpecificTypeResolverTransformer.
2021-07-22 20:39:56 +03:00
Tianyu Geng
6dc75c2e51 FIR IDE: allow KtClassOrObject to resolve to null KtSymbol
At PSI level, an enum entry is a `KtClassOrObject`. But the resolved
FIR counterpart `FirEnumEntry` is not an `FirRegularClass`.
2021-07-22 20:39:56 +03:00
Tianyu Geng
bea90e0578 FIR: remove unused diagnsotics
These diagnostics do not exist in FE1.0 and they are not used
anywhere.
2021-07-22 20:39:55 +03:00
Alexander Udalov
3b513ba299 Minor, add test on typeOf subtyping with mutable collections 2021-07-22 15:55:15 +02:00
Alexander Udalov
9ebd665c96 Report error on annotated type inside typeOf on JVM
Since it's not feasible to support annotated types in 1.6, we're making
this an explicit error in 1.6, so that typeOf can become stable and this
feature can be supported in the future without breaking changes to the
existing code.

Note that extension function types are a special case of annotated
types. A separate error is created for them just because the message
"annotated types are not supported" would be confusing, since such types
don't have explicit annotations in the source code.

 #KT-29919
2021-07-22 15:54:48 +02:00
Alexander Udalov
a383d45534 Disable -Werror if test.progressive.mode is enabled
The reason is that when advancing language version, for example from 1.5
to 1.6, there is a brief period between bootstraps where the
bootstrapped compiler has latest stable language version 1.6, yet the
project is still built with 1.5. That leads to a (correct) warning that
progressive mode makes no sense unless the latest language version is
used, which fails the build because of Werror.

When testing bootstrap in progressive mode, we don't actually care about
these warnings, so disable Werror in this case.

The only case where this could matter would be if we were introducing
_warnings_ in progressive mode and checking that there are no new
warnings on Kotlin would be important for us, but so far progressive
mode has only been used to turn already existing warnings to errors.
2021-07-22 15:41:51 +02:00
Mikhael Bogdanov
60458214a5 Update ReadMe.md 2021-07-22 12:41:34 +00:00
Elena Lepilkina
e29a67b3a3 [K/N][perf] Added autoreleasepool in swiftinterop benchmarks 2021-07-22 11:37:55 +00:00
Sergey Bogolepov
f8528c5cca [K/N] Dockerfile for building LLVM
Provide a stable environment for building LLVM for Linux
by using Docker. Note that the base image is Ubuntu 16.04,
so after LLVM update building Kotlin/Native on Linux will
require glibc 2.23 or higher.
2021-07-22 10:44:03 +00:00
Leonid Startsev
83c1a75c1e Revert "Revert "Instantiation of annotations for JVM IR with the corresponding feature flag""
Fix incorrectly rebased ce0a3a57df

This reverts commit 3d0126d5
2021-07-21 18:24:07 +03:00
Philipp Smorygo
54b9ad6bf5 Slightly improve Kotlin library podspec
Add additional parameters to Podspec for clarity.
Add ability to skip building by using an environment variable
2021-07-21 18:07:46 +03:00
Ilya Chernikov
db61665ab8 [minor] IR: clean unnecessary ObsoleteDescriptorBasedAPI opt-ins 2021-07-21 18:05:42 +03:00
Dmitriy Novozhilov
a710a8d10f [FE 1.0] Report warning on non-exhaustive when statements only after 1.6
^KT-47709
2021-07-21 17:53:05 +03:00
Igor Laevsky
865ad3698b WASM: Fix flaky test 2021-07-21 16:53:45 +03:00
Mikhael Bogdanov
d8f839a7e4 Properly process separate process inputStream/outputStream 2021-07-21 13:19:31 +00:00
Leonid Startsev
3d0126d5dd Revert "Instantiation of annotations for JVM IR with the corresponding feature flag"
because of incorrect rebase

This reverts commit ce0a3a57
2021-07-21 15:23:24 +03:00
max-kammerer
5b21444805 Update worker11.kt 2021-07-21 13:36:02 +02:00
Leonid Startsev
ce0a3a57df Instantiation of annotations for JVM IR with the corresponding feature flag
Seperate checker for platforms that do not support this language feature yet

Synthetic implementations of annotations are generated on-demand with proper 
equals, hashCode, and annotationType methods

#KT-47699 Fixed
2021-07-21 10:23:51 +00:00
Leonid Startsev
4bc521249b kotlinx.serialization: Support InheritableSerialInfo 2021-07-21 10:06:12 +00:00
Alexander Dudinsky
8eea749231 Accept android licenses in setUp PureAndroidAndJavaConsumeMppLibIT 2021-07-21 12:33:07 +03:00
Nikolay Krasko
a1a1bda5f3 Drop unused runIdeTask and excludeInAndroidStudio from localDependencies 2021-07-21 11:23:56 +02:00
Nikolay Krasko
6a0b71d3e4 Drop old IDEA run configurations 2021-07-21 11:23:56 +02:00
Nikita Bobko
d1e46e8ce7 Delete Kotlin IntelliJ IDEA plugin modules from settings.gradle 2021-07-21 11:23:53 +02:00
Nikita Bobko
39fa2b0baf Delete Kotlin IntelliJ IDEA plugin sources
Kotlin plugin sources were migrated to intellij-community:
https://github.com/JetBrains/intellij-community/tree/master/plugins/kotlin

Preserve `jps-plugin/testData/incremental`
because it's used in `compiler/incremental-compilation-impl/test`

Preserve `idea/testData/multiModuleHighlighting/multiplatform`
because it's used in `MppHighlightingTestDataWithGradleIT`
2021-07-21 11:23:43 +02:00
Elena Lepilkina
b8d74698f1 [K/N][Docs] Update HACKING.md after repositories merging and adding information about debugging and using CLion 2021-07-21 08:39:10 +00:00
Mads Ager
6436a1686d [JVM_IR] Recursively perform constant lowering.
Otherwise constants in child expressions are not transformed.

^KT-47716 Fixed.
2021-07-21 02:11:41 +02:00
Mads Ager
2877f1cabe [JVM_IR] Fix check for inline class property backing in lowering.
The inline class lowering would attempt to lower a companion object
property backing field.

^KT-47762 Fixed.
2021-07-21 01:56:46 +02:00
Dmitry Petrov
46d2e52543 JVM Minor: move uninitialized value check to stack recovery 2021-07-20 19:51:04 +03:00
Dmitry Petrov
e72d24960d JVM we don't merge frames in stack normalization 2021-07-20 19:51:03 +03:00
Dmitry Petrov
91afa3335c JVM represent uninitialized values explicitly in stack normalization 2021-07-20 19:51:02 +03:00
Dmitry Petrov
bb202318ee Minor: regenerate tests 2021-07-20 19:51:01 +03:00
Dmitry Petrov
35b4a9d4cc JVM treat all variable loads as "initialized" in stack normalization 2021-07-20 19:51:00 +03:00
Dmitry Petrov
c8b705fd2d JVM update license for HackedFixStackMethodAnalyzerBase.kt 2021-07-20 19:50:59 +03:00
Dmitry Petrov
8763235053 JVM specially hacked method analyzer for FixStack 2021-07-20 19:50:58 +03:00
Dmitry Petrov
3ecd612ce7 JVM FixStackValue & FixStackInterpreter 2021-07-20 19:50:57 +03:00
Ilya Chernikov
8eb7e719d3 [minor] fix compiler warnings in scripting modules 2021-07-20 19:42:34 +03:00
Roman Golyshev
59304ba70c FIR IDE: use correct out of block modification tracker
Follow-up to eead868cd2
2021-07-20 19:15:38 +03:00
Roman Golyshev
4e67afcaba FIR IDE: Use write lock in KtFirOverrideInfoProvider implementation
`withFir` takes read lock, but checking visibility or implementation
status actually requires resolving declaration to `STATUS` phase. But
resolve cannot be done in `withFir` function, since resolve requires
write lock, and you cannot take both read and write lock

Now we use `withFirWithPossibleResolveInside`, which takes write lock
and allows to perform resolve in it

This should fix failing `FirOverrideImplementTest` tests
in Kotlin IDE plugin
2021-07-20 19:02:26 +03:00
Roman Golyshev
f3bdadb7d9 FIR IDE: Use correct class symbol in getImplementationStatus
The previous check `if (parentClassSymbol !is FirClassSymbol<*>)`
always succeeded, because `parentClassSymbol` was a declaration,
not a symbol
2021-07-20 19:02:24 +03:00
Abduqodiri Qurbonzoda
b65c477e68 Regex.splitToSequence, CharSequence.splitToSequence(Regex) #KT-23351 2021-07-20 14:09:24 +00:00
Abduqodiri Qurbonzoda
1fee6b191f Fix typo in Sequence.constrainOnce() doc 2021-07-20 14:09:24 +00:00
Mikhael Bogdanov
ff26a471b4 Update diagnostics test affected by ApproximateIntegerLiteralTypesInReceiverPosition and ProhibitSimplificationOfNonTrivialConstBooleanExpressions features 2021-07-20 12:19:57 +00:00
Mikhael Bogdanov
fd605a13d7 Update box tests affected by ApproximateIntegerLiteralTypesInReceiverPosition feature 2021-07-20 11:42:29 +00:00
Andrey Zinovyev
6ef4523555 [FIR] Cache callable names in some composite scopes 2021-07-20 14:25:16 +03:00
Andrey Zinovyev
15be38192b [FIR] Mark implicit types in accessors as fake
To not check their types in deprecation checker
2021-07-20 14:25:14 +03:00
Yahor Berdnikau
caa6b630ab Apply 'kotlin-android' plugin dynamically.
Only apply when one of android plugins are also applied to the project.

If none of AGP plugins are applied and 'kotlin-android' is - exception
 in 'afterEvaluate {..}' will be thrown.

^KT-46626 Fixed
2021-07-20 13:44:45 +03:00
Dmitriy Novozhilov
f3116cb64a Fix NON_EXHAUSTIVE_WHEN_STATEMENT warnings in project code 2021-07-20 13:33:46 +03:00
Dmitriy Novozhilov
a6edd852ff [FIR] Report NON_EXHAUSTIVE_WHEN_STATEMENT/NO_ELSE_IN_WHEN for when's on logical types
^KT-47709 In Progress
2021-07-20 13:33:44 +03:00
Dmitriy Novozhilov
ef635f6a96 [FE 1.0] Report NON_EXHAUSTIVE_WHEN_STATEMENT/NO_ELSE_IN_WHEN for when's on logical types
^KT-47709 In Progress
2021-07-20 13:33:43 +03:00
Dmitriy Novozhilov
85c7f386eb Add Kotlin 1.7 language version 2021-07-20 13:33:41 +03:00
Andrey Zinovyev
4a37de51bb [FIR] Add ANONYMOUS_INITIALIZER_IN_INTERFACE diagnostic 2021-07-20 13:29:00 +03:00
Yahor Berdnikau
304d01127f Fix false positive on Java/Kotlin JVM target validation.
Fix false positive case when java toolchain was set to <JDK1.8. In such
case Java tasks return '8' (or less) for target instead of '1.8'.

^KT-47520 Fixed
2021-07-20 09:25:06 +00:00
nataliya.valtman
f76864260a Log changed files into ES statistic 2021-07-20 11:26:55 +03:00
Dmitriy Novozhilov
9b3b386f0a [FIR IDE] Ignore HMMP compiler test 2021-07-20 10:33:54 +03:00
Dmitriy Novozhilov
749dbf4d44 [FIR] Safe dependency symbol provider in IDE session 2021-07-20 10:33:53 +03:00
Dmitriy Novozhilov
37c096cb10 [FIR] Support creation of IR of common + platform sources in FirAnalyzerFacade 2021-07-20 10:33:52 +03:00
Dmitriy Novozhilov
df11ccf755 [FIR] Fix dependency on jvm descriptors for running fir2ir tests with JPS 2021-07-20 10:33:51 +03:00
Dmitriy Novozhilov
5354e4afe4 [FIR] Ignore some MPP backend tests
FIR doesn't support actual declarations in same module where expect
  declarations lay
2021-07-20 10:33:50 +03:00
Dmitriy Novozhilov
c3060e861f [FIR] Add expect actual checker 2021-07-20 10:33:49 +03:00
Dmitriy Novozhilov
faadb08174 [FIR-IDE] Fix generating conversions for pair with non-trivial converters 2021-07-20 10:33:48 +03:00
Dmitriy Novozhilov
b363d95160 [FIR-IDE] Add conversion for Map type 2021-07-20 10:33:47 +03:00
Dmitriy Novozhilov
3b2df7ade3 [FIR] Inherit expect modifier from outer classes 2021-07-20 10:33:46 +03:00
Dmitriy Novozhilov
18af4155b8 [FIR] Properly infer open modality for functions of expect interfaces 2021-07-20 10:33:45 +03:00
Dmitriy Novozhilov
3991383853 [FIR] Provide compiler light classes from all source modules 2021-07-20 10:33:44 +03:00
Dmitriy Novozhilov
8729421e7a [FIR] Add kind to all FirSessions 2021-07-20 10:33:43 +03:00
Dmitriy Novozhilov
2c1ada131d [FIR] Don't generate implicit primary constructor for expect classes 2021-07-20 10:33:42 +03:00
Dmitriy Novozhilov
b1e47a46cd [FIR] Inherit isExpect flag of members from containing class 2021-07-20 10:33:41 +03:00
Dmitriy Novozhilov
9fd25af1a7 [FIR] Add pretty toString to FirSession and ModuleData 2021-07-20 10:33:40 +03:00
Dmitriy Novozhilov
55775a7beb [FIR] Use proper moduleData in fake override generator 2021-07-20 10:33:38 +03:00
Dmitriy Novozhilov
7f20b83159 [FIR] Use proper moduleData in synthetic properties scope 2021-07-20 10:33:37 +03:00
Dmitriy Novozhilov
7008f02962 [FIR] Create fir classes for java annotations and enums with Final modality 2021-07-20 10:33:34 +03:00
Dmitriy Novozhilov
6e83820f97 Move ExpectActualCompatibility to :compiler:resolution.common 2021-07-20 10:33:33 +03:00
Dmitriy Novozhilov
950db81aa4 [FIR] Split compileModulesUsingFrontendIR to multiple functions 2021-07-20 10:33:32 +03:00
Dmitriy Novozhilov
ec1651df92 [FIR] Store dependencies symbol provider as separate session component 2021-07-20 10:33:31 +03:00
Ilya Matveev
1c5361dacd [K/N] disable throwThroughBridge test for wasm32 2021-07-20 07:19:38 +00:00
Hung Nguyen
ecf6001365 KotlinCompile: Prepare for classpath snapshotting and diffing
This commit prepares necessary components only. The core parts of
classpath snapshotting and diffing will be implemented next.

Bug: KT-45777
Test: Existing IncrementalCompilationClasspathSnapshotJvmMultiProjectIT
      and IncrementalJavaChangeClasspathSnapshotIT
2021-07-20 04:04:43 +03:00
Hung Nguyen
41345b2c50 Pass classpath changes from KotlinCompile task to Kotlin compiler
This commit wires necessary components only. The actual classpath
changes will be provided later.

Bug: KT-45777
Test: Existing IncrementalCompilationClasspathSnapshotJvmMultiProjectIT
      and IncrementalJavaChangeClasspathSnapshotIT
2021-07-20 04:04:43 +03:00
Hung Nguyen
c8b3b6df9c KotlinCompile: Set up artifact transform to take classpath snapshot
This commit sets up the artifact transform only. The actual classpath
snapshotting and computation of classpath changes will be done later.

Bug: KT-45777
Test: Existing IncrementalCompilationClasspathSnapshotJvmMultiProjectIT
      and IncrementalJavaChangeClasspathSnapshotIT
2021-07-20 04:04:43 +03:00
Ilmir Usmanov
5517aa36e1 Minor. Add debugger test
#KT-47749
2021-07-19 22:07:17 +00:00
Ilmir Usmanov
e870a200c4 Merge consequent LVT records
that is, if LVT record starts where previous one ends, merge them.
 #KT-47749 Fixed
2021-07-19 22:07:16 +00:00
Ilmir Usmanov
5ae01c8b2a Do not duplicate $result in LVT
#KT-47749
2021-07-19 22:07:16 +00:00
Ilmir Usmanov
b4d356c5bd Split LVT record for known nulls
Since they are not spilled, the logic for splitting LVT records, that
is applied for spilled variables, was not applied for known nulls.
Fix that by applying the logic to them.
 #KT-47749
2021-07-19 22:07:15 +00:00
Mads Ager
83dddd73b0 Always add a local variable for its live ranges.
There used to be code that extended a previous range instead.
However, that does not work as that extension could have the
local cover code where it does not exists. Since we no longer
extend the range of locals, we should always introduce a new
one even if there was another one for a previous range.
2021-07-19 22:07:14 +00:00
Ilya Muradyan
ae650ef19b Add EPL 1.0 licence text for Eclipse Aether dependencies 2021-07-19 21:31:50 +03:00
Ilya Muradyan
46bbe5b1cb Replace Ivy resolver with Maven resolver in all places 2021-07-19 21:31:49 +03:00
Ilya Muradyan
014765a302 Add dependencies-maven-all artifact 2021-07-19 21:31:48 +03:00
Ilya Muradyan
f7c2adae30 Always use wagon classloader as a plexus class world
In CLI compiler, system classloader doesn't load all classes directly,
so wagons (including HttpWagon) happen to be invisible to
Plexus DI that leads to artifacts download failures.
2021-07-19 21:31:46 +03:00
Alexander Likhachev
b93bd1fe09 [Gradle] Simplify optInAnnotation function name to optIn in DSL
#KT-38111
2021-07-19 19:57:00 +03:00
Dmitry Petrov
e276dec4de JVM don't merge local values in FixStackAnalyzer
We care only about stacks there.
This yields about 10-15% in a pathological case such as KT-41510.
2021-07-19 19:24:57 +03:00
Ilya Kirillov
230fce65e5 LL API: add kt -> fir mapping tests for types 2021-07-19 18:45:44 +03:00
Ilya Kirillov
1423aa2c43 LL API: fix kt -> fir mapping of type inside nullable type 2021-07-19 18:45:43 +03:00
Ilya Kirillov
ddd257adc2 LL API: add test for kt -> fir mapping of qualified calls 2021-07-19 18:45:42 +03:00
Ilya Kirillov
3ae1fe69da LL API: add test for kt -> fir mapping 2021-07-19 18:45:41 +03:00
Ilya Kirillov
b380bcfd99 LL API: add kt -> fir mapping tests for expressions 2021-07-19 18:45:40 +03:00
Ilya Kirillov
0554e2a083 LL API: fix kt -> fir mapping for KtStringTemplateEntryWithExpression 2021-07-19 18:45:38 +03:00
Ilya Kirillov
9d53ad4346 LL API: fix kt -> fir mapping for KtObjectLiteralExpression 2021-07-19 18:45:37 +03:00
Ilya Kirillov
32baac52e6 LL API: add kt -> fir mapping tests for property delegation 2021-07-19 18:45:36 +03:00
Ilya Kirillov
831f05a802 LL API: fix kt -> fir mapping for KtImportList 2021-07-19 18:45:35 +03:00
Ilya Kirillov
c266d3e075 LL API: fix kt -> fir mapping for KtValueArgumentList 2021-07-19 18:45:34 +03:00
Ilya Kirillov
f6a97cdec6 LL API: fix kt -> fir mapping for KtValueArgument 2021-07-19 18:45:32 +03:00
Ilya Kirillov
6139d97b2a LL API: allow getOrBuildFir to return null 2021-07-19 18:45:31 +03:00
Ilya Kirillov
4bca296dc6 LL API: introduce helper function for throwing invalid FirElement exception 2021-07-19 18:45:29 +03:00
Ilya Kirillov
c0eb669191 LL API: add basic tests for kt -> fir mapping 2021-07-19 18:45:28 +03:00
Elena Lepilkina
609296a46b [K/N] Use libclang_rt version for simulator for last Xcode versions (KT-47333 fixed) 2021-07-19 14:12:41 +00:00
Mikhael Bogdanov
03ccbf1b17 Upgrade kotlinx-metadata-jvm and binary-compatibility-validator versions 2021-07-19 13:49:05 +00:00
Ilya Chernikov
0cd29adcc7 Get rid of kotlinx-coroutines usage in scripting libs and plugins
the dependency on the coroutines library caused various problems like
KT-30778, or stdlib/runtime version conflicts.
The only function used was `runBlocking`, so this change replaces it
with the internal implementation based on the similar internal thing
from the stdlib.
#KT-30778 fixed
2021-07-19 16:35:36 +03:00
Alexander Udalov
9b1de90452 Cache async-profiler when using -Xprofile 2021-07-19 15:14:57 +02:00
Igor Chevdar
bea82ba2cd [K/N][stdlib] Added @EagerInitialization annotation
It is needed in the lazy top level properties initialization strategy to
revert to the previous strategy at least for the transition period
2021-07-19 17:23:35 +05:00
Mikhael Bogdanov
4de6fd8be2 Prepare NewMultiplatformIT tests for compiler migration to 1.6 2021-07-19 12:15:26 +00:00
Dmitriy Novozhilov
c304363aea [FE 1.0] Report WRONG_ANNOTATION_TARGET on annotations on type arguments
^KT-47772 Fixed
2021-07-19 14:00:24 +03:00
Andrey Zinovyev
046d886850 [FIR] Fix Nothing returning expressions when checking for not null 2021-07-19 13:40:32 +03:00
Andrey Zinovyev
7e9f27436a [FIR] Fix cfg for safe call inside elvis 2021-07-19 13:40:31 +03:00
Andrey Zinovyev
c160511244 [FIR] Basic support for break inside try-finally blocks
Support single try expression only
2021-07-19 13:40:30 +03:00
Andrey Zinovyev
a6984c5198 [FIR] Add NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY diagnostic 2021-07-19 13:40:28 +03:00
Ilmir Usmanov
151478aa27 Raise deprecations of suspend calls with dangling lambda to error
#KT-22562
2021-07-19 08:36:36 +00:00
Dmitry Petrov
d41fc0b599 PSI2IR fix suspend conversion tests
- support chained suspend conversion + SAM conversion
- support suspend conversion in vararg elements
2021-07-17 09:10:19 +03:00
Victor Petukhov
0cc6fbbc6e Add tests for converting expressions of function types to suspending functional types 2021-07-17 09:10:17 +03:00
Viacheslav Kormushkin
780b9a032b Link CocoaPods frameworks with iosTest binary
#KT-44857 #KT-37513
2021-07-16 19:42:24 +00:00
Mads Ager
b51ff799cb Fix IteratorNext intrinsic to cast its dispatch receiver to
the expected type.

^KT-47741 Fixed.
2021-07-16 21:07:11 +02:00
Ilya Kirillov
f83cc69379 HL API: hacky fix garbage collected diagnostic in call 2021-07-16 21:06:05 +03:00
Ilya Kirillov
d7f1353d3d HL API: update resolve call tests 2021-07-16 21:06:04 +03:00
Ilya Kirillov
44812ae45a HL API: update symbols testdata after adding hasStableParameterNames to function symbol 2021-07-16 21:06:03 +03:00
Mark Punzalan
cb85fd26f5 FIR IDE: Expand KtCall API to include annotation calls and delegated
constructor calls.
2021-07-16 21:06:02 +03:00
Mark Punzalan
d30d8037cf FIR IDE: Add KtFunctionLikeSymbol.hasStableParameterNames. 2021-07-16 21:06:00 +03:00
Mark Punzalan
5c111f8979 FIR IDE: Add argument mapping to KtFunctionCall. 2021-07-16 21:05:59 +03:00
Alexander Likhachev
6fe730a12e [Gradle, JS] Add IT that no tasks configured on help task execution
#KT-47559 Fixed
2021-07-16 20:14:51 +03:00
Alexander Likhachev
0740d11378 [Gradle, JS] Configure run tasks lazily
#KT-47559 In Progress
2021-07-16 20:14:49 +03:00
Victor Petukhov
6a1ec92d39 Introduce specific error for calls which could be resolved only with unrestricted builder inference
^KT-47747 Fixed
2021-07-16 19:32:36 +03:00
Victor Petukhov
357fda2efa Initialize builder inference lambda anyway, even a call is inapplicable
^KT-47744 Fixed
2021-07-16 19:32:35 +03:00
Alexander Likhachev
2b0ba6fa40 [Gradle, MPP] Add test for KT-47611, KT-47612
#KT-47611 Fixed
#KT-47612 Fixed
2021-07-16 18:33:45 +03:00
Alexander Likhachev
8109b66a79 [Gradle, MPP] Make publishing compatible with configuration cache
Capture artifact coordinates more accurately to conform with configuration cache
#KT-47611 In Progress
2021-07-16 18:33:45 +03:00
Alexander Likhachev
77471c0cd8 [Gradle, MPP] Make kotlin tooling metadata task compatible w/ conf cache
The value should be memoized in task, so it can be serialized in a way to not use project in execution time
#KT-47612 In Progress
2021-07-16 18:33:43 +03:00
Mikhael Bogdanov
5f53a2071d Update test affected by ProperTypeInferenceConstraintsProcessing feature 2021-07-16 13:26:37 +00:00
Mikhael Bogdanov
392dce9a40 Update test affected by PrivateInFileEffectiveVisibility feature 2021-07-16 13:26:36 +00:00
Mikhael Bogdanov
c519003e13 Update test affected by ProhibitSimplificationOfNonTrivialConstBooleanExpressions feature 2021-07-16 13:26:36 +00:00
Mikhael Bogdanov
a657e63dbb Update test affected by ForbidUsingExtensionPropertyTypeParameterInDelegate feature 2021-07-16 13:26:35 +00:00
Mikhael Bogdanov
70df4f10c5 Update test affected by AbstractClassMemberNotImplementedWithIntermediateAbstractClass feature 2021-07-16 13:26:34 +00:00
Mikhael Bogdanov
f05d470f6a Update test affected by 'ProhibitJvmFieldOnOverrideFromInterfaceInPrimaryConstructor' feature 2021-07-16 13:26:33 +00:00
pyos
f5dd5ead1f JVM: produce a better error on @JvmStatic external in interface
Java does not permit `static native` methods in interfaces, so this
never worked on any existing JRE.

 #KT-43696 Fixed
2021-07-16 15:24:09 +02:00
pyos
ad7ed483f3 JVM_IR: copy correspondingProperty of static external functions
Required for correctly mapping their names.

 #KT-47715 Fixed
2021-07-16 15:24:05 +02:00
Ilya Goncharov
adeb2f527b [Gradle, JS] Fail incremental test if there is source maps warning
^KT-47751 fixed
2021-07-16 15:39:52 +03:00
Ilya Goncharov
f73726c330 [Gradle, JS] Ignore source maps arguments in cache building
^KT-47751 fixed
2021-07-16 15:39:50 +03:00
Yahor Berdnikau
d82681889b Ignore empty directories on input properties hash calculation.
Annotate all '@InputFiles' and '@InputDirectory' input properties
with '@IgnoreEmptyDirectories' annotation, so empty directories
will be excluded from input hash calculation.

^KT-27687 Fixed
2021-07-16 12:35:15 +00:00
Dmitriy Novozhilov
22f57220c1 [FE 1.0] Report INTEGER_OPERATOR_RESOLVE_WILL_CHANGE on rhs of assign
^KT-47729 Fixed
2021-07-16 15:18:46 +03:00
Dmitriy Novozhilov
afb7625d0c [FE 1.0] Fix false positive INTEGER_OPERATOR_RESOLVE_WILL_CHANGE
^KT-47729 In progress
2021-07-16 15:18:44 +03:00
Dmitriy Novozhilov
2fb5f776d8 [FE 1.0] Report INTEGER_OPERATOR_RESOLVE_WILL_CHANGE on calls in parenthesis
^KT-47729 In progress
2021-07-16 15:18:38 +03:00
Victor Petukhov
ea4ab46765 Report implicit inferred Nothing only for own type parameters and in delegation resolve
^KT-47724 Fixed
2021-07-16 11:21:51 +03:00
Alexander Likhachev
7bb4612149 [Gradle] Add IT that useExperimentalAnnotation produces deprecation warn
#KT-38111 Fixed
2021-07-16 11:01:15 +03:00
Alexander Likhachev
68ced78d89 [Gradle] Rename experimental annotations to opt-in in test data
#KT-38111 In Progress
2021-07-16 11:01:14 +03:00
Alexander Likhachev
fa68dbc736 [Gradle] Rename experimental annotations to opt-in annotations in DSL
Methods and accessors with old names are preserved in public API and marked as deprecated now
#KT-38111 In Progress
2021-07-16 11:01:12 +03:00
Aleksei.Cherepanov
d9701d57bb Fix JPS tests after 2d65383a 2021-07-16 05:35:05 +03:00
Ilya Chernikov
c83614386e [minor] FIR: (temporarily) fix testdata due to different builtins behavior 2021-07-16 02:24:45 +03:00
Ilya Chernikov
02bf745eef IR: Remove some unused IrBuiltIns methods 2021-07-16 02:24:44 +03:00
Ilya Chernikov
51dc829aae IR: Move unsigned classes loading from builtins back to symbols
see #KT-47540 for the motivation
2021-07-16 02:24:43 +03:00
Ilya Chernikov
808f5148f3 IR: implemented generic knownBuiltIns property 2021-07-16 02:24:42 +03:00
Ilya Chernikov
a7d494480c [minor] FIR: minor fixes in FIR-based IrBuiltIns 2021-07-16 02:24:41 +03:00
Ilya Chernikov
56805dded8 [minor] IR: minor builtins infrastructure fixes 2021-07-16 02:24:40 +03:00
Ilya Chernikov
19f52d9aae [minor] FIR: fix irbuiltins implementation after rebase 2021-07-16 02:24:38 +03:00
Ilya Chernikov
873a7c6ef1 FIR: Implement delayed binding of overriddens in the delegated members
fixes the problem when overridden symbols on delegated members were
build on the incomplete fake overrides leading to the incorrect
generation of the function for default parameter and thus to the
codegen error (see withDefaultsMultipleFilesOrder test for an example)
2021-07-16 02:24:37 +03:00
Ilya Chernikov
c9b6847d83 FIR: Add test on delegated member with default param in overridden...
sensitive to the file processing order, therefore failing on the
current fir2ir at least with the new irBuiltIns
2021-07-16 02:24:36 +03:00
Ilya Chernikov
a2385b5edd [minor] FIR: Fix Fir2ir jvmmappedscope functions origins 2021-07-16 02:24:35 +03:00
Ilya Chernikov
6001a81a30 [minor] FIR: Fix IR builtins modality 2021-07-16 02:24:34 +03:00
Ilya Chernikov
5b2acea98f FIR: Add analysis flag for loading IR builtins from sources 2021-07-16 02:24:32 +03:00
Ilya Chernikov
c2c02ddb27 FIR: refactoring IrBuiltIns initialization logic...
to allow to try to load them from dependencies first
and to intialize fake overrides properly
2021-07-16 02:24:31 +03:00
Ilya Chernikov
9de27bc4d8 FIR: Avoid "Mutating Fir2Ir lazy elements" error
for classes came from sources
2021-07-16 02:24:30 +03:00
Ilya Chernikov
8f5d5c3ace FIR: Fixes in testdata after implementing FIR-specific IrBuiltIns 2021-07-16 02:24:29 +03:00
Ilya Chernikov
01f26ec699 FIR: Switch to FIR-based IrBuiltIns in FIR compilation
get rid of using old FE for builtins on FIR compilation
2021-07-16 02:24:28 +03:00
Ilya Chernikov
3b20ec46ef FIR: Set correct modality to default accessors on deserialization
fixes some tests with new IrBuiltIns
2021-07-16 02:24:27 +03:00
Ilya Chernikov
5b677c068f FIR: Refactor JvmMappedScope to fix container-related tests with new builtins 2021-07-16 02:24:25 +03:00
Ilya Chernikov
80a710a5c5 FIR: implementing IrBuiltIns over FIR 2021-07-16 02:24:24 +03:00
Ilya Chernikov
cb4999f23c Native: port native to the new IrBuiltIns 2021-07-16 02:24:22 +03:00
Ilya Chernikov
48a3c64901 IR: Refactor primitive arrays handling in the new IrBuiltIns
for better compatibility e.g. with native
2021-07-16 02:24:20 +03:00
Ilya Chernikov
3b2bb2ba9f IR: Fix error rendering on IR symbol binding conflict
it could be called with uninitialized `owner` parameter, leading
to the NPE on render
2021-07-16 02:24:19 +03:00
Ilya Chernikov
dee0487185 IR: Refactor IrBuiltIns to abstract it from descriptors 2021-07-16 02:24:18 +03:00
Nikolay Lunyak
25d2e61a82 [FIR2IR] Adding 2 new runners for fir2ir-specific tests 2021-07-15 23:15:39 +03:00
Alexander Likhachev
a6e477fa88 [Build] Add dependency verification data for jna 2021-07-15 20:41:59 +03:00
Alexander Likhachev
1a77b57a7b [Gradle] Provide JNA jar to compiler classpath with intellij-core 203+
#KT-47748 Fixed
2021-07-15 20:41:57 +03:00
Yahor Berdnikau
da1d49e622 Add new ways to set Kotlin daemon JVM arguments.
Additionally to inheriting Gradle daemon arguments or configuring via
 Gradle daemon arguments system property, it is also possible now
 to configure arguments either using "kotlin.daemon.jvmargs" property
 or extension DSL.

Extension DSL overrides special gradle property arguments, which
overrides Gradle daemon arguments.

^KT-45747 Fixed
2021-07-15 17:27:38 +00:00
Dmitry Petrov
b98322c1b4 JVM don't optimize methods with too many TCBs 2021-07-15 20:18:18 +03:00
Dmitry Petrov
d65d66c03a JVM reserve 2 slots for node predecessors/successors in CFG 2021-07-15 20:18:15 +03:00
Dmitry Petrov
6c2d93bb8b JVM traverse nodes in reverse order in 'findSafelyReachableReturns' 2021-07-15 20:18:13 +03:00
Mikhael Bogdanov
f080dbb78c Update resolveAnnotations tests in new infrastructure 2021-07-15 17:08:17 +00:00
Mikhael Bogdanov
671ef7dfff Regenerate tests 2021-07-15 17:08:16 +00:00
Mikhael Bogdanov
3aeb9291fe Move resolveAnnotations tests into diagnostics tests 2021-07-15 17:08:16 +00:00
Jinseong Jeon
9ec4d19a3f FIR IDE: avoid finding symbol for function type parameter 2021-07-15 18:29:33 +02:00
Jinseong Jeon
2e502bd01e FIR IDE: fix anonymous function symbol retrieval from function literal 2021-07-15 18:29:32 +02:00
Dmitry Petrov
8ea4916d64 JVM_IR KT-47739 recognize fake override external stubs 2021-07-15 19:20:39 +03:00
Ivan Kochurkin
dd54338ec0 [FIR] Fix positioning and detecting of WRONG_NUMBER_OF_TYPE_ARGUMENTS
Refactor code and fix compilation errors caused by changes to symbol.fir
2021-07-15 19:02:58 +03:00
Ivan Kochurkin
345152d198 [FIR] Add containingDeclarationSymbol to FirTypeParameter 2021-07-15 19:02:56 +03:00
Ivan Kochurkin
0c25d280ee [FIR] Fix calculating of source of TypeArgumentList, add source to FirQualifierPart
Fix positioning for TYPE_ARGUMENTS_NOT_ALLOWED
2021-07-15 19:02:54 +03:00
Ivan Kochurkin
28a6928873 [FIR] Check rest OUTER_CLASS_ARGUMENTS_REQUIRED diagnostics on checkers stage
Add FirOuterClassArgumentsRequiredChecker
2021-07-15 19:02:45 +03:00
Ivan Kochurkin
0fc8be4d60 [FIR] Implement OUTER_CLASS_ARGUMENTS_REQUIRED diagnostics 2021-07-15 19:02:40 +03:00
Yahor Berdnikau
f7ed2f813d Exclude Gradle Kotlin runtime dependencies from 'no-arg' plugin.
This should remove warnings on multiple versions in build classpath
runtime.

^KT-47635 Fixed
2021-07-15 15:27:56 +00:00
Yahor Berdnikau
8db1c52c09 Exclude Gradle Kotlin runtime from 'sam-with-receiver' plugin.
This should remove warnings on multiple dependencies versions
in the build classpath runtime.

^KT-47636 Fixed
2021-07-15 15:27:24 +00:00
Mikhail Glukhikh
40c3c317b2 RawFirBuilder: optimize package name calculation in compiler mode 2021-07-15 12:46:23 +00:00
Ilya Goncharov
dcc54101a7 [Gradle, JS] Add test with icremental JS Ir in parallel build 2021-07-15 11:42:48 +00:00
Svyatoslav Kuzmich
a468792a19 [Wasm] Support Milestone 3 of V8 Wasm GC
Advance V8 version to 9.2.212

Relevant Wasm GC changes:
f9f8ffa445
2021-07-15 10:59:06 +00:00
sebastian.sellmair
9500b2d36e [Commonizer] Add HierarchicalCInteropCallableAnnotationCommonizationTest.test single platform not marked as objc 2021-07-15 10:04:45 +00:00
sebastian.sellmair
17ed498390 [Commonizer] approximationKeys: Fix closing ] for type parameter types' upper bounds 2021-07-15 10:04:45 +00:00
sebastian.sellmair
daa046589e [Commonizer] approximationKeys: Minor cleanup of buildApproximationSignature 2021-07-15 10:04:44 +00:00
sebastian.sellmair
2c8ce2539b [Commonizer] HierarchicalPropertyCommonizationTest: Add test property with and without setter 2021-07-15 10:04:43 +00:00
sebastian.sellmair
8bab6c3076 [Commonizer] Commonize 'val' and 'var' properties
If a setter is not present on all platforms a fallback private setter
shall be emitted.

^KT-47502 Verification Pending
^KT-47691 Verification Pending
2021-07-15 10:04:43 +00:00
sebastian.sellmair
c4d90dc744 [Commonizer] Implement alis type substitution as CirNodeTransformer
This has the advantage, that the substitution only has to run on
functions or properties that are 'incomplete' (missing at least
one other target declaration)

^KT-47433 Verification Pending
2021-07-15 10:04:42 +00:00
sebastian.sellmair
7c450f9884 [Commonizer] Implement CirAliasTypeSubstitutor
This will substitute non-commonizable classifiers with known
type-aliases (which might be commonizable).

A simple example depending on this substitution comes from posix:
Most function and properties use the `FILE` typealias which
is available across all platforms.

Some linux platforms use `__IO_FILE` in their signature, which
is just linux specific. This type substitution will figure out, that
this type can be substituted with `FILE`.

^KT-47433 Verification Pending
2021-07-15 10:04:41 +00:00
sebastian.sellmair
906346b7d9 [Commonizer] Drop CirProperty interface for plain data class 2021-07-15 10:04:41 +00:00
sebastian.sellmair
f0feca286e [Commonizer] Drop CirExtensionReceiver interface for plain data class 2021-07-15 10:04:40 +00:00
sebastian.sellmair
fdee49ee59 [Commonizer] Drop CirTypeParameter interface for plain data class 2021-07-15 10:04:39 +00:00
sebastian.sellmair
4a4516731a [Commonizer] Drop CirValueParameter interface for plain class 2021-07-15 10:04:39 +00:00
sebastian.sellmair
e246a12cd3 [Commonizer] Drop CirFunction interface for plain data class 2021-07-15 10:04:38 +00:00
sebastian.sellmair
0c32abed02 [Commonizer] Remove now unnecessary ArtificialCirDeclaration
This marker interface is not necessary anymore, since no new actuals
will be generated by the Commonizer. It was used to filter declarations
during the serializ
2021-07-15 10:04:37 +00:00
sebastian.sellmair
e041532dd2 [Commonizer] InlineSourceBuilder: Also mark ModuleBuilder functions with InlineSourcesCommonizationTestDsl 2021-07-15 10:04:37 +00:00
sebastian.sellmair
87ac436a35 [Commonizer] Implement HierarchicalCInteropCallableAnnotationCommonizationTest 2021-07-15 10:04:36 +00:00
sebastian.sellmair
8acfeb3e17 [Commonizer] Remove computing signatures from metadata 2021-07-15 10:04:36 +00:00
sebastian.sellmair
f3ff9814a8 [Commonizer] Create approximation keys based on Cir instead of metadata 2021-07-15 10:04:35 +00:00
sebastian.sellmair
09f9a1ce5b [Commonizer] Share Test: Commonizer / Light run configuration
This run configuration can be used to run only light weight/faster tests
2021-07-15 10:04:34 +00:00
Andrey Kuleshov
26a71af6b3 [Native, All platforms] HotFix of the incorrect parsing of long strings to Float and Double (#4492)
### What's done:
- Fixed incorrect logic of String.toFloat() and String.toDouble().
  Long string without any digits were treated as Float or Double:
  "this string does not look as float isn't it?".toFloat() == "Infinity".

- Fixed incorrect parsing of floating point constants "NaN" and "Infinity":
  String values like "NaNPICEZy" or "InfinityN" were treated as valid numbers.

- Merged parsing logic for Double and Float:
  Removed the code duplication, unified methods, made the code more Kotlin-like, not C++-like.

- Updated tests:
  Removed useless tests that checked nothing, updated tests with regression scenarios.
2021-07-15 14:47:55 +07:00
Sergey Bogolepov
118889add5 [K/N] Fix mingw_x86 compilation
It was broken in 9ed97a27f1.
2021-07-15 04:55:36 +00:00
Roman Artemev
447900c3f2 [K/N] Make sure all module names are uniq
In case of klib -> binary compilation there were two different modules
with the same. It breaks invariant about uniqueness if module name.
2021-07-15 03:09:46 +03:00
Georgy Bronnikov
ba61700be6 Regenerate tests 2021-07-14 21:20:49 +03:00
Georgy Bronnikov
4af2aaedb1 IR, temporary: a simpler mangling for flexible types
Mangling for flexible types will need another look.
Complicated cases still do not work.
2021-07-14 21:20:48 +03:00
Georgy Bronnikov
c3f4fcde0b JVM_IR: compute signatures for fake overrides of Java fields 2021-07-14 21:20:47 +03:00
Georgy Bronnikov
8c3386b607 IR: set file in declarationTable when serializing IR 2021-07-14 21:20:46 +03:00
Georgy Bronnikov
05a42b8cd5 IR: handle CompositeSignature in DescriptorByIdSignatureFinder 2021-07-14 21:20:45 +03:00
Georgy Bronnikov
da946e464f Fix compilation after rebase: add debugInfo to JvmIr.proto 2021-07-14 21:20:43 +03:00
Georgy Bronnikov
f4d358069c Fixes after rebase, not related to IrLibraryFile 2021-07-14 21:20:42 +03:00
Georgy Bronnikov
08b950fc2a JVM_IR: Supply fake file name to signatures of file local declarations 2021-07-14 21:20:41 +03:00
Georgy Bronnikov
225705a237 IR: do not serialize nonlocal initializers in inline-only mode 2021-07-14 21:20:40 +03:00
Georgy Bronnikov
28bff2ba4f JVM_IR: add test for calling monitorEnter/Exit from serialized code. 2021-07-14 21:20:38 +03:00
Georgy Bronnikov
dffb22de9d JVM_IR: avoid duplication in declaration lists during deserialization 2021-07-14 21:20:36 +03:00
Georgy Bronnikov
fa4efd3303 JVM_IR: fix deserialization of Java static field symbols 2021-07-14 21:20:35 +03:00
Georgy Bronnikov
955ee07517 IR: compute signature for scripts 2021-07-14 21:20:33 +03:00
Georgy Bronnikov
9d0c6fb157 IR: remove an overly optimistic assert 2021-07-14 21:20:32 +03:00
Georgy Bronnikov
c3a94e1e62 FIR: adapt to changes in IR interface
JvmGeneratorExtensionsImpl, JvmIrCodegenFactory need new arguments.
2021-07-14 21:20:31 +03:00
Georgy Bronnikov
20b76d4149 JVM_IR: reorganize initialization of JvmGeneratorExtensionsImpl
CachedFields are now created at initialization.
Therefore we need CompilerConfiguration as a constructor parameter.
2021-07-14 21:20:30 +03:00
Georgy Bronnikov
7bbc04b6a2 JVM_IR: reconstruct fake overrides after IR deserialization.
We need to keep track of local signatures for deserialized symbols.
2021-07-14 21:20:29 +03:00
Georgy Bronnikov
a63cc95a2a JVM_IR: untangle backend.jvm and serialization.jvm (again) 2021-07-14 21:20:28 +03:00
Georgy Bronnikov
1c4466951f IR: a flag to GeneratorExtensions to control IR deserialization
There is no need to search for IR embedded in toplevel classes when none
is expected (in npon-JVM backends or when -Xserialize-ir is not set).
2021-07-14 21:20:27 +03:00
Georgy Bronnikov
ec1c97c684 JVM_IR: register builtin annotation constructors in SymbolTable
When deserializing IR, these annotations need to be visible.
2021-07-14 21:20:26 +03:00
Georgy Bronnikov
8d15a1d13d JVM_IR: use signatures in AbstractIrSerializeCompileKotlinAgainstInlineKotlinTest
Using signatures allows us to identify calls from a new module to an old
one.
2021-07-14 21:20:24 +03:00
Georgy Bronnikov
49619cda48 Restore Native compilation 2021-07-14 21:20:23 +03:00
Georgy Bronnikov
931733f8cc JVM_IR: deal with JvmStatic in imported IR 2021-07-14 21:20:22 +03:00
Georgy Bronnikov
96ce124268 JVM_IR: serialize fake overrides in IR 2021-07-14 21:20:21 +03:00
Georgy Bronnikov
2d3a558d50 JVM_IR: normalize visibility before serializing 2021-07-14 21:20:20 +03:00
Georgy Bronnikov
a328ebc889 JVM_IR: extract cached fields into a separate class 2021-07-14 21:20:18 +03:00
Georgy Bronnikov
50068607b9 JVM_IR: call serializeIr from a phase
This circumvents the need to run expect/actual resolution on
deserialized IR.
2021-07-14 21:20:17 +03:00
Georgy Bronnikov
0d5fe0b029 JVM_IR: load serialized data for every affected property of IrLazyFunction 2021-07-14 21:20:16 +03:00
Georgy Bronnikov
f4e6eb00fd JVM_IR: generate unbound symbols after deserializing IR 2021-07-14 21:20:15 +03:00
Georgy Bronnikov
6b80c00cc6 JVM_IR: deserialize lazy declarations 2021-07-14 21:20:14 +03:00
Georgy Bronnikov
ad8892f71f JVM_IR: test that inline functions have deserialized bodies 2021-07-14 21:20:12 +03:00
Georgy Bronnikov
7b52a8c07d JVM_IR: deal with facade classes when computing signature 2021-07-14 21:20:11 +03:00
Georgy Bronnikov
97d3eda23c JVM_IR: run Kotlin against Kotlin tests with serialization 2021-07-14 21:20:10 +03:00
Georgy Bronnikov
ab3d6490ed JVM_IR: save auxTables as byte strings 2021-07-14 21:20:09 +03:00
Georgy Bronnikov
7dbdb311e1 JVM_IR: read serialized IR from annotation 2021-07-14 21:20:08 +03:00
Georgy Bronnikov
baaecaa052 JVM_IR: write serialized IR to an annotation 2021-07-14 21:20:06 +03:00
Georgy Bronnikov
b177779b66 IR: compute signatures for fields 2021-07-14 21:20:05 +03:00
Georgy Bronnikov
b2617199bc JVM_IR: call serialization for IR.
Serializer for IR is called when -Xserialize-ir flag is set.
2021-07-14 21:20:04 +03:00
Georgy Bronnikov
9efd0d7589 JVM_IR: JvmIrSerializer 2021-07-14 21:20:02 +03:00
Mikhail Glukhikh
113d2653aa Drop deprecated -Xexperimental flag from compiler and tests 2021-07-14 21:18:23 +03:00
anastasiia.spaseeva
cbcec8d624 Add changelog for 1.5.21 2021-07-14 19:37:14 +03:00
Margarita Bobova
ed3326fd83 Add changelog for 1.5.20 2021-07-14 19:37:12 +03:00
Nikita Bobko
bf6718e0a5 Fix compilation in kotlin-ide 2021-07-14 17:17:19 +02:00
Ilya Goncharov
047041dc6e [Gradle, JS] Await worker which builds cache 2021-07-14 14:46:04 +00:00
Pavel Kunyavskiy
92789984e0 [K/N] Make SafeContinuation thread-safe 2021-07-14 09:03:31 +00:00
pyos
07cb3a5ff8 JVM: do not reify methods of objects in lambdas
All type parameters used in them are not from the inline function
anyway.
2021-07-14 10:11:05 +02:00
pyos
717cf2066a JVM: remove more redundant properties from LambdaInfo 2021-07-14 10:11:05 +02:00
pyos
c1c56ca388 JVM: refactor extraction of default inline lambdas a bit more 2021-07-14 10:11:05 +02:00
pyos
91cf1a1a4d JVM: remove a redundant DefaultLambda field
and add a comment explaining one branch of the inliner... Better than
nothing, I guess?
2021-07-14 10:11:05 +02:00
pyos
100d2d629c JVM: inline default lambda coercions from bridge invoke
The type of the default lambda may be a subtype of the parameter type,
so we can't really generate our own coercions at all as we don't know
the precise Kotlin type of the `invoke` method.
2021-07-14 10:11:05 +02:00
pyos
d0b9c4ae6b JVM: generalize getMethodNode
to allow matching by arbitrary predicates.
2021-07-14 10:11:05 +02:00
Alexander Likhachev
f986591ba9 [Build] Suppress ivy url senseless comparison warning
It's marked as not null in Gradle, but it's still possible to declare Ivy repository with null url which leads to GeneralKotlin2JsGradlePluginIT#testJsBothModeWithTests test false fail (cache redirector script is used in Gradle integration tests)
2021-07-14 10:59:14 +03:00
Ilya Matveev
922aad6865 [K/N] Add exp10 and exp10f to good function list for call checker
Clang may replace a call to `pow (10.0, x)` with a call to `exp10(x)`
(or `__exp10` on MacOS).

We use this function in float parsing logic, so this function should
be added to the good function list.
2021-07-14 04:49:04 +00:00
Nikolay Krasko
0f2e653625 Use cache-redirector for yarn download (KTI-577) 2021-07-13 22:36:51 +03:00
Nikolay Krasko
ec04af9eea Update cache redirector list 2021-07-13 22:36:50 +03:00
Dmitry Petrov
dc16d66fb1 Minor: regenerate tests 2021-07-13 21:23:17 +03:00
pyos
3dc7b6c3ee IR: preserve argument evaluation order more carefully
1. receivers should be evaluated before named arguments;
 2. just because an argument has no side effects doesn't mean it is not
    affected by the other arguments' side effects - in that case it
    should still be evaluated in source order.

 #KT-47660 Fixed
2021-07-13 21:23:15 +03:00
Roman Artemev
b5942204dc [KLIB] Enable accidentally disabled IC for klibs in K/JS 2021-07-13 18:58:57 +03:00
Roman Artemev
ece9307471 [JS IR] Fix destination directory in Incremental compiler runner for JS 2021-07-13 18:58:56 +03:00
Aleksei.Cherepanov
d2881a7920 Improve performance of Lookup storage
Reduce size of lookup map after rebuild, reduce waiting time by replacing operations of read+write with append, also split remove garbage process into smaller operations in get

#KT-46804 Fixed
2021-07-13 18:39:38 +03:00
Alexander Udalov
35f6337de3 Remove obsolete kotlin.build.useIR flag
(cherry picked from commit 91e47f1fd7)
2021-07-13 14:01:19 +02:00
Elena Lepilkina
c401cf961d [K/N][C interop] Support Kotlin special names processing (KT-47209 fixed) 2021-07-13 11:56:31 +00:00
Roman Artemev
0326518fc9 [KLIB] Cutting down usages of moduleDescriptor in linker
Replace map key `ModuleDescriptor` with `String` which is module name
2021-07-13 14:43:42 +03:00
Roman Artemev
eadf252de9 [KLIB] Provide KotlinLibrary for Konan Interop Deserializer 2021-07-13 14:43:41 +03:00
Roman Artemev
0a49b24320 [JS IR] Move klib resolution from cli into compiler
Simplify CLI -> Compiler API
Clean up code
2021-07-13 14:43:40 +03:00
Roman Artemev
103e4ef2a5 [JS IR] Disable ts export check in PIR mode in box tests
Since that feature is not declared as working yet
2021-07-13 14:43:38 +03:00
Elena Lepilkina
025e572462 [K/N] Fixed case with parameter which can be optimized with BCE 2021-07-13 09:22:13 +00:00
Elena Lepilkina
2477ea80c6 Reverted loops order processing in ForLoopsLowering 2021-07-13 09:22:12 +00:00
Elena Lepilkina
c096e6a3eb [K/N] Analyze vals in bounds check elimination 2021-07-13 09:22:11 +00:00
Elena Lepilkina
9503627864 Changed an order of processing loops in ForLoopsLowering 2021-07-13 09:22:11 +00:00
Elena Lepilkina
0e04c21625 [K/N] Bounds check elimination in basic for loops forms 2021-07-13 09:22:10 +00:00
Elena Lepilkina
7975311ca2 [K/N] Added tests for bounds checks 2021-07-13 09:22:09 +00:00
Elena Lepilkina
ac074207c7 [K/N] ForLoopsLowering: Use get without bounds check in ArrayIterationHandler 2021-07-13 09:22:08 +00:00
Dmitriy Novozhilov
f33f3c769f Fix USELESS_IS_CHECK warnings in compiler code 2021-07-13 10:35:05 +03:00
Dmitriy Novozhilov
968f823b72 [JVM IR]Fix detecting annotation retention 2021-07-13 10:35:04 +03:00
Dmitriy Novozhilov
47b0071560 [FE 1.0] Properly handle intersection types in check if cast possible or not
^KT-47685 Fixed
2021-07-13 10:35:03 +03:00
Dmitriy Novozhilov
f0c4d06fc9 [FE 1.0] Cleanup PatternMatchingTypingVisitor.kt 2021-07-13 10:35:02 +03:00
Dmitriy Novozhilov
7b5a5f5682 [FE 1.0] Report USELESS_IS_CHECK if is expression is always false
^KT-47684 Fixed
2021-07-13 10:35:01 +03:00
Dmitriy Novozhilov
785e2f862c [PSI] Ignore when failed to get file text
This is change from 36ff952 which was forgotten when applying 203 bunch
2021-07-13 10:34:59 +03:00
Dmitriy Novozhilov
daa4c708a2 [FIR] Remove unused parameter from ensureResolvedForCalls 2021-07-13 10:31:36 +03:00
Dmitriy Novozhilov
c3b20c9ccb [FIR IDE] Add forgotten space to renderer in diagnostic generator 2021-07-13 10:31:34 +03:00
Dmitriy Novozhilov
22a4da024b [FIR] Fix all illegal usages of symbol.fir in checkers module 2021-07-13 10:31:34 +03:00
Dmitriy Novozhilov
e94d75d433 [FIR] Add opt-in annotation which prevents from using symbol.fir 2021-07-13 10:31:32 +03:00
Dmitriy Novozhilov
c99a02796f [FIR] Replace getContainingClass usages with getContainingClassSymbol 2021-07-13 10:31:31 +03:00
Dmitriy Novozhilov
48a25e2fe6 [FIR] Add some status utils over symbols to addition to utils over fir 2021-07-13 10:31:30 +03:00
Dmitriy Novozhilov
b2c6dd8d53 Convert ClassKind.java to Kotlin 2021-07-13 10:31:29 +03:00
Dmitriy Novozhilov
0062f1ba27 Rename ClassKind.java to ClassKind.kt 2021-07-13 10:31:28 +03:00
Dmitriy Novozhilov
22938522b3 [FIR] Add forgotten updating phase of value parameters 2021-07-13 10:31:27 +03:00
Dmitriy Novozhilov
d3966e8844 [FIR] Add accessors to parts of signatures to symbols 2021-07-13 10:31:26 +03:00
Dmitriy Novozhilov
0f06ab537f [FIR] Remove useSiteSession parameter from ensureResolved 2021-07-13 10:31:25 +03:00
Dmitriy Novozhilov
92cfaf68bb [FIR] Remove unused FirFunctionSymbol.parameters 2021-07-13 10:31:24 +03:00
Dmitriy Novozhilov
4deb935f76 [FIR] Mark value classes as inline in raw fir building 2021-07-13 10:31:23 +03:00
Dmitriy Novozhilov
8df56af068 [FIR] Add forgotten settings of resolve phase 2021-07-13 10:31:22 +03:00
Dmitriy Novozhilov
9f161f16b3 [FIR] Move FirPhaseManager to :compiler:fir:tree 2021-07-13 10:31:21 +03:00
Dmitriy Novozhilov
51fc2e453f [FIR] Unity FirCallableDeclaration and FirCallableMemberDeclaration
After removal of all diamonds in FirDeclaration hierarchy
  FirCallableMemberDeclaration was only one inheritor of
  FirCallableDeclaration, so there is no need to keep them both
2021-07-13 10:31:20 +03:00
Dmitriy Novozhilov
adc45fd3dd [FIR] Remove useless generic parameter from deprecation utils 2021-07-13 10:31:18 +03:00
Dmitriy Novozhilov
c50fe4e399 [FIR] Move some components implementations from :entrypoint to appropriate modules 2021-07-13 10:31:17 +03:00
Alexander Udalov
173e194dac Remove dependency on JVM specifics in serialization.common
Move handling of EnhancedNullability to JVM subclasses in
serialization.jvm. Looks like this was possible because of accidental
dependency of frontend on compiler.common.jvm introduced in 564d382b9d.

Also fix a minor typo in the file name typeEnhancementUtils.kt.
2021-07-13 01:54:41 +02:00
Alexander Udalov
7a42f603f2 JVM IR: rename mangler implementation classes 2021-07-13 01:54:41 +02:00
Alexander Udalov
1e16c7d8d4 Minor, update kotlinx-metadata-jvm changelog
According to changes in 1e7295c6.
2021-07-12 22:40:02 +02:00
pyos
d988853c11 JVM_IR: optimize out redundant delegated property receiver fields
Now this:

    class C {
        val x = something
        val y by x::property
    }

is *exactly* the same as this:

    class C {
        val x = something
        val y get() = x.property
    }

(plus a `getY$delegate` method)
2021-07-12 22:38:45 +02:00
pyos
2fe7cf27ad kotlinp: use JVM_IR backend for compiling tests
Also, test optimized delegated properties.
2021-07-12 22:38:45 +02:00
pyos
791fa411d8 JVM_IR: write correct lambda invoke() signature in metadata 2021-07-12 22:38:45 +02:00
pyos
a7c13db575 JVM_IR: add $delegate methods to a few exclusion lists
1. they don't need type annotations;
 2. internal ones include the module name before the `$delegate` part,
    so further mangling is redundant
 3. they don't need multifile facade bridges.

Unlike `$annotations`, delegated properties don't appear in interfaces,
so exclusions in InterfaceLowering would be redundant.
2021-07-12 22:38:45 +02:00
pyos
6897e89bbc JVM: add tests for optimized getDelegate 2021-07-12 22:38:45 +02:00
pyos
debd58d377 JVM: use $delegate methods in KProperty[0-2].getDelegate
#KT-39055 Fixed
2021-07-12 22:38:44 +02:00
pyos
1e7295c64e JVM: add $delegate method support to kotlinx-metadata
and kotlinp as well -- it is now possible to see the effect of the
previous commit.
2021-07-12 22:38:44 +02:00
pyos
5d0102a966 JVM_IR: generate $delegate methods for val x by ::y 2021-07-12 22:38:44 +02:00
pyos
7ae4303e1b JVM_IR: slightly refactor JvmPropertiesLowering
to make it easier to generate different kinds of synthetic methods.

 #KT-47609 Fixed
2021-07-12 22:38:44 +02:00
pyos
a943cdadef JVM_IR: support generation of bound reflected property references
Not currently used though, since only references for delegated
properties' accessors are reflected, and those are unbound.
2021-07-12 22:38:43 +02:00
pyos
664bb055c8 JVM_IR: support codegen of property delegate methods
The purpose of a property-related method is now determined by its
origin; codegen no longer assumes all methods with Property metadata
source are `getX$annotations`.
2021-07-12 22:38:43 +02:00
pyos
6a3c79bb9e JVM: support on-the-fly generation of property delegates in metadata
Optimizations may remove the `x$delegate` field, in which case there
should be a `getX$delegate` method to reconstruct the value if needed
due to a call to `KProperty{0,1,2}.getDelegate`. We need to know the
signature of this method somehow.
2021-07-12 22:38:43 +02:00
pyos
e49410e07b JVM_IR: optimize delegation by property references
E.g. a statement like

    var x by ::y

is semantically equivalent to

    var x
      get() = y
      set(value) { y = value }

and thus does not need a full property reference object, or even a field
if the receiver is not bound.

 #KT-39054 Fixed
 #KT-47102 Fixed
2021-07-12 22:38:43 +02:00
Ivan Kochurkin
66e052b9b3 [FIR] Implement SPREAD_OF_NULLABLE 2021-07-12 23:16:47 +03:00
Nikita Bobko
83c5c41dd4 Fix that marketplace identifies newly uploaded Kotlin plugin artifacts as Kotlin 1.2 artifacts
This `compiler.xml` is packed into `kotlin-idea.jar` and causes troubles for marketplace
in identifying correct Kotlin plugin version
2021-07-12 22:04:20 +03:00
Mikhail Glukhikh
a997a98054 Commend -Xopt-in deprecation warning (due to bootstrap problems) 2021-07-12 21:26:21 +03:00
Mikhail Glukhikh
a92ab1bc86 Deprecate EXPERIMENTAL_IS_NOT_ENABLED diagnostic #KT-47638 Fixed 2021-07-12 21:26:20 +03:00
Mikhail Glukhikh
5871f3d663 CLI: support -option=value syntax for non-advanced flags #KT-47640 Fixed 2021-07-12 21:26:19 +03:00
Mikhail Glukhikh
d8417fd622 Introduce -opt-in stable compiler option instead of -Xopt-in
#KT-47099 Fixed
2021-07-12 21:26:18 +03:00
Mikhail Glukhikh
47c8bab48e Replace -Xuse-experimental with -Xopt-in in codebase 2021-07-12 21:26:17 +03:00
Mikhail Glukhikh
195b6d1fb1 Deprecate -Xuse-experimental #KT-47623 Fixed 2021-07-12 21:26:16 +03:00
Mikhail Glukhikh
d9531f0c61 Don't report EXPERIMENTAL_ANNOTATION_ON_WRONG_TARGET for forbidden targets
#KT-47589 Fixed
2021-07-12 21:26:15 +03:00
Ilmir Usmanov
ac7538a269 Set receivers for inline class default function stub calls
Default function stubs have dispatch and receiver parameters, but
inline class methods are static by design with receivers as ordinary
parameters. So, take these parameters and set them as receivers during
lowerings.
 #KT-46230: Fixed
2021-07-12 19:46:09 +03:00
Florian Kistner
31420a934c MI-187 Add asserts for module dependencies 2021-07-12 18:23:19 +03:00
Florian Kistner
3fe388bd17 MI-187 Also allow foreign DerivedModuleInfos, if their original module is known to the ResolverForProject 2021-07-12 18:23:17 +03:00
Mikhail Glukhikh
5f6be619c0 FIR: Don't get all*Checkers multiple times 2021-07-12 15:47:59 +03:00
Elena Lepilkina
3cabfb6a85 [K/N][New MM] Rare GC calls to optimize swiftinterop benchmarks 2021-07-12 12:27:05 +00:00
Elena Lepilkina
cdeda58ed4 [K/N][perf] Added opportunity to set up tagged branch and added benchmarks plots for new MM 2021-07-12 12:26:20 +00:00
Victor Petukhov
33a281c637 Introduce separate compiler flag for unrestricted builder inference 2021-07-12 13:57:13 +03:00
Alexander Shabalin
274dabb61d Collect stacktraces without allocating kotlin objects. 2021-07-12 08:49:33 +00:00
Alexander Shabalin
fca89c2118 Backport span from C++20
Does not support ranges and construction from arbitrary contiguous iterators as both need C++20 concepts for an adequate implementation.
2021-07-12 08:48:20 +00:00
Dmitriy Novozhilov
5efde67a0c [FIR IDE] Register java enhancement state in FirIdeSessions
This was forgotten in 6d364a5f
2021-07-12 11:47:25 +03:00
Dmitry Petrov
1f8d6d6edb JVM additional DCE tests 2021-07-12 11:09:30 +03:00
Dmitriy Novozhilov
6d364a5fee [FIR] Register enhancement state in library session too
This is needed for enhancement scopes for deserialized java declarations
2021-07-12 10:15:07 +03:00
Dmitriy Novozhilov
8e0793091a Add @NoInfer to safeAs type
This change will force specify type argument of every safeAs call
2021-07-12 10:11:36 +03:00
Dmitriy Novozhilov
ddc3ef1121 Fix all illegal usages of safeAs function
Call of `safeAs` without specifying explicit type argument is hardly
  readable and may leads to hardly detectable errors
2021-07-12 10:11:36 +03:00
Ilya Gorbunov
5072653957 Duration: parse explicit positive values parenthesized 2021-07-12 04:39:28 +00:00
Ilya Gorbunov
682cb8e34a Duration default toString: use 0, 1, 2, 3, 6, or 9 decimal digits
KT-42851
2021-07-12 04:39:27 +00:00
Ilya Gorbunov
7551719b85 Duration parsing: simplify range checks 2021-07-12 04:39:27 +00:00
Ilya Gorbunov
0427eec20f Quote invalid strings in exception messages 2021-07-12 04:39:26 +00:00
Ilya Gorbunov
3f6e2be687 Duration: do not use scientific format for large values
The largest duration value formatted in ns with maximal decimals
would fit in 40 chars.
2021-07-12 04:39:25 +00:00
Ilya Gorbunov
1be1e5279c Duration: parse and format negative values parenthesized 2021-07-12 04:39:25 +00:00
Ilya Gorbunov
ca1a9e4ca3 Duration: longer than long values in ISO components, test negative cases 2021-07-12 04:39:24 +00:00
Ilya Gorbunov
1c6ab08220 Introduce functions to parse a duration from a string KT-45325 2021-07-12 04:39:23 +00:00
Ilya Gorbunov
7ab6f6c9b2 Change Duration.INFINITE.toIsoString representation 2021-07-12 04:39:23 +00:00
Ilya Gorbunov
ae3d9cc3cd Small durations are formatted with sub-second units KT-42851 2021-07-12 04:39:22 +00:00
Ilya Gorbunov
150ce812f1 Use days component in the default duration format KT-42851 2021-07-12 04:39:21 +00:00
Ilya Gorbunov
255c4b405e Duration: round Double value to Long ns instead of truncating it KT-47675 2021-07-12 04:39:21 +00:00
Ilya Gorbunov
42cd2e65e6 Change Duration.toString format KT-42851 2021-07-12 04:39:20 +00:00
Dmitry Petrov
804db3ce91 JVM KT-47613 custom control flow analyzer for CFG builder 2021-07-11 20:16:09 +03:00
Dmitry Petrov
fe71435104 JVM KT-47613 traverse nodes backwards in backward analysis 2021-07-11 20:16:09 +03:00
Viacheslav Kormushkin
8c021af646 M1 support for cocoapods
#KT-47078
2021-07-10 19:23:51 +00:00
Ilya Gorbunov
455fee29e4 Find correct next match after matchAt and matchEntire KT-47676 2021-07-10 21:31:20 +03:00
Ilya Gorbunov
28a0698463 Regex.matchAt/matchesAt #KT-34021 2021-07-10 21:31:19 +03:00
Dmitry Petrov
d99d25e51e JVM use SPBs in fix stack analyzer 2021-07-10 19:25:25 +03:00
Dmitry Petrov
38f45d2969 JVM update licence for InstructionLivenessAnalyzer.kt 2021-07-10 19:25:24 +03:00
Dmitry Petrov
68560c60f3 JVM use FastMethodAnalyzer when possible 2021-07-10 19:25:22 +03:00
Dmitry Petrov
c54e680021 JVM FastMethodAnalyzer: prune some exception edges 2021-07-10 19:25:21 +03:00
Dmitry Petrov
07b89c6b4b JVM FastMethodAnalyzer 2021-07-10 19:25:20 +03:00
Alexander Udalov
6f72c681ed JVM IR: fix name and parent of JvmSymbols.kClassJava
In contrast to other top-level functions/properties declared in
JvmSymbols (unsafeCoerce, signatureString, etc), kClassJava refers to a
real symbol from the library. Since not all calls to it are intrinsified
(see KClassJavaProperty.kt:30), it makes sense to allow to reference it
when constructing IR. For that, it needs to have the correct file facade
as the parent, and the JvmName annotation so that its name is mapped
correctly in the codegen.

Co-authored-by: Leonid Startsev <leonid.startsev@jetbrains.com>
2021-07-10 15:33:25 +02:00
Alexander Udalov
d33debdf7c IR: minor, cleanup Symbols 2021-07-10 15:33:25 +02:00
Yahor Berdnikau
de22a467a1 Ensure default toolchain is also set to java only modules.
^KT-46972 Fixed
2021-07-09 19:36:27 +03:00
Victor Petukhov
a8e28e4b69 Update compiler tests 2021-07-09 19:21:28 +03:00
Victor Petukhov
967304ffca Don't compute default type for a fixing type variable for self type if the corresponding feature is disabled 2021-07-09 19:21:27 +03:00
Victor Petukhov
584facc95f Fix fir-related problems and tests for inferring self types 2021-07-09 19:21:25 +03:00
Victor Petukhov
9e48ef85ea Add tests for inferring self types from Java 2021-07-09 19:21:22 +03:00
Victor Petukhov
3b16865152 Don't approximate captured types while substitute them in upper bound position 2021-07-09 19:21:17 +03:00
Victor Petukhov
c2cf2f36cd Implement inferring materialized self types through a default type in ResultTypeResolver 2021-07-09 19:21:04 +03:00
Victor Petukhov
3787099a38 Put the type inference on calls with self types under the compiler flag 2021-07-09 19:20:56 +03:00
Victor Petukhov
51c5a54e31 Support type inference for self type materialization calls 2021-07-09 19:20:54 +03:00
Mikhail Zarechenskiy
44cf4be1e5 Inference for some kind of self types 2021-07-09 19:20:52 +03:00
Andrey Zinovyev
db72fd1e93 [FIR] Fix inheritance check for substitution overrides
And delegates
2021-07-09 17:14:37 +03:00
Alexander Udalov
d43ed1cf75 Minor, add test on typeOf with intersection type 2021-07-09 14:53:57 +02:00
Alexander Udalov
a7e48c3af1 Improve toString of platform types created by typeOf
In the stdlib implementation, render "!" if the type is only
nullability-flexible. Otherwise, render "($lower..$upper)".

Note that full kotlin-reflect has a much more complicated logic (see
`DescriptorRendererImpl.renderFlexibleType`) that renders things like
`(Mutable)List` and so on. It is not a goal of the stdlib implementation
to replicate all of that, since it requires copying a large amount of
code, namely the entirety of `JavaToKotlinClassMap` to map Java class
names to Kotlin.
2021-07-09 14:53:56 +02:00
Alexander Udalov
ddfa94e7e9 Support Nothing type in typeOf
The proper support will come in KT-15518, but that would be a breaking
change even for stable Kotlin without kotlin-reflect. Before that issue
is fixed, represent Nothing in types with the Void class, and use a flag
in the no-reflect implementation to remember that it's not actually the
Void class itself.

 #KT-39166 Fixed
2021-07-09 14:40:05 +02:00
Alexander Udalov
02774fae0c Report error on non-reified type parameter with recursive bound in typeOf
Instead of throwing an exception.

 #KT-40173
2021-07-09 14:31:52 +02:00
Alexander Udalov
438ce57183 Report error on typeOf<suspend ...>()
Otherwise an invalid type is constructed which causes kotlin-reflect to
crash, and stdlib implementation to render the type incorrectly. The
reason is that suspend functional types are not properly supported in
reflection. Once they are supported, this error can be removed.

 #KT-47562
2021-07-09 14:31:52 +02:00
Alexander Udalov
68432f0c20 Fix deprecation/unchecked warnings after update to 203 2021-07-09 14:24:07 +02:00
Dmitriy Novozhilov
c6f754cf7a [Build] remove dependency on IDEA classes from :visualizer 2021-07-09 14:38:03 +03:00
Dmitriy Novozhilov
aa3a73c6c2 [FIR] Move JavaTypeEnhancementState to session component 2021-07-09 14:38:02 +03:00
Simon Ogorodnik
e102bdea20 [Build] Fix xerces usage in FIR modularized tests 2021-07-09 11:08:13 +00:00
Victor Petukhov
c3a5a7754d Use proper applicability for constraint warnings
^KT-47316 Fixed
2021-07-09 14:07:01 +03:00
Victor Petukhov
1224d28deb Move java type enhancement stuff to :core:compiler.common.jvm 2021-07-09 13:22:02 +03:00
Nikita Bobko
c112e768de Update ReadMe to point to up-to-date Kotlin IDEA plugin location 2021-07-09 10:14:41 +00:00
Pavel Kunyavskiy
31857f23a3 [K/N] Refactoring: remove copypaste 2021-07-09 08:53:08 +00:00
Pavel Kunyavskiy
594ff1474d [K/N] Make llvm Int1 boolean, not byte 2021-07-09 08:53:08 +00:00
Pavel Kunyavskiy
eec8fdf16a [K/N] Implement isExperimentalMM intrinsic 2021-07-09 08:53:07 +00:00
Ilya Muradyan
55ec6729b0 [REPL] Fix completion after final expressions 2021-07-09 04:06:53 +03:00
Vyacheslav Gerasimov
a915eddf22 Build: Upgrade Idea Ext plugin to 1.0.1 2021-07-08 23:24:09 +03:00
Dmitry Petrov
24fcadb869 JVM don't run CCE on methods without optimizable conditional jumps 2021-07-08 22:11:59 +03:00
Alexander Udalov
25f0beed12 Load async-profiler.jar if possible when using -Xprofile
Instead of requiring it to be on the compiler classpath.

This will make it much easier to profile the Kotlin compiler daemon in
Gradle, by just specifying a compiler argument instead of also manually
patching the compiler jar.
2021-07-08 20:44:45 +02:00
Ilya Muradyan
787ce6335c Change nestedClasses logic to accept classes with nested type aliases
#KT-47650 fixed
2021-07-08 21:04:53 +03:00
Simon Ogorodnik
ca86b7ff7d [Build] Make getToolchainCompilerFor private and fix LibrariesCommon 2021-07-08 17:06:31 +00:00
Simon Ogorodnik
c0e479eadb [Build] Allow to override JDK 10 with JDK 11 2021-07-08 17:06:31 +00:00
Simon Ogorodnik
18eccdbc1f [Build] Allow to override JDK 9 with JDK 11 2021-07-08 17:06:30 +00:00
Simon Ogorodnik
a31bdc6454 [Build] Respect overrides in getToolchainLauncherFor 2021-07-08 17:06:29 +00:00
Simon Ogorodnik
bf25ccfc0e [Build] Allow kotlin.build.isObsoleteJdkOverrideEnabled=true on CI 2021-07-08 17:06:28 +00:00
Ilya Kirillov
eab1a78d48 FIR IDE: mute failing multimodule tests 2021-07-08 18:25:44 +03:00
Roman Golyshev
dcc30cb672 FIR IDE: Mute test with java file in the dependency
The corresponding JavaSymbolProvider currently is unable to
see the `Foo` class, because under the hood it uses
`JvmDependenciesIndexImpl` which doesn't know about the corresponding
.java file because it is created for m2-module `project`

I wasn't able to fix it yet
2021-07-08 18:25:42 +03:00
Roman Golyshev
0d443d526d FIR IDE: Use more correct implementation of TestModuleSourceInfo::dependencies
When only `regularDependencies` were used, multiplatform tests were
failing because `actual` modules did not see the `expected` ones
2021-07-08 18:25:41 +03:00
Ilya Kirillov
a9bb577154 FIR IDE: add ability to run multimodule tests 2021-07-08 18:25:39 +03:00
Andrey Zinovyev
1cb34541bd [FIR] Fixes after delegation scope rework 2021-07-08 18:13:52 +03:00
Andrey Zinovyev
02297d2c75 [FIR] Rollback exposure of j.u.List.sort method 2021-07-08 18:13:51 +03:00
Andrey Zinovyev
221e642d97 [FIR] Fix inheritance diagnostics for new FirDeclaration hierarchy
Plus several small fixes in reporting itself
2021-07-08 18:13:49 +03:00
Andrey Zinovyev
b36f8ed8f5 [FIR] DATA_CLASS_OVERRIDE_CONFLICT diagnostic 2021-07-08 18:13:48 +03:00
Andrey Zinovyev
b44785c24e [FIR] NOTHING_TO_OVERRIDE diagnostic 2021-07-08 18:13:47 +03:00
Andrey Zinovyev
9452b788bf [FIR] Implement CANNOT_OVERRIDE_INVISIBLE_MEMBER diagnostic 2021-07-08 18:13:46 +03:00
Andrey Zinovyev
f4c8108ee0 [FIR] Substitute type parameters in inheritance checker 2021-07-08 18:13:45 +03:00
Andrey Zinovyev
3f7d050f8f [FIR] Implement CONFLICTING_INHERITED_MEMBERS diagnostic 2021-07-08 18:13:44 +03:00
Andrey Zinovyev
78519f851e [FIR] Implement VAR_OVERRIDDEN_BY_VAL_BY_DELEGATION diagnostic 2021-07-08 18:13:43 +03:00
Andrey Zinovyev
c98cd3b190 [FIR] Implement properties types mismatch on inheritence
PROPERTY_TYPE_MISMATCH_ON_INHERITANCE,
VAR_TYPE_MISMATCH_ON_INHERITANCE,
PROPERTY_TYPE_MISMATCH_BY_DELEGATION
2021-07-08 18:13:41 +03:00
Andrey Zinovyev
8c7ee0b714 [FIR] Implement RETURN_TYPE_MISMATCH_BY_DELEGATION diagnostic 2021-07-08 18:13:40 +03:00
Andrey Zinovyev
94da1e37aa [FIR] Implement RETURN_TYPE_MISMATCH_ON_INHERITANCE diagnostic 2021-07-08 18:13:38 +03:00
Konstantin Tskhovrebov
8012eb3214 Add support Apple M1 for KMP embedAndSign task.
#KT-47077
2021-07-08 16:43:59 +03:00
Hung Nguyen
a0e003ac5d Add tests for kotlin.incremental.useClasspathSnapshot feature
This ensures we don't regress when developing the feature.

Bug: KT-45777
Test: New IncrementalCompilationClasspathSnapshotJvmMultiProjectIT
      and IncrementalJavaChangeClasspathSnapshotIT
2021-07-08 15:05:38 +03:00
Dmitriy Novozhilov
d44a2f6fd3 Fix dependency on javac2.jar
In 203.8084.24 this jar was moved from intellij dependencies to
  libraries of intellij java plugin
2021-07-08 13:29:22 +03:00
Dmitriy Novozhilov
30578cfb95 Delete DynamicBundle copy
We can safely use it from IDEA after IDEA-248785 was fixed
2021-07-08 13:29:21 +03:00
Dmitriy Novozhilov
d6a6ec42a2 Use 203.8084.24 as IDEA dependency instead of 203.6682.168 2021-07-08 13:29:21 +03:00
Dmitriy Novozhilov
d473d22d8c [Test] Migrate SpecTestsConsistencyTest to JUnit5 2021-07-08 13:29:21 +03:00
Dmitriy Novozhilov
c0c9e4a114 Update testadata of PSI dump of java records 2021-07-08 13:29:21 +03:00
Dmitriy Novozhilov
955c506294 Update load java testdata with type use annotations 2021-07-08 13:29:21 +03:00
Dmitriy Novozhilov
4d4d3a998b [FIR] Update load java testdata according to new sealed modifier 2021-07-08 13:29:20 +03:00
Dmitriy Novozhilov
5552f5f5b2 [FIR] Update light classes testdata
In 203 platform java.lang.Object in position of type parameter
  bound is not rendered
2021-07-08 13:29:20 +03:00
Dmitriy Novozhilov
a710cdf822 [FIR] Properly unregister java element finder in CLI compiler 2021-07-08 13:29:20 +03:00
Dmitriy Novozhilov
817c4381f5 Fix asm version in kotlinp 2021-07-08 13:29:20 +03:00
Dmitriy Novozhilov
11faf04a4c [Test] Remove dependencies on IDEA classes from test modules
Some of IDEA services (like in `com.intellij/execution`) was copied,
  because they are used in tests but jars with them compiled with
  jdk 11 and we run our tests on jdk 8, so their bytecode can not
  be read
2021-07-08 13:29:19 +03:00
Dmitriy Novozhilov
11dfbd41ac [Test] Delete obsolete descriptor renderer tests 2021-07-08 13:29:19 +03:00
Dmitriy Novozhilov
eb94575c69 Remove redundant usages of IDEA services in CLI 2021-07-08 13:29:19 +03:00
Dmitriy Novozhilov
82e3e00bf5 Fix compilation after migrating to ASM 9 2021-07-08 13:29:19 +03:00
Yan Zhulanow
9e2fb6e25a Add verification metadata for IntelliJ 2020.3 2021-07-08 13:29:18 +03:00
Dmitriy Novozhilov
80971d7b8b ~~~~ switch 203 ~~~~ 2021-07-08 13:29:18 +03:00
Yan Zhulanow
ca8e35e7db Return 203 bunch back 2021-07-08 13:29:18 +03:00
Yan Zhulanow
cf65754ea4 Update 203 bunch 2021-07-08 13:29:18 +03:00
Dmitriy Novozhilov
ccc3e3510c [Test] Remove useless dependencies on IDEA from FIR test modules 2021-07-08 13:29:18 +03:00
Dmitriy Novozhilov
b6bc57fa09 [Test] Remove useless dependencies on IDEA from :compiler:tests-common-new 2021-07-08 13:29:17 +03:00
Dmitriy Novozhilov
88b7694762 [Test] Remove useless dependencies on IDEA from :compiler:tests-common 2021-07-08 13:29:17 +03:00
Nikita Bobko
2a26c29390 Disable kotlin-scripting-ide-common publishing
We don't need this artifact in IDE anymore since we are not
going to move ide-common classes to kotlin repo. See previous commit
2021-07-08 10:01:35 +00:00
Nikita Bobko
3ca0e11dab Add README to scripting-ide-common
Originally, we though that we would move classes from `ide-common` from Kotlin plugin to this
module but it turns that these classes are heavily used in Kotlin plugin and it's better to
keep them with the rest of Kotlin plugin. So now classes in `scripting-ide-common` are copy-pasted
2021-07-08 10:01:34 +00:00
Anton Yalyshev
e32a975814 Add change notes for 1.5.30-M1 2021-07-08 10:25:25 +03:00
Dmitry Petrov
1a0a3df9d2 JVM_IR simplify BridgeLowering
Generate bridges immediately for each class.

No need to compute existing signatures for a given method name unless it
requires a special bridge.
2021-07-07 21:24:55 +03:00
Xin Wang
8317daa00b Don't generate nullability assertions in methods for directly invoked lambdas 2021-07-07 20:32:47 +03:00
Nikita Bobko
fbe062ee64 [refactoring] Move files in scripting-ide-common into unique subpackage
I am afraid of FQN clashes with classes in `ide-common` in kotlin-ide
2021-07-07 16:51:45 +02:00
Nikita Bobko
339231b05e Move KtFunctionLiteral.findLabelAndCall from kotlin-ide.frontend-independent to compiler.psi
I want to be able to use this function in `:kotlin-scripting-ide-common` & `frontend-independent`

This commit also allows to remove copy-pasted `findLabelAndCall` in `scripting-ide-services` module
2021-07-07 16:51:44 +02:00
Dmitry Gridin
a8a6f51a0e [common] fix flexible type approximation in renders
^KTIJ-3030 Fixed

(cherry picked from commit 4855d88a9f6fbce9aeeea6fe1f29dd099a833aed)

KT-CR-2373
2021-07-07 16:51:44 +02:00
Matthew Gharrity
958b0ff24a Ignore diagnostics in ShadowedDeclarationsFilter
During code completion, ShadowedDeclarationsFilter resolves many
synthetic calls (sometimes >1000 for certain projects/scenarios).
By ignoring diagnostics we can avoid running call checkers
during this process (pending a sibling change in the compiler).

Relates to KT-44276 and github.com/JetBrains/kotlin/pull/4027
2021-07-07 16:51:44 +02:00
Matthew Gharrity
e2109c3f8f ShadowedDeclarationsFilter: check for equivalence
If there are multiple copies of the same library on the classpath,
then ShadowedDeclarationsFilter becomes very slow because it
encounters many equal-signature declarations and thus has to resolve
a lot of calls in order to pick among them.

Having multiple copies of the same library on the classpath is
somewhat common in real-world projects. It occurs in the
JetBrains/intellij-kotlin project, for example. In that project,
ShadowedDeclarationsFilter ends up resolving thousands of calls,
accounting for around 80% of completion time when there are
many completion results (see KT-44276).

We can optimize ShadowedDeclarationsFilter by checking whether the
descriptors in an equal-signature group are structurally equivalent.
If they are, we can just pick one rather than running resolve.

Testing on a small project with Kotlin stdlib duplicated on the
classpath, this change reduces overhead in ShadowedDeclarationsFilter
from 1200 ms to 20 ms when running completion on the prefix 'a'.
End-to-end completion time is cut in half.

Test: JvmBasicCompletionTestGenerated.Common.Shadowing
2021-07-07 16:51:43 +02:00
Andrei Klunnyi
decfcd28d2 KT-39398 Wrong import of unrelated object member is suggested for receiver
Receiver of a function call '<receiver>.foo()' (where receiver is a
class/object/alias name) might be specified incorrectly - corresponding
[companion] object might not be declared.

Before this commit '<receiver>' was considered to be undefined (null).
As a consequence, import suggestion included all 'foo()' functions from
the search scope.

Now as a value of '<receiver>' we set class/object/alias itself
resulting in an empty import suggestion list.
See org/jetbrains/kotlin/idea/util/CallType.kt:307
(#extractReceiverTypeFrom(descriptor: ClassDescriptor)).
2021-07-07 16:51:43 +02:00
Nikita Bobko
365821ae54 2/2 Extract code which is required for :kotlin-scripting-ide-services from ide-common into seprate module
Extract the code and keep it in Kotlin repo. See previous preparation commit as well
2021-07-07 16:51:43 +02:00
Nikita Bobko
cf3f35e1c8 1/2 Preparation commit: move ide-common files which are required for scripting to separate directory
This commit is needed to preserve git history
2021-07-07 16:51:43 +02:00
pyos
50797dba8d JVM: do not use crossinline flag when inlining assertions
Crossinline lambdas *can* be inlined into objects, but don't *have* to;
the correct place should be determined from the context, not from the
parameter.
2021-07-07 16:48:01 +02:00
pyos
e64cda61d5 JVM_IR: do not generate $assertionsDisabled twice during inlining 2021-07-07 16:48:01 +02:00
Ilya Matveev
123c76053f [Gradle][tests] Fix running CocoaPods on Apple M1 2021-07-07 17:13:34 +03:00
Ilya Matveev
5fad5e017e [Gradle][tests] Disable workaround for XCode 12.3 2021-07-07 17:13:31 +03:00
Ilya Matveev
53a4187427 [Gradle][tests] Install CocoaPods to a temp dir instead of HOME 2021-07-07 17:13:29 +03:00
Ilya Matveev
aa9ff3d6bb [Gradle][tests] Install cocoapods in MPP plugin tests 2021-07-07 17:13:26 +03:00
Svyatoslav Scherbina
2d0dbf9729 Native: improve ObjCExport thread state switching 2021-07-07 13:53:27 +00:00
Ilya Goncharov
1a27f91a98 [Gradle, JS] Remove redundant suppression 2021-07-07 16:40:22 +03:00
Ilya Goncharov
f7e69fb2ef [Gradle, JS] Update verification data with Yarn 2021-07-07 16:40:20 +03:00
Ilya Goncharov
da1bdf87cb [Gradle, JS] Use injected services of fs 2021-07-07 16:40:19 +03:00
Ilya Goncharov
e2adf9793c [Gradle, JS] Node into PATH during installing of dependencies
^KT-37895 fixed
2021-07-07 16:40:17 +03:00
Ilya Goncharov
065a5d98fb [Gradle, JS] Configuration cache friendly 2021-07-07 16:40:16 +03:00
Ilya Goncharov
81ac48390c [Gradle, JS] Make yarn working without downloading
^KT-32071 fixed
2021-07-07 16:40:15 +03:00
Ilya Goncharov
eb73527b9f [Gradle, JS] No additional checks of setup tasks 2021-07-07 16:40:13 +03:00
Ilya Goncharov
54d47de008 [Gradle, JS] Yarn as a dependency with ivy repository like Node.js
^KT-34985 fixed
2021-07-07 16:40:11 +03:00
Anton Yalyshev
1507f1a9c0 Add change notes for 1.5.21 2021-07-07 16:30:34 +03:00
Andrey Zinovyev
de3f31cf78 [FIR] Partial implementation of DEPRECATION(_ERROR) diagnostics
No support for inheritance deprecations
and deprecations in qualifier's parts
2021-07-07 16:19:28 +03:00
Andrey Zinovyev
9fad55d551 [FIR] Use @DeprecatedSinceKotlin in the resolution 2021-07-07 16:19:27 +03:00
Igor Yakovlev
b64f7909b8 [FIR IDE] Implement own fir light classes support 2021-07-07 14:08:41 +02:00
Yahor Berdnikau
7fff282565 Fix AllOpen plugin exposes common with Gradle runtime dependencies.
^KT-47354 Fixed
2021-07-07 11:31:18 +00:00
Mikhail Glukhikh
fa086d22c2 Don't build kotlin-gradle-statistics in FIR mode at all 2021-07-07 14:28:03 +03:00
Mikhail Glukhikh
863a2c6498 Disable kotlin-gradle-statistics and wasm.ir under FIR 2021-07-07 14:28:02 +03:00
Mikhail Glukhikh
c7877cb440 FIR: fix contract deserialization for assertIs<T> 2021-07-07 14:28:00 +03:00
Ilya Goncharov
e0c1f50f03 [Gradle, JS] Fix node.js repository declaration
^KT-47557 fixed
2021-07-07 08:26:07 +00:00
Sergey Bogolepov
f05110f99b [K/N] Add some tests for https://youtrack.jetbrains.com/issue/KT-47605 2021-07-07 07:50:57 +00:00
Sergey Bogolepov
9ed97a27f1 [K/N] Introduce LLD compatibility checker for MinGW
We are going to switch to LLD linker for MinGW targets.
Right now LLD for MinGW doesn't support all features
of ld.bfd and thus this change might be breaking for some users.
To make transition smoother, we run lld -### to show a warning to user
so they can update their compilation options before LLD will be turned
on by default.

More details: https://youtrack.jetbrains.com/issue/KT-47605
2021-07-07 07:50:57 +00:00
Ilya Kirillov
30d0fea003 FIR IDE: enable explicit API mode in idea-frontend-fir module 2021-07-07 01:40:03 +03:00
Ilya Kirillov
51576c70b6 FIR: introduce package directive
The package directive is needed for KtElement -> FirElement mapping in IDE.
There should be some FirElement which will be result of mapping of elements
inside KtPackageDirective.
2021-07-06 22:49:50 +03:00
Mikhail Glukhikh
bf40c07cc3 FIR: drop questionable DiagnosticKind.NotRootCause 2021-07-06 18:43:16 +03:00
Mikhail Glukhikh
7d583973ab Disable -Werror in FIR mode inside disableDeprecatedJvmTargetWarning 2021-07-06 18:27:53 +03:00
Tianyu Geng
768ddea18f FIR checker: ILLEGAL_DECLARATION_IN_WHEN_SUBJECT 2021-07-06 18:27:47 +03:00
Tianyu Geng
31573a98e8 FIR checker: report EXPECTED_CONDITION 2021-07-06 18:27:23 +03:00
Sergey Bogolepov
e396da0562 [K/N] Update list of targets with stable caches
Enable compiler caches for iosSimulatorArm64 and macosArm64 targets
to make Apple Silicon distribution feature complete with
Intel-based one.
2021-07-06 18:15:30 +03:00
Victor Petukhov
65fd8fc174 Add generated files with descriptors for foreign annotation tests 2021-07-06 18:10:22 +03:00
Ilya Goncharov
c797d38312 [Gradle, JS]Add base dirs and prefix for correct source maps calculating 2021-07-06 12:59:03 +00:00
Alexander Udalov
e7b37d99cb Fix new compiler warnings in daemon and build-common 2021-07-06 13:31:21 +02:00
Sergey Shanshin
0d211a53cb Support serializable classes clash with JVM primitive types by name
Fixes Kotlin/kotlinx.serialization#1353
2021-07-06 12:52:53 +03:00
Ilya Goncharov
7181631051 [Gradle, JS] Add statistics for Kotlin/JS
- source map usages (legacy, ir)
- incremental klib
- incremental JS IR
- property lazy initialization

^KT-47435 fixed
2021-07-06 07:38:56 +00:00
53982 changed files with 103678 additions and 1199681 deletions

4
.bunch
View File

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

View File

@@ -2,6 +2,7 @@
<dictionary name="skuzmich">
<words>
<w>anyref</w>
<w>dataref</w>
<w>ushr</w>
<w>wasm</w>
</words>

2
.idea/kotlinc.xml generated
View File

@@ -13,6 +13,6 @@
</option>
</component>
<component name="KotlinCompilerSettings">
<option name="additionalArguments" value="-version -Xallow-kotlin-package -Xskip-metadata-version-check -Xread-deserialized-contracts" />
<option name="additionalArguments" value="-version -Xallow-kotlin-package -Xskip-metadata-version-check" />
</component>
</project>

View File

@@ -1,20 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA" type="GradleRunConfiguration" factoryName="Gradle" singleton="true" folderName="IDEA">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runIde" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method />
</configuration>
</component>

View File

@@ -1,20 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA Ultimate" type="GradleRunConfiguration" factoryName="Gradle" folderName="IDEA">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-P intellijUltimateEnabled" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runUltimate" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method />
</configuration>
</component>

View File

@@ -1,20 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA Ultimate (No ProcessCanceledException) " type="GradleRunConfiguration" factoryName="Gradle" folderName="IDEA">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-PnoPCE" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runUltimate" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method />
</configuration>
</component>

View File

@@ -1,20 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA (No ProcessCanceledException)" type="GradleRunConfiguration" factoryName="Gradle" folderName="IDEA">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-PnoPCE" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runIde" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
<method />
</configuration>
</component>

View File

@@ -1,19 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA (Not Internal)" type="GradleRunConfiguration" factoryName="Gradle" folderName="IDEA">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="scriptParameters" value="-Pidea.is.internal=false" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value="runIde" />
</list>
</option>
<option name="vmOptions" value="" />
</ExternalSystemSettings>
</configuration>
</component>

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

@@ -0,0 +1,23 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test: Commonizer / Light" type="GradleRunConfiguration" factoryName="Gradle" folderName="Tests">
<ExternalSystemSettings>
<option name="executionName" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="externalSystemIdString" value="GRADLE" />
<option name="taskDescriptions">
<list />
</option>
<option name="taskNames">
<list>
<option value=":native:kotlin-klib-commonizer-api:test" />
<option value=":native:kotlin-klib-commonizer:test" />
</list>
</option>
<option name="vmOptions" />
</ExternalSystemSettings>
<ExternalSystemDebugServerProcess>false</ExternalSystemDebugServerProcess>
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
<DebugAllEnabled>false</DebugAllEnabled>
<method v="2" />
</configuration>
</component>

View File

@@ -1,5 +1,307 @@
# CHANGELOG
## 1.5.21
### Compiler
- [`KT-47320`](https://youtrack.jetbrains.com/issue/KT-47320) "StringConcatException: Mismatched number of concat arguments" String concatenation fails when template contains special character
- [`KT-47445`](https://youtrack.jetbrains.com/issue/KT-47445) "definitely not null type parameters is only available since language version 1.6" error in cast expression
- [`KT-47446`](https://youtrack.jetbrains.com/issue/KT-47446) Improve warning message INTEGER_OPERATOR_RESOLVE_WILL_CHANGE
- [`KT-47447`](https://youtrack.jetbrains.com/issue/KT-47447) False positive INTEGER_OPERATOR_RESOLVE_WILL_CHANGE warning: "expression will be resolved to Int in future releases"
- [`KT-47449`](https://youtrack.jetbrains.com/issue/KT-47449) JVM / IR: ClassCastException IrStarProjectionImpl cannot be cast to IrTypeProjection
- [`KT-47459`](https://youtrack.jetbrains.com/issue/KT-47459) "IndexOutOfBoundsException: Index 0 out of bounds for length 0" caused by MarkertManager dependency
- [`KT-47480`](https://youtrack.jetbrains.com/issue/KT-47480) StackOverflowError: Recursion on erasion of raw type with interdependent type parameters
### Tools. Compiler Plugins
- [`KT-47161`](https://youtrack.jetbrains.com/issue/KT-47161) Serializable class can't be inherited from serializable class in other module with: e: org.jetbrains.kotlin.codegen.CompilationException: Back-end (JVM) Internal error: Couldn't transform method node: write$Self
- [`KT-47455`](https://youtrack.jetbrains.com/issue/KT-47455) Kotlin lombok plugin NullPointerException
- [`KT-47513`](https://youtrack.jetbrains.com/issue/KT-47513) Lombok compiler plugin failed with 'Recursion detected in a lazy value under LockBasedStorageManager@1c21db60 (TopDownAnalyzer for JVM)'
### Tools. Gradle
- [`KT-47444`](https://youtrack.jetbrains.com/issue/KT-47444) Gradle Plugin: Publishing project with "maven-publish" fails when dependency versions are omitted (NPE in MppDependencyRewritingUtilsKt.associateDependenciesWithActualModuleDependencies)
### Tools. kapt
- [`KT-47416`](https://youtrack.jetbrains.com/issue/KT-47416) Kapt Gradle DSL ignores javaCompilerOptions in 1.5.20
## 1.5.20
### Compiler
#### New Features
- [`KT-43262`](https://youtrack.jetbrains.com/issue/KT-43262) No error for Java generic class @NotNull type parameter used in Kotlin with nullable type argument
- [`KT-44373`](https://youtrack.jetbrains.com/issue/KT-44373) FIR: support error / warning suppression
- [`KT-45189`](https://youtrack.jetbrains.com/issue/KT-45189) Support nullability annotations at module level
- [`KT-45284`](https://youtrack.jetbrains.com/issue/KT-45284) Emit warnings based on jspecify annotations
- [`KT-45525`](https://youtrack.jetbrains.com/issue/KT-45525) Allow to omit JvmInline annotation for expect value classes
- [`KT-46545`](https://youtrack.jetbrains.com/issue/KT-46545) Emit annotations on function type parameters into bytecode for -jvm-target 1.8 and above
#### Performance Improvements
- [`KT-36646`](https://youtrack.jetbrains.com/issue/KT-36646) Don't box primitive values in equality comparison with objects in JVM_IR
#### Fixes
- [`KT-8325`](https://youtrack.jetbrains.com/issue/KT-8325) Unresolved annotation should be an error
- [`KT-19455`](https://youtrack.jetbrains.com/issue/KT-19455) Type annotation unresolved on a type parameter of a supertype in anonymous object expression
- [`KT-24643`](https://youtrack.jetbrains.com/issue/KT-24643) Prohibit using a type parameter declared for an extension property inside delegate
- [`KT-25876`](https://youtrack.jetbrains.com/issue/KT-25876) Annotations on return types and supertypes are not analyzed
- [`KT-28449`](https://youtrack.jetbrains.com/issue/KT-28449) Annotation target is not analyzed in several cases for type annotations
- [`KT-36770`](https://youtrack.jetbrains.com/issue/KT-36770) Prohibit unsafe calls with expected @NotNull T and given Kotlin generic parameter with nullable bound
- [`KT-36880`](https://youtrack.jetbrains.com/issue/KT-36880) K/N IR: Reference to expect property in actual declaration is not remapped
- [`KT-38325`](https://youtrack.jetbrains.com/issue/KT-38325) IllegalStateException: No parameter with index 0-0 when iterating Scala 2.12.11 List
- [`KT-38342`](https://youtrack.jetbrains.com/issue/KT-38342) FIR: Consider renaming diagnostic from AMBIGUITY to OVERLOAD_RESOLUTION_AMBIGUITY
- [`KT-38476`](https://youtrack.jetbrains.com/issue/KT-38476) [FIR] Forgotten type approximation
- [`KT-38540`](https://youtrack.jetbrains.com/issue/KT-38540) Kotlin/Native Set<T>.contains fails with specific enum setup
- [`KT-40425`](https://youtrack.jetbrains.com/issue/KT-40425) IrGenerationExtension. Support simple reporting to compiler output (for development/debug)
- [`KT-41620`](https://youtrack.jetbrains.com/issue/KT-41620) ClassCastException: Class cannot be cast to java.lang.Void
- [`KT-41679`](https://youtrack.jetbrains.com/issue/KT-41679) NI: TYPE_MISMATCH wrong type inference of collection with type Any and integer literal
- [`KT-41818`](https://youtrack.jetbrains.com/issue/KT-41818) NI: False positive IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION leads to NothingValueException on delegated properties
- [`KT-42239`](https://youtrack.jetbrains.com/issue/KT-42239) IR: Report compilation error instead of throwing an exception (effectively crash compiler) when some declaration wasn't found while deserialization
- [`KT-42631`](https://youtrack.jetbrains.com/issue/KT-42631) ArrayIndexOutOfBoundsException was thrown during IR lowering
- [`KT-43258`](https://youtrack.jetbrains.com/issue/KT-43258) NI: False positive "Suspend function 'invoke' should be called only from a coroutine or another suspend function" when calling suspend operator fun on object property from last expression of a crossinlined suspend lambda
- [`KT-44036`](https://youtrack.jetbrains.com/issue/KT-44036) Enum initialization order
- [`KT-44511`](https://youtrack.jetbrains.com/issue/KT-44511) FIR DFA: smartcast after `if (nullable ?: boolean)`
- [`KT-44554`](https://youtrack.jetbrains.com/issue/KT-44554) RAW FIR: NPE in RawFirBuilder
- [`KT-44682`](https://youtrack.jetbrains.com/issue/KT-44682) raw FIR: incorrect source for qualified access
- [`KT-44695`](https://youtrack.jetbrains.com/issue/KT-44695) *_TYPE_MISMATCH_ON_OVERRIDE checkers do not work for anonymous objects
- [`KT-44699`](https://youtrack.jetbrains.com/issue/KT-44699) FIR: incorrect lambda return type (led to a false alarm: PROPERTY_TYPE_MISMATCH_ON_OVERRIDE)
- [`KT-44802`](https://youtrack.jetbrains.com/issue/KT-44802) FIR bootstrap: trying to access package private class
- [`KT-44813`](https://youtrack.jetbrains.com/issue/KT-44813) FIR bootstrap: various errors in collection-like classes
- [`KT-44814`](https://youtrack.jetbrains.com/issue/KT-44814) FIR bootstrap: incorrect cast in when branch
- [`KT-44942`](https://youtrack.jetbrains.com/issue/KT-44942) [FIR] ClassCastException in boostrap tests
- [`KT-44995`](https://youtrack.jetbrains.com/issue/KT-44995) FIR: false positive for ANNOTATION_ARGUMENT_MUST_BE_CONST
- [`KT-45010`](https://youtrack.jetbrains.com/issue/KT-45010) FIR: lambda arguments of inapplicable call is not resolved
- [`KT-45048`](https://youtrack.jetbrains.com/issue/KT-45048) FIR bootstrap: VerifyError on KtUltraLightClass
- [`KT-45052`](https://youtrack.jetbrains.com/issue/KT-45052) FIR bootstrap: inapplicable candidate in GenerateSpecTests.kt
- [`KT-45121`](https://youtrack.jetbrains.com/issue/KT-45121) FIR IDE: redundant vararg parameter type transformation
- [`KT-45136`](https://youtrack.jetbrains.com/issue/KT-45136) Native: dividing Int.MIN_VALUE by -1 crashes or hangs
- [`KT-45236`](https://youtrack.jetbrains.com/issue/KT-45236) JVM / IR: "IllegalStateException: Symbol with IrTypeParameterSymbolImpl is unbound" caused by contracts and sealed class
- [`KT-45308`](https://youtrack.jetbrains.com/issue/KT-45308) Psi2ir: "AssertionError: TypeAliasDescriptor expected" caused by using typealias from one module as a type in another module without a transitive dependency
- [`KT-45316`](https://youtrack.jetbrains.com/issue/KT-45316) [FIR] Ambiguity between two implicit invokes with receiver
- [`KT-45344`](https://youtrack.jetbrains.com/issue/KT-45344) FIR: Wrong inferred type for nullable type parameter
- [`KT-45385`](https://youtrack.jetbrains.com/issue/KT-45385) FIR: false positive MUST_BE_INITIALIZED_OR_BE_ABSTRACT after rethrow
- [`KT-45475`](https://youtrack.jetbrains.com/issue/KT-45475) [FIR] No smartcast after throw in if inside try block
- [`KT-45508`](https://youtrack.jetbrains.com/issue/KT-45508) False negative ABSTRACT_CLASS_MEMBER_NOT_IMPLEMENTED on a fake override with an abstract super class member
- [`KT-45578`](https://youtrack.jetbrains.com/issue/KT-45578) REPL: Unresolved imports are cached for the subsequent compilations
- [`KT-45685`](https://youtrack.jetbrains.com/issue/KT-45685) JVM IR: capturing a variable into crossinline suspend lambda makes the function inside inline function no longer unbox Result
- [`KT-45584`](https://youtrack.jetbrains.com/issue/KT-45584) [FIR] Fix overriding property and java function in java class
- [`KT-45697`](https://youtrack.jetbrains.com/issue/KT-45697) JVM IR: ISE "Function has no body" on getter of private field in a class present both in sources and dependencies
- [`KT-45842`](https://youtrack.jetbrains.com/issue/KT-45842) Compiler doesn't allow a shared class to inherit a platform-specific sealed class
- [`KT-45848`](https://youtrack.jetbrains.com/issue/KT-45848) False negative [SEALED_INHERITOR_IN_DIFFERENT_MODULE] error in compiler for a platform-specific inheritor of a shared sealed class
- [`KT-45931`](https://youtrack.jetbrains.com/issue/KT-45931) There is no warning based on nullability java annotation
- [`KT-45998`](https://youtrack.jetbrains.com/issue/KT-45998) JVM IR: AE when an accessor to a protected companion object member is being generated in child class
- [`KT-46048`](https://youtrack.jetbrains.com/issue/KT-46048) Enum entries init order in companion object
- [`KT-46074`](https://youtrack.jetbrains.com/issue/KT-46074) FIR: private-in-file fun interface is considered invisible in this file
- [`KT-46173`](https://youtrack.jetbrains.com/issue/KT-46173) No error reporting on annotations on target type of `as` expression in return
- [`KT-46235`](https://youtrack.jetbrains.com/issue/KT-46235) JVM IR: Stack overflow error on large expressions
- [`KT-46270`](https://youtrack.jetbrains.com/issue/KT-46270) [FIR] Support `@PublishedAPI` in inline checker
- [`KT-46539`](https://youtrack.jetbrains.com/issue/KT-46539) Generate annotations on type parameters bounds in bytecode
- [`KT-46578`](https://youtrack.jetbrains.com/issue/KT-46578) JVM IR: IllegalAccessError accessing property delegated to java super class protected field reference
- [`KT-46597`](https://youtrack.jetbrains.com/issue/KT-46597) JVM IR: AssertionError: SyntheticAccessorLowering should not attempt to modify other files - crossinline accessor
- [`KT-46601`](https://youtrack.jetbrains.com/issue/KT-46601) JVM / IR: IllegalStateException: "Can't find method 'invokeinvoke`" when default lambda takes inline class parameters
- [`KT-46670`](https://youtrack.jetbrains.com/issue/KT-46670) StackOverflowError on inheritance from raw type where class has protobuf-like recursive generics
- [`KT-46715`](https://youtrack.jetbrains.com/issue/KT-46715) JVM / IR: "AssertionError: Unbound symbols not allowed IrConstructorSymbolImpl" with enum classes with the same name in test and src folders
- [`KT-46759`](https://youtrack.jetbrains.com/issue/KT-46759) JVM IR: CCE in LateinitUsageLowering on @JvmStatic lateinit property in object
- [`KT-46777`](https://youtrack.jetbrains.com/issue/KT-46777) [Native] [IR] Support suspend function as super type
- [`KT-46802`](https://youtrack.jetbrains.com/issue/KT-46802) JVM / IR: "UnsupportedOperationException: Unknown structure of ADAPTER_FOR_CALLABLE_REFERENCE" caused by function reference on @JvmStatic function with unused default parameters
- [`KT-46813`](https://youtrack.jetbrains.com/issue/KT-46813) JVM / IR: "ClassCastException: Integer cannot be cast to class Result" with Flow and `fold` method
- [`KT-46822`](https://youtrack.jetbrains.com/issue/KT-46822) JVM IR: StackOverflowError on compiling a large data class
- [`KT-46837`](https://youtrack.jetbrains.com/issue/KT-46837) Backend Internal error: Exception during IR lowering: assert at IrOverridingUtilKt.buildFakeOverrideMember
- [`KT-46921`](https://youtrack.jetbrains.com/issue/KT-46921) JVM / IR: "IndexOutOfBoundsException: Cannot pop operand off an empty stack" caused by crossinline parameter and label return
- [`KT-46984`](https://youtrack.jetbrains.com/issue/KT-46984) Type parameter bounds aren't used to report corresponding mismatch warnings
- [`KT-46985`](https://youtrack.jetbrains.com/issue/KT-46985) There aren't warnings by java nullability annotations
- [`KT-46986`](https://youtrack.jetbrains.com/issue/KT-46986) There aren't warnings by java nullability annotations
- [`KT-46989`](https://youtrack.jetbrains.com/issue/KT-46989) There aren't warnings by java nullability annotations
- [`KT-46990`](https://youtrack.jetbrains.com/issue/KT-46990) There aren't warnings by java nullability annotations on method's violated type arguments
- [`KT-47019`](https://youtrack.jetbrains.com/issue/KT-47019) K/N: IrProperty.overriddenSymbols can't be used in common IR backend modules yet because it doesn't fully work in Native
### Docs & Examples
- [`KT-33783`](https://youtrack.jetbrains.com/issue/KT-33783) Document when a range created with rangeTo is empty
### IDE
- [`KT-44638`](https://youtrack.jetbrains.com/issue/KT-44638) `clone()` call is unresolved in JVM module of a multiplatform project
- [`KT-45629`](https://youtrack.jetbrains.com/issue/KT-45629) [ULC] KtUltraLightFieldForSourceDeclaration.nameIdentifier returns null
- [`KT-44825`](https://youtrack.jetbrains.com/issue/KT-44825) Can't open Kotlin compiler settings in newly created project
- [`KT-45908`](https://youtrack.jetbrains.com/issue/KT-45908) Reproduciable 'org.jetbrains.kotlin.idea.caches.resolve.KotlinIdeaResolutionException: Kotlin resolution encountered a problem while analyzing KtNameReferenceExpression'
### IDE. FIR
- [`KT-45175`](https://youtrack.jetbrains.com/issue/KT-45175) FIR IDE: Exception with local property in `init` block
- [`KT-45199`](https://youtrack.jetbrains.com/issue/KT-45199) FIR IDE: Error while collecting diagnostic on stale element after replacing element in quickfix
- [`KT-45312`](https://youtrack.jetbrains.com/issue/KT-45312) FIR IDE: FIR plugin throws exception on synthetic function
### IDE. Gradle Integration
- [`KT-34401`](https://youtrack.jetbrains.com/issue/KT-34401) KotlinGradleModelBuilder builds models for non-kotlin modules and always trigger full task configuration.
- [`KT-45277`](https://youtrack.jetbrains.com/issue/KT-45277) Wrong jvm target in gradle module in IDEA
- [`KT-46488`](https://youtrack.jetbrains.com/issue/KT-46488) Import of a multiplatform project with MPP module depending on Kotlin/JVM one fails
### IDE. Inspections and Intentions
- [`KT-45075`](https://youtrack.jetbrains.com/issue/KT-45075) Inspection: Redundant creation of Json format
- [`KT-45347`](https://youtrack.jetbrains.com/issue/KT-45347) Sealed interfaces: quickfix to move to package/module of sealed class/interface should not be shown in case of read-only declaration
- [`KT-45348`](https://youtrack.jetbrains.com/issue/KT-45348) Sealed interfaces: show error for usage of sealed class/interface from a library in Java source code
- [`KT-46063`](https://youtrack.jetbrains.com/issue/KT-46063) In multiplatform code, suggest to generate remaining `when` branches at least for shared sealed classes
### IDE. Refactorings
- [`KT-44431`](https://youtrack.jetbrains.com/issue/KT-44431) Quickfix to move class/interface to proper location: it is allowed to choose test source in JPS project while compiler does not allow it
### IDE. Native
- [`KT-39320`](https://youtrack.jetbrains.com/issue/KT-39320) [Commonizer] Reduce memory consumption
### JavaScript
- [`KT-40235`](https://youtrack.jetbrains.com/issue/KT-40235) KJS: IR. Broken support for external interface companion
- [`KT-40689`](https://youtrack.jetbrains.com/issue/KT-40689) KJS / IR: strange and slow code for kotlin.math.max and kotlin.math.min for Double
- [`KT-44138`](https://youtrack.jetbrains.com/issue/KT-44138) KJS / IR: Constant folding works incorrectly with unsigned arithmetic
- [`KT-44394`](https://youtrack.jetbrains.com/issue/KT-44394) KJS / IR: `null` companion object for existed stdlib interfaces `NodeFilter` and `SVGUnitTypes`
- [`KT-44950`](https://youtrack.jetbrains.com/issue/KT-44950) KJS / IR: "IllegalStateException: Can't find name for declaration" in case of extending export declared class without @JsExport annotation
- [`KT-45057`](https://youtrack.jetbrains.com/issue/KT-45057) KJS / IR: "ClassCastException" when using `js` function in init block
- [`KT-45361`](https://youtrack.jetbrains.com/issue/KT-45361) KJS / IR: `IrConstructorCall` representing annotation always returns `Unit`
- [`KT-46608`](https://youtrack.jetbrains.com/issue/KT-46608) KJS: "Could not load content..." for source maps
- [`KT-45655`](https://youtrack.jetbrains.com/issue/KT-45655) KJS: "REINTERPRET_CAST" is not copyable
- [`KT-45866`](https://youtrack.jetbrains.com/issue/KT-45866) Default parameter with generic in expect-actual declarations
- [`KT-46859`](https://youtrack.jetbrains.com/issue/KT-46859) Exception during IR lowering: NullPointerException was thrown at: optimizations.FoldConstantLowering.tryFoldingUnaryOps
### KMM Plugin
- [`KT-43899`](https://youtrack.jetbrains.com/issue/KT-43899) KMM: Fix "stale framework" usage by XCode & AppCode in default build script
### Libraries
- [`KT-43701`](https://youtrack.jetbrains.com/issue/KT-43701) Stdlib: Expand KDoc of inc() and dec() for operators
- [`KT-46002`](https://youtrack.jetbrains.com/issue/KT-46002) Support all Unicode digit chars in digitToInt (JS and Native)
- [`KT-46183`](https://youtrack.jetbrains.com/issue/KT-46183) Add default value for ignoreCase in K/N String.replace/replaceFirst
- [`KT-46184`](https://youtrack.jetbrains.com/issue/KT-46184) Equivalize isLowerCase and isUpperCase behavior in all platforms
### Native
- [`KT-33175`](https://youtrack.jetbrains.com/issue/KT-33175) IR: String constants with incorrect surrogate pairs aren't preserved during serialization/deserialization
- [`KT-44799`](https://youtrack.jetbrains.com/issue/KT-44799) Different behavior with functional interfaces in Kotlin/Native on iOS
### Native. C Export
- [`KT-42796`](https://youtrack.jetbrains.com/issue/KT-42796) [Reverse C Interop] Package with no public methods generate empty struct in the header, leading to an error
### Native. ObjC Export
- [`KT-38600`](https://youtrack.jetbrains.com/issue/KT-38600) Kotlin MP iOS Target doesn't contain kdoc comments
- [`KT-45127`](https://youtrack.jetbrains.com/issue/KT-45127) KMM: hard to pass an error to Kotlin code from implementation of Kotlin method in Swift code
### Native. Runtime. Memory
- [`KT-45063`](https://youtrack.jetbrains.com/issue/KT-45063) Profiling indicates that a lot of time is spent on updateHeapRef on Apple platforms when running KMP code
### Reflection
- [`KT-10838`](https://youtrack.jetbrains.com/issue/KT-10838) Provide sensible toString() for property accessors in reflection
- [`KT-13490`](https://youtrack.jetbrains.com/issue/KT-13490) Equality doesn't work for KProperty.Accessor implementations
### Tools. CLI
- [`KT-14772`](https://youtrack.jetbrains.com/issue/KT-14772) ISE (FNFE "Not a directory") on compilation with destination argument clashing with an existing file which is not a directory
- [`KT-18184`](https://youtrack.jetbrains.com/issue/KT-18184) CompileEnvironmentException: Invalid jar path on "-d" with .jar in non-existing directory
- [`KT-40977`](https://youtrack.jetbrains.com/issue/KT-40977) Report a readable diagnostic on empty -J argument in CLI
### Tools. Commonizer
- [`KT-45497`](https://youtrack.jetbrains.com/issue/KT-45497) [Commonizer] c-interop commonization: Dependency commonization
- [`KT-46077`](https://youtrack.jetbrains.com/issue/KT-46077) [Commonizer] Add `commonizer_target` to commonized klib's manifest
- [`KT-46107`](https://youtrack.jetbrains.com/issue/KT-46107) [Commonizer] CInteropCommonizerTask receives faulty dependencies in multi module projects containing multiple c-interops
- [`KT-46248`](https://youtrack.jetbrains.com/issue/KT-46248) MPP: Compile KotlinMetadata fails with Unresolved reference if only one native platform from shared source set is available
- [`KT-46856`](https://youtrack.jetbrains.com/issue/KT-46856) [Commonizer] Many targets can fail with 'filename too long'
### Tools. Compiler Plugins
- [`KT-7112`](https://youtrack.jetbrains.com/issue/KT-7112) Support calling Lombok-generated methods within same module
- [`KT-45538`](https://youtrack.jetbrains.com/issue/KT-45538) Serialization, JVM IR: "AssertionError: No such type argument slot in IrConstructorCallImpl" with inner classes
- [`KT-45541`](https://youtrack.jetbrains.com/issue/KT-45541) JVM / IR / Serialization: NullPointerException caused by "Serializable" annotation and local data class
- [`KT-46469`](https://youtrack.jetbrains.com/issue/KT-46469) Kotlin Lombok: accessors with `AccessLevel.MODULE` fail to resolve
- [`KT-46529`](https://youtrack.jetbrains.com/issue/KT-46529) Kotlin Lombok: with `@Accessors` without explicit `prefix` the prefix from lombok.config is not taken into account
- [`KT-46531`](https://youtrack.jetbrains.com/issue/KT-46531) Kotlin Lombok: `lombok.getter.noIsPrefix` is processed depending on character case
- [`KT-46920`](https://youtrack.jetbrains.com/issue/KT-46920) NullPointerException in CodeGeneratorVisitor when packing for xcode
### Tools. Gradle
- [`KT-24533`](https://youtrack.jetbrains.com/issue/KT-24533) Kapt should not run when annotation processors are not configured
- [`KT-43988`](https://youtrack.jetbrains.com/issue/KT-43988) Enable plugin validation during build
- [`KT-45301`](https://youtrack.jetbrains.com/issue/KT-45301) Gradle: Empty `build/kotlin` dir with custom build directory
- [`KT-45519`](https://youtrack.jetbrains.com/issue/KT-45519) loadAndroidPluginVersion() impacts performance negatively and noticeably in multimodule Android build
- [`KT-45744`](https://youtrack.jetbrains.com/issue/KT-45744) Create Kotlin Gradle Plugin JUnit5 basic test setup
- [`KT-45834`](https://youtrack.jetbrains.com/issue/KT-45834) Gradle Plugin read system property related to kotlinCompilerClasspath breaks use of configuration cache
- [`KT-46401`](https://youtrack.jetbrains.com/issue/KT-46401) Deprecate 'kotlin.parallel.tasks.in.project' build property
- [`KT-46820`](https://youtrack.jetbrains.com/issue/KT-46820) Gradle: kotlinc (1.5.0) race condition causes a NullPointerException
- [`KT-47317`](https://youtrack.jetbrains.com/issue/KT-47317) Restore 'kotlinPluginVersion' property in 'KotlinBasePluginWrapper'
### Tools. Gradle. JS
- [`KT-42911`](https://youtrack.jetbrains.com/issue/KT-42911) Support Gradle configuration cache for K/JS tasks
- [`KT-45294`](https://youtrack.jetbrains.com/issue/KT-45294) KJS / Gradle: Number of modules in project affects JS tasks configuration cache state size
- [`KT-45754`](https://youtrack.jetbrains.com/issue/KT-45754) KJS / IR: Remove adding option of source maps in Gradle plugin
- [`KT-46178`](https://youtrack.jetbrains.com/issue/KT-46178) KJS / Dukat: Added as a dependency always without condition
- [`KT-46976`](https://youtrack.jetbrains.com/issue/KT-46976) KJS: Broken support for dynamically created `webpack.config.d`
- [`KT-47045`](https://youtrack.jetbrains.com/issue/KT-47045) [Gradle, JS] Task requirements are added to all compilations with same name
### Tools. Gradle. Multiplatform
- [`KT-36679`](https://youtrack.jetbrains.com/issue/KT-36679) MPP Gradle plugin: Improve messaging for the commonizer
- [`KT-45832`](https://youtrack.jetbrains.com/issue/KT-45832) CInteropCommonization: Filter out illegal dependencies
- [`KT-46394`](https://youtrack.jetbrains.com/issue/KT-46394) Multiplatform: Gradle 7 support
- [`KT-46517`](https://youtrack.jetbrains.com/issue/KT-46517) Add kotlin-project-model as api dependency to kotlin-gradle-plugin-api
### Tools. Gradle. Native
- [`KT-27240`](https://youtrack.jetbrains.com/issue/KT-27240) MPP Gradle plugin: Provide a framework packing task for Kotlin/Native
- [`KT-39016`](https://youtrack.jetbrains.com/issue/KT-39016) Missing stdlib when the downloading process was aborted
- [`KT-40907`](https://youtrack.jetbrains.com/issue/KT-40907) Xcode error after switching between device and simulator: Building for iOS, but the linked and embedded framework was built for iOS Simulator.
- [`KT-44059`](https://youtrack.jetbrains.com/issue/KT-44059) iosSimTest tasks are never up-to-date
- [`KT-45801`](https://youtrack.jetbrains.com/issue/KT-45801) compileIosMainKotlinMetadata compilation property of gradle task is not initialized and fails with `Execution failed for task ':shared:generateProjectStructureMetadata'`
- [`KT-46680`](https://youtrack.jetbrains.com/issue/KT-46680) Register concrete "embedAndSign" tasks instead umbrella
- [`KT-46892`](https://youtrack.jetbrains.com/issue/KT-46892) Kotlin Multiplatform Gradle Plugin: EmbedAndSign task always contains a default framework name
### Tools. Incremental Compile
- [`KT-44741`](https://youtrack.jetbrains.com/issue/KT-44741) Incremental compilation: inspectClassesForKotlinIC doesn't determine changes with imported constant
### Tools. JPS
- [`KT-34351`](https://youtrack.jetbrains.com/issue/KT-34351) KotlinTargetsIndex creation takes too long even if project doesn't have any kotlin
- [`KT-45191`](https://youtrack.jetbrains.com/issue/KT-45191) [JPS] Marking method as "default" in Java SAM interface doesn't affect dependencies
- [`KT-46242`](https://youtrack.jetbrains.com/issue/KT-46242) Support Lombok kotlin plugin in JPS and maven
### Tools. kapt
#### Performance Improvements
- [`KT-28901`](https://youtrack.jetbrains.com/issue/KT-28901) Consider caching annotation processors classloaders
#### Fixes
- [`KT-27123`](https://youtrack.jetbrains.com/issue/KT-27123) kapt: missing space in error log makes location non-clickable
- [`KT-29929`](https://youtrack.jetbrains.com/issue/KT-29929) [Kapt] Stub generator uses constant value in method annotation instead of constant name 2.
- [`KT-31146`](https://youtrack.jetbrains.com/issue/KT-31146) kapt: executableElement.getAnnotation(JvmOverloads::class.java) returns null
- [`KT-32202`](https://youtrack.jetbrains.com/issue/KT-32202) Gradle task kaptKotlin fails: "module not found" in Java 11 modular application
- [`KT-34838`](https://youtrack.jetbrains.com/issue/KT-34838) Kapt: 'cannot find symbol' for a top-level property with anonymous delegate
- [`KT-35104`](https://youtrack.jetbrains.com/issue/KT-35104) Support @JvmStatic in KAPT stubs
- [`KT-35167`](https://youtrack.jetbrains.com/issue/KT-35167) Kapt Gradle plugin doesn't handle --module-path javac argument
- [`KT-37586`](https://youtrack.jetbrains.com/issue/KT-37586) KAPT: When delegated property use an unknown type (to-be-generated class), `correctTypeError` will mess up the `$delegate` field type
- [`KT-39060`](https://youtrack.jetbrains.com/issue/KT-39060) Kapt: correctErrorTypes don't retain return type of getter in Java stub
- [`KT-39715`](https://youtrack.jetbrains.com/issue/KT-39715) KaptGenerateStubsTask resolves annotation processor options too early (before execution time)
- [`KT-41581`](https://youtrack.jetbrains.com/issue/KT-41581) Kapt doesn't have line breaks between warnings
- [`KT-43804`](https://youtrack.jetbrains.com/issue/KT-43804) Kapt fails to preserve parameter names in open suspend functions
- [`KT-43686`](https://youtrack.jetbrains.com/issue/KT-43686) KaptWithoutKotlincTask should use `@CompileClasspath` for `kotlinStdlibClasspath` for cache relocateability.
- [`KT-45032`](https://youtrack.jetbrains.com/issue/KT-45032) Kapt: NullPointerException: insnList.first must not be null
- [`KT-46176`](https://youtrack.jetbrains.com/issue/KT-46176) Kapt: "java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 3" with delegation and property reference
## 1.5.10
### Compiler

View File

@@ -35,7 +35,7 @@ Support for multiplatform programming is one of Kotlins key benefits. It redu
## Editing Kotlin
* [Kotlin IntelliJ IDEA Plugin](https://kotlinlang.org/docs/tutorials/getting-started.html)
* [Kotlin IntelliJ IDEA Plugin](https://kotlinlang.org/docs/tutorials/getting-started.html) ([source code](https://github.com/JetBrains/intellij-community/tree/master/plugins/kotlin))
* [Kotlin Eclipse Plugin](https://kotlinlang.org/docs/tutorials/getting-started-eclipse.html)
* [Kotlin Sublime Text Package](https://github.com/vkostyukov/kotlin-sublime-package)
@@ -56,7 +56,7 @@ Alternatively, it is still possible to only provide required JDKs via environmen
from environmental variables - disable Gradle toolchain auto-detection by passing `-Porg.gradle.java.installations.auto-detect=false` option
(or put it into `$GRADLE_USER_HOME/gradle.properties`).
For local development, if you're not working on bytecode generation or the standard library, it's OK to avoid installing JDK 1.6 and JDK 1.7.
For local development, if you're not working on the standard library, it's OK to avoid installing JDK 1.6 and JDK 1.7.
Add `kotlin.build.isObsoleteJdkOverrideEnabled=true` to the `local.properties` file, so build will only use JDK 1.8+. Note, that in this
case, build will have Gradle remote build cache misses for some tasks.
@@ -97,13 +97,10 @@ command line parameters on the first run:
- `clean` - clean build results
- `dist` - assembles the compiler distribution into `dist/kotlinc/` folder
- `ideaPlugin` - assembles the Kotlin IDEA plugin distribution into `dist/artifacts/ideaPlugin/Kotlin/` folder
- `install` - build and install all public artifacts into local maven repository
- `runIde` - build IDEA plugin and run IDEA with it
- `coreLibsTest` - build and run stdlib, reflect and kotlin-test tests
- `gradlePluginTest` - build and run gradle plugin tests
- `compilerTest` - build and run all compiler tests
- `ideaPluginTest` - build and run all IDEA plugin tests
To reproduce TeamCity build use `-Pteamcity=true` flag. Local builds don't run proguard and have jar compression disabled by default.
@@ -143,14 +140,6 @@ To be able to run tests from IntelliJ easily, check `Delegate IDE build/run acti
At this time, you can use the latest released `1.3.x` version of the Kotlin plugin for working with the code. To make sure you have the latest version installed, use `Tools` -> `Kotlin` -> `Configure Kotlin Plugin Updates`.
### Compiling and running
From this root project there are Run/Debug Configurations for running `IDEA` or the `Generate Compiler Tests` for example; so if you want to try out the latest and greatest IDEA plugin
* `VCS` -> `Git` -> `Pull`
* Run the `IDEA` run configuration in the project
* A child IntelliJ IDEA with the Kotlin plugin will then startup
### Dependency verification
We have a [dependencies verification](https://docs.gradle.org/current/userguide/dependency_verification.html) feature enabled in the

View File

@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.context.withModule
import org.jetbrains.kotlin.context.withProject
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.fir.builder.PsiHandlingMode
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.createSessionForTests
import org.jetbrains.kotlin.fir.java.FirJavaElementFinder
@@ -154,7 +155,7 @@ abstract class AbstractSimpleFileBenchmark {
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(env.project))
val session = createSessionForTests(env, scope)
val firProvider = session.firProvider as FirProviderImpl
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider)
val builder = RawFirBuilder(session, firProvider.kotlinScopeProvider, PsiHandlingMode.COMPILER)
val totalTransformer = FirTotalResolveProcessor(session)
val firFile = builder.buildFirFile(file).also(firProvider::recordFile)

View File

@@ -40,7 +40,7 @@ abstract class BuildMetaInfoFactory<T : BuildMetaInfo>(private val metaInfoClass
): T
fun create(args: CommonCompilerArguments): T {
val languageVersion = args.languageVersion?.let((LanguageVersion)::fromVersionString) ?: LanguageVersion.LATEST_STABLE
val languageVersion = args.languageVersion?.let { LanguageVersion.fromVersionString(it) } ?: LanguageVersion.LATEST_STABLE
return create(
isEAP = languageVersion.isPreRelease(),
@@ -51,7 +51,7 @@ abstract class BuildMetaInfoFactory<T : BuildMetaInfo>(private val metaInfoClass
ownVersion = OWN_VERSION,
coroutinesVersion = COROUTINES_VERSION,
multiplatformVersion = MULTIPLATFORM_VERSION,
metadataVersionArray = args.metadataVersion?.let((BinaryVersion)::parseVersionArray)
metadataVersionArray = args.metadataVersion?.let { BinaryVersion.parseVersionArray(it) }
)
}

View File

@@ -118,7 +118,7 @@ class ChangesCollector {
storage[packageProtoKey?.let { FqName(it) } ?: fqName] = newData
}
}
} else {
} else if (oldData != null) {
when (oldData) {
is ClassProtoData -> {
removed.add(oldData.nameResolver.getClassId(oldData.proto.fqName).asSingleFqName())

View File

@@ -0,0 +1,76 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.name.FqName
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.io.Serializable
/**
* Changes to the classpath of the `KotlinCompile` task, used to compute the source files that need to be recompiled during an incremental
* run.
*/
sealed class ClasspathChanges : Serializable {
class Available() : ClasspathChanges() {
lateinit var lookupSymbols: List<LookupSymbol>
private set
lateinit var fqNames: List<FqName>
private set
constructor(lookupSymbols: List<LookupSymbol>, fqNames: List<FqName>) : this() {
this.lookupSymbols = lookupSymbols
this.fqNames = fqNames
}
private fun writeObject(out: ObjectOutputStream) {
out.writeInt(lookupSymbols.size)
lookupSymbols.forEach {
out.writeUTF(it.name)
out.writeUTF(it.scope)
}
out.writeInt(fqNames.size)
fqNames.forEach {
out.writeUTF(it.asString())
}
}
private fun readObject(ois: ObjectInputStream) {
val lookupSymbolsSize = ois.readInt()
val lookupSymbols = ArrayList<LookupSymbol>(lookupSymbolsSize)
repeat(lookupSymbolsSize) {
val name = ois.readUTF()
val scope = ois.readUTF()
lookupSymbols.add(LookupSymbol(name, scope))
}
this.lookupSymbols = lookupSymbols
val fqNamesSize = ois.readInt()
val fqNames = ArrayList<FqName>(fqNamesSize)
repeat(fqNamesSize) {
val fqNameString = ois.readUTF()
fqNames.add(FqName(fqNameString))
}
this.fqNames = fqNames
}
companion object {
private const val serialVersionUID = 0L
}
}
sealed class NotAvailable : ClasspathChanges() {
object UnableToCompute : NotAvailable()
object ForNonIncrementalRun : NotAvailable()
object ClasspathSnapshotIsDisabled : NotAvailable()
object ReservedForTestsOnly : NotAvailable()
object ForJSCompiler : NotAvailable()
}
}

View File

@@ -39,12 +39,11 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.org.objectweb.asm.*
import java.io.File
import java.security.MessageDigest
import java.util.*
val KOTLIN_CACHE_DIRECTORY_NAME = "kotlin"
open class IncrementalJvmCache(
private val targetDataRoot: File,
targetDataRoot: File,
targetOutputDir: File?,
pathConverter: FileToPathConverter
) : AbstractIncrementalCache<JvmClassName>(
@@ -114,32 +113,43 @@ open class IncrementalJvmCache(
}
open fun saveFileToCache(generatedClass: GeneratedJvmClass, changesCollector: ChangesCollector) {
val sourceFiles: Collection<File> = generatedClass.sourceFiles
val kotlinClass: LocalFileKotlinClass = generatedClass.outputClass
val className = kotlinClass.className
saveClassToCache(KotlinClassInfo(generatedClass.outputClass), generatedClass.sourceFiles, changesCollector)
}
/**
* Saves information about the given (kotlinc-generated) class to this cache, and stores changes between this class and its previous
* version into the given [ChangesCollector].
*
* @param kotlinClassInfo A kotlin-generated class
* @param sourceFiles The source files that the given class was generated from, or `null` if this information is not available
* @param changesCollector A [ChangesCollector]
*/
fun saveClassToCache(kotlinClassInfo: KotlinClassInfo, sourceFiles: List<File>?, changesCollector: ChangesCollector) {
val className = kotlinClassInfo.className
dirtyOutputClassesMap.notDirty(className)
sourceFiles.forEach {
sourceFiles?.forEach {
sourceToClassesMap.add(it, className)
}
internalNameToSource[className.internalName] = sourceFiles
sourceFiles?.let { internalNameToSource[className.internalName] = it }
if (kotlinClass.classId.isLocal) return
if (kotlinClassInfo.classId.isLocal) return
val header = kotlinClass.classHeader
when (header.kind) {
when (kotlinClassInfo.classKind) {
KotlinClassHeader.Kind.FILE_FACADE -> {
assert(sourceFiles.size == 1) { "Package part from several source files: $sourceFiles" }
if (sourceFiles != null) {
assert(sourceFiles.size == 1) { "Package part from several source files: $sourceFiles" }
}
packagePartMap.addPackagePart(className)
protoMap.process(kotlinClass, changesCollector)
constantsMap.process(kotlinClass, changesCollector)
inlineFunctionsMap.process(kotlinClass, changesCollector)
protoMap.process(kotlinClassInfo, changesCollector)
constantsMap.process(kotlinClassInfo, changesCollector)
inlineFunctionsMap.process(kotlinClassInfo, changesCollector)
}
KotlinClassHeader.Kind.MULTIFILE_CLASS -> {
val partNames = kotlinClass.classHeader.data?.toList()
?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}")
val partNames = kotlinClassInfo.classHeaderData?.toList()
?: throw AssertionError("Multifile class has no parts: $className")
multifileFacadeToParts[className] = partNames
// When a class is replaced with a facade with the same name,
// the class' proto wouldn't ever be deleted,
@@ -154,25 +164,29 @@ open class IncrementalJvmCache(
internalNameToSource.remove(className.internalName)
// TODO NO_CHANGES? (delegates only)
constantsMap.process(kotlinClass, changesCollector)
inlineFunctionsMap.process(kotlinClass, changesCollector)
constantsMap.process(kotlinClassInfo, changesCollector)
inlineFunctionsMap.process(kotlinClassInfo, changesCollector)
}
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
assert(sourceFiles.size == 1) { "Multifile class part from several source files: $sourceFiles" }
if (sourceFiles != null) {
assert(sourceFiles.size == 1) { "Multifile class part from several source files: $sourceFiles" }
}
packagePartMap.addPackagePart(className)
partToMultifileFacade.set(className.internalName, header.multifileClassName!!)
partToMultifileFacade.set(className.internalName, kotlinClassInfo.multifileClassName!!)
protoMap.process(kotlinClass, changesCollector)
constantsMap.process(kotlinClass, changesCollector)
inlineFunctionsMap.process(kotlinClass, changesCollector)
protoMap.process(kotlinClassInfo, changesCollector)
constantsMap.process(kotlinClassInfo, changesCollector)
inlineFunctionsMap.process(kotlinClassInfo, changesCollector)
}
KotlinClassHeader.Kind.CLASS -> {
assert(sourceFiles.size == 1) { "Class is expected to have only one source file: $sourceFiles" }
addToClassStorage(kotlinClass, sourceFiles.first())
if (sourceFiles != null) {
assert(sourceFiles.size == 1) { "Class is expected to have only one source file: $sourceFiles" }
addToClassStorage(kotlinClassInfo, sourceFiles.first())
}
protoMap.process(kotlinClass, changesCollector)
constantsMap.process(kotlinClass, changesCollector)
inlineFunctionsMap.process(kotlinClass, changesCollector)
protoMap.process(kotlinClassInfo, changesCollector)
constantsMap.process(kotlinClassInfo, changesCollector)
inlineFunctionsMap.process(kotlinClassInfo, changesCollector)
}
KotlinClassHeader.Kind.UNKNOWN, KotlinClassHeader.Kind.SYNTHETIC_CLASS -> {
}
@@ -278,8 +292,8 @@ open class IncrementalJvmCache(
private inner class ProtoMap(storageFile: File) : BasicStringMap<ProtoMapValue>(storageFile, ProtoMapValueExternalizer) {
@Synchronized
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
return put(kotlinClass, changesCollector)
fun process(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
return put(kotlinClassInfo, changesCollector)
}
// A module mapping (.kotlin_module file) is stored in a cache,
@@ -295,19 +309,17 @@ open class IncrementalJvmCache(
}
@Synchronized
private fun put(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
val header = kotlinClass.classHeader
val key = kotlinClass.className.internalName
private fun put(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
val key = kotlinClassInfo.className.internalName
val oldData = storage[key]
val newData = ProtoMapValue(
header.kind != KotlinClassHeader.Kind.CLASS,
BitEncoding.decodeBytes(header.data!!),
header.strings!!
kotlinClassInfo.classKind != KotlinClassHeader.Kind.CLASS,
BitEncoding.decodeBytes(kotlinClassInfo.classHeaderData!!),
kotlinClassInfo.classHeaderStrings!!
)
storage[key] = newData
val packageFqName = kotlinClass.className.packageFqName
val packageFqName = kotlinClassInfo.className.packageFqName
changesCollector.collectProtoChanges(oldData?.toProtoData(packageFqName), newData.toProtoData(packageFqName), packageProtoKey = key)
}
@@ -368,31 +380,16 @@ open class IncrementalJvmCache(
// todo: reuse code with InlineFunctionsMap?
private inner class ConstantsMap(storageFile: File) : BasicStringMap<Map<String, Any>>(storageFile, ConstantsMapExternalizer) {
private fun getConstantsMap(bytes: ByteArray): Map<String, Any> {
val result = HashMap<String, Any>()
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
val staticFinal = Opcodes.ACC_STATIC or Opcodes.ACC_FINAL or Opcodes.ACC_PRIVATE
if (value != null && access and staticFinal == Opcodes.ACC_STATIC or Opcodes.ACC_FINAL) {
result[name] = value
}
return null
}
}, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
return result
}
operator fun contains(className: JvmClassName): Boolean =
className.internalName in storage
@Synchronized
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
val key = kotlinClass.className.internalName
fun process(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
val key = kotlinClassInfo.className.internalName
val oldMap = storage[key] ?: emptyMap()
val newMap = getConstantsMap(kotlinClass.fileContents)
val newMap = kotlinClassInfo.constantsMap
if (newMap.isNotEmpty()) {
storage[key] = newMap
} else {
@@ -401,8 +398,18 @@ open class IncrementalJvmCache(
for (const in oldMap.keys + newMap.keys) {
//Constant can be declared via companion object or via const field declaration
changesCollector.collectMemberIfValueWasChanged(kotlinClass.scopeFqName(companion = true), const, oldMap[const], newMap[const])
changesCollector.collectMemberIfValueWasChanged(kotlinClass.scopeFqName(companion = false), const, oldMap[const], newMap[const])
changesCollector.collectMemberIfValueWasChanged(
kotlinClassInfo.scopeFqName(companion = true),
const,
oldMap[const],
newMap[const]
)
changesCollector.collectMemberIfValueWasChanged(
kotlinClassInfo.scopeFqName(companion = false),
const,
oldMap[const],
newMap[const]
)
}
}
@@ -490,67 +497,20 @@ open class IncrementalJvmCache(
value.dumpCollection()
}
private fun addToClassStorage(kotlinClass: LocalFileKotlinClass, srcFile: File) {
val (nameResolver, proto) = JvmProtoBufUtil.readClassDataFrom(kotlinClass.classHeader.data!!, kotlinClass.classHeader.strings!!)
private fun addToClassStorage(classInfo: KotlinClassInfo, srcFile: File) {
val (nameResolver, proto) = JvmProtoBufUtil.readClassDataFrom(classInfo.classHeaderData!!, classInfo.classHeaderStrings!!)
addToClassStorage(proto, nameResolver, srcFile)
}
private inner class InlineFunctionsMap(storageFile: File) :
BasicStringMap<Map<String, Long>>(storageFile, StringToLongMapExternalizer) {
private fun getInlineFunctionsMap(header: KotlinClassHeader, bytes: ByteArray): Map<String, Long> {
val inlineFunctions = inlineFunctionsJvmNames(header)
if (inlineFunctions.isEmpty()) return emptyMap()
val result = HashMap<String, Long>()
var dummyVersion: Int = -1
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visit(
version: Int,
access: Int,
name: String?,
signature: String?,
superName: String?,
interfaces: Array<out String>?
) {
super.visit(version, access, name, signature, superName, interfaces)
dummyVersion = version
}
override fun visitMethod(
access: Int,
name: String,
desc: String,
signature: String?,
exceptions: Array<out String>?
): MethodVisitor? {
val dummyClassWriter = ClassWriter(0)
dummyClassWriter.visit(dummyVersion, 0, "dummy", null, AsmTypes.OBJECT_TYPE.internalName, null)
return object : MethodVisitor(Opcodes.API_VERSION, dummyClassWriter.visitMethod(0, name, desc, null, exceptions)) {
override fun visitEnd() {
val jvmName = name + desc
if (jvmName !in inlineFunctions) return
val dummyBytes = dummyClassWriter.toByteArray()!!
val hash = dummyBytes.md5()
result[jvmName] = hash
}
}
}
}, 0)
return result
}
@Synchronized
fun process(kotlinClass: LocalFileKotlinClass, changesCollector: ChangesCollector) {
val key = kotlinClass.className.internalName
fun process(kotlinClassInfo: KotlinClassInfo, changesCollector: ChangesCollector) {
val key = kotlinClassInfo.className.internalName
val oldMap = storage[key] ?: emptyMap()
val newMap = getInlineFunctionsMap(kotlinClass.classHeader, kotlinClass.fileContents)
val newMap = kotlinClassInfo.inlineFunctionsMap
if (newMap.isNotEmpty()) {
storage[key] = newMap
} else {
@@ -559,7 +519,7 @@ open class IncrementalJvmCache(
for (fn in oldMap.keys + newMap.keys) {
changesCollector.collectMemberIfValueWasChanged(
kotlinClass.scopeFqName(),
kotlinClassInfo.scopeFqName(),
functionNameBySignature(fn),
oldMap[fn],
newMap[fn]
@@ -602,13 +562,6 @@ sealed class ChangeInfo(val fqName: FqName) {
}
}
private fun LocalFileKotlinClass.scopeFqName(companion: Boolean = false) = when (classHeader.kind) {
KotlinClassHeader.Kind.CLASS -> {
className.fqNameForClassNameWithoutDollars.let { if (companion) it.child(DEFAULT_NAME_FOR_COMPANION_OBJECT) else it }
}
else -> className.packageFqName
}
fun ByteArray.md5(): Long {
val d = MessageDigest.getInstance("MD5").digest(this)!!
return ((d[0].toLong() and 0xFFL)
@@ -640,3 +593,105 @@ fun <K : Comparable<K>, V> Map<K, V>.dumpMap(dumpValue: (V) -> String): String =
@TestOnly
fun <T : Comparable<T>> Collection<T>.dumpCollection(): String =
"[${sorted().joinToString(", ", transform = Any::toString)}]"
/**
* Minimal information about a kotlinc-generated class that will be used to compute recompilation-triggered changes to support incremental
* compilation (see [IncrementalJvmCache.saveClassToCache]).
*
* It's important that this class contain only the minimal required information, as it will be part of the classpath snapshot of the
* `KotlinCompile` task and the task needs to support compile avoidance. For example, this class should contain public method signatures,
* and should not contain private method signatures, or method implementations.
*/
class KotlinClassInfo private constructor(
val classId: ClassId,
val classKind: KotlinClassHeader.Kind,
val classHeaderData: Array<String>?,
val classHeaderStrings: Array<String>?,
@Suppress("SpellCheckingInspection") val multifileClassName: String?,
val constantsMap: LinkedHashMap<String, Any>,
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) {
KotlinClassHeader.Kind.CLASS -> {
className.fqNameForClassNameWithoutDollars.let { if (companion) it.child(DEFAULT_NAME_FOR_COMPANION_OBJECT) else it }
}
else -> className.packageFqName
}
}
private fun getConstantsMap(bytes: ByteArray): LinkedHashMap<String, Any> {
val result = LinkedHashMap<String, Any>()
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
val staticFinal = Opcodes.ACC_STATIC or Opcodes.ACC_FINAL or Opcodes.ACC_PRIVATE
if (value != null && access and staticFinal == Opcodes.ACC_STATIC or Opcodes.ACC_FINAL) {
result[name] = value
}
return null
}
}, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
return result
}
private fun getInlineFunctionsMap(header: KotlinClassHeader, bytes: ByteArray): LinkedHashMap<String, Long> {
val inlineFunctions = inlineFunctionsJvmNames(header)
if (inlineFunctions.isEmpty()) return LinkedHashMap()
val result = LinkedHashMap<String, Long>()
var dummyVersion: Int = -1
ClassReader(bytes).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visit(
version: Int,
access: Int,
name: String?,
signature: String?,
superName: String?,
interfaces: Array<out String>?
) {
super.visit(version, access, name, signature, superName, interfaces)
dummyVersion = version
}
override fun visitMethod(
access: Int,
name: String,
desc: String,
signature: String?,
exceptions: Array<out String>?
): MethodVisitor {
val dummyClassWriter = ClassWriter(0)
dummyClassWriter.visit(dummyVersion, 0, "dummy", null, AsmTypes.OBJECT_TYPE.internalName, null)
return object : MethodVisitor(Opcodes.API_VERSION, dummyClassWriter.visitMethod(0, name, desc, null, exceptions)) {
override fun visitEnd() {
val jvmName = name + desc
if (jvmName !in inlineFunctions) return
val dummyBytes = dummyClassWriter.toByteArray()!!
val hash = dummyBytes.md5()
result[jvmName] = hash
}
}
}
}, 0)
return result
}

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.incremental
import com.intellij.openapi.diagnostic.Logger
import com.intellij.util.containers.MultiMap
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -33,6 +34,8 @@ open class LookupStorage(
targetDataDir: File,
pathConverter: FileToPathConverter
) : BasicMapsOwner(targetDataDir) {
val LOG = Logger.getInstance("#org.jetbrains.kotlin.jps.build.KotlinBuilder")
companion object {
private val DELETED_TO_SIZE_TRESHOLD = 0.5
private val MINIMUM_GARBAGE_COLLECTIBLE_SIZE = 10000
@@ -46,31 +49,39 @@ open class LookupStorage(
@Volatile
private var size: Int = 0
@Volatile
private var deletedCount: Int = 0
init {
try {
if (countersFile.exists()) {
val lines = countersFile.readLines()
size = lines[0].toInt()
deletedCount = lines[1].toInt()
}
} catch (e: Exception) {
throw IOException("Could not read $countersFile", e)
}
}
@Synchronized
fun get(lookupSymbol: LookupSymbol): Collection<String> {
val key = LookupSymbolKey(lookupSymbol.name, lookupSymbol.scope)
val fileIds = lookupMap[key] ?: return emptySet()
val paths = mutableSetOf<String>()
val filtered = mutableSetOf<Int>()
for (fileId in fileIds) {
val path = idToFile[fileId]?.path
if (path != null) {
paths.add(path)
filtered.add(fileId)
}
return fileIds.mapNotNull {
// null means it's outdated
idToFile[it]?.path
}
if (size > MINIMUM_GARBAGE_COLLECTIBLE_SIZE && filtered.size.toDouble() / fileIds.size.toDouble() < DELETED_TO_SIZE_TRESHOLD) {
lookupMap[key] = filtered
}
return paths
}
@Synchronized
@@ -81,8 +92,8 @@ open class LookupStorage(
val key = LookupSymbolKey(lookupSymbol.name, lookupSymbol.scope)
val paths = lookups[lookupSymbol]
val fileIds = paths.mapTo(TreeSet()) { pathToId[it]!! }
fileIds.addAll(lookupMap[key] ?: emptySet())
lookupMap[key] = fileIds
lookupMap.append(key, fileIds)
}
}
@@ -92,7 +103,6 @@ open class LookupStorage(
val id = fileToId[file] ?: continue
idToFile.remove(id)
fileToId.remove(file)
deletedCount++
}
}
@@ -103,7 +113,6 @@ open class LookupStorage(
}
size = 0
deletedCount = 0
super.clean()
}
@@ -111,18 +120,15 @@ open class LookupStorage(
@Synchronized
override fun flush(memoryCachesOnly: Boolean) {
try {
removeGarbageIfNeeded()
if (size > 0) {
if (!countersFile.exists()) {
countersFile.parentFile.mkdirs()
countersFile.createNewFile()
}
countersFile.writeText("$size\n$deletedCount")
countersFile.writeText("$size\n0")
}
}
finally {
} finally {
super.flush(memoryCachesOnly)
}
}
@@ -137,13 +143,7 @@ open class LookupStorage(
return id
}
private fun removeGarbageIfNeeded(force: Boolean = false) {
if (force || (size > MINIMUM_GARBAGE_COLLECTIBLE_SIZE && deletedCount.toDouble() / size > DELETED_TO_SIZE_TRESHOLD)) {
doRemoveGarbage()
}
}
private fun doRemoveGarbage() {
private fun removeGarbageForTests() {
for (hash in lookupMap.keys) {
lookupMap[hash] = lookupMap[hash]!!.filter { it in idToFile }.toSet()
}
@@ -153,7 +153,6 @@ open class LookupStorage(
idToFile.clean()
fileToId.clean()
size = 0
deletedCount = 0
for ((file, oldId) in oldFileToId.entries.sortedBy { it.key.path }) {
val newId = addFileIfNeeded(file)
@@ -165,15 +164,16 @@ open class LookupStorage(
if (fileIds.isEmpty()) {
lookupMap.remove(lookup)
}
else {
} else {
lookupMap[lookup] = fileIds
}
}
}
@TestOnly fun forceGC() {
removeGarbageIfNeeded(force = true)
@TestOnly
fun forceGC() {
removeGarbageForTests()
flush(false)
}

View File

@@ -1104,6 +1104,11 @@ open class ProtoCompareGenerated(
if (!checkEquals(old.setter, new.setter)) return false
}
if (old.hasDelegateMethod() != new.hasDelegateMethod()) return false
if (old.hasDelegateMethod()) {
if (!checkEquals(old.delegateMethod, new.delegateMethod)) return false
}
return true
}
@@ -2353,6 +2358,10 @@ fun JvmProtoBuf.JvmPropertySignature.hashCode(stringIndexes: (Int) -> Int, fqNam
hashCode = 31 * hashCode + setter.hashCode(stringIndexes, fqNameIndexes, typeById)
}
if (hasDelegateMethod()) {
hashCode = 31 * hashCode + delegateMethod.hashCode(stringIndexes, fqNameIndexes, typeById)
}
return hashCode
}

View File

@@ -27,6 +27,10 @@ class LookupMap(storage: File) : BasicMap<LookupSymbolKey, Collection<Int>>(stor
storage.append(LookupSymbolKey(name, scope), listOf(fileId))
}
fun append(lookup: LookupSymbolKey, fileIds: Collection<Int>) {
storage.append(lookup, fileIds)
}
operator fun get(key: LookupSymbolKey): Collection<Int>? = storage[key]
operator fun set(key: LookupSymbolKey, fileIds: Set<Int>) {

View File

@@ -3443,6 +3443,34 @@ public final class DebugJvmProtoBuf {
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature setter = 4;</code>
*/
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder getSetterOrBuilder();
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
boolean hasDelegateMethod();
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature getDelegateMethod();
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder getDelegateMethodOrBuilder();
}
/**
* Protobuf type {@code org.jetbrains.kotlin.metadata.jvm.JvmPropertySignature}
@@ -3548,6 +3576,19 @@ public final class DebugJvmProtoBuf {
bitField0_ |= 0x00000008;
break;
}
case 42: {
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder subBuilder = null;
if (((bitField0_ & 0x00000010) == 0x00000010)) {
subBuilder = delegateMethod_.toBuilder();
}
delegateMethod_ = input.readMessage(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.PARSER, extensionRegistry);
if (subBuilder != null) {
subBuilder.mergeFrom(delegateMethod_);
delegateMethod_ = subBuilder.buildPartial();
}
bitField0_ |= 0x00000010;
break;
}
}
}
} catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) {
@@ -3684,11 +3725,48 @@ public final class DebugJvmProtoBuf {
return setter_;
}
public static final int DELEGATE_METHOD_FIELD_NUMBER = 5;
private org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature delegateMethod_;
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public boolean hasDelegateMethod() {
return ((bitField0_ & 0x00000010) == 0x00000010);
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature getDelegateMethod() {
return delegateMethod_;
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder getDelegateMethodOrBuilder() {
return delegateMethod_;
}
private void initFields() {
field_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmFieldSignature.getDefaultInstance();
syntheticMethod_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
getter_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
setter_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
delegateMethod_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
}
private byte memoizedIsInitialized = -1;
public final boolean isInitialized() {
@@ -3715,6 +3793,9 @@ public final class DebugJvmProtoBuf {
if (((bitField0_ & 0x00000008) == 0x00000008)) {
output.writeMessage(4, setter_);
}
if (((bitField0_ & 0x00000010) == 0x00000010)) {
output.writeMessage(5, delegateMethod_);
}
getUnknownFields().writeTo(output);
}
@@ -3740,6 +3821,10 @@ public final class DebugJvmProtoBuf {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeMessageSize(4, setter_);
}
if (((bitField0_ & 0x00000010) == 0x00000010)) {
size += org.jetbrains.kotlin.protobuf.CodedOutputStream
.computeMessageSize(5, delegateMethod_);
}
size += getUnknownFields().getSerializedSize();
memoizedSerializedSize = size;
return size;
@@ -3853,6 +3938,7 @@ public final class DebugJvmProtoBuf {
getSyntheticMethodFieldBuilder();
getGetterFieldBuilder();
getSetterFieldBuilder();
getDelegateMethodFieldBuilder();
}
}
private static Builder create() {
@@ -3885,6 +3971,12 @@ public final class DebugJvmProtoBuf {
setterBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000008);
if (delegateMethodBuilder_ == null) {
delegateMethod_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
} else {
delegateMethodBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000010);
return this;
}
@@ -3945,6 +4037,14 @@ public final class DebugJvmProtoBuf {
} else {
result.setter_ = setterBuilder_.build();
}
if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
to_bitField0_ |= 0x00000010;
}
if (delegateMethodBuilder_ == null) {
result.delegateMethod_ = delegateMethod_;
} else {
result.delegateMethod_ = delegateMethodBuilder_.build();
}
result.bitField0_ = to_bitField0_;
onBuilt();
return result;
@@ -3973,6 +4073,9 @@ public final class DebugJvmProtoBuf {
if (other.hasSetter()) {
mergeSetter(other.getSetter());
}
if (other.hasDelegateMethod()) {
mergeDelegateMethod(other.getDelegateMethod());
}
this.mergeUnknownFields(other.getUnknownFields());
return this;
}
@@ -4500,6 +4603,167 @@ public final class DebugJvmProtoBuf {
return setterBuilder_;
}
private org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature delegateMethod_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder> delegateMethodBuilder_;
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public boolean hasDelegateMethod() {
return ((bitField0_ & 0x00000010) == 0x00000010);
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature getDelegateMethod() {
if (delegateMethodBuilder_ == null) {
return delegateMethod_;
} else {
return delegateMethodBuilder_.getMessage();
}
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public Builder setDelegateMethod(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature value) {
if (delegateMethodBuilder_ == null) {
if (value == null) {
throw new NullPointerException();
}
delegateMethod_ = value;
onChanged();
} else {
delegateMethodBuilder_.setMessage(value);
}
bitField0_ |= 0x00000010;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public Builder setDelegateMethod(
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder builderForValue) {
if (delegateMethodBuilder_ == null) {
delegateMethod_ = builderForValue.build();
onChanged();
} else {
delegateMethodBuilder_.setMessage(builderForValue.build());
}
bitField0_ |= 0x00000010;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public Builder mergeDelegateMethod(org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature value) {
if (delegateMethodBuilder_ == null) {
if (((bitField0_ & 0x00000010) == 0x00000010) &&
delegateMethod_ != org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance()) {
delegateMethod_ =
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.newBuilder(delegateMethod_).mergeFrom(value).buildPartial();
} else {
delegateMethod_ = value;
}
onChanged();
} else {
delegateMethodBuilder_.mergeFrom(value);
}
bitField0_ |= 0x00000010;
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public Builder clearDelegateMethod() {
if (delegateMethodBuilder_ == null) {
delegateMethod_ = org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.getDefaultInstance();
onChanged();
} else {
delegateMethodBuilder_.clear();
}
bitField0_ = (bitField0_ & ~0x00000010);
return this;
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder getDelegateMethodBuilder() {
bitField0_ |= 0x00000010;
onChanged();
return getDelegateMethodFieldBuilder().getBuilder();
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
public org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder getDelegateMethodOrBuilder() {
if (delegateMethodBuilder_ != null) {
return delegateMethodBuilder_.getMessageOrBuilder();
} else {
return delegateMethod_;
}
}
/**
* <code>optional .org.jetbrains.kotlin.metadata.jvm.JvmMethodSignature delegate_method = 5;</code>
*
* <pre>
* The delegate field of delegated properties may be optimized out; `getDelegate` should
* then call this method instead
* </pre>
*/
private org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder>
getDelegateMethodFieldBuilder() {
if (delegateMethodBuilder_ == null) {
delegateMethodBuilder_ = new org.jetbrains.kotlin.protobuf.SingleFieldBuilder<
org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignature.Builder, org.jetbrains.kotlin.metadata.jvm.DebugJvmProtoBuf.JvmMethodSignatureOrBuilder>(
getDelegateMethod(),
getParentForChildren(),
isClean());
delegateMethod_ = null;
}
return delegateMethodBuilder_;
}
// @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.metadata.jvm.JvmPropertySignature)
}
@@ -4740,7 +5004,7 @@ public final class DebugJvmProtoBuf {
"\020DESC_TO_CLASS_ID\020\002\"<\n\022JvmMethodSignatur" +
"e\022\022\n\004name\030\001 \001(\005B\004\230\265\030\001\022\022\n\004desc\030\002 \001(\005B\004\230\265\030" +
"\001\";\n\021JvmFieldSignature\022\022\n\004name\030\001 \001(\005B\004\230\265" +
"\030\001\022\022\n\004desc\030\002 \001(\005B\004\230\265\030\001\"\272\002\n\024JvmPropertySi" +
"\030\001\022\022\n\004desc\030\002 \001(\005B\004\230\265\030\001\"\212\003\n\024JvmPropertySi" +
"gnature\022C\n\005field\030\001 \001(\01324.org.jetbrains.k" +
"otlin.metadata.jvm.JvmFieldSignature\022O\n\020",
"synthetic_method\030\002 \001(\01325.org.jetbrains.k" +
@@ -4748,11 +5012,13 @@ public final class DebugJvmProtoBuf {
"\006getter\030\003 \001(\01325.org.jetbrains.kotlin.met" +
"adata.jvm.JvmMethodSignature\022E\n\006setter\030\004" +
" \001(\01325.org.jetbrains.kotlin.metadata.jvm" +
".JvmMethodSignature\022N\n\017delegate_method\030\005" +
" \001(\01325.org.jetbrains.kotlin.metadata.jvm" +
".JvmMethodSignature:\200\001\n\025constructor_sign" +
"ature\022*.org.jetbrains.kotlin.metadata.Co" +
"nstructor\030d \001(\01325.org.jetbrains.kotlin.m" +
"nstructor\030d \001(\01325.org.jetbrains.kotlin.m",
"etadata.jvm.JvmMethodSignature:x\n\020method" +
"_signature\022\'.org.jetbrains.kotlin.metada",
"_signature\022\'.org.jetbrains.kotlin.metada" +
"ta.Function\030d \001(\01325.org.jetbrains.kotlin" +
".metadata.jvm.JvmMethodSignature:O\n\030lamb" +
"da_class_origin_name\022\'.org.jetbrains.kot" +
@@ -4760,9 +5026,9 @@ public final class DebugJvmProtoBuf {
"perty_signature\022\'.org.jetbrains.kotlin.m" +
"etadata.Property\030d \001(\01327.org.jetbrains.k" +
"otlin.metadata.jvm.JvmPropertySignature:" +
"9\n\005flags\022\'.org.jetbrains.kotlin.metadata" +
"9\n\005flags\022\'.org.jetbrains.kotlin.metadata",
".Property\030e \001(\005:\0010:g\n\017type_annotation\022#." +
"org.jetbrains.kotlin.metadata.Type\030d \003(\013",
"org.jetbrains.kotlin.metadata.Type\030d \003(\013" +
"2).org.jetbrains.kotlin.metadata.Annotat" +
"ion:3\n\006is_raw\022#.org.jetbrains.kotlin.met" +
"adata.Type\030e \001(\010:z\n\031type_parameter_annot" +
@@ -4770,9 +5036,9 @@ public final class DebugJvmProtoBuf {
"peParameter\030d \003(\0132).org.jetbrains.kotlin" +
".metadata.Annotation:E\n\021class_module_nam" +
"e\022$.org.jetbrains.kotlin.metadata.Class\030" +
"e \001(\005B\004\230\265\030\001:k\n\024class_local_variable\022$.or" +
"e \001(\005B\004\230\265\030\001:k\n\024class_local_variable\022$.or",
"g.jetbrains.kotlin.metadata.Class\030f \003(\0132" +
"\'.org.jetbrains.kotlin.metadata.Property",
"\'.org.jetbrains.kotlin.metadata.Property" +
":P\n\034anonymous_object_origin_name\022$.org.j" +
"etbrains.kotlin.metadata.Class\030g \001(\005B\004\230\265" +
"\030\001:@\n\017jvm_class_flags\022$.org.jetbrains.ko" +
@@ -4780,7 +5046,7 @@ public final class DebugJvmProtoBuf {
"module_name\022&.org.jetbrains.kotlin.metad" +
"ata.Package\030e \001(\005B\004\230\265\030\001:o\n\026package_local" +
"_variable\022&.org.jetbrains.kotlin.metadat" +
"a.Package\030f \003(\0132\'.org.jetbrains.kotlin.m" +
"a.Package\030f \003(\0132\'.org.jetbrains.kotlin.m",
"etadata.PropertyB\022B\020DebugJvmProtoBuf"
};
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
@@ -4826,7 +5092,7 @@ public final class DebugJvmProtoBuf {
internal_static_org_jetbrains_kotlin_metadata_jvm_JvmPropertySignature_fieldAccessorTable = new
org.jetbrains.kotlin.protobuf.GeneratedMessage.FieldAccessorTable(
internal_static_org_jetbrains_kotlin_metadata_jvm_JvmPropertySignature_descriptor,
new java.lang.String[] { "Field", "SyntheticMethod", "Getter", "Setter", });
new java.lang.String[] { "Field", "SyntheticMethod", "Getter", "Setter", "DelegateMethod", });
constructorSignature.internalInit(descriptor.getExtensions().get(0));
methodSignature.internalInit(descriptor.getExtensions().get(1));
lambdaClassOriginName.internalInit(descriptor.getExtensions().get(2));

View File

@@ -148,12 +148,9 @@ extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
extra["versions.ktor-network"] = "1.0.1"
if (!project.hasProperty("versions.kotlin-native")) {
extra["versions.kotlin-native"] = "1.6.0-dev-248"
extra["versions.kotlin-native"] = "1.6.0-dev-1728"
}
val effectSystemEnabled by extra(project.getBooleanProperty("kotlin.compiler.effectSystemEnabled") ?: false)
val newInferenceEnabled by extra(project.getBooleanProperty("kotlin.compiler.newInferenceEnabled") ?: false)
val useJvmIrBackend by extra(project.kotlinBuildProperties.useIR)
val useJvmFir by extra(project.kotlinBuildProperties.useFir)
val intellijSeparateSdks = project.getBooleanProperty("intellijSeparateSdks") ?: false
@@ -162,7 +159,7 @@ extra["intellijSeparateSdks"] = intellijSeparateSdks
extra["IntellijCoreDependencies"] =
listOf(
"asm-all-8.0.1",
"asm-all-9.0",
"guava",
"jdom",
"jna",
@@ -351,7 +348,12 @@ val coreLibProjects = listOfNotNull(
val projectsWithDisabledFirBootstrap = coreLibProjects + listOf(
":kotlin-gradle-plugin",
":kotlinx-metadata",
":kotlinx-metadata-jvm"
":kotlinx-metadata-jvm",
// For some reason stdlib isn't imported correctly for this module
// Probably it's related to kotlin-test module usage
":kotlin-gradle-statistics",
// Requires serialization plugin
":wasm:wasm.ir"
)
val gradlePluginProjects = listOf(
@@ -443,7 +445,6 @@ allprojects {
val commonCompilerArgs = listOfNotNull(
"-Xopt-in=kotlin.RequiresOptIn",
"-Xread-deserialized-contracts",
"-progressive".takeIf { hasProperty("test.progressive.mode") }
)
@@ -459,17 +460,13 @@ allprojects {
"-Xjvm-default=compatibility",
"-Xno-optimized-callable-references",
"-Xno-kotlin-nothing-value-exception",
"-Xnormalize-constructor-calls=enable"
"-Xsuppress-deprecated-jvm-target-warning" // Remove as soon as there are no modules for JDK 1.6 & 1.7
)
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile> {
kotlinOptions {
freeCompilerArgs = commonCompilerArgs + jvmCompilerArgs
if (useJvmIrBackend) {
useIR = true
}
if (useJvmFir && this@allprojects.path !in projectsWithDisabledFirBootstrap) {
freeCompilerArgs += "-Xuse-fir"
freeCompilerArgs += "-Xabi-stability=stable"
@@ -477,7 +474,7 @@ allprojects {
}
}
if (!kotlinBuildProperties.isInJpsBuildIdeaSync && !kotlinBuildProperties.useFir && !kotlinBuildProperties.disableWerror) {
if (!kotlinBuildProperties.disableWerror) {
// For compiler and stdlib, allWarningsAsErrors is configured in the corresponding "root" projects
// (compiler/build.gradle.kts and libraries/commonConfiguration.gradle).
val projectsWithWarningsAsErrors = listOf("core", "plugins").map { File(it).absoluteFile }
@@ -730,14 +727,8 @@ tasks {
dependsOn(":kotlin-scripting-jsr223-test:embeddableTest")
dependsOn(":kotlin-main-kts-test:test")
dependsOn(":kotlin-main-kts-test:testWithIr")
if (kotlinBuildProperties.getOrNull("attachedIntellijVersion") == null &&
!kotlinBuildProperties.getBoolean("disableKotlinPluginModules", false)
) {
dependsOn(":kotlin-scripting-ide-services-test:test")
dependsOn(":kotlin-scripting-ide-services-test:embeddableTest")
}
dependsOn(":kotlin-scripting-ide-services-test:test")
dependsOn(":kotlin-scripting-ide-services-test:embeddableTest")
dependsOn(":kotlin-scripting-js-test:test")
}
@@ -857,8 +848,8 @@ tasks {
":idea-frontend-fir:idea-fir-low-level-api:test"
)
}
register("android-ide-tests") {
dependsOn("dist")
@@ -1131,4 +1122,14 @@ plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin:
extensions.configure(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension::class.java) {
nodeVersion = "16.2.0"
}
}
}
afterEvaluate {
val cacheRedirectorEnabled = findProperty("cacheRedirectorEnabled")?.toString()?.toBoolean() == true
if (cacheRedirectorEnabled) {
rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.yarn.YarnPlugin::class.java) {
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.yarn.YarnRootExtension>().downloadBaseUrl =
"https://cache-redirector.jetbrains.com/github.com/yarnpkg/yarn/releases/download"
}
}
}

View File

@@ -155,7 +155,7 @@ dependencies {
implementation("net.sf.proguard:proguard-gradle:6.2.2")
implementation("org.jetbrains.intellij.deps:asm-all:8.0.1")
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:0.5")
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:1.0.1")
implementation("org.gradle:test-retry-gradle-plugin:1.2.0")
implementation("com.gradle.enterprise:test-distribution-gradle-plugin:2.1")

View File

@@ -19,8 +19,8 @@ val KotlinBuildProperties.jarCompression: Boolean get() = getBoolean("kotlin.bui
val KotlinBuildProperties.ignoreTestFailures: Boolean get() = getBoolean("ignoreTestFailures", isTeamcityBuild)
val KotlinBuildProperties.disableWerror: Boolean get() = getBoolean("kotlin.build.disable.werror", false)
val KotlinBuildProperties.disableWerror: Boolean
get() = getBoolean("kotlin.build.disable.werror") || useFir || isInJpsBuildIdeaSync || getBoolean("test.progressive.mode")
val KotlinBuildProperties.isObsoleteJdkOverrideEnabled: Boolean
get() = !isTeamcityBuild &&
getBoolean("kotlin.build.isObsoleteJdkOverrideEnabled", false)
get() = getBoolean("kotlin.build.isObsoleteJdkOverrideEnabled", false)

View File

@@ -0,0 +1,144 @@
/*
* 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.
*/
import com.github.jengelman.gradle.plugins.shadow.relocation.RelocateClassContext
import com.github.jengelman.gradle.plugins.shadow.transformers.Transformer
import com.github.jengelman.gradle.plugins.shadow.transformers.TransformerContext
import org.gradle.api.file.FileTreeElement
import shadow.org.apache.tools.zip.ZipEntry
import shadow.org.apache.tools.zip.ZipOutputStream
import shadow.org.codehaus.plexus.util.IOUtil
import shadow.org.codehaus.plexus.util.ReaderFactory
import shadow.org.codehaus.plexus.util.WriterFactory
import shadow.org.codehaus.plexus.util.xml.Xpp3Dom
import shadow.org.codehaus.plexus.util.xml.Xpp3DomBuilder
import shadow.org.codehaus.plexus.util.xml.Xpp3DomWriter
import java.io.*
import java.lang.Exception
import java.util.LinkedHashMap
/**
* A resource processor that aggregates plexus `components.xml` files.
*
* Fixed version of [com.github.jengelman.gradle.plugins.shadow.transformers.ComponentsXmlResourceTransformer],
* may be dropped after [the fix in ShadowJAR](https://github.com/johnrengelman/shadow/pull/678/files) will be accepted
*/
class ComponentsXmlResourceTransformerPatched : Transformer {
private val components: MutableMap<String, Xpp3Dom> =
LinkedHashMap<String, Xpp3Dom>()
override fun canTransformResource(element: FileTreeElement): Boolean {
val path = element.relativePath.pathString
return COMPONENTS_XML_PATH == path
}
override fun transform(context: TransformerContext) {
val newDom: Xpp3Dom = try {
val bis: BufferedInputStream = object : BufferedInputStream(context.getIs()) {
override fun close() {
// leave ZIP open
}
}
val reader: Reader = ReaderFactory.newXmlReader(bis)
Xpp3DomBuilder.build(reader)
} catch (e: Exception) {
throw (IOException("Error parsing components.xml in " + context.getIs()).initCause(e) as IOException)
}
// Only try to merge in components if there are some elements in the component-set
if (newDom.getChild("components") == null) {
return
}
val children: Array<Xpp3Dom>? = newDom.getChild("components")?.getChildren("component")
children?.forEach { component ->
var role: String? = getValue(component, "role")
role = getRelocatedClass(role, context)
setValue(component, "role", role)
val roleHint = getValue(component, "role-hint")
var impl: String? = getValue(component, "implementation")
impl = getRelocatedClass(impl, context)
setValue(component, "implementation", impl)
val key = "$role:$roleHint"
if (components.containsKey(key)) {
// configuration carry over
val dom: Xpp3Dom? = components[key]
if (dom?.getChild("configuration") != null) {
component.addChild(dom.getChild("configuration"))
}
}
val requirements: Xpp3Dom? = component.getChild("requirements")
if (requirements != null && requirements.childCount > 0) {
for (r in requirements.childCount - 1 downTo 0) {
val requirement: Xpp3Dom = requirements.getChild(r)
var requiredRole: String? = getValue(requirement, "role")
requiredRole = getRelocatedClass(requiredRole, context)
setValue(requirement, "role", requiredRole)
}
}
components[key] = component
}
}
override fun modifyOutputStream(os: ZipOutputStream, preserveFileTimestamps: Boolean) {
val data = transformedResource
val entry = ZipEntry(COMPONENTS_XML_PATH)
entry.time = TransformerContext.getEntryTimestamp(preserveFileTimestamps, entry.time)
os.putNextEntry(entry)
IOUtil.copy(data, os)
components.clear()
}
override fun hasTransformedResource(): Boolean {
return components.isNotEmpty()
}
private val transformedResource: ByteArray
get() {
val baos = ByteArrayOutputStream(1024 * 4)
val writer: Writer = WriterFactory.newXmlWriter(baos)
try {
val dom = Xpp3Dom("component-set")
val componentDom = Xpp3Dom("components")
dom.addChild(componentDom)
for (component in components.values) {
componentDom.addChild(component)
}
Xpp3DomWriter.write(writer, dom)
} finally {
IOUtil.close(writer)
}
return baos.toByteArray()
}
companion object {
private const val COMPONENTS_XML_PATH = "META-INF/plexus/components.xml"
private fun getRelocatedClass(className: String?, context: TransformerContext): String? {
val relocators = context.relocators
val stats = context.stats
if (className != null && className.isNotEmpty() && relocators != null) {
for (relocator in relocators) {
if (relocator.canRelocateClass(className)) {
val relocateClassContext = RelocateClassContext(className, stats)
return relocator.relocateClass(relocateClassContext)
}
}
}
return className
}
private fun getValue(dom: Xpp3Dom, element: String): String {
val child: Xpp3Dom? = dom.getChild(element)
return if (child?.value != null) child.value else ""
}
private fun setValue(dom: Xpp3Dom, element: String, value: String?) {
val child: Xpp3Dom? = dom.getChild(element)
if (value == null || value.isEmpty()) {
return
}
child?.value = value
}
}
}

View File

@@ -26,7 +26,7 @@ fun CompatibilityPredicate.or(other: CompatibilityPredicate): CompatibilityPredi
}
enum class Platform : CompatibilityPredicate {
P202, P203;
P203;
val version: Int = name.drop(1).toInt()
@@ -43,10 +43,7 @@ enum class Platform : CompatibilityPredicate {
}
enum class Ide(val platform: Platform) : CompatibilityPredicate {
IJ202(Platform.P202),
IJ203(Platform.P203),
AS42(Platform.P202);
IJ203(Platform.P203);
val kind = Kind.values().first { it.shortName == name.take(2) }
val version = name.dropWhile { !it.isDigit() }.toInt()

View File

@@ -18,11 +18,12 @@ enum class JdkMajorVersion(
JDK_1_6(6, targetName = "1.6", overrideMajorVersion = 8),
JDK_1_7(7, targetName = "1.7", overrideMajorVersion = 8),
JDK_1_8(8, targetName = "1.8"),
JDK_9(9),
JDK_10(10, mandatory = false),
JDK_9(9, overrideMajorVersion = 11),
JDK_10(10, mandatory = false, overrideMajorVersion = 11),
JDK_11(11, mandatory = false),
JDK_15(15, mandatory = false),
JDK_16(16, mandatory = false);
JDK_16(16, mandatory = false),
JDK_17(17, mandatory = false);
fun isMandatory(): Boolean = mandatory
@@ -43,6 +44,9 @@ fun Project.shouldOverrideObsoleteJdk(
fun Project.configureJvmToolchain(
jdkVersion: JdkMajorVersion
) {
// Ensure java only modules also set default toolchain
configureJavaOnlyToolchain(jdkVersion)
plugins.withId("org.jetbrains.kotlin.jvm") {
val kotlinExtension = extensions.getByType<KotlinTopLevelExtension>()
@@ -151,7 +155,7 @@ fun Project.updateJvmTarget(
}
}
fun Project.getToolchainCompilerFor(
private fun Project.getToolchainCompilerFor(
jdkVersion: JdkMajorVersion
): Provider<JavaCompiler> {
val service = project.extensions.getByType<JavaToolchainService>()
@@ -164,7 +168,17 @@ fun Project.getToolchainLauncherFor(
jdkVersion: JdkMajorVersion
): Provider<JavaLauncher> {
val service = project.extensions.getByType<JavaToolchainService>()
val jdkVersionWithOverride = project.getJdkVersionWithOverride(jdkVersion)
return service.launcherFor {
this.languageVersion.set(JavaLanguageVersion.of(jdkVersion.majorVersion))
this.languageVersion.set(JavaLanguageVersion.of(jdkVersionWithOverride.majorVersion))
}
}
fun Project.getJdkVersionWithOverride(jdkVersion: JdkMajorVersion): JdkMajorVersion {
return if (project.shouldOverrideObsoleteJdk(jdkVersion)) {
JdkMajorVersion.fromMajorVersion(jdkVersion.overrideMajorVersion!!)
} else {
jdkVersion
}
}

View File

@@ -9,12 +9,8 @@ import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.provideDelegate
import org.gradle.kotlin.dsl.withType
import org.gradle.process.CommandLineArgumentProvider
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
@JvmOverloads
fun Project.configureJava9Compilation(
@@ -26,9 +22,9 @@ fun Project.configureJava9Compilation(
tasks.named("compileJava9Java", JavaCompile::class.java) {
dependsOn(moduleOutputs)
javaCompiler.set(getToolchainCompilerFor(JdkMajorVersion.JDK_9))
targetCompatibility = JavaVersion.VERSION_1_9.toString()
sourceCompatibility = JavaVersion.VERSION_1_9.toString()
configureTaskToolchain(JdkMajorVersion.JDK_9)
// module-info.java should be in java9 source set by convention
val java9SourceSet = sourceSets["java9"].java
@@ -59,17 +55,3 @@ private class Java9AdditionalArgumentsProvider(
"-Xlint:-requires-transitive-automatic" // suppress automatic module transitive dependencies in kotlin.test
)
}
fun Project.disableDeprecatedJvmTargetWarning() {
if (!kotlinBuildProperties.disableWerror) {
val tasksWithWarnings: List<String> by rootProject.extra
tasks.withType<KotlinCompile>().configureEach {
if (!tasksWithWarnings.contains(path)) {
kotlinOptions {
allWarningsAsErrors = true
freeCompilerArgs += "-Xsuppress-deprecated-jvm-target-warning"
}
}
}
}
}

View File

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

View File

@@ -24,16 +24,16 @@ fun ProjectSettings.compiler(block: IdeaCompilerConfiguration.() -> Unit) =
fun ProjectSettings.delegateActions(block: ActionDelegationConfig.() -> Unit) =
(this@delegateActions as ExtensionAware).extensions.configure(block)
fun ProjectSettings.runConfigurations(block: DefaultRunConfigurationContainer.() -> Unit) =
fun ProjectSettings.runConfigurations(block: RunConfigurationContainer.() -> Unit) =
(this@runConfigurations as ExtensionAware).extensions.configure("runConfigurations", block)
inline fun <reified T: RunConfiguration> DefaultRunConfigurationContainer.defaults(noinline block: T.() -> Unit) =
inline fun <reified T: RunConfiguration> RunConfigurationContainer.defaults(noinline block: T.() -> Unit) =
defaults(T::class.java, block)
fun DefaultRunConfigurationContainer.junit(name: String, block: JUnit.() -> Unit) =
fun RunConfigurationContainer.junit(name: String, block: JUnit.() -> Unit) =
create(name, JUnit::class.java, block)
fun DefaultRunConfigurationContainer.application(name: String, block: Application.() -> Unit) =
fun RunConfigurationContainer.application(name: String, block: Application.() -> Unit) =
create(name, Application::class.java, block)
fun ProjectSettings.ideArtifacts(block: NamedDomainObjectContainer<org.jetbrains.gradle.ext.TopLevelArtifact>.() -> Unit) =

View File

@@ -17,16 +17,11 @@
// usages in build scripts are not tracked properly
@file:Suppress("unused")
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.api.artifacts.repositories.IvyArtifactRepository
import org.gradle.api.tasks.JavaExec
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.DependencyHandlerScope
import org.gradle.kotlin.dsl.extra
import org.gradle.kotlin.dsl.register
import java.io.File
private fun Project.kotlinBuildLocalDependenciesDir(): File =
@@ -146,70 +141,4 @@ fun ModuleDependency.includeIntellijCoreJarDependencies(project: Project, jarsFi
rootProject = project.rootProject
)
fun Project.intellijRootDir() = IntellijRootUtils.getIntellijRootDir(project)
fun DependencyHandlerScope.excludeInAndroidStudio(rootProject: Project, block: DependencyHandlerScope.() -> Unit) {
if (!rootProject.extra.has("versions.androidStudioRelease")) {
block()
}
}
fun Project.runIdeTask(name: String, ideaPluginDir: File, ideaSandboxDir: File, body: JavaExec.() -> Unit): TaskProvider<JavaExec> {
return tasks.register<JavaExec>(name) {
val ideaSandboxConfigDir = File(ideaSandboxDir, "config")
classpath = mainSourceSet.runtimeClasspath
mainClass.set("com.intellij.idea.Main")
workingDir = File(intellijRootDir(), "bin")
jvmArgs(
"-Xmx1250m",
"-XX:ReservedCodeCacheSize=240m",
"-XX:+HeapDumpOnOutOfMemoryError",
"-ea",
"-Didea.debug.mode=true",
"-Didea.system.path=$ideaSandboxDir",
"-Didea.config.path=$ideaSandboxConfigDir",
"-Didea.tooling.debug=true",
"-Dfus.internal.test.mode=true",
"-Dapple.laf.useScreenMenuBar=true",
"-Dapple.awt.graphics.UseQuartz=true",
"-Dsun.io.useCanonCaches=false",
"-Dplugin.path=${ideaPluginDir.absolutePath}"
)
jvmArgs("-Didea.platform.prefix=Idea")
if (rootProject.findProperty("versions.androidStudioRelease") != null) {
jvmArgs("-Didea.platform.prefix=AndroidStudio")
}
if (project.hasProperty("noPCE")) {
jvmArgs("-Didea.ProcessCanceledException=disabled")
}
jvmArgs("-Didea.is.internal=${project.findProperty("idea.is.internal") ?: true}")
project.findProperty("idea.args")?.let { arguments ->
jvmArgs(arguments.toString().split(" "))
}
args()
doFirst {
val disabledPluginsFile = File(ideaSandboxConfigDir, "disabled_plugins.txt")
val disabledPluginsContents = disabledPluginsFile.takeIf { it.isFile }?.readLines()
val filteredContents = disabledPluginsContents?.filterNot { it.contains("org.jetbrains.kotlin") }
if (filteredContents != null && filteredContents.size != disabledPluginsContents.size) {
with(disabledPluginsFile.printWriter()) {
filteredContents.forEach(this::println)
}
}
}
body()
}
}
fun Project.intellijRootDir() = IntellijRootUtils.getIntellijRootDir(project)

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

@@ -34,6 +34,7 @@ dependencies {
testCompile(jpsBuildTest())
testRuntimeOnly(compile(intellijCoreDep()) { includeJars("intellij-core") })
testRuntimeOnly(compile(intellijDep()) { includeJars("jna", rootProject = rootProject) })
testCompile("org.junit.platform:junit-platform-launcher:${commonVer("org.junit.platform", "")}")
}

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

@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument
import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.kotlin.types.upperIfFlexible
import org.jetbrains.org.objectweb.asm.Type
@@ -51,7 +52,7 @@ class CallBasedArgumentGenerator(
callGenerator.putValueIfNeeded(
getJvmKotlinType(i),
StackValue.createDefaultValue(valueParameterTypes[i]),
ValueKind.DEFAULT_PARAMETER,
if (InlineUtil.isInlineParameter(valueParameters[i])) ValueKind.DEFAULT_INLINE_PARAMETER else ValueKind.DEFAULT_PARAMETER,
i
)
}

View File

@@ -15,9 +15,9 @@ enum class ValueKind {
GENERAL,
GENERAL_VARARG,
DEFAULT_PARAMETER,
DEFAULT_INLINE_PARAMETER,
DEFAULT_MASK,
METHOD_HANDLE_IN_DEFAULT,
CAPTURED,
NON_INLINEABLE_ARGUMENT_FOR_INLINE_PARAMETER_CALLED_IN_SUSPEND,
NON_INLINEABLE_ARGUMENT_FOR_INLINE_SUSPEND_PARAMETER
}

View File

@@ -27,24 +27,16 @@ import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.config.AnalysisFlags;
import org.jetbrains.kotlin.config.JvmAnalysisFlags;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.DescriptorUtilKt;
import org.jetbrains.kotlin.descriptors.ModuleDescriptor;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.load.kotlin.ModuleMappingUtilKt;
import org.jetbrains.kotlin.metadata.ProtoBuf;
import org.jetbrains.kotlin.metadata.jvm.JvmModuleProtoBuf;
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping;
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMappingKt;
import org.jetbrains.kotlin.metadata.jvm.deserialization.PackageParts;
import org.jetbrains.kotlin.metadata.serialization.StringTable;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.kotlin.serialization.StringTableImpl;
import org.jetbrains.org.objectweb.asm.Type;
@@ -52,7 +44,6 @@ import org.jetbrains.org.objectweb.asm.Type;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.getMappingFileName;
@@ -134,11 +125,6 @@ public class ClassFileFactory implements OutputFileCollection {
StringTableImpl stringTable = new StringTableImpl();
ClassFileUtilsKt.addDataFromCompiledModule(builder, packagePartRegistry, stringTable, state);
List<String> experimental = state.getLanguageVersionSettings().getFlag(AnalysisFlags.getExperimental());
if (!experimental.isEmpty()) {
writeExperimentalMarkers(state.getModule(), builder, experimental, stringTable);
}
Pair<ProtoBuf.StringTable, ProtoBuf.QualifiedNameTable> tables = stringTable.buildProto();
builder.setStringTable(tables.getFirst());
builder.setQualifiedNameTable(tables.getSecond());
@@ -162,26 +148,6 @@ public class ClassFileFactory implements OutputFileCollection {
});
}
private static void writeExperimentalMarkers(
@NotNull ModuleDescriptor module,
@NotNull JvmModuleProtoBuf.Module.Builder builder,
@NotNull List<String> experimental,
@NotNull StringTable stringTable
) {
for (String fqName : experimental) {
ClassDescriptor descriptor =
DescriptorUtilKt.resolveClassByFqName(module, new FqName(fqName), NoLookupLocation.FOR_ALREADY_TRACKED);
if (descriptor != null) {
ProtoBuf.Annotation.Builder annotation = ProtoBuf.Annotation.newBuilder();
ClassId classId = DescriptorUtilsKt.getClassId(descriptor);
if (classId != null) {
annotation.setId(stringTable.getQualifiedClassNameIndex(classId.asString(), false));
builder.addAnnotation(annotation);
}
}
}
}
@NotNull
@Override
public List<OutputFile> asList() {

View File

@@ -1264,7 +1264,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
// Thus, do not generate it. Otherwise, it leads to VerifyError on run-time.
boolean isCrossinlineLambda = (callGenerator instanceof PsiInlineCodegen) &&
Objects.requireNonNull(((PsiInlineCodegen) callGenerator).getActiveLambda(),
"no active lambda found").isCrossInline;
"no active lambda found").isCrossInline();
if (!isCrossinlineLambda) {
v.aconst(null);
}
@@ -2971,8 +2971,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (isDefaultCompilation) {
return new InlineCodegenForDefaultBody(functionDescriptor, this, state, signature, sourceCompiler);
} else {
return new PsiInlineCodegen(this, state, functionDescriptor, signature, typeParameterMappings, sourceCompiler,
typeMapper.mapImplementationOwner(functionDescriptor), typeMapper.mapOwner(descriptor));
return new PsiInlineCodegen(
this, state, functionDescriptor, signature, typeParameterMappings, sourceCompiler,
typeMapper.mapImplementationOwner(functionDescriptor), typeMapper.mapOwner(descriptor), callElement
);
}
}

View File

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

View File

@@ -136,8 +136,6 @@ class CoroutineTransformerMethodVisitor(
UninitializedStoresProcessor(methodNode, shouldPreserveClassInitialization).run()
updateLvtAccordingToLiveness(methodNode, isForNamedFunction)
val spilledToVariableMapping = spillVariables(suspensionPoints, methodNode)
val suspendMarkerVarIndex = methodNode.maxLocals++
@@ -194,6 +192,8 @@ class CoroutineTransformerMethodVisitor(
dropUnboxInlineClassMarkers(methodNode, suspensionPoints)
methodNode.removeEmptyCatchBlocks()
updateLvtAccordingToLiveness(methodNode, isForNamedFunction)
if (languageVersionSettings.isReleaseCoroutines()) {
writeDebugMetadata(methodNode, suspensionPointLineNumbers, spilledToVariableMapping)
}
@@ -791,19 +791,30 @@ class CoroutineTransformerMethodVisitor(
// Mutate method node
fun generateSpillAndUnspill(suspension: SuspensionPoint, slot: Int, spillableVariable: SpillableVariable?) {
if (spillableVariable == null) {
with(instructions) {
insert(suspension.tryCatchBlockEndLabelAfterSuspensionCall, withInstructionAdapter {
aconst(null)
store(slot, AsmTypes.OBJECT_TYPE)
})
fun splitLvtRecord(local: LocalVariableNode?, localRestart: LabelNode) {
// Split the local variable range for the local so that it is visible until the next state label, but is
// not visible until it has been unspilled from the continuation on the reentry path.
if (local != null) {
val previousEnd = local.end
local.end = suspension.stateLabel
// Add the local back, but end it at the next state label.
methodNode.localVariables.add(local)
// Add a new entry that starts after the local variable is restored from the continuation.
methodNode.localVariables.add(
LocalVariableNode(
local.name,
local.desc,
local.signature,
localRestart,
previousEnd,
local.index
)
)
}
return
}
// Find and remove the local variable node, if any, in the local variable table corresponding to the slot that is spilled.
var local: LocalVariableNode? = null
val localRestart = LabelNode().linkWithLabel()
val iterator = methodNode.localVariables.listIterator()
while (iterator.hasNext()) {
val node = iterator.next()
@@ -817,6 +828,19 @@ class CoroutineTransformerMethodVisitor(
}
}
if (spillableVariable == null) {
with(instructions) {
insert(suspension.tryCatchBlockEndLabelAfterSuspensionCall, withInstructionAdapter {
aconst(null)
store(slot, AsmTypes.OBJECT_TYPE)
})
}
val newStart = suspension.tryCatchBlocksContinuationLabel.findNextOrNull { it is LabelNode } as? LabelNode ?: return
splitLvtRecord(local, newStart)
return
}
val localRestart = LabelNode().linkWithLabel()
with(instructions) {
// store variable before suspension call
insertBefore(suspension.suspensionCallBegin, withInstructionAdapter {
@@ -846,25 +870,7 @@ class CoroutineTransformerMethodVisitor(
})
}
// Split the local variable range for the local so that it is visible until the next state label, but is
// not visible until it has been unspilled from the continuation on the reentry path.
if (local != null) {
val previousEnd = local.end
local.end = suspension.stateLabel
// Add the local back, but end it at the next state label.
methodNode.localVariables.add(local)
// Add a new entry that starts after the local variable is restored from the continuation.
methodNode.localVariables.add(
LocalVariableNode(
local.name,
local.desc,
local.signature,
localRestart,
previousEnd,
local.index
)
)
}
splitLvtRecord(local, localRestart)
}
fun cleanUpField(suspension: SuspensionPoint, fieldIndex: Int) {
@@ -1254,6 +1260,9 @@ internal fun replaceFakeContinuationsWithRealOnes(methodNode: MethodNode, contin
}
}
private fun MethodNode.nodeTextWithLiveness(liveness: List<VariableLivenessFrame>): String =
liveness.zip(this.instructions.asSequence().toList()).joinToString("\n") { (a, b) -> "$a|${b.insnText}" }
/* We do not want to spill dead variables, thus, we shrink its LVT record to region, where the variable is alive,
* so, the variable will not be visible in debugger. User can still prolong life span of the variable by using it.
*
@@ -1279,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
}
@@ -1288,17 +1297,15 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
fun min(a: LabelNode, b: LabelNode): LabelNode =
if (method.instructions.indexOf(a) < method.instructions.indexOf(b)) a else b
fun max(a: LabelNode, b: LabelNode): LabelNode =
if (method.instructions.indexOf(a) < method.instructions.indexOf(b)) b else a
val oldLvt = arrayListOf<LocalVariableNode>()
for (record in method.localVariables) {
oldLvt += record
}
method.localVariables.clear()
val oldLvtNodeToLatestNewLvtNode = mutableMapOf<LocalVariableNode, LocalVariableNode>()
// Skip `this` for suspend lambda
val start = if (isForNamedFunction) 0 else 1
val oldLvtNodeToLatestNewLvtNode = mutableMapOf<LocalVariableNode, LocalVariableNode>()
for (variableIndex in start until method.maxLocals) {
if (oldLvt.none { it.index == variableIndex }) continue
var startLabel: LabelNode? = null
@@ -1310,7 +1317,7 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
if (isAlive(insnIndex, variableIndex) && !isAlive(insnIndex + 1, variableIndex)) {
// No variable in LVT -> do not add one
val lvtRecord = oldLvt.findRecord(insnIndex, variableIndex) ?: continue
if (lvtRecord.name == CONTINUATION_VARIABLE_NAME) continue
if (lvtRecord.name == CONTINUATION_VARIABLE_NAME || lvtRecord.name == SUSPEND_CALL_RESULT_NAME) continue
// End the local when it is no longer live. Since it is not live, we will not spill and unspill it across
// suspension points. It is tempting to keep it alive until the next suspension point to leave it visible in
// the debugger for as long as possible. However, in the case of loops, the resumption after suspension can
@@ -1336,11 +1343,37 @@ 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)
if (lvtRecord !in oldLvtNodeToLatestNewLvtNode) {
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
}
oldLvtNodeToLatestNewLvtNode[lvtRecord] = node
}
}
}

View File

@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.codegen.coroutines
import org.jetbrains.kotlin.codegen.optimization.boxing.isUnitInstance
import org.jetbrains.kotlin.codegen.optimization.common.MethodAnalyzer
import org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
import org.jetbrains.kotlin.codegen.optimization.common.removeAll
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
@@ -85,7 +85,7 @@ private class UnitSourceInterpreter(private val localVariables: Set<Int>) : Basi
}
fun run(internalClassName: String, methodNode: MethodNode): Array<Frame<BasicValue>?> {
val frames = MethodAnalyzer<BasicValue>(internalClassName, methodNode, this).analyze()
val frames = FastMethodAnalyzer<BasicValue>(internalClassName, methodNode, this).analyze()
// The ASM analyzer does not visit POP instructions, so we do so here.
for ((insn, frame) in methodNode.instructions.asSequence().zip(frames.asSequence())) {
if (frame != null && insn.opcode == Opcodes.POP) {

View File

@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.codegen.coroutines
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.optimization.common.MethodAnalyzer
import org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes
@@ -130,11 +130,11 @@ internal fun performSpilledVariableFieldTypesAnalysis(
thisName: String
): Array<out Frame<BasicValue>?> {
val interpreter = IntLikeCoerceInterpreter()
MethodAnalyzer(thisName, methodNode, interpreter).analyze()
FastMethodAnalyzer(thisName, methodNode, interpreter).analyze()
for ((insn, type) in interpreter.needsToBeCoerced) {
methodNode.instructions.insert(insn, withInstructionAdapter { coerceInt(type, this) })
}
return MethodAnalyzer(thisName, methodNode, OptimizationBasicInterpreter()).analyze()
return FastMethodAnalyzer(thisName, methodNode, OptimizationBasicInterpreter()).analyze()
}
private fun coerceInt(to: Type, v: InstructionAdapter) {

View File

@@ -159,8 +159,8 @@ internal class MethodNodeExaminer(
* @return indices of safely reachable returns for each instruction in the method node
*/
private fun findSafelyReachableReturns(): Array<Set<Int>?> {
val insns = methodNode.instructions
val reachableReturnsIndices = Array(insns.size()) init@{ index ->
val insns = methodNode.instructions.toArray()
val reachableReturnsIndices = Array(insns.size) init@{ index ->
val insn = insns[index]
if (insn.opcode == Opcodes.ARETURN && !insn.isAreturnAfterSafeUnitInstance()) {
@@ -182,7 +182,7 @@ internal class MethodNodeExaminer(
var changed: Boolean
do {
changed = false
for (index in 0 until insns.size()) {
for (index in insns.indices.reversed()) {
if (insns[index].opcode == Opcodes.ARETURN) continue
@Suppress("RemoveExplicitTypeArguments")

View File

@@ -73,8 +73,8 @@ import kotlin.math.max
* - restore constructor arguments
*/
class UninitializedStoresProcessor(
private val methodNode: MethodNode,
private val shouldPreserveClassInitialization: Boolean
private val methodNode: MethodNode,
private val shouldPreserveClassInitialization: Boolean
) {
// <init> method is "special", because it will invoke <init> from this class or from a base class for #0
//
@@ -87,10 +87,10 @@ class UninitializedStoresProcessor(
fun run() {
val interpreter = UninitializedNewValueMarkerInterpreter(methodNode.instructions)
val frames = CustomFramesMethodAnalyzer(
"fake", methodNode, interpreter,
this::UninitializedNewValueFrame
).analyze()
if (methodNode.instructions.toArray().none { it.opcode == Opcodes.NEW })
return
val frames = CustomFramesMethodAnalyzer("fake", methodNode, interpreter, this::UninitializedNewValueFrame).analyze()
interpreter.analyzePopInstructions(frames)
@@ -115,12 +115,12 @@ class UninitializedStoresProcessor(
// POP
val typeNameForClass = newInsn.desc.replace('/', '.')
insertBefore(newInsn, LdcInsnNode(typeNameForClass))
insertBefore(newInsn, MethodInsnNode(
Opcodes.INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false
))
insertBefore(
newInsn,
MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Class", "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false)
)
set(newInsn, InsnNode(Opcodes.POP))
}
else {
} else {
remove(newInsn)
}
}
@@ -138,10 +138,7 @@ class UninitializedStoresProcessor(
}
methodNode.maxLocals = max(methodNode.maxLocals, nextVarIndex)
methodNode.instructions.insertBefore(insn, insnListOf(
TypeInsnNode(Opcodes.NEW, newInsn.desc),
InsnNode(Opcodes.DUP)
))
methodNode.instructions.insertBefore(insn, insnListOf(TypeInsnNode(Opcodes.NEW, newInsn.desc), InsnNode(Opcodes.DUP)))
for (type in storedTypes.reversed()) {
nextVarIndex -= type.size
@@ -174,11 +171,11 @@ class UninitializedStoresProcessor(
assert(insn.opcode == Opcodes.INVOKESPECIAL) { "Expected opcode Opcodes.INVOKESPECIAL for <init>, but ${insn.opcode} found" }
val paramsCountIncludingReceiver = Type.getArgumentTypes((insn as MethodInsnNode).desc).size + 1
val newValue = peek(paramsCountIncludingReceiver) as? UninitializedNewValue ?:
if (isInSpecialMethod)
return null
else
error("Expected value generated with NEW")
val newValue = peek(paramsCountIncludingReceiver) as? UninitializedNewValue
?: if (isInSpecialMethod)
return null
else
error("Expected value generated with NEW")
assert(peek(paramsCountIncludingReceiver - 1) is UninitializedNewValue) {
"Next value after NEW should be one generated by DUP"
@@ -188,8 +185,8 @@ class UninitializedStoresProcessor(
}
private class UninitializedNewValue(
val newInsn: TypeInsnNode,
val internalName: String
val newInsn: TypeInsnNode,
val internalName: String
) : StrictBasicValue(Type.getObjectType(internalName)) {
override fun toString() = "UninitializedNewValue(internalName='$internalName')"
}
@@ -236,7 +233,8 @@ class UninitializedStoresProcessor(
private fun checkUninitializedObjectCopy(newInsn: TypeInsnNode, usageInsn: AbstractInsnNode) {
when (usageInsn.opcode) {
Opcodes.DUP, Opcodes.ASTORE, Opcodes.ALOAD -> {}
Opcodes.DUP, Opcodes.ASTORE, Opcodes.ALOAD -> {
}
else -> error("Unexpected copy instruction for ${newInsn.debugText}: ${usageInsn.debugText}")
}
}

View File

@@ -295,7 +295,6 @@ class AnonymousObjectTransformer(
capturedBuilder: ParametersBuilder,
isConstructor: Boolean
): InlineResult {
val typeParametersToReify = inliningContext.root.inlineMethodReifier.reifyInstructions(sourceNode)
val parameters =
if (isConstructor) capturedBuilder.buildParameters() else getMethodParametersWithCaptured(capturedBuilder, sourceNode)
@@ -304,7 +303,10 @@ class AnonymousObjectTransformer(
transformationInfo.capturedLambdasToInline, parentRemapper, isConstructor
)
val inliner = MethodInliner(
val reifiedTypeParametersUsages = if (inliningContext.shouldReifyTypeParametersInObjects)
inliningContext.root.inlineMethodReifier.reifyInstructions(sourceNode)
else null
val result = MethodInliner(
sourceNode,
parameters,
inliningContext.subInline(transformationInfo.nameGenerator),
@@ -318,11 +320,10 @@ class AnonymousObjectTransformer(
inliningContext.callSiteInfo.isInlineOrInsideInline,
inliningContext.callSiteInfo.file,
inliningContext.callSiteInfo.lineNumber
), null
)
val result = inliner.doInline(deferringVisitor, LocalVarRemapper(parameters, 0), false, mapOf())
result.reifiedTypeParametersUsages.mergeAll(typeParametersToReify)
),
null
).doInline(deferringVisitor, LocalVarRemapper(parameters, 0), false, mapOf())
reifiedTypeParametersUsages?.let(result.reifiedTypeParametersUsages::mergeAll)
deferringVisitor.visitMaxs(-1, -1)
return result
}
@@ -421,11 +422,13 @@ class AnonymousObjectTransformer(
}
private fun getMethodParametersWithCaptured(capturedBuilder: ParametersBuilder, sourceNode: MethodNode): Parameters {
val builder = ParametersBuilder.initializeBuilderFrom(
oldObjectType,
sourceNode.desc,
isStatic = sourceNode.access and Opcodes.ACC_STATIC != 0
)
val builder = ParametersBuilder.newBuilder()
if (sourceNode.access and Opcodes.ACC_STATIC == 0) {
builder.addThis(oldObjectType, skipped = false)
}
for (type in Type.getArgumentTypes(sourceNode.desc)) {
builder.addNextParameter(type, false)
}
for (param in capturedBuilder.listCaptured()) {
builder.addCapturedParamCopy(param)
}

View File

@@ -33,9 +33,9 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
protected val invocationParamBuilder = ParametersBuilder.newBuilder()
protected val expressionMap = linkedMapOf<Int, FunctionalArgument>()
protected val maskValues = ArrayList<Int>()
protected var maskStartIndex = -1
protected var methodHandleInDefaultMethodIndex = -1
private val maskValues = ArrayList<Int>()
private var maskStartIndex = -1
private var methodHandleInDefaultMethodIndex = -1
protected fun generateStub(text: String, codegen: BaseExpressionCodegen) {
leaveTemps()
@@ -71,14 +71,25 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
private fun inlineCall(nodeAndSmap: SMAPAndMethodNode, isInlineOnly: Boolean): InlineResult {
val node = nodeAndSmap.node
if (maskStartIndex != -1) {
for (lambda in extractDefaultLambdas(node)) {
invocationParamBuilder.buildParameters().getParameterByDeclarationSlot(lambda.offset).functionalArgument = lambda
val prev = expressionMap.put(lambda.offset, lambda)
assert(prev == null) { "Lambda with offset ${lambda.offset} already exists: $prev" }
if (lambda.needReification) {
val parameters = invocationParamBuilder.buildParameters()
val infos = expandMaskConditionsAndUpdateVariableNodes(
node, maskStartIndex, maskValues, methodHandleInDefaultMethodIndex,
parameters.parameters.filter { it.functionalArgument === DefaultValueOfInlineParameter }
.mapTo(mutableSetOf()) { parameters.getDeclarationSlot(it) }
)
for (info in infos) {
val lambda = DefaultLambda(info, sourceCompiler)
parameters.getParameterByDeclarationSlot(info.offset).functionalArgument = lambda
val prev = expressionMap.put(info.offset, lambda)
assert(prev == null) { "Lambda with offset ${info.offset} already exists: $prev" }
if (info.needReification) {
lambda.reifiedTypeParametersUsages.mergeAll(reifiedTypeInliner.reifyInstructions(lambda.node.node))
}
rememberCapturedForDefaultLambda(lambda)
for (captured in lambda.capturedVars) {
val param = invocationParamBuilder.addCapturedParam(captured, captured.fieldName, false)
param.remapValue = StackValue.local(codegen.frameMap.enterTemp(param.type), param.type)
param.isSynthetic = true
}
}
}
@@ -121,7 +132,9 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
// In case `codegen.visitor` is `<clinit>`, initializer for the `$assertionsDisabled` field
// needs to be inserted before the code that actually uses it.
generateAssertFieldIfNeeded(info)
if (info.generateAssertField) {
generateAssertField()
}
val shouldSpillStack = node.requiresEmptyStackOnEntry()
if (shouldSpillStack) {
@@ -134,16 +147,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
return result
}
abstract fun extractDefaultLambdas(node: MethodNode): List<DefaultLambda>
protected inline fun <T> extractDefaultLambdas(
node: MethodNode, parameters: Map<Int, T>, block: ExtractedDefaultLambda.(T) -> DefaultLambda
): List<DefaultLambda> = expandMaskConditionsAndUpdateVariableNodes(
node, maskStartIndex, maskValues, methodHandleInDefaultMethodIndex, parameters.keys
).map {
it.block(parameters[it.offset]!!)
}
private fun generateAndInsertFinallyBlocks(
intoNode: MethodNode,
insertPoints: List<MethodInliner.PointForExternalFinallyBlocks>,
@@ -184,6 +187,9 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
val splitBy = SimpleInterval(start.info as LabelNode, extension.finallyIntervalEnd)
processor.tryBlocksMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true)
processor.localVarsMetaInfo.splitAndRemoveCurrentIntervals(splitBy, true)
finallyNode.localVariables.forEach {
processor.localVarsMetaInfo.addNewInterval(LocalVarNodeWrapper(it))
}
}
curInstr = curInstr.next
@@ -193,7 +199,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
processor.substituteLocalVarTable(intoNode)
}
protected abstract fun generateAssertFieldIfNeeded(info: RootInliningContext)
protected abstract fun generateAssertField()
private fun isInlinedToInlineFunInKotlinRuntime(): Boolean {
val codegen = this.codegen as? ExpressionCodegen ?: return false
@@ -236,10 +242,12 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
NonInlineableArgumentForInlineableParameterCalledInSuspend
ValueKind.NON_INLINEABLE_ARGUMENT_FOR_INLINE_SUSPEND_PARAMETER ->
NonInlineableArgumentForInlineableSuspendParameter
ValueKind.DEFAULT_INLINE_PARAMETER ->
DefaultValueOfInlineParameter
else -> null
}
when {
kind === ValueKind.DEFAULT_PARAMETER ->
kind === ValueKind.DEFAULT_PARAMETER || kind === ValueKind.DEFAULT_INLINE_PARAMETER ->
codegen.frameMap.enterTemp(info.type) // the inline function will put the value into this slot
stackValue.isLocalWithNoBoxing(jvmKotlinType) ->
info.remapValue = stackValue
@@ -258,14 +266,6 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
}
}
private fun rememberCapturedForDefaultLambda(defaultLambda: DefaultLambda) {
for (captured in defaultLambda.capturedVars) {
val info = invocationParamBuilder.addCapturedParam(captured, captured.fieldName, false)
info.remapValue = StackValue.local(codegen.frameMap.enterTemp(info.type), info.type)
info.isSynthetic = true
}
}
private fun processDefaultMaskOrMethodHandler(value: StackValue, kind: ValueKind) {
assert(value is StackValue.Constant) { "Additional default method argument should be constant, but $value" }
val constantValue = (value as StackValue.Constant).value

View File

@@ -44,8 +44,16 @@ open class InliningContext(
val lambdaInfo: LambdaInfo?,
val classRegeneration: Boolean
) {
val isInliningLambda
get() = lambdaInfo != null
val isInliningLambda = lambdaInfo != null
// Consider this arrangement:
// inline fun <reified T> f(x: () -> Unit = { /* uses `T` in a local class */ }) = x()
// inline fun <reified V> g() = f<...> { /* uses `V` in a local class */ }
// When inlining `f` into `g`, we need to reify the contents of the default for `x` (if it was used), but not the
// contents of the lambda passed as the argument in `g` as all reified type parameters used by the latter are not from `f`.
val shouldReifyTypeParametersInObjects: Boolean
get() = lambdaInfo == null || lambdaInfo is DefaultLambda
var generateAssertField = false
@@ -54,7 +62,8 @@ open class InliningContext(
var isContinuation: Boolean = false
val isRoot: Boolean = parent == null
val isRoot: Boolean
get() = parent == null
val root: RootInliningContext
get() = if (isRoot) this as RootInliningContext else parent!!.root

View File

@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.coroutines.isCoroutineSuperClass
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.org.objectweb.asm.ClassReader
@@ -16,12 +17,7 @@ import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
interface FunctionalArgument
abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgument {
abstract val isBoundCallableReference: Boolean
abstract val isSuspend: Boolean
abstract class LambdaInfo : FunctionalArgument {
abstract val lambdaClassType: Type
abstract val invokeMethod: Method
@@ -39,11 +35,17 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
val reifiedTypeParametersUsages = ReifiedTypeParametersUsages()
open val hasDispatchReceiver = true
open val hasDispatchReceiver
get() = true
fun addAllParameters(remapper: FieldRemapper): Parameters {
val builder = ParametersBuilder.initializeBuilderFrom(OBJECT_TYPE, invokeMethod.descriptor, this)
val builder = ParametersBuilder.newBuilder()
if (hasDispatchReceiver) {
builder.addThis(lambdaClassType, skipped = true).functionalArgument = this
}
for (type in Type.getArgumentTypes(invokeMethod.descriptor)) {
builder.addNextParameter(type, skipped = false)
}
for (info in capturedVars) {
val field = remapper.findField(FieldInsnNode(0, info.containingLambdaName, info.fieldName, ""))
?: error("Captured field not found: " + info.containingLambdaName + "." + info.fieldName)
@@ -65,76 +67,73 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : FunctionalArgu
object NonInlineableArgumentForInlineableParameterCalledInSuspend : FunctionalArgument
object NonInlineableArgumentForInlineableSuspendParameter : FunctionalArgument
object DefaultValueOfInlineParameter : FunctionalArgument
abstract class ExpressionLambda(isCrossInline: Boolean) : LambdaInfo(isCrossInline) {
abstract class ExpressionLambda : LambdaInfo() {
fun generateLambdaBody(sourceCompiler: SourceCompilerForInline) {
node = sourceCompiler.generateLambdaBody(this, reifiedTypeParametersUsages)
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
}
}
abstract class DefaultLambda(
final override val lambdaClassType: Type,
capturedArgs: Array<Type>,
isCrossinline: Boolean,
val offset: Int,
val needReification: Boolean,
sourceCompiler: SourceCompilerForInline
) : LambdaInfo(isCrossinline) {
final override val isSuspend
get() = false // TODO: it should probably be true sometimes, but it never was
final override val isBoundCallableReference: Boolean
final override val capturedVars: List<CapturedParamDesc>
class DefaultLambda(info: ExtractedDefaultLambda, sourceCompiler: SourceCompilerForInline) : LambdaInfo() {
val isBoundCallableReference: Boolean
final override val invokeMethod: Method
override val lambdaClassType: Type = info.type
override val capturedVars: List<CapturedParamDesc>
override val invokeMethod: Method
get() = Method(node.node.name, node.node.desc)
private val nullableAnyType = sourceCompiler.state.module.builtIns.nullableAnyType
override val invokeMethodParameters: List<KotlinType>
get() = List(invokeMethod.argumentTypes.size) { nullableAnyType }
override val invokeMethodReturnType: KotlinType
get() = nullableAnyType
val originalBoundReceiverType: Type?
protected val isPropertyReference: Boolean
protected val isFunctionReference: Boolean
init {
val classBytes = loadClass(sourceCompiler)
val classBytes =
sourceCompiler.state.inlineCache.classBytes.getOrPut(lambdaClassType.internalName) {
loadClassBytesByInternalName(sourceCompiler.state, lambdaClassType.internalName)
}
val superName = ClassReader(classBytes).superName
isPropertyReference = superName in PROPERTY_REFERENCE_SUPER_CLASSES
isFunctionReference = superName == FUNCTION_REFERENCE.internalName || superName == FUNCTION_REFERENCE_IMPL.internalName
val constructorDescriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *capturedArgs)
val constructor = getMethodNode(classBytes, "<init>", constructorDescriptor, lambdaClassType)?.node
assert(constructor != null || capturedArgs.isEmpty()) {
"Can't find non-default constructor <init>$constructorDescriptor for default lambda $lambdaClassType"
// TODO: suspend lambdas are their own continuations, so the body is pre-inlined into `invokeSuspend`
// and thus can't be detangled from the state machine. To make them inlinable, this needs to be redesigned.
// See `SuspendLambdaLowering`.
require(!sourceCompiler.state.languageVersionSettings.isCoroutineSuperClass(superName)) {
"suspend default lambda ${lambdaClassType.internalName} cannot be inlined; use a function reference instead"
}
val constructorMethod = Method("<init>", Type.VOID_TYPE, info.capturedArgs)
val constructor = getMethodNode(classBytes, lambdaClassType, constructorMethod)?.node
assert(constructor != null || info.capturedArgs.isEmpty()) {
"can't find constructor '$constructorMethod' for default lambda '${lambdaClassType.internalName}'"
}
val isPropertyReference = superName in PROPERTY_REFERENCE_SUPER_CLASSES
val isReference = isPropertyReference ||
superName == FUNCTION_REFERENCE.internalName || superName == FUNCTION_REFERENCE_IMPL.internalName
// This only works for primitives but not inline classes, since information about the Kotlin type of the bound
// receiver is not present anywhere. This is why with JVM_IR the constructor argument of bound references
// is already `Object`, and this field is never used.
originalBoundReceiverType =
capturedArgs.singleOrNull()?.takeIf { (isFunctionReference || isPropertyReference) && AsmUtil.isPrimitive(it) }
info.capturedArgs.singleOrNull()?.takeIf { isReference && AsmUtil.isPrimitive(it) }
capturedVars =
if (isFunctionReference || isPropertyReference)
capturedArgs.singleOrNull()?.let {
listOf(capturedParamDesc(AsmUtil.RECEIVER_PARAMETER_NAME, AsmUtil.boxType(it), isSuspend = false))
if (isReference)
info.capturedArgs.singleOrNull()?.let {
// See `InlinedLambdaRemapper`
listOf(capturedParamDesc(AsmUtil.RECEIVER_PARAMETER_NAME, OBJECT_TYPE, isSuspend = false))
} ?: emptyList()
else
constructor?.findCapturedFieldAssignmentInstructions()?.map { fieldNode ->
capturedParamDesc(fieldNode.name, Type.getType(fieldNode.desc), isSuspend = false)
}?.toList() ?: emptyList()
isBoundCallableReference = (isFunctionReference || isPropertyReference) && capturedVars.isNotEmpty()
}
private fun loadClass(sourceCompiler: SourceCompilerForInline): ByteArray =
sourceCompiler.state.inlineCache.classBytes.getOrPut(lambdaClassType.internalName) {
loadClassBytesByInternalName(sourceCompiler.state, lambdaClassType.internalName)
}
// Returns whether the loaded invoke is erased, i.e. the name equals the fallback and all types are `Object`.
protected fun loadInvoke(sourceCompiler: SourceCompilerForInline, erasedName: String, actualMethod: Method): Boolean {
val classBytes = loadClass(sourceCompiler)
// TODO: `signatureAmbiguity = true` ignores the argument types from `invokeMethod` and only looks at the count.
node = getMethodNode(classBytes, actualMethod.name, actualMethod.descriptor, lambdaClassType, signatureAmbiguity = true)
?: getMethodNode(classBytes, erasedName, actualMethod.descriptor, lambdaClassType, signatureAmbiguity = true)
?: error("Can't find method '$actualMethod' in '${lambdaClassType.internalName}'")
return invokeMethod.run { name == erasedName && returnType == OBJECT_TYPE && argumentTypes.all { it == OBJECT_TYPE } }
isBoundCallableReference = isReference && capturedVars.isNotEmpty()
node = loadDefaultLambdaBody(classBytes, lambdaClassType, isPropertyReference)
}
private companion object {

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.fixStack.peek
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.codegen.optimization.common.*
import org.jetbrains.kotlin.codegen.optimization.fixStack.*
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNotNull
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
import org.jetbrains.kotlin.config.LanguageFeature
@@ -36,8 +32,6 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.LocalVariablesSorter
import org.jetbrains.org.objectweb.asm.commons.MethodRemapper
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicInterpreter
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.util.Printer
import java.util.*
@@ -57,8 +51,10 @@ class MethodInliner(
) {
private val languageVersionSettings = inliningContext.state.languageVersionSettings
private val invokeCalls = ArrayList<InvokeCall>()
//keeps order
private val transformations = ArrayList<TransformationInfo>()
//current state
private val currentTypeMapping = HashMap<String, String?>()
private val result = InlineResult.create()
@@ -92,10 +88,6 @@ class MethodInliner(
): InlineResult {
//analyze body
var transformedNode = markPlacesForInlineAndRemoveInlinable(node, returnLabels, finallyDeepShift)
if (inliningContext.isInliningLambda && isDefaultLambdaWithReification(inliningContext.lambdaInfo!!)) {
//TODO maybe move reification in one place
inliningContext.root.inlineMethodReifier.reifyInstructions(transformedNode)
}
//substitute returns with "goto end" instruction to keep non local returns in lambdas
val end = linkedLabel()
@@ -232,7 +224,7 @@ class MethodInliner(
val expectedParameters = info.invokeMethod.argumentTypes
val expectedKotlinParameters = info.invokeMethodParameters
val argumentCount = Type.getArgumentTypes(desc).size.let {
if (!inliningContext.root.state.isIrBackend && info.isSuspend && it < expectedParameters.size) {
if (info is PsiExpressionLambda && info.invokeMethodDescriptor.isSuspend && it < expectedParameters.size) {
// Inlining suspend lambda into a function that takes a non-suspend lambda.
// In the IR backend, this cannot happen as inline lambdas are not lowered.
addFakeContinuationMarker(this)
@@ -277,7 +269,8 @@ class MethodInliner(
val varRemapper = LocalVarRemapper(lambdaParameters, valueParamShift)
//TODO add skipped this and receiver
val lambdaResult = inliner.doInline(localVariablesSorter, varRemapper, true, info.returnLabels, invokeCall.finallyDepthShift)
val lambdaResult =
inliner.doInline(localVariablesSorter, varRemapper, true, info.returnLabels, invokeCall.finallyDepthShift)
result.mergeWithNotChangeInfo(lambdaResult)
result.reifiedTypeParametersUsages.mergeAll(lambdaResult.reifiedTypeParametersUsages)
result.reifiedTypeParametersUsages.mergeAll(info.reifiedTypeParametersUsages)
@@ -307,7 +300,7 @@ class MethodInliner(
} else capturedParamDesc
visitFieldInsn(
Opcodes.GETSTATIC, realDesc.containingLambdaName,
FieldRemapper.foldName(realDesc.fieldName), realDesc.type.descriptor
foldName(realDesc.fieldName), realDesc.type.descriptor
)
}
super.visitMethodInsn(opcode, info.newClassName, name, info.newConstructorDescriptor, itf)
@@ -321,10 +314,11 @@ class MethodInliner(
} else {
super.visitMethodInsn(opcode, owner, name, desc, itf)
}
} else if ((!inliningContext.isInliningLambda || isDefaultLambdaWithReification(inliningContext.lambdaInfo!!)) &&
ReifiedTypeInliner.isNeedClassReificationMarker(MethodInsnNode(opcode, owner, name, desc, false))
) {
//we shouldn't process here content of inlining lambda it should be reified at external level except default lambdas
} else if (ReifiedTypeInliner.isNeedClassReificationMarker(MethodInsnNode(opcode, owner, name, desc, false))) {
// If objects are reified, the marker will be recreated by `handleAnonymousObjectRegeneration` above.
if (!inliningContext.shouldReifyTypeParametersInObjects) {
super.visitMethodInsn(opcode, owner, name, desc, itf)
}
} else {
super.visitMethodInsn(opcode, owner, name, desc, itf)
}
@@ -349,9 +343,6 @@ class MethodInliner(
return resultNode
}
private fun isDefaultLambdaWithReification(lambdaInfo: LambdaInfo) =
lambdaInfo is DefaultLambda && lambdaInfo.needReification
private fun prepareNode(node: MethodNode, finallyDeepShift: Int): MethodNode {
node.instructions.resetLabels()
@@ -381,10 +372,7 @@ class MethodInliner(
private fun getNewIndex(`var`: Int): Int {
val lambdaInfo = inliningContext.lambdaInfo
if (reorderIrLambdaParameters && lambdaInfo is IrExpressionLambda) {
val extensionSize =
if (lambdaInfo.isExtensionLambda && !lambdaInfo.isBoundCallableReference)
lambdaInfo.invokeMethod.argumentTypes[0].size
else 0
val extensionSize = if (lambdaInfo.isExtensionLambda) lambdaInfo.invokeMethod.argumentTypes[0].size else 0
return when {
// v-- extensionSize v-- argsSizeOnStack
// |- extension -|- captured -|- real -|- locals -| old descriptor
@@ -450,7 +438,7 @@ class MethodInliner(
else -> ""
}
val varName = if (!varSuffix.isEmpty() && name == AsmUtil.THIS) AsmUtil.INLINE_DECLARATION_SITE_THIS else name
val varName = if (varSuffix.isNotEmpty() && name == AsmUtil.THIS) AsmUtil.INLINE_DECLARATION_SITE_THIS else name
super.visitLocalVariable(varName + varSuffix, desc, signature, start, end, getNewIndex(index))
}
}
@@ -542,36 +530,36 @@ class MethodInliner(
cur.opcode == Opcodes.GETSTATIC -> {
val fieldInsnNode = cur as FieldInsnNode?
val className = fieldInsnNode!!.owner
if (isAnonymousSingletonLoad(className, fieldInsnNode.name)) {
recordTransformation(
AnonymousObjectTransformationInfo(
className, awaitClassReification, isAlreadyRegenerated(className), true,
inliningContext.nameGenerator
when {
isAnonymousSingletonLoad(className, fieldInsnNode.name) -> {
recordTransformation(
AnonymousObjectTransformationInfo(
className, awaitClassReification, isAlreadyRegenerated(className), true,
inliningContext.nameGenerator
)
)
)
awaitClassReification = false
} else if (isWhenMappingAccess(className, fieldInsnNode.name)) {
recordTransformation(
WhenMappingTransformationInfo(
className, inliningContext.nameGenerator, isAlreadyRegenerated(className), fieldInsnNode
awaitClassReification = false
}
isWhenMappingAccess(className, fieldInsnNode.name) -> {
recordTransformation(
WhenMappingTransformationInfo(
className, inliningContext.nameGenerator, isAlreadyRegenerated(className), fieldInsnNode
)
)
)
} else if (fieldInsnNode.isCheckAssertionsStatus()) {
fieldInsnNode.owner = inlineCallSiteInfo.ownerClassName
if (inliningContext.isInliningLambda) {
if (inliningContext.lambdaInfo!!.isCrossInline) {
assert(inliningContext.parent?.parent is RegeneratedClassContext) {
"$inliningContext grandparent shall be RegeneratedClassContext but got ${inliningContext.parent?.parent}"
}
inliningContext.parent!!.parent!!.generateAssertField = true
} else {
assert(inliningContext.parent != null) {
"$inliningContext parent shall not be null"
}
inliningContext.parent!!.generateAssertField = true
}
} else {
inliningContext.generateAssertField = true
}
fieldInsnNode.isCheckAssertionsStatus() -> {
fieldInsnNode.owner = inlineCallSiteInfo.ownerClassName
when {
// In inline function itself:
inliningContext.parent == null -> inliningContext
// In method of regenerated object - field should already exist:
inliningContext.parent is RegeneratedClassContext -> inliningContext.parent
// In lambda inlined into the root function:
inliningContext.parent.parent == null -> inliningContext.parent
// In lambda inlined into a method of a regenerated object:
else -> inliningContext.parent.parent as? RegeneratedClassContext
?: throw AssertionError("couldn't find class for \$assertionsDisabled (context = $inliningContext)")
}.generateAssertField = true
}
}
}
@@ -601,7 +589,7 @@ class MethodInliner(
assert(lambdaInfo.lambdaClassType.internalName == nodeRemapper.originalLambdaInternalName) {
"Wrong bytecode template for contract template: ${lambdaInfo.lambdaClassType.internalName} != ${nodeRemapper.originalLambdaInternalName}"
}
fieldInsn.name = FieldRemapper.foldName(fieldInsn.name)
fieldInsn.name = foldName(fieldInsn.name)
fieldInsn.opcode = Opcodes.PUTSTATIC
toDelete.addAll(stackTransformations)
}
@@ -641,9 +629,8 @@ class MethodInliner(
private fun replaceContinuationAccessesWithFakeContinuationsIfNeeded(processingNode: MethodNode) {
// in ir backend inline suspend lambdas do not use ALOAD 0 to get continuation, since they are generated as static functions
// instead they get continuation from parameter.
if (inliningContext.state.isIrBackend) return
val lambdaInfo = inliningContext.lambdaInfo ?: return
if (!lambdaInfo.isSuspend) return
if (lambdaInfo !is PsiExpressionLambda || !lambdaInfo.invokeMethodDescriptor.isSuspend) return
val sources = analyzeMethodNodeWithInterpreter(processingNode, Aload0Interpreter(processingNode))
val cfg = ControlFlowGraph.build(processingNode)
val aload0s = processingNode.instructions.asSequence().filter { it.opcode == Opcodes.ALOAD && it.safeAs<VarInsnNode>()?.`var` == 0 }
@@ -756,7 +743,9 @@ class MethodInliner(
ApiVersionCallsPreprocessingMethodTransformer(targetApiVersion).transform("fake", node)
}
val frames = analyzeMethodNodeWithInterpreter(node, BasicInterpreter())
removeFakeVariablesInitializationIfPresent(node)
val frames = FastStackAnalyzer("<fake>", node, FixStackInterpreter()).analyze()
val localReturnsNormalizer = LocalReturnsNormalizer()
@@ -778,6 +767,73 @@ class MethodInliner(
localReturnsNormalizer.transform(node)
}
private fun removeFakeVariablesInitializationIfPresent(node: MethodNode) {
// Before 1.6, we generated fake variable initialization instructions
// ICONST_0
// ISTORE x
// for all inline functions. Original intent was to mark inline function body for the debugger with corresponding LVT entry.
// However, for @InlineOnly functions corresponding LVT entries were not copied (assuming that nobody is actually debugging
// @InlineOnly functions).
// Since 1.6, we no longer generate fake variables for @InlineOnly functions
// Here we erase fake variable initialization for @InlineOnly functions inlined into existing bytecode (e.g., inline function
// inside third-party library).
// We consider a sequence of instructions 'ICONST_0; ISTORE x' a fake variable initialization if the corresponding variable 'x'
// is not used in the bytecode (see below).
val insnArray = node.instructions.toArray()
// Very conservative variable usage check.
// Here we look at integer variables only (this includes integral primitive types: byte, char, short, boolean).
// Variable is considered "used" if:
// - it's loaded with ILOAD instruction
// - it's incremented with IINC instruction
// - there's a local variable table entry for this variable
val usedIntegerVar = BooleanArray(node.maxLocals)
for (insn in insnArray) {
if (insn.type == AbstractInsnNode.VAR_INSN && insn.opcode == Opcodes.ILOAD) {
usedIntegerVar[(insn as VarInsnNode).`var`] = true
} else if (insn.type == AbstractInsnNode.IINC_INSN) {
usedIntegerVar[(insn as IincInsnNode).`var`] = true
}
}
for (localVariable in node.localVariables) {
val d0 = localVariable.desc[0]
// byte || char || short || int || boolean
if (d0 == 'B' || d0 == 'C' || d0 == 'S' || d0 == 'I' || d0 == 'Z') {
usedIntegerVar[localVariable.index] = true
}
}
// Looking for sequences of instructions:
// p0: ICONST_0
// p1: ISTORE x
// p2: <label>
// If variable 'x' is not "used" (see above), remove p0 and p1 instructions.
var changes = false
for (p0 in insnArray) {
if (p0.opcode != Opcodes.ICONST_0) continue
val p1 = p0.next ?: break
if (p1.opcode != Opcodes.ISTORE) continue
val p2 = p1.next ?: break
if (p2.type != AbstractInsnNode.LABEL) continue
val varIndex = (p1 as VarInsnNode).`var`
if (!usedIntegerVar[varIndex]) {
changes = true
node.instructions.remove(p0)
node.instructions.remove(p1)
}
}
if (changes) {
// If we removed some instructions, some TCBs could (in theory) become empty.
// Remove empty TCBs if there are any.
node.removeEmptyCatchBlocks()
}
}
private fun isAnonymousClassThatMustBeRegenerated(type: Type?): Boolean {
if (type == null || type.sort != Type.OBJECT) return false
return inliningContext.isRegeneratedAnonymousObject(type.internalName)
@@ -845,9 +901,9 @@ class MethodInliner(
if (inliningContext.isInliningLambda && inliningContext.lambdaInfo is IrExpressionLambda && !inliningContext.parent!!.isInliningLambda) {
val capturedVars = inliningContext.lambdaInfo.capturedVars
var offset = parameters.realParametersSizeOnStack
val map = capturedVars.map {
val map = capturedVars.associate {
offset to it.also { offset += it.type.size }
}.toMap()
}
var cur: AbstractInsnNode? = node.instructions.first
while (cur != null) {
@@ -892,6 +948,7 @@ class MethodInliner(
}
}
@Suppress("SameParameterValue")
private fun wrapException(originalException: Throwable, node: MethodNode, errorSuffix: String): RuntimeException {
return if (originalException is InlineException) {
InlineException("$errorPrefix: $errorSuffix", originalException)
@@ -904,7 +961,7 @@ class MethodInliner(
private class LocalReturn(
private val returnInsn: AbstractInsnNode,
private val insertBeforeInsn: AbstractInsnNode,
private val frame: Frame<BasicValue>
private val frame: Frame<FixStackValue>
) {
fun transform(insnList: InsnList, returnVariableIndex: Int) {
@@ -915,22 +972,19 @@ class MethodInliner(
if (expectedStackSize == actualStackSize) return
var stackSize = actualStackSize
val topValue = frame.getStack(stackSize - 1)
if (isReturnWithValue) {
val storeOpcode = Opcodes.ISTORE + returnInsn.opcode - Opcodes.IRETURN
insnList.insertBefore(insertBeforeInsn, VarInsnNode(storeOpcode, returnVariableIndex))
insnList.insertBefore(insertBeforeInsn, VarInsnNode(topValue.storeOpcode, returnVariableIndex))
stackSize--
}
while (stackSize > 0) {
val stackElementSize = frame.getStack(stackSize - 1).size
val popOpcode = if (stackElementSize == 1) Opcodes.POP else Opcodes.POP2
insnList.insertBefore(insertBeforeInsn, InsnNode(popOpcode))
insnList.insertBefore(insertBeforeInsn, InsnNode(frame.getStack(stackSize - 1).popOpcode))
stackSize--
}
if (isReturnWithValue) {
val loadOpcode = Opcodes.ILOAD + returnInsn.opcode - Opcodes.IRETURN
insnList.insertBefore(insertBeforeInsn, VarInsnNode(loadOpcode, returnVariableIndex))
insnList.insertBefore(insertBeforeInsn, VarInsnNode(topValue.loadOpcode, returnVariableIndex))
}
}
}
@@ -940,10 +994,10 @@ class MethodInliner(
private var returnVariableSize = 0
private var returnOpcode = -1
internal fun addLocalReturnToTransform(
fun addLocalReturnToTransform(
returnInsn: AbstractInsnNode,
insertBeforeInsn: AbstractInsnNode,
sourceValueFrame: Frame<BasicValue>
sourceValueFrame: Frame<FixStackValue>
) {
assert(isReturnOpcode(returnInsn.opcode)) { "return instruction expected" }
assert(returnOpcode < 0 || returnOpcode == returnInsn.opcode) { "Return op should be " + Printer.OPCODES[returnOpcode] + ", got " + Printer.OPCODES[returnInsn.opcode] }
@@ -952,11 +1006,7 @@ class MethodInliner(
localReturns.add(LocalReturn(returnInsn, insertBeforeInsn, sourceValueFrame))
if (returnInsn.opcode != Opcodes.RETURN) {
returnVariableSize = if (returnInsn.opcode == Opcodes.LRETURN || returnInsn.opcode == Opcodes.DRETURN) {
2
} else {
1
}
returnVariableSize = if (returnInsn.opcode == Opcodes.LRETURN || returnInsn.opcode == Opcodes.DRETURN) 2 else 1
}
}

View File

@@ -5,11 +5,11 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNotNull
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
@@ -17,15 +17,6 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.VarInsnNode
import org.jetbrains.org.objectweb.asm.tree.analysis.*
fun parameterOffsets(isStatic: Boolean, valueParameters: List<JvmMethodParameterSignature>): Array<Int> {
var nextOffset = if (isStatic) 0 else 1
return Array(valueParameters.size) { index ->
nextOffset.also {
nextOffset += valueParameters[index].asmType.size
}
}
}
fun MethodNode.remove(instructions: Sequence<AbstractInsnNode>) =
instructions.forEach {
this@remove.instructions.remove(it)
@@ -136,7 +127,7 @@ internal class Aload0Interpreter(private val node: MethodNode) : BasicInterprete
internal fun AbstractInsnNode.isAload0() = opcode == Opcodes.ALOAD && (this as VarInsnNode).`var` == 0
internal fun analyzeMethodNodeWithInterpreter(node: MethodNode, interpreter: BasicInterpreter): Array<out Frame<BasicValue>?> {
val analyzer = object : Analyzer<BasicValue>(interpreter) {
val analyzer = object : FastMethodAnalyzer<BasicValue>("fake", node, interpreter) {
override fun newFrame(nLocals: Int, nStack: Int): Frame<BasicValue> {
return object : Frame<BasicValue>(nLocals, nStack) {
@@ -151,7 +142,7 @@ internal fun analyzeMethodNodeWithInterpreter(node: MethodNode, interpreter: Bas
}
try {
return analyzer.analyze("fake", node)
return analyzer.analyze()
} catch (e: AnalyzerException) {
throw RuntimeException(e)
}

View File

@@ -107,22 +107,5 @@ class ParametersBuilder private constructor() {
fun newBuilder(): ParametersBuilder {
return ParametersBuilder()
}
@JvmOverloads
@JvmStatic
fun initializeBuilderFrom(
objectType: Type, descriptor: String, inlineLambda: LambdaInfo? = null, isStatic: Boolean = false
): ParametersBuilder {
val builder = newBuilder()
if (inlineLambda?.hasDispatchReceiver != false && !isStatic) {
//skipped this for inlined lambda cause it will be removed
builder.addThis(objectType, inlineLambda != null).functionalArgument = inlineLambda
}
for (type in Type.getArgumentTypes(descriptor)) {
builder.addNextParameter(type, false)
}
return builder
}
}
}

View File

@@ -5,16 +5,13 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getMethodAsmFlags
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.coroutines.getOrCreateJvmSuspendFunctionView
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
@@ -28,12 +25,9 @@ import org.jetbrains.kotlin.resolve.inline.isInlineOnly
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.tree.MethodNode
class PsiInlineCodegen(
codegen: ExpressionCodegen,
@@ -43,19 +37,17 @@ class PsiInlineCodegen(
typeParameterMappings: TypeParameterMappings<KotlinType>,
sourceCompiler: SourceCompilerForInline,
private val methodOwner: Type,
private val actualDispatchReceiver: Type
private val actualDispatchReceiver: Type,
reportErrorsOn: KtElement,
) : InlineCodegen<ExpressionCodegen>(
codegen, state, signature, typeParameterMappings, sourceCompiler,
ReifiedTypeInliner(
typeParameterMappings, PsiInlineIntrinsicsSupport(state), codegen.typeSystem,
typeParameterMappings, PsiInlineIntrinsicsSupport(state, reportErrorsOn), codegen.typeSystem,
state.languageVersionSettings, state.unifiedNullChecks
),
), CallGenerator {
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
if (info.generateAssertField) {
codegen.parentCodegen.generateAssertField()
}
}
override fun generateAssertField() =
codegen.parentCodegen.generateAssertField()
override fun genCallInner(
callableMethod: Callable,
@@ -97,8 +89,7 @@ class PsiInlineCodegen(
private val hiddenParameters = mutableListOf<Pair<ParameterInfo, Int>>()
override fun processHiddenParameters() {
val contextKind = (sourceCompiler as PsiSourceCompilerForInline).context.contextKind
if (getMethodAsmFlags(functionDescriptor, contextKind, state) and Opcodes.ACC_STATIC == 0) {
if (!DescriptorAsmUtil.isStaticMethod((sourceCompiler as PsiSourceCompilerForInline).context.contextKind, functionDescriptor)) {
hiddenParameters += invocationParamBuilder.addNextParameter(methodOwner, false, actualDispatchReceiver) to
codegen.frameMap.enterTemp(methodOwner)
}
@@ -120,14 +111,6 @@ class PsiInlineCodegen(
hiddenParameters.clear()
}
/*lambda or callable reference*/
private fun isInliningParameter(expression: KtExpression, valueParameterDescriptor: ValueParameterDescriptor): Boolean {
//TODO deparenthesize typed
val deparenthesized = KtPsiUtil.deparenthesize(expression)
return InlineUtil.isInlineParameter(valueParameterDescriptor) && isInlinableParameterExpression(deparenthesized)
}
override fun genValueAndPut(
valueParameterDescriptor: ValueParameterDescriptor?,
argumentExpression: KtExpression,
@@ -139,7 +122,9 @@ class PsiInlineCodegen(
"which cannot be declared in Kotlin and thus be inline: $codegen"
}
if (isInliningParameter(argumentExpression, valueParameterDescriptor)) {
val isInlineParameter = InlineUtil.isInlineParameter(valueParameterDescriptor)
//TODO deparenthesize typed
if (isInlineParameter && isInlinableParameterExpression(KtPsiUtil.deparenthesize(argumentExpression))) {
rememberClosure(argumentExpression, parameterType.type, valueParameterDescriptor)
} else {
val value = codegen.gen(argumentExpression)
@@ -184,7 +169,7 @@ class PsiInlineCodegen(
}
}
var activeLambda: LambdaInfo? = null
var activeLambda: PsiExpressionLambda? = null
private set
private fun putClosureParametersOnStack(next: PsiExpressionLambda, receiverValue: StackValue?) {
@@ -200,11 +185,6 @@ class PsiInlineCodegen(
putCapturedToLocalVal(stackValue, activeLambda!!.capturedVars[paramIndex], stackValue.kotlinType)
override fun reorderArgumentsIfNeeded(actualArgsWithDeclIndex: List<ArgumentAndDeclIndex>, valueParameterTypes: List<Type>) = Unit
override fun extractDefaultLambdas(node: MethodNode): List<DefaultLambda> =
extractDefaultLambdas(node, extractDefaultLambdaOffsetAndDescriptor(jvmSignature, functionDescriptor)) { parameter ->
PsiDefaultLambda(type, capturedArgs, parameter, offset, needReification, sourceCompiler)
}
}
private val FunctionDescriptor.explicitParameters
@@ -213,9 +193,9 @@ private val FunctionDescriptor.explicitParameters
class PsiExpressionLambda(
expression: KtExpression,
private val state: GenerationState,
isCrossInline: Boolean,
override val isBoundCallableReference: Boolean
) : ExpressionLambda(isCrossInline) {
val isCrossInline: Boolean,
val isBoundCallableReference: Boolean
) : ExpressionLambda() {
override val lambdaClassType: Type
override val invokeMethod: Method
@@ -224,7 +204,7 @@ class PsiExpressionLambda(
override val invokeMethodParameters: List<KotlinType?>
get() {
val actualInvokeDescriptor = if (isSuspend)
val actualInvokeDescriptor = if (invokeMethodDescriptor.isSuspend)
getOrCreateJvmSuspendFunctionView(invokeMethodDescriptor, state)
else
invokeMethodDescriptor
@@ -242,8 +222,6 @@ class PsiExpressionLambda(
override val returnLabels: Map<String, Label?>
override val isSuspend: Boolean
val closure: CalculatedClosure
init {
@@ -272,7 +250,6 @@ class PsiExpressionLambda(
?: throw AssertionError("null closure for lambda ${expression.text}")
returnLabels = getDeclarationLabels(expression, invokeMethodDescriptor).associateWith { null }
invokeMethod = state.typeMapper.mapAsmMethod(invokeMethodDescriptor)
isSuspend = invokeMethodDescriptor.isSuspend
}
// This can only be computed after generating the body, hence `lazy`.
@@ -303,32 +280,3 @@ class PsiExpressionLambda(
val isPropertyReference: Boolean
get() = propertyReferenceInfo != null
}
class PsiDefaultLambda(
lambdaClassType: Type,
capturedArgs: Array<Type>,
parameterDescriptor: ValueParameterDescriptor,
offset: Int,
needReification: Boolean,
sourceCompiler: SourceCompilerForInline
) : DefaultLambda(lambdaClassType, capturedArgs, parameterDescriptor.isCrossinline, offset, needReification, sourceCompiler) {
private val invokeMethodDescriptor: FunctionDescriptor
override val invokeMethodParameters: List<KotlinType?>
get() = invokeMethodDescriptor.explicitParameters.map { it.returnType }
override val invokeMethodReturnType: KotlinType?
get() = invokeMethodDescriptor.returnType
init {
val name = if (isPropertyReference) OperatorNameConventions.GET else OperatorNameConventions.INVOKE
val descriptor = parameterDescriptor.type.memberScope
.getContributedFunctions(OperatorNameConventions.INVOKE, NoLookupLocation.FROM_BACKEND)
.single()
.let { if (parameterDescriptor.type.isSuspendFunctionType) getOrCreateJvmSuspendFunctionView(it, sourceCompiler.state) else it }
// This is technically wrong as it always uses `invoke`, but `loadInvoke` will fall back to `get` which is never mangled...
val asmMethod = sourceCompiler.state.typeMapper.mapAsmMethod(descriptor)
val invokeIsErased = loadInvoke(sourceCompiler, name.asString(), asmMethod)
invokeMethodDescriptor = if (invokeIsErased) descriptor.original else descriptor
}
}

View File

@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.state.GenerationState
@@ -12,8 +13,12 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.*
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.model.TypeParameterMarker
import org.jetbrains.org.objectweb.asm.Type
@@ -21,7 +26,10 @@ import org.jetbrains.org.objectweb.asm.Type.INT_TYPE
import org.jetbrains.org.objectweb.asm.Type.VOID_TYPE
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
class PsiInlineIntrinsicsSupport(override val state: GenerationState) : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
class PsiInlineIntrinsicsSupport(
override val state: GenerationState,
private val reportErrorsOn: KtElement,
) : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
override fun putClassInstance(v: InstructionAdapter, type: KotlinType) {
DescriptorAsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper)
}
@@ -64,4 +72,20 @@ class PsiInlineIntrinsicsSupport(override val state: GenerationState) : ReifiedT
}
override fun toKotlinType(type: KotlinType): KotlinType = type
override fun checkAnnotatedType(type: KotlinType) {
if (type.annotations.hasAnnotation(StandardNames.FqNames.extensionFunctionType)) {
state.diagnostics.report(TYPEOF_EXTENSION_FUNCTION_TYPE.on(reportErrorsOn))
} else if (type.annotations.any { it.fqName != JvmAnnotationNames.ENHANCED_NULLABILITY_ANNOTATION }) {
state.diagnostics.report(TYPEOF_ANNOTATED_TYPE.on(reportErrorsOn))
}
}
override fun reportSuspendTypeUnsupported() {
state.diagnostics.report(TYPEOF_SUSPEND_TYPE.on(reportErrorsOn))
}
override fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name) {
state.diagnostics.report(TYPEOF_NON_REIFIED_TYPE_PARAMETER_WITH_RECURSIVE_BOUND.on(reportErrorsOn, typeParameterName.asString()))
}
}

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

@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.isReleaseCoroutines
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
@@ -73,6 +74,10 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
fun isMutableCollectionType(type: KT): Boolean
fun toKotlinType(type: KT): KotlinType
fun checkAnnotatedType(type: KT)
fun reportSuspendTypeUnsupported()
fun reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameterName: Name)
}
companion object {

View File

@@ -78,12 +78,12 @@ fun loadCompiledInlineFunction(
state: GenerationState
): SMAPAndMethodNode {
val containerType = AsmUtil.asmTypeByClassId(containerId)
val bytes = state.inlineCache.classBytes.getOrPut(containerType.internalName) {
findVirtualFile(state, containerId)?.contentsToByteArray()
?: throw IllegalStateException("Couldn't find declaration file for $containerId")
}
val resultInCache = state.inlineCache.methodNodeById.getOrPut(MethodId(containerType.descriptor, asmMethod)) {
getMethodNode(containerType, bytes, asmMethod.name, asmMethod.descriptor, isSuspend, isMangled)
val bytes = state.inlineCache.classBytes.getOrPut(containerType.internalName) {
findVirtualFile(state, containerId)?.contentsToByteArray()
?: throw IllegalStateException("Couldn't find declaration file for $containerId")
}
getMethodNode(containerType, bytes, asmMethod, isSuspend, isMangled)
}
return SMAPAndMethodNode(cloneMethodNode(resultInCache.node), resultInCache.classSMAP)
}
@@ -91,25 +91,24 @@ fun loadCompiledInlineFunction(
private fun getMethodNode(
owner: Type,
bytes: ByteArray,
name: String,
descriptor: String,
method: Method,
isSuspend: Boolean,
isMangled: Boolean
): SMAPAndMethodNode {
getMethodNode(owner, bytes, name, descriptor, isSuspend)?.let { return it }
getMethodNode(owner, bytes, method, isSuspend)?.let { return it }
if (isMangled) {
// Compatibility with old inline class ABI versions.
val dashIndex = name.indexOf('-')
val nameWithoutManglingSuffix = if (dashIndex > 0) name.substring(0, dashIndex) else name
if (nameWithoutManglingSuffix != name) {
getMethodNode(owner, bytes, nameWithoutManglingSuffix, descriptor, isSuspend)?.let { return it }
val dashIndex = method.name.indexOf('-')
val nameWithoutManglingSuffix = if (dashIndex > 0) method.name.substring(0, dashIndex) else method.name
if (nameWithoutManglingSuffix != method.name) {
getMethodNode(owner, bytes, Method(nameWithoutManglingSuffix, method.descriptor), isSuspend)?.let { return it }
}
getMethodNode(owner, bytes, "$nameWithoutManglingSuffix-impl", descriptor, isSuspend)?.let { return it }
getMethodNode(owner, bytes, Method("$nameWithoutManglingSuffix-impl", method.descriptor), isSuspend)?.let { return it }
}
throw IllegalStateException("couldn't find inline method $owner.$name$descriptor")
throw IllegalStateException("couldn't find inline method $owner.$method")
}
// If an `inline suspend fun` has a state machine, it should have a `$$forInline` version without one.
private fun getMethodNode(owner: Type, bytes: ByteArray, name: String, descriptor: String, isSuspend: Boolean) =
(if (isSuspend) getMethodNode(bytes, name + FOR_INLINE_SUFFIX, descriptor, owner) else null)
?: getMethodNode(bytes, name, descriptor, owner)
private fun getMethodNode(owner: Type, bytes: ByteArray, method: Method, isSuspend: Boolean) =
(if (isSuspend) getMethodNode(bytes, owner, Method(method.name + FOR_INLINE_SUFFIX, method.descriptor)) else null)
?: getMethodNode(bytes, owner, method)

View File

@@ -16,20 +16,16 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil
import org.jetbrains.kotlin.codegen.OwnerKind
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner.Companion.isNeedClassReificationMarker
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.tree.*
import kotlin.math.max
private data class Condition(
val mask: Int, val constant: Int,
@@ -41,25 +37,6 @@ private data class Condition(
val varIndex = varInsNode?.`var` ?: 0
}
fun extractDefaultLambdaOffsetAndDescriptor(
jvmSignature: JvmMethodSignature,
functionDescriptor: FunctionDescriptor
): Map<Int, ValueParameterDescriptor> {
val valueParameters = jvmSignature.valueParameters
val containingDeclaration = functionDescriptor.containingDeclaration
val kind =
if (DescriptorUtils.isInterface(containingDeclaration)) OwnerKind.DEFAULT_IMPLS
else OwnerKind.getMemberOwnerKind(containingDeclaration)
val parameterOffsets = parameterOffsets(DescriptorAsmUtil.isStaticMethod(kind, functionDescriptor), valueParameters)
val valueParameterOffset = valueParameters.takeWhile { it.kind != JvmMethodParameterKind.VALUE }.size
return functionDescriptor.valueParameters.filter {
InlineUtil.isInlineParameter(it) && it.declaresDefaultValue()
}.associateBy {
parameterOffsets[valueParameterOffset + it.index]
}
}
class ExtractedDefaultLambda(val type: Type, val capturedArgs: Array<Type>, val offset: Int, val needReification: Boolean)
fun expandMaskConditionsAndUpdateVariableNodes(
@@ -202,3 +179,68 @@ private fun defaultLambdaFakeCallStub(args: Array<Type>, lambdaOffset: Int): Met
false
)
}
fun loadDefaultLambdaBody(classBytes: ByteArray, classType: Type, isPropertyReference: Boolean): SMAPAndMethodNode {
// In general we can't know what the correct unboxed `invoke` is, and what Kotlin types its arguments have,
// as the type of this object may be any subtype of the parameter's type. All we know is that Function<N>
// has to have a `invoke` that takes `Object`s and returns an `Object`; everything else needs to be figured
// out from its contents. TODO: for > 22 arguments, the only argument is an array. `MethodInliner` can't do that.
val invokeName = if (isPropertyReference) OperatorNameConventions.GET.asString() else OperatorNameConventions.INVOKE.asString()
val invokeNode = getMethodNode(classBytes, classType) {
it.name == invokeName && it.returnType == AsmTypes.OBJECT_TYPE && it.argumentTypes.all { arg -> arg == AsmTypes.OBJECT_TYPE }
} ?: error("can't find erased invoke '$invokeName(Object...): Object' in default lambda '${classType.internalName}'")
return if (invokeNode.node.access.and(Opcodes.ACC_BRIDGE) == 0)
invokeNode
else
invokeNode.node.inlineBridge(classBytes, classType)
}
private fun MethodNode.inlineBridge(classBytes: ByteArray, classType: Type): SMAPAndMethodNode {
// If the erased invoke is a bridge, we need to locate the unboxed invoke and inline it. As mentioned above,
// we don't know what the Kotlin types of its arguments/returned value are, so we can't generate our own
// boxing/unboxing code; luckily, the bridge already has that.
val invokeInsn = instructions.singleOrNull { it is MethodInsnNode && it.owner == classType.internalName } as MethodInsnNode?
?: error("no single invoke of method on this in '${name}${desc}' of default lambda '${classType.internalName}'")
val targetMethod = Method(invokeInsn.name, invokeInsn.desc)
val target = getMethodNode(classBytes, classType, targetMethod)
?: error("can't find non-bridge invoke '$targetMethod' in default lambda '${classType.internalName}")
// Store unboxed/casted arguments in the correct variable slots
val targetArgs = targetMethod.argumentTypes
val targetArgsSize = targetArgs.sumOf { it.size } + if (target.node.access.and(Opcodes.ACC_STATIC) == 0) 1 else 0
var offset = targetArgsSize
for (type in targetArgs.reversed()) {
offset -= type.size
instructions.insertBefore(invokeInsn, VarInsnNode(type.getOpcode(Opcodes.ISTORE), offset))
}
if (target.node.access.and(Opcodes.ACC_STATIC) == 0) {
instructions.insertBefore(invokeInsn, InsnNode(Opcodes.POP)) // this
}
// Remap returns and ranges for arguments' LVT entries
val invokeLabel = LabelNode()
val returnLabel = LabelNode()
instructions.insertBefore(invokeInsn, invokeLabel)
instructions.insert(invokeInsn, returnLabel)
for (insn in target.node.instructions) {
if (insn.opcode in Opcodes.IRETURN..Opcodes.RETURN) {
target.node.instructions.set(insn, JumpInsnNode(Opcodes.GOTO, returnLabel))
}
}
for (local in target.node.localVariables) {
if (local.index < targetArgsSize) {
local.start = invokeLabel
local.end = returnLabel
}
}
// Insert contents of the method into the bridge
instructions.filterIsInstance<LineNumberNode>().forEach { instructions.remove(it) } // those are not meaningful
instructions.insertBefore(invokeInsn, target.node.instructions)
instructions.remove(invokeInsn)
localVariables = target.node.localVariables
tryCatchBlocks = target.node.tryCatchBlocks
maxLocals = max(maxLocals, target.node.maxLocals)
maxStack = max(maxStack, target.node.maxStack)
return SMAPAndMethodNode(this, target.classSMAP)
}

View File

@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.util.Printer
import org.jetbrains.org.objectweb.asm.util.Textifier
@@ -84,40 +85,18 @@ private const val INLINE_MARKER_AFTER_INLINE_SUSPEND_ID = 7
private const val INLINE_MARKER_BEFORE_UNBOX_INLINE_CLASS = 8
private const val INLINE_MARKER_AFTER_UNBOX_INLINE_CLASS = 9
internal fun getMethodNode(
classData: ByteArray,
methodName: String,
methodDescriptor: String,
classType: Type,
signatureAmbiguity: Boolean = false
): SMAPAndMethodNode? {
val cr = ClassReader(classData)
internal inline fun getMethodNode(classData: ByteArray, classType: Type, crossinline match: (Method) -> Boolean): SMAPAndMethodNode? {
var node: MethodNode? = null
val debugInfo = arrayOfNulls<String>(2)
cr.accept(object : ClassVisitor(Opcodes.API_VERSION) {
var sourceFile: String? = null
var sourceMap: String? = null
ClassReader(classData).accept(object : ClassVisitor(Opcodes.API_VERSION) {
override fun visitSource(source: String?, debug: String?) {
super.visitSource(source, debug)
debugInfo[0] = source
debugInfo[1] = debug
sourceFile = source
sourceMap = debug
}
override fun visitMethod(
access: Int,
name: String,
desc: String,
signature: String?,
exceptions: Array<String>?
): MethodVisitor? {
if (methodName != name || (signatureAmbiguity && access.and(Opcodes.ACC_SYNTHETIC) != 0)) return null
if (methodDescriptor != desc) {
val sameNumberOfParameters = Type.getArgumentTypes(methodDescriptor).size == Type.getArgumentTypes(desc).size
if (!signatureAmbiguity || !sameNumberOfParameters) {
return null
}
}
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?): MethodVisitor? {
if (!match(Method(name, desc))) return null
node?.let { existing ->
throw AssertionError("Can't find proper '$name' method for inline: ambiguity between '${existing.name + existing.desc}' and '${name + desc}'")
}
@@ -126,15 +105,15 @@ internal fun getMethodNode(
}
}, ClassReader.SKIP_FRAMES or if (GENERATE_SMAP) 0 else ClassReader.SKIP_DEBUG)
if (node == null) {
return null
return node?.let{
val (first, last) = listOfNotNull(it).lineNumberRange()
SMAPAndMethodNode(it, SMAPParser.parseOrCreateDefault(sourceMap, sourceFile, classType.internalName, first, last))
}
val (first, last) = listOfNotNull(node).lineNumberRange()
val smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classType.internalName, first, last)
return SMAPAndMethodNode(node!!, smap)
}
internal fun getMethodNode(classData: ByteArray, classType: Type, method: Method): SMAPAndMethodNode? =
getMethodNode(classData, classType) { it == method }
internal fun Collection<MethodNode>.lineNumberRange(): Pair<Int, Int> {
var minLine = Int.MAX_VALUE
var maxLine = Int.MIN_VALUE
@@ -347,8 +326,42 @@ internal val AbstractInsnNode?.insnText: String
return sw.toString().trim()
}
fun AbstractInsnNode?.insnText(insnList: InsnList): String {
if (this == null) return "<null>"
fun AbstractInsnNode.indexOf() =
insnList.indexOf(this)
fun LabelNode.labelText() =
"L#${this.indexOf()}"
return when (this) {
is LabelNode ->
labelText()
is JumpInsnNode ->
"$insnOpcodeText ${label.labelText()}"
is LookupSwitchInsnNode ->
"$insnOpcodeText " +
this.keys.zip(this.labels).joinToString(prefix = "[", postfix = "]") { (key, label) -> "$key:${label.labelText()}" }
is TableSwitchInsnNode ->
"$insnOpcodeText " +
(min..max).zip(this.labels).joinToString(prefix = "[", postfix = "]") { (key, label) -> "$key:${label.labelText()}" }
else ->
insnText
}
}
internal val AbstractInsnNode?.insnOpcodeText: String
get() = if (this == null) "null" else Printer.OPCODES[opcode]
get() = when (this) {
null -> "null"
is LabelNode -> "LABEL"
is LineNumberNode -> "LINENUMBER"
is FrameNode -> "FRAME"
else -> Printer.OPCODES[opcode]
}
internal fun TryCatchBlockNode.text(insns: InsnList): String =
"[${insns.indexOf(start)} .. ${insns.indexOf(end)} -> ${insns.indexOf(handler)}]"
internal fun loadClassBytesByInternalName(state: GenerationState, internalName: String): ByteArray {
//try to find just compiled classes then in dependencies

View File

@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
@@ -43,9 +44,9 @@ fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
val typeParameter = type.typeConstructor().getTypeParameterClassifier()
if (typeParameter != null) {
if (!doesTypeContainTypeParametersWithRecursiveBounds(type)) {
throw UnsupportedOperationException(
"Non-reified type parameters with recursive bounds are not supported yet: ${typeParameter.getName()}"
)
intrinsicsSupport.reportNonReifiedTypeParameterWithRecursiveBoundUnsupported(typeParameter.getName())
v.aconst(null)
return
}
generateNonReifiedTypeParameter(v, typeParameter, intrinsicsSupport)
@@ -90,9 +91,17 @@ fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
v.invokestatic(REFLECTION, methodName, signature, false)
if (intrinsicsSupport.toKotlinType(type).isSuspendFunctionType) {
intrinsicsSupport.reportSuspendTypeUnsupported()
}
intrinsicsSupport.checkAnnotatedType(type)
if (intrinsicsSupport.state.stableTypeOf) {
if (intrinsicsSupport.isMutableCollectionType(type)) {
v.invokestatic(REFLECTION, "mutableCollectionType", Type.getMethodDescriptor(K_TYPE, K_TYPE), false)
} else if (type.typeConstructor().isNothingConstructor()) {
v.invokestatic(REFLECTION, "nothingType", Type.getMethodDescriptor(K_TYPE, K_TYPE), false)
}
if (type.isFlexible()) {

View File

@@ -34,11 +34,26 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
class ConstantConditionEliminationMethodTransformer : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) {
if (!methodNode.hasOptimizableConditions()) {
return
}
do {
val changes = ConstantConditionsOptimization(internalClassName, methodNode).run()
} while (changes)
}
private fun MethodNode.hasOptimizableConditions(): Boolean {
val insns = instructions.toArray()
return insns.any { it.isIntJump() } && insns.any { it.isIntConst() }
}
private fun AbstractInsnNode.isIntConst() =
opcode in Opcodes.ICONST_M1..Opcodes.ICONST_5 || opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH ||
(opcode == Opcodes.LDC && this is LdcInsnNode && cst is Int)
private fun AbstractInsnNode.isIntJump() =
opcode in Opcodes.IFEQ..Opcodes.IFLE || opcode in Opcodes.IF_ICMPEQ..Opcodes.IF_ICMPLE
private class ConstantConditionsOptimization(val internalClassName: String, val methodNode: MethodNode) {
fun run(): Boolean {
val actions = collectRewriteActions()

View File

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

View File

@@ -41,7 +41,7 @@ class OptimizationMethodVisitor(
val normalizationMethodTransformer = CompositeMethodTransformer(
FixStackWithLabelNormalizationMethodTransformer(),
MethodVerifier("AFTER mandatory stack transformations")
MethodVerifier("AFTER mandatory stack transformations", generationState)
)
val optimizationTransformer = CompositeMethodTransformer(
@@ -55,7 +55,7 @@ class OptimizationMethodVisitor(
DeadCodeEliminationMethodTransformer(),
RedundantGotoMethodTransformer(),
RedundantNopsCleanupMethodTransformer(),
MethodVerifier("AFTER optimizations")
MethodVerifier("AFTER optimizations", generationState)
)
override fun performTransformations(methodNode: MethodNode) {
@@ -72,18 +72,30 @@ class OptimizationMethodVisitor(
}
companion object {
private val MEMORY_LIMIT_BY_METHOD_MB = 50
private const val MEMORY_LIMIT_BY_METHOD_MB = 50
private const val TRY_CATCH_BLOCKS_SOFT_LIMIT = 16
fun canBeOptimized(node: MethodNode): Boolean {
val totalFramesSizeMb = node.instructions.size() * (node.maxLocals + node.maxStack) / (1024 * 1024)
return totalFramesSizeMb < MEMORY_LIMIT_BY_METHOD_MB
if (node.tryCatchBlocks.size > TRY_CATCH_BLOCKS_SOFT_LIMIT) {
if (getTotalFramesWeight(getTotalTcbSize(node), node) > MEMORY_LIMIT_BY_METHOD_MB)
return false
}
return getTotalFramesWeight(node.instructions.size(), node) < MEMORY_LIMIT_BY_METHOD_MB
}
fun canBeOptimizedUsingSourceInterpreter(node: MethodNode): Boolean {
val frameSize = node.maxLocals + node.maxStack
val methodSize = node.instructions.size().toLong()
val totalFramesSizeMb = methodSize * methodSize * frameSize / (1024 * 1024)
return totalFramesSizeMb < MEMORY_LIMIT_BY_METHOD_MB
val methodSize = node.instructions.size()
if (node.tryCatchBlocks.size > TRY_CATCH_BLOCKS_SOFT_LIMIT) {
if (getTotalFramesWeight(getTotalTcbSize(node) * methodSize, node) > MEMORY_LIMIT_BY_METHOD_MB)
return false
}
return getTotalFramesWeight(methodSize * methodSize, node) < MEMORY_LIMIT_BY_METHOD_MB
}
private fun getTotalFramesWeight(size: Int, node: MethodNode) =
size.toLong() * (node.maxLocals + node.maxStack) / (1024 * 1024)
private fun getTotalTcbSize(node: MethodNode) =
node.tryCatchBlocks.sumOf { node.instructions.indexOf(it.end) - node.instructions.indexOf(it.start) }
}
}

View File

@@ -56,7 +56,7 @@ class TaintedBoxedValue(private val boxedBasicValue: CleanBoxedValue) : BoxedBas
class BoxedValueDescriptor(
private val boxedType: Type,
boxedType: Type,
val boxingInsn: AbstractInsnNode,
val progressionIterator: ProgressionIteratorBasicValue?,
val generationState: GenerationState

View File

@@ -17,13 +17,16 @@
package org.jetbrains.kotlin.codegen.optimization.boxing
import org.jetbrains.kotlin.codegen.optimization.OptimizationMethodVisitor
import org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer
import org.jetbrains.kotlin.codegen.optimization.common.isLoadOperation
import org.jetbrains.kotlin.codegen.optimization.fixStack.peekWords
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.Analyzer
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
@@ -52,7 +55,7 @@ class PopBackwardPropagationTransformer : MethodTransformer() {
private val dontTouchInsnIndices = BitSet(insns.size)
fun transform() {
val frames = Analyzer(HazardsTrackingInterpreter()).analyze("fake", methodNode)
val frames = FastMethodAnalyzer("fake", methodNode, HazardsTrackingInterpreter()).analyze()
for ((i, insn) in insns.withIndex()) {
val frame = frames[i] ?: continue
when (insn.opcode) {

View File

@@ -38,6 +38,10 @@ import java.util.*
class RedundantBoxingMethodTransformer(private val generationState: GenerationState) : MethodTransformer() {
override fun transform(internalClassName: String, node: MethodNode) {
val insns = node.instructions.toArray()
if (insns.none { it.isBoxing(generationState) || it.isMethodInsnWith(Opcodes.INVOKEINTERFACE) { name == "next" } })
return
val interpreter = RedundantBoxingInterpreter(node.instructions, generationState)
val frames = analyze(internalClassName, node, interpreter)

View File

@@ -5,46 +5,160 @@
package org.jetbrains.kotlin.codegen.optimization.common
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
import gnu.trove.TIntHashSet
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.*
class ControlFlowGraph private constructor(private val insns: InsnList) {
private val edges: Array<MutableList<Int>> = Array(insns.size()) { arrayListOf<Int>() }
private val backwardEdges: Array<MutableList<Int>> = Array(insns.size()) { arrayListOf<Int>() }
private val successors: Array<MutableList<Int>> = Array(insns.size()) { ArrayList(2) }
private val predecessors: Array<MutableList<Int>> = Array(insns.size()) { ArrayList(2) }
fun getSuccessorsIndices(insn: AbstractInsnNode): List<Int> = getSuccessorsIndices(insns.indexOf(insn))
fun getSuccessorsIndices(index: Int): List<Int> = edges[index]
fun getSuccessorsIndices(index: Int): List<Int> = successors[index]
fun getPredecessorsIndices(insn: AbstractInsnNode): List<Int> = getPredecessorsIndices(insns.indexOf(insn))
fun getPredecessorsIndices(index: Int): List<Int> = backwardEdges[index]
fun getPredecessorsIndices(index: Int): List<Int> = predecessors[index]
private class Builder(
private val method: MethodNode,
private val followExceptions: Boolean
) {
private val instructions = method.instructions
private val nInsns = instructions.size()
private val handlers: Array<MutableList<TryCatchBlockNode>?> = arrayOfNulls(nInsns)
private val queued = BooleanArray(nInsns)
private val queue = IntArray(nInsns)
private var top = 0
private val predecessors = Array(nInsns) { TIntHashSet() }
private val AbstractInsnNode.indexOf get() = instructions.indexOf(this)
fun build(): ControlFlowGraph {
val graph = ControlFlowGraph(method.instructions)
if (nInsns == 0) return graph
checkAssertions()
computeExceptionHandlersForEachInsn()
initControlFlowAnalysis()
traverseCfg()
for ((i, preds) in predecessors.withIndex()) {
for (pred in preds.toArray()) {
graph.predecessors[i].add(pred)
graph.successors[pred].add(i)
}
}
return graph
}
private fun traverseCfg() {
while (top > 0) {
val insn = queue[--top]
val insnNode = method.instructions[insn]
val insnOpcode = insnNode.opcode
when (insnNode.type) {
AbstractInsnNode.LABEL, AbstractInsnNode.LINE, AbstractInsnNode.FRAME ->
visitOpInsn(insn)
AbstractInsnNode.JUMP_INSN ->
visitJumpInsnNode(insnNode as JumpInsnNode, insn, insnOpcode)
AbstractInsnNode.LOOKUPSWITCH_INSN ->
visitLookupSwitchInsnNode(insn, insnNode as LookupSwitchInsnNode)
AbstractInsnNode.TABLESWITCH_INSN ->
visitTableSwitchInsnNode(insn, insnNode as TableSwitchInsnNode)
else -> {
if (insnOpcode != Opcodes.ATHROW && (insnOpcode < Opcodes.IRETURN || insnOpcode > Opcodes.RETURN)) {
visitOpInsn(insn)
}
}
}
handlers[insn]?.forEach { tcb ->
visitExceptionEdge(insn, tcb.handler.indexOf)
}
}
}
private fun checkAssertions() {
if (instructions.any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET })
throw AssertionError("Subroutines are deprecated since Java 6")
}
private fun visitOpInsn(insn: Int) {
visitEdge(insn, insn + 1)
}
private fun visitTableSwitchInsnNode(insn: Int, insnNode: TableSwitchInsnNode) {
var jump = insnNode.dflt.indexOf
visitEdge(insn, jump)
for (label in insnNode.labels) {
jump = label.indexOf
visitEdge(insn, jump)
}
}
private fun visitLookupSwitchInsnNode(insn: Int, insnNode: LookupSwitchInsnNode) {
var jump = insnNode.dflt.indexOf
visitEdge(insn, jump)
for (label in insnNode.labels) {
jump = label.indexOf
visitEdge(insn, jump)
}
}
private fun visitJumpInsnNode(insnNode: JumpInsnNode, insn: Int, insnOpcode: Int) {
if (insnOpcode != Opcodes.GOTO && insnOpcode != Opcodes.JSR) {
visitEdge(insn, insn + 1)
}
val jump = insnNode.label.indexOf
visitEdge(insn, jump)
}
private fun initControlFlowAnalysis() {
queued[0] = true
queue[top++] = 0
}
private fun computeExceptionHandlersForEachInsn() {
for (tcb in method.tryCatchBlocks) {
val begin = tcb.start.indexOf
val end = tcb.end.indexOf
for (j in begin until end) {
val insnHandlers = handlers[j]
?: ArrayList<TryCatchBlockNode>().also { handlers[j] = it }
insnHandlers.add(tcb)
}
}
}
private fun visitExceptionEdge(from: Int, to: Int) {
if (followExceptions) {
predecessors[to].add(from)
}
enqueue(to)
}
private fun visitEdge(from: Int, to: Int) {
predecessors[to].add(from)
enqueue(to)
}
private fun enqueue(insn: Int) {
if (!queued[insn]) {
queued[insn] = true
queue[top++] = insn
}
}
}
companion object {
@JvmStatic
fun build(node: MethodNode, followExceptions: Boolean = true): ControlFlowGraph {
val graph = ControlFlowGraph(node.instructions)
fun addEdge(from: Int, to: Int) {
graph.edges[from].add(to)
graph.backwardEdges[to].add(from)
}
object : MethodAnalyzer<BasicValue>("fake", node, OptimizationBasicInterpreter()) {
override fun visitControlFlowEdge(insn: Int, successor: Int): Boolean {
addEdge(insn, successor)
return true
}
override fun visitControlFlowExceptionEdge(insn: Int, successor: Int): Boolean {
if (followExceptions) {
addEdge(insn, successor)
}
return true
}
}.analyze()
return graph
return Builder(node, followExceptions).build()
}
}
}

View File

@@ -24,6 +24,6 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Value
class CustomFramesMethodAnalyzer<V : Value>(
owner: String, method: MethodNode, interpreter: Interpreter<V>,
private val frameFactory: (Int, Int) -> Frame<V>
) : MethodAnalyzer<V>(owner, method, interpreter) {
) : FastMethodAnalyzer<V>(owner, method, interpreter) {
override fun newFrame(nLocals: Int, nStack: Int) = frameFactory(nLocals, nStack)
}

View File

@@ -0,0 +1,255 @@
/*
* 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.
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jetbrains.kotlin.codegen.optimization.common
import org.jetbrains.kotlin.codegen.inline.insnText
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
import org.jetbrains.org.objectweb.asm.tree.analysis.Value
/**
* @see org.jetbrains.kotlin.codegen.optimization.fixStack.FastStackAnalyzer
*/
@Suppress("DuplicatedCode")
open class FastMethodAnalyzer<V : Value>(
private val owner: String,
val method: MethodNode,
private val interpreter: Interpreter<V>
) {
private val insnsArray = method.instructions.toArray()
private val nInsns = method.instructions.size()
private val isMergeNode = BooleanArray(nInsns)
private val frames: Array<Frame<V>?> = arrayOfNulls(nInsns)
private val handlers: Array<MutableList<TryCatchBlockNode>?> = arrayOfNulls(nInsns)
private val queued = BooleanArray(nInsns)
private val queue = IntArray(nInsns)
private var top = 0
protected open fun newFrame(nLocals: Int, nStack: Int): Frame<V> =
Frame(nLocals, nStack)
fun analyze(): Array<Frame<V>?> {
if (nInsns == 0) return frames
checkAssertions()
computeExceptionHandlersForEachInsn(method)
initMergeNodes()
val current = newFrame(method.maxLocals, method.maxStack)
val handler = newFrame(method.maxLocals, method.maxStack)
initLocals(current)
mergeControlFlowEdge(0, current)
while (top > 0) {
val insn = queue[--top]
val f = frames[insn]!!
queued[insn] = false
val insnNode = method.instructions[insn]
try {
val insnOpcode = insnNode.opcode
val insnType = insnNode.type
if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
mergeControlFlowEdge(insn + 1, f)
} else {
current.init(f).execute(insnNode, interpreter)
when {
insnType == AbstractInsnNode.JUMP_INSN ->
visitJumpInsnNode(insnNode as JumpInsnNode, current, insn, insnOpcode)
insnType == AbstractInsnNode.LOOKUPSWITCH_INSN ->
visitLookupSwitchInsnNode(insnNode as LookupSwitchInsnNode, current)
insnType == AbstractInsnNode.TABLESWITCH_INSN ->
visitTableSwitchInsnNode(insnNode as TableSwitchInsnNode, current)
insnOpcode != Opcodes.ATHROW && (insnOpcode < Opcodes.IRETURN || insnOpcode > Opcodes.RETURN) ->
visitOpInsn(current, insn)
else -> {
}
}
}
handlers[insn]?.forEach { tcb ->
val exnType = Type.getObjectType(tcb.type ?: "java/lang/Throwable")
val jump = tcb.handler.indexOf()
handler.init(f)
handler.clearStack()
handler.push(interpreter.newValue(exnType))
mergeControlFlowEdge(jump, handler)
}
} catch (e: AnalyzerException) {
throw AnalyzerException(e.node, "Error at instruction #$insn ${insnNode.insnText}: ${e.message}", e)
} catch (e: Exception) {
throw AnalyzerException(insnNode, "Error at instruction #$insn ${insnNode.insnText}: ${e.message}", e)
}
}
return frames
}
internal fun initLocals(current: Frame<V>) {
current.setReturn(interpreter.newValue(Type.getReturnType(method.desc)))
val args = Type.getArgumentTypes(method.desc)
var local = 0
if ((method.access and Opcodes.ACC_STATIC) == 0) {
val ctype = Type.getObjectType(owner)
current.setLocal(local++, interpreter.newValue(ctype))
}
for (arg in args) {
current.setLocal(local++, interpreter.newValue(arg))
if (arg.size == 2) {
current.setLocal(local++, interpreter.newValue(null))
}
}
while (local < method.maxLocals) {
current.setLocal(local++, interpreter.newValue(null))
}
}
private fun AbstractInsnNode.indexOf() =
method.instructions.indexOf(this)
private fun initMergeNodes() {
for (insn in insnsArray) {
when (insn.type) {
AbstractInsnNode.JUMP_INSN -> {
val jumpInsn = insn as JumpInsnNode
isMergeNode[jumpInsn.label.indexOf()] = true
}
AbstractInsnNode.LOOKUPSWITCH_INSN -> {
val switchInsn = insn as LookupSwitchInsnNode
isMergeNode[switchInsn.dflt.indexOf()] = true
for (label in switchInsn.labels) {
isMergeNode[label.indexOf()] = true
}
}
AbstractInsnNode.TABLESWITCH_INSN -> {
val switchInsn = insn as TableSwitchInsnNode
isMergeNode[switchInsn.dflt.indexOf()] = true
for (label in switchInsn.labels) {
isMergeNode[label.indexOf()] = true
}
}
}
}
for (tcb in method.tryCatchBlocks) {
isMergeNode[tcb.handler.indexOf()] = true
}
}
fun getFrame(insn: AbstractInsnNode): Frame<V>? =
frames[insn.indexOf()]
private fun checkAssertions() {
if (insnsArray.any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET })
throw AssertionError("Subroutines are deprecated since Java 6")
}
private fun visitOpInsn(current: Frame<V>, insn: Int) {
mergeControlFlowEdge(insn + 1, current)
}
private fun visitTableSwitchInsnNode(insnNode: TableSwitchInsnNode, current: Frame<V>) {
mergeControlFlowEdge(insnNode.dflt.indexOf(), current)
// In most cases order of visiting switch labels should not matter
// The only one is a tableswitch being added in the beginning of coroutine method, these switch' labels may lead
// in the middle of try/catch block, and FixStackAnalyzer is not ready for this (trying to restore stack before it was saved)
// So we just fix the order of labels being traversed: the first one should be one at the method beginning
// Using 'reversed' is because nodes are processed in LIFO order
for (label in insnNode.labels.asReversed()) {
mergeControlFlowEdge(label.indexOf(), current)
}
}
private fun visitLookupSwitchInsnNode(insnNode: LookupSwitchInsnNode, current: Frame<V>) {
mergeControlFlowEdge(insnNode.dflt.indexOf(), current)
for (label in insnNode.labels) {
mergeControlFlowEdge(label.indexOf(), current)
}
}
private fun visitJumpInsnNode(insnNode: JumpInsnNode, current: Frame<V>, insn: Int, insnOpcode: Int) {
if (insnOpcode != Opcodes.GOTO) {
mergeControlFlowEdge(insn + 1, current)
}
mergeControlFlowEdge(insnNode.label.indexOf(), current)
}
private fun computeExceptionHandlersForEachInsn(m: MethodNode) {
for (tcb in m.tryCatchBlocks) {
val begin = tcb.start.indexOf()
val end = tcb.end.indexOf()
for (j in begin until end) {
if (!insnsArray[j].isMeaningful) continue
var insnHandlers: MutableList<TryCatchBlockNode>? = handlers[j]
if (insnHandlers == null) {
insnHandlers = SmartList()
handlers[j] = insnHandlers
}
insnHandlers.add(tcb)
}
}
}
private fun mergeControlFlowEdge(dest: Int, frame: Frame<V>) {
val oldFrame = frames[dest]
val changes = when {
oldFrame == null -> {
frames[dest] = newFrame(frame.locals, frame.maxStackSize).apply { init(frame) }
true
}
!isMergeNode[dest] -> {
oldFrame.init(frame)
true
}
else ->
oldFrame.merge(frame, interpreter)
}
if (changes && !queued[dest]) {
queued[dest] = true
queue[top++] = dest
}
}
}

View File

@@ -1,6 +1,35 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jetbrains.kotlin.codegen.optimization.common
@@ -95,7 +124,7 @@ class InstructionLivenessAnalyzer(val method: MethodNode) {
var jump = insnNode.dflt.indexOf
visitControlFlowEdge(jump)
for (label in insnNode.labels) {
jump = instructions.indexOf(label)
jump = label.indexOf
visitControlFlowEdge(jump)
}
}
@@ -126,9 +155,10 @@ class InstructionLivenessAnalyzer(val method: MethodNode) {
val begin = tcb.start.indexOf
val end = tcb.end.indexOf
for (j in begin until end) {
if (!instructions[j].isMeaningful) continue
var insnHandlers = handlers[j]
if (insnHandlers == null) {
insnHandlers = ArrayList<TryCatchBlockNode>()
insnHandlers = ArrayList()
handlers[j] = insnHandlers
}
insnHandlers.add(tcb)

View File

@@ -1,263 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package org.jetbrains.kotlin.codegen.optimization.common
import org.jetbrains.kotlin.codegen.inline.insnText
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
import org.jetbrains.org.objectweb.asm.tree.analysis.Value
import java.util.*
/**
* This class is a modified version of `org.objectweb.asm.tree.analysis.Analyzer`
* @author Eric Bruneton
* @author Dmitry Petrov
*/
open class MethodAnalyzer<V : Value>(
private val owner: String,
val method: MethodNode,
protected val interpreter: Interpreter<V>
) {
val instructions: InsnList = method.instructions
private val nInsns: Int = instructions.size()
val frames: Array<Frame<V>?> = arrayOfNulls(nInsns)
private val handlers: Array<MutableList<TryCatchBlockNode>?> = arrayOfNulls(nInsns)
private val queued: BooleanArray = BooleanArray(nInsns)
private val queue: IntArray = IntArray(nInsns)
private var top: Int = 0
protected open fun init(owner: String, m: MethodNode) {}
protected open fun newFrame(nLocals: Int, nStack: Int): Frame<V> = Frame(nLocals, nStack)
protected open fun newFrame(src: Frame<out V>): Frame<V> {
val frame = newFrame(src.locals, src.maxStackSize)
frame.init(src)
return frame
}
protected open fun visitControlFlowEdge(insn: Int, successor: Int): Boolean = true
protected open fun visitControlFlowExceptionEdge(insn: Int, successor: Int): Boolean = true
protected open fun visitControlFlowExceptionEdge(insn: Int, tcb: TryCatchBlockNode): Boolean =
visitControlFlowExceptionEdge(insn, instructions.indexOf(tcb.handler))
fun analyze(): Array<Frame<V>?> {
if (nInsns == 0) return frames
checkAssertions()
computeExceptionHandlersForEachInsn(method)
val current = newFrame(method.maxLocals, method.maxStack)
val handler = newFrame(method.maxLocals, method.maxStack)
initControlFlowAnalysis(current, method, owner)
while (top > 0) {
val insn = queue[--top]
val f = frames[insn]!!
queued[insn] = false
val insnNode = method.instructions[insn]
try {
val insnOpcode = insnNode.opcode
val insnType = insnNode.type
if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
visitNopInsn(f, insn)
} else {
current.init(f).execute(insnNode, interpreter)
when {
insnNode is JumpInsnNode ->
visitJumpInsnNode(insnNode, current, insn, insnOpcode)
insnNode is LookupSwitchInsnNode ->
visitLookupSwitchInsnNode(insnNode, current, insn)
insnNode is TableSwitchInsnNode ->
visitTableSwitchInsnNode(insnNode, current, insn)
insnOpcode != Opcodes.ATHROW && (insnOpcode < Opcodes.IRETURN || insnOpcode > Opcodes.RETURN) ->
visitOpInsn(current, insn)
else -> {
}
}
}
handlers[insn]?.forEach { tcb ->
val exnType = Type.getObjectType(tcb.type ?: "java/lang/Throwable")
val jump = instructions.indexOf(tcb.handler)
if (visitControlFlowExceptionEdge(insn, tcb)) {
handler.init(f)
handler.clearStack()
handler.push(interpreter.newValue(exnType))
mergeControlFlowEdge(jump, handler)
}
}
} catch (e: AnalyzerException) {
throw AnalyzerException(e.node, "Error at instruction #$insn ${insnNode.insnText}: ${e.message}", e)
} catch (e: Exception) {
throw AnalyzerException(insnNode, "Error at instruction #$insn ${insnNode.insnText}: ${e.message}", e)
}
}
return frames
}
fun getFrame(insn: AbstractInsnNode): Frame<V>? =
frames[instructions.indexOf(insn)]
private fun checkAssertions() {
if (instructions.toArray().any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET })
throw AssertionError("Subroutines are deprecated since Java 6")
}
private fun visitOpInsn(current: Frame<V>, insn: Int) {
processControlFlowEdge(current, insn, insn + 1)
}
private fun visitTableSwitchInsnNode(insnNode: TableSwitchInsnNode, current: Frame<V>, insn: Int) {
var jump = instructions.indexOf(insnNode.dflt)
processControlFlowEdge(current, insn, jump)
// In most cases order of visiting switch labels should not matter
// The only one is a tableswitch being added in the beginning of coroutine method, these switch' labels may lead
// in the middle of try/catch block, and FixStackAnalyzer is not ready for this (trying to restore stack before it was saved)
// So we just fix the order of labels being traversed: the first one should be one at the method beginning
// Using 'reversed' is because nodes are processed in LIFO order
for (label in insnNode.labels.reversed()) {
jump = instructions.indexOf(label)
processControlFlowEdge(current, insn, jump)
}
}
private fun visitLookupSwitchInsnNode(insnNode: LookupSwitchInsnNode, current: Frame<V>, insn: Int) {
var jump = instructions.indexOf(insnNode.dflt)
processControlFlowEdge(current, insn, jump)
for (label in insnNode.labels) {
jump = instructions.indexOf(label)
processControlFlowEdge(current, insn, jump)
}
}
private fun visitJumpInsnNode(insnNode: JumpInsnNode, current: Frame<V>, insn: Int, insnOpcode: Int) {
if (insnOpcode != Opcodes.GOTO && insnOpcode != Opcodes.JSR) {
processControlFlowEdge(current, insn, insn + 1)
}
val jump = instructions.indexOf(insnNode.label)
processControlFlowEdge(current, insn, jump)
}
private fun visitNopInsn(f: Frame<V>, insn: Int) {
processControlFlowEdge(f, insn, insn + 1)
}
private fun processControlFlowEdge(current: Frame<V>, insn: Int, jump: Int) {
if (visitControlFlowEdge(insn, jump)) {
mergeControlFlowEdge(jump, current)
}
}
private fun initControlFlowAnalysis(current: Frame<V>, m: MethodNode, owner: String) {
current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)))
val args = Type.getArgumentTypes(m.desc)
var local = 0
if ((m.access and Opcodes.ACC_STATIC) == 0) {
val ctype = Type.getObjectType(owner)
current.setLocal(local++, interpreter.newValue(ctype))
}
for (arg in args) {
current.setLocal(local++, interpreter.newValue(arg))
if (arg.size == 2) {
current.setLocal(local++, interpreter.newValue(null))
}
}
while (local < m.maxLocals) {
current.setLocal(local++, interpreter.newValue(null))
}
mergeControlFlowEdge(0, current)
init(owner, m)
}
private fun computeExceptionHandlersForEachInsn(m: MethodNode) {
for (tcb in m.tryCatchBlocks) {
val begin = instructions.indexOf(tcb.start)
val end = instructions.indexOf(tcb.end)
for (j in begin until end) {
var insnHandlers: MutableList<TryCatchBlockNode>? = handlers[j]
if (insnHandlers == null) {
insnHandlers = ArrayList<TryCatchBlockNode>()
handlers[j] = insnHandlers
}
insnHandlers.add(tcb)
}
}
}
private fun mergeControlFlowEdge(insn: Int, frame: Frame<V>) {
val oldFrame = frames[insn]
val changes =
if (oldFrame != null)
oldFrame.merge(frame, interpreter)
else {
frames[insn] = newFrame(frame)
true
}
if (changes && !queued[insn]) {
queued[insn] = true
queue[top++] = insn
}
}
}

View File

@@ -38,13 +38,12 @@ fun <F : VarFrame<F>> analyze(node: MethodNode, interpreter: BackwardAnalysisInt
val frames = (1..insnList.size()).map { interpreter.newFrame(node.maxLocals) }.toMutableList()
val insnArray = insnList.toArray()
// see Figure 9.16 from Dragon book
var wereChanges: Boolean
do {
wereChanges = false
for (insn in insnArray) {
val index = insnList.indexOf(insn)
for (index in insnArray.indices.reversed()) {
val insn = insnArray[index]
val newFrame = interpreter.newFrame(node.maxLocals)
for (successorIndex in graph.getSuccessorsIndices(insn)) {
newFrame.mergeFrom(frames[successorIndex])

View File

@@ -0,0 +1,239 @@
/*
* 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.
*
* ASM: a very small and fast Java bytecode manipulation framework
* Copyright (c) 2000-2011 INRIA, France Telecom
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.jetbrains.kotlin.codegen.optimization.fixStack
import org.jetbrains.kotlin.codegen.inline.insnText
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.AnalyzerException
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
import org.jetbrains.org.objectweb.asm.tree.analysis.Value
/**
* @see org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer
*/
@Suppress("DuplicatedCode")
internal open class FastStackAnalyzer<V : Value>(
private val owner: String,
val method: MethodNode,
protected val interpreter: Interpreter<V>
) {
protected val insnsArray: Array<AbstractInsnNode> = method.instructions.toArray()
private val nInsns = insnsArray.size
private val frames: Array<Frame<V>?> = arrayOfNulls(nInsns)
private val handlers: Array<MutableList<TryCatchBlockNode>?> = arrayOfNulls(nInsns)
private val queued = BooleanArray(nInsns)
private val queue = IntArray(nInsns)
private var top = 0
protected open fun newFrame(nLocals: Int, nStack: Int): Frame<V> = Frame(nLocals, nStack)
protected open fun visitControlFlowEdge(insn: Int, successor: Int): Boolean = true
protected open fun visitControlFlowExceptionEdge(insn: Int, successor: Int): Boolean = true
fun analyze(): Array<Frame<V>?> {
if (nInsns == 0) return frames
// This is a very specific version of method bytecode analyzer that doesn't perform any DFA,
// but infers stack types for reachable instructions instead.
checkAssertions()
computeExceptionEdges()
val current = newFrame(method.maxLocals, method.maxStack)
val handler = newFrame(method.maxLocals, method.maxStack)
initControlFlowAnalysis(current, method, owner)
while (top > 0) {
val insn = queue[--top]
val f = frames[insn]!!
queued[insn] = false
val insnNode = method.instructions[insn]
val insnOpcode = insnNode.opcode
val insnType = insnNode.type
try {
if (insnType == AbstractInsnNode.LABEL || insnType == AbstractInsnNode.LINE || insnType == AbstractInsnNode.FRAME) {
visitNopInsn(f, insn)
} else {
current.init(f)
if (insnOpcode != Opcodes.RETURN) {
// Don't care about possibly incompatible return type
current.execute(insnNode, interpreter)
}
when {
insnType == AbstractInsnNode.JUMP_INSN ->
visitJumpInsnNode(insnNode as JumpInsnNode, current, insn, insnOpcode)
insnType == AbstractInsnNode.LOOKUPSWITCH_INSN ->
visitLookupSwitchInsnNode(insnNode as LookupSwitchInsnNode, current, insn)
insnType == AbstractInsnNode.TABLESWITCH_INSN ->
visitTableSwitchInsnNode(insnNode as TableSwitchInsnNode, current, insn)
insnOpcode != Opcodes.ATHROW && (insnOpcode < Opcodes.IRETURN || insnOpcode > Opcodes.RETURN) ->
visitOpInsn(current, insn)
else -> {
}
}
}
handlers[insn]?.forEach { tcb ->
val exnType = Type.getObjectType(tcb.type ?: "java/lang/Throwable")
val jump = tcb.handler.indexOf()
if (visitControlFlowExceptionEdge(insn, tcb.handler.indexOf())) {
handler.init(f)
handler.clearStack()
handler.push(interpreter.newValue(exnType))
mergeControlFlowEdge(jump, handler)
}
}
} catch (e: AnalyzerException) {
throw AnalyzerException(e.node, "Error at instruction #$insn ${insnNode.insnText}: ${e.message}", e)
} catch (e: Exception) {
throw AnalyzerException(insnNode, "Error at instruction #$insn ${insnNode.insnText}: ${e.message}", e)
}
}
return frames
}
private fun AbstractInsnNode.indexOf() = method.instructions.indexOf(this)
fun getFrame(insn: AbstractInsnNode): Frame<V>? =
frames[insn.indexOf()]
private fun checkAssertions() {
if (insnsArray.any { it.opcode == Opcodes.JSR || it.opcode == Opcodes.RET })
throw AssertionError("Subroutines are deprecated since Java 6")
}
private fun visitOpInsn(current: Frame<V>, insn: Int) {
processControlFlowEdge(current, insn, insn + 1)
}
private fun visitTableSwitchInsnNode(insnNode: TableSwitchInsnNode, current: Frame<V>, insn: Int) {
var jump = insnNode.dflt.indexOf()
processControlFlowEdge(current, insn, jump)
// In most cases order of visiting switch labels should not matter
// The only one is a tableswitch being added in the beginning of coroutine method, these switch' labels may lead
// in the middle of try/catch block, and FixStackAnalyzer is not ready for this (trying to restore stack before it was saved)
// So we just fix the order of labels being traversed: the first one should be one at the method beginning
// Using 'reversed' is because nodes are processed in LIFO order
for (label in insnNode.labels.reversed()) {
jump = label.indexOf()
processControlFlowEdge(current, insn, jump)
}
}
private fun visitLookupSwitchInsnNode(insnNode: LookupSwitchInsnNode, current: Frame<V>, insn: Int) {
var jump = insnNode.dflt.indexOf()
processControlFlowEdge(current, insn, jump)
for (label in insnNode.labels) {
jump = label.indexOf()
processControlFlowEdge(current, insn, jump)
}
}
private fun visitJumpInsnNode(insnNode: JumpInsnNode, current: Frame<V>, insn: Int, insnOpcode: Int) {
if (insnOpcode != Opcodes.GOTO) {
processControlFlowEdge(current, insn, insn + 1)
}
val jump = insnNode.label.indexOf()
processControlFlowEdge(current, insn, jump)
}
private fun visitNopInsn(f: Frame<V>, insn: Int) {
processControlFlowEdge(f, insn, insn + 1)
}
private fun processControlFlowEdge(current: Frame<V>, insn: Int, jump: Int) {
if (visitControlFlowEdge(insn, jump)) {
mergeControlFlowEdge(jump, current)
}
}
private fun initControlFlowAnalysis(current: Frame<V>, m: MethodNode, owner: String) {
current.setReturn(interpreter.newValue(Type.getReturnType(m.desc)))
val args = Type.getArgumentTypes(m.desc)
var local = 0
if ((m.access and Opcodes.ACC_STATIC) == 0) {
val ctype = Type.getObjectType(owner)
current.setLocal(local++, interpreter.newValue(ctype))
}
for (arg in args) {
current.setLocal(local++, interpreter.newValue(arg))
if (arg.size == 2) {
current.setLocal(local++, interpreter.newValue(null))
}
}
while (local < m.maxLocals) {
current.setLocal(local++, interpreter.newValue(null))
}
mergeControlFlowEdge(0, current)
}
private fun computeExceptionEdges() {
for (tcb in method.tryCatchBlocks) {
// Don't have to visit same exception handler multiple times - we care only about stack state at TCB start.
val start = tcb.start.indexOf()
var insnHandlers: MutableList<TryCatchBlockNode>? = handlers[start]
if (insnHandlers == null) {
insnHandlers = ArrayList()
handlers[start] = insnHandlers
}
insnHandlers.add(tcb)
}
}
private fun mergeControlFlowEdge(dest: Int, frame: Frame<V>) {
val destFrame = frames[dest]
if (destFrame == null) {
// Don't have to visit same instruction multiple times - we care only about "initial" stack state.
frames[dest] = newFrame(frame.locals, frame.maxStackSize).apply { init(frame) }
if (!queued[dest]) {
queued[dest] = true
queue[top++] = dest
}
}
}
}

View File

@@ -19,9 +19,6 @@ package org.jetbrains.kotlin.codegen.optimization.fixStack
import com.intellij.util.containers.Stack
import org.jetbrains.kotlin.codegen.inline.isAfterInlineMarker
import org.jetbrains.kotlin.codegen.inline.isBeforeInlineMarker
import org.jetbrains.kotlin.codegen.inline.isMarkedReturn
import org.jetbrains.kotlin.codegen.optimization.common.MethodAnalyzer
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.org.objectweb.asm.Opcodes
@@ -29,7 +26,6 @@ import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode
import org.jetbrains.org.objectweb.asm.tree.LabelNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
import kotlin.math.max
@@ -49,9 +45,14 @@ internal class FixStackAnalyzer(
val maxExtraStackSize: Int get() = analyzer.maxExtraStackSize
fun getStackToSpill(location: AbstractInsnNode) = analyzer.spilledStacks[location]
fun getActualStack(location: AbstractInsnNode) = getFrame(location)?.getStackContent()
fun getActualStackSize(location: AbstractInsnNode) = getFrame(location)?.stackSizeWithExtra ?: DEAD_CODE_STACK_SIZE
fun getStackToSpill(location: AbstractInsnNode): List<FixStackValue>? =
analyzer.spilledStacks[location]
fun getActualStack(location: AbstractInsnNode): List<FixStackValue>? =
getFrame(location)?.getStackContent()
fun getActualStackSize(location: AbstractInsnNode): Int =
getFrame(location)?.stackSizeWithExtra ?: DEAD_CODE_STACK_SIZE
fun getExpectedStackSize(location: AbstractInsnNode): Int {
// We should look for expected stack size at loop entry point markers if available,
@@ -88,25 +89,27 @@ internal class FixStackAnalyzer(
private val analyzer = InternalAnalyzer(owner)
private inner class InternalAnalyzer(owner: String) : MethodAnalyzer<BasicValue>(owner, method, OptimizationBasicInterpreter()) {
val spilledStacks = hashMapOf<AbstractInsnNode, List<BasicValue>>()
private inner class InternalAnalyzer(owner: String) :
FastStackAnalyzer<FixStackValue>(owner, method, FixStackInterpreter()) {
val spilledStacks = hashMapOf<AbstractInsnNode, List<FixStackValue>>()
var maxExtraStackSize = 0; private set
override fun visitControlFlowEdge(insn: Int, successor: Int): Boolean {
if (!skipBreakContinueGotoEdges) return true
val insnNode = instructions[insn]
val insnNode = insnsArray[insn]
return !(insnNode is JumpInsnNode && context.breakContinueGotoNodes.contains(insnNode))
}
override fun newFrame(nLocals: Int, nStack: Int): Frame<BasicValue> =
override fun newFrame(nLocals: Int, nStack: Int): Frame<FixStackValue> =
FixStackFrame(nLocals, nStack)
private fun indexOf(node: AbstractInsnNode) = method.instructions.indexOf(node)
inner class FixStackFrame(nLocals: Int, nStack: Int) : Frame<BasicValue>(nLocals, nStack) {
val extraStack = Stack<BasicValue>()
inner class FixStackFrame(nLocals: Int, nStack: Int) : Frame<FixStackValue>(nLocals, nStack) {
val extraStack = Stack<FixStackValue>()
override fun init(src: Frame<out BasicValue>): Frame<BasicValue> {
override fun init(src: Frame<out FixStackValue>): Frame<FixStackValue> {
extraStack.clear()
extraStack.addAll((src as FixStackFrame).extraStack)
return super.init(src)
@@ -117,7 +120,7 @@ internal class FixStackAnalyzer(
super.clearStack()
}
override fun execute(insn: AbstractInsnNode, interpreter: Interpreter<BasicValue>) {
override fun execute(insn: AbstractInsnNode, interpreter: Interpreter<FixStackValue>) {
when {
PseudoInsn.SAVE_STACK_BEFORE_TRY.isa(insn) ->
executeSaveStackBeforeTry(insn)
@@ -127,10 +130,8 @@ internal class FixStackAnalyzer(
executeBeforeInlineCallMarker(insn)
isAfterInlineMarker(insn) ->
executeAfterInlineCallMarker(insn)
isMarkedReturn(insn) -> {
// KT-9644: might throw "Incompatible return type" on non-local return, in fact we don't care.
if (insn.opcode == Opcodes.RETURN) return
}
insn.opcode == Opcodes.RETURN ->
return
}
super.execute(insn, interpreter)
@@ -138,14 +139,16 @@ internal class FixStackAnalyzer(
val stackSizeWithExtra: Int get() = super.getStackSize() + extraStack.size
fun getStackContent(): List<BasicValue> {
val savedStack = arrayListOf<BasicValue>()
IntRange(0, super.getStackSize() - 1).mapTo(savedStack) { super.getStack(it) }
fun getStackContent(): List<FixStackValue> {
val savedStack = ArrayList<FixStackValue>()
for (i in 0 until super.getStackSize()) {
savedStack.add(super.getStack(i))
}
savedStack.addAll(extraStack)
return savedStack
}
override fun push(value: BasicValue) {
override fun push(value: FixStackValue) {
if (super.getStackSize() < maxStackSize) {
super.push(value)
} else {
@@ -154,24 +157,27 @@ internal class FixStackAnalyzer(
}
}
fun pushAll(values: Collection<BasicValue>) {
fun pushAll(values: Collection<FixStackValue>) {
values.forEach { push(it) }
}
override fun pop(): BasicValue {
return if (extraStack.isNotEmpty()) {
override fun pop(): FixStackValue =
if (extraStack.isNotEmpty()) {
extraStack.pop()
} else {
super.pop()
}
override fun setStack(i: Int, value: FixStackValue) {
if (i < super.getMaxStackSize()) {
super.setStack(i, value)
} else {
extraStack[i - maxStackSize] = value
}
}
override fun getStack(i: Int): BasicValue {
return if (i < super.getMaxStackSize()) {
super.getStack(i)
} else {
extraStack[i - maxStackSize]
}
override fun merge(frame: Frame<out FixStackValue>, interpreter: Interpreter<FixStackValue>): Boolean {
throw UnsupportedOperationException("Stack normalization should not merge frames")
}
}

View File

@@ -0,0 +1,157 @@
/*
* 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.optimization.fixStack
import org.jetbrains.kotlin.codegen.inline.insnOpcodeText
import org.jetbrains.org.objectweb.asm.Handle
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
open class FixStackInterpreter : Interpreter<FixStackValue>(API_VERSION) {
override fun newValue(type: Type?): FixStackValue =
type?.toFixStackValue()
?: FixStackValue.UNINITIALIZED
override fun newOperation(insn: AbstractInsnNode): FixStackValue? =
when (insn.opcode) {
ACONST_NULL ->
FixStackValue.OBJECT
ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5 ->
FixStackValue.INT
LCONST_0, LCONST_1 ->
FixStackValue.LONG
FCONST_0, FCONST_1, FCONST_2 ->
FixStackValue.FLOAT
DCONST_0, DCONST_1 ->
FixStackValue.DOUBLE
BIPUSH, SIPUSH ->
FixStackValue.INT
LDC -> {
when (val cst = (insn as LdcInsnNode).cst) {
is Int ->
FixStackValue.INT
is Float ->
FixStackValue.FLOAT
is Long ->
FixStackValue.LONG
is Double ->
FixStackValue.DOUBLE
is String, is Handle ->
FixStackValue.OBJECT
is Type -> {
val sort = cst.sort
if (sort == Type.OBJECT || sort == Type.ARRAY || sort == Type.METHOD)
FixStackValue.OBJECT
else
throw IllegalArgumentException("Illegal LDC constant $cst")
}
else ->
throw IllegalArgumentException("Illegal LDC constant $cst")
}
}
GETSTATIC ->
newValue(Type.getType((insn as FieldInsnNode).desc))
NEW ->
newValue(Type.getObjectType((insn as TypeInsnNode).desc))
else ->
throw IllegalArgumentException("Unexpected instruction: " + insn.insnOpcodeText)
}
override fun copyOperation(insn: AbstractInsnNode, value: FixStackValue?): FixStackValue =
when (insn.opcode) {
ILOAD -> FixStackValue.INT
LLOAD -> FixStackValue.LONG
FLOAD -> FixStackValue.FLOAT
DLOAD -> FixStackValue.DOUBLE
ALOAD -> FixStackValue.OBJECT
else -> value!!
}
override fun binaryOperation(insn: AbstractInsnNode, value1: FixStackValue?, value2: FixStackValue?): FixStackValue? =
when (insn.opcode) {
IALOAD, BALOAD, CALOAD, SALOAD, IADD, ISUB, IMUL, IDIV, IREM, ISHL, ISHR, IUSHR, IAND, IOR, IXOR ->
FixStackValue.INT
FALOAD, FADD, FSUB, FMUL, FDIV, FREM ->
FixStackValue.FLOAT
LALOAD, LADD, LSUB, LMUL, LDIV, LREM, LSHL, LSHR, LUSHR, LAND, LOR, LXOR ->
FixStackValue.LONG
DALOAD, DADD, DSUB, DMUL, DDIV, DREM ->
FixStackValue.DOUBLE
AALOAD ->
FixStackValue.OBJECT
LCMP, FCMPL, FCMPG, DCMPL, DCMPG ->
FixStackValue.INT
IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, PUTFIELD ->
null
else ->
throw IllegalArgumentException("Unexpected instruction: " + insn.insnOpcodeText)
}
override fun ternaryOperation(
insn: AbstractInsnNode,
value1: FixStackValue?,
value2: FixStackValue?,
value3: FixStackValue?
): FixStackValue? =
null
override fun naryOperation(insn: AbstractInsnNode, values: List<FixStackValue?>): FixStackValue? =
when (insn.opcode) {
MULTIANEWARRAY ->
newValue(Type.getType((insn as MultiANewArrayInsnNode).desc))
INVOKEDYNAMIC ->
newValue(Type.getReturnType((insn as InvokeDynamicInsnNode).desc))
else ->
newValue(Type.getReturnType((insn as MethodInsnNode).desc))
}
override fun returnOperation(insn: AbstractInsnNode?, value: FixStackValue?, expected: FixStackValue?) {
}
override fun unaryOperation(insn: AbstractInsnNode, value: FixStackValue?): FixStackValue? =
when (insn.opcode) {
INEG, IINC, L2I, F2I, D2I, I2B, I2C, I2S ->
FixStackValue.INT
FNEG, I2F, L2F, D2F ->
FixStackValue.FLOAT
LNEG, I2L, F2L, D2L ->
FixStackValue.LONG
DNEG, I2D, L2D, F2D ->
FixStackValue.DOUBLE
IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, TABLESWITCH, LOOKUPSWITCH, IRETURN, LRETURN, FRETURN, DRETURN, ARETURN, PUTSTATIC ->
null
GETFIELD ->
newValue(Type.getType((insn as FieldInsnNode).desc))
NEWARRAY ->
FixStackValue.OBJECT
ANEWARRAY -> {
FixStackValue.OBJECT
}
ARRAYLENGTH ->
FixStackValue.INT
ATHROW ->
null
CHECKCAST ->
FixStackValue.OBJECT
INSTANCEOF ->
FixStackValue.INT
MONITORENTER, MONITOREXIT, IFNULL, IFNONNULL ->
null
else ->
throw IllegalArgumentException("Unexpected instruction: " + insn.insnOpcodeText)
}
override fun merge(v: FixStackValue?, w: FixStackValue?): FixStackValue? =
when {
v == w -> v
v == null -> w
w == null -> v
else -> throw AssertionError("Mismatching value kinds: $v != $w")
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen.optimization.fixStack
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.analysis.Value
enum class FixStackValue(
private val _size: Int,
val loadOpcode: Int,
val storeOpcode: Int,
val popOpcode: Int
) : Value {
INT(1, Opcodes.ILOAD, Opcodes.ISTORE, Opcodes.POP),
LONG(2, Opcodes.LLOAD, Opcodes.LSTORE, Opcodes.POP2),
FLOAT(1, Opcodes.FLOAD, Opcodes.FSTORE, Opcodes.POP),
DOUBLE(2, Opcodes.DLOAD, Opcodes.DSTORE, Opcodes.POP2),
OBJECT(1, Opcodes.ALOAD, Opcodes.ASTORE, Opcodes.POP),
UNINITIALIZED(1, -1, -1, -1)
;
override fun getSize(): Int = _size
}
fun Type.toFixStackValue(): FixStackValue? =
when (this.sort) {
Type.VOID -> null
Type.BOOLEAN, Type.BYTE, Type.CHAR, Type.SHORT, Type.INT -> FixStackValue.INT
Type.LONG -> FixStackValue.LONG
Type.FLOAT -> FixStackValue.FLOAT
Type.DOUBLE -> FixStackValue.DOUBLE
Type.OBJECT, Type.ARRAY, Type.METHOD -> FixStackValue.OBJECT
else -> throw AssertionError("Unexpected type: $this")
}

View File

@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.codegen.optimization.fixStack
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
import kotlin.math.max
internal class LocalVariablesManager(val context: FixStackContext, val methodNode: MethodNode) {
@@ -39,7 +38,10 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
methodNode.maxLocals = max(methodNode.maxLocals, newValue)
}
fun allocateVariablesForSaveStackMarker(saveStackMarker: AbstractInsnNode, savedStackValues: List<BasicValue>): SavedStackDescriptor {
fun allocateVariablesForSaveStackMarker(
saveStackMarker: AbstractInsnNode,
savedStackValues: List<FixStackValue>
): SavedStackDescriptor {
val numRestoreStackMarkers = context.restoreStackMarkersForSaveMarker[saveStackMarker]!!.size
return allocateNewHandle(numRestoreStackMarkers, saveStackMarker, savedStackValues)
}
@@ -47,10 +49,10 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
private fun allocateNewHandle(
numRestoreStackMarkers: Int,
saveStackMarker: AbstractInsnNode,
savedStackValues: List<BasicValue>
savedStackValues: List<FixStackValue>
): SavedStackDescriptor {
if (savedStackValues.any { it.type == null }) {
throw AssertionError("Uninitialized value on stack at ${methodNode.instructions.indexOf(saveStackMarker)}")
if (savedStackValues.any { it == FixStackValue.UNINITIALIZED }) {
throw AssertionError("Uninitialized value on stack at ${methodNode.instructions.indexOf(saveStackMarker)}: $savedStackValues")
}
val firstUnusedLocalVarIndex = getFirstUnusedLocalVariableIndex()
@@ -78,7 +80,7 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
fun allocateVariablesForBeforeInlineMarker(
beforeInlineMarker: AbstractInsnNode,
savedStackValues: List<BasicValue>
savedStackValues: List<FixStackValue>
): SavedStackDescriptor {
return allocateNewHandle(1, beforeInlineMarker, savedStackValues)
}
@@ -101,7 +103,7 @@ internal class LocalVariablesManager(val context: FixStackContext, val methodNod
}
}
fun createReturnValueVariable(returnValue: BasicValue): Int {
fun createReturnValueVariable(returnValue: FixStackValue): Int {
val returnValueIndex = getFirstUnusedLocalVariableIndex()
updateMaxLocals(returnValueIndex + returnValue.size)
return returnValueIndex

View File

@@ -54,10 +54,10 @@ fun <V : Value> Frame<V>.peekWords(size1: Int, size2: Int): List<V>? {
}
class SavedStackDescriptor(
val savedValues: List<BasicValue>,
val savedValues: List<FixStackValue>,
val firstLocalVarIndex: Int
) {
private val savedValuesSize = savedValues.fold(0, { size, value -> size + value.size })
private val savedValuesSize = savedValues.fold(0) { size, value -> size + value.size }
val firstUnusedLocalVarIndex = firstLocalVarIndex + savedValuesSize
override fun toString(): String =
@@ -88,13 +88,13 @@ fun restoreStackWithReturnValue(
methodNode: MethodNode,
nodeToReplace: AbstractInsnNode,
savedStackDescriptor: SavedStackDescriptor,
returnValue: BasicValue,
returnValue: FixStackValue,
returnValueLocalVarIndex: Int
) {
with(methodNode.instructions) {
insertBefore(nodeToReplace, VarInsnNode(returnValue.type.getOpcode(Opcodes.ISTORE), returnValueLocalVarIndex))
insertBefore(nodeToReplace, VarInsnNode(returnValue.storeOpcode, returnValueLocalVarIndex))
generateLoadInstructions(methodNode, nodeToReplace, savedStackDescriptor)
insertBefore(nodeToReplace, VarInsnNode(returnValue.type.getOpcode(Opcodes.ILOAD), returnValueLocalVarIndex))
insertBefore(nodeToReplace, VarInsnNode(returnValue.loadOpcode, returnValueLocalVarIndex))
remove(nodeToReplace)
}
}
@@ -102,10 +102,7 @@ fun restoreStackWithReturnValue(
fun generateLoadInstructions(methodNode: MethodNode, location: AbstractInsnNode, savedStackDescriptor: SavedStackDescriptor) {
var localVarIndex = savedStackDescriptor.firstLocalVarIndex
for (value in savedStackDescriptor.savedValues) {
methodNode.instructions.insertBefore(
location,
VarInsnNode(value.type.getOpcode(Opcodes.ILOAD), localVarIndex)
)
methodNode.instructions.insertBefore(location, VarInsnNode(value.loadOpcode, localVarIndex))
localVarIndex += value.size
}
}
@@ -114,10 +111,7 @@ fun generateStoreInstructions(methodNode: MethodNode, location: AbstractInsnNode
var localVarIndex = savedStackDescriptor.firstUnusedLocalVarIndex
for (value in savedStackDescriptor.savedValues.asReversed()) {
localVarIndex -= value.size
methodNode.instructions.insertBefore(
location,
VarInsnNode(value.type.getOpcode(Opcodes.ISTORE), localVarIndex)
)
methodNode.instructions.insertBefore(location, VarInsnNode(value.storeOpcode, localVarIndex))
}
}
@@ -146,10 +140,10 @@ fun replaceAlwaysTrueIfeqWithGoto(methodNode: MethodNode, node: AbstractInsnNode
}
}
fun replaceMarkerWithPops(methodNode: MethodNode, node: AbstractInsnNode, expectedStackSize: Int, stackContent: List<BasicValue>) {
fun replaceMarkerWithPops(methodNode: MethodNode, node: AbstractInsnNode, expectedStackSize: Int, stackContent: List<FixStackValue>) {
with(methodNode.instructions) {
for (stackValue in stackContent.subList(expectedStackSize, stackContent.size)) {
insert(node, getPopInstruction(stackValue))
insert(node, InsnNode(stackValue.popOpcode))
}
remove(node)
}

View File

@@ -17,13 +17,14 @@
package org.jetbrains.kotlin.codegen.optimization.transformer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.optimization.common.FastMethodAnalyzer;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
import org.jetbrains.org.objectweb.asm.tree.analysis.*;
public abstract class MethodTransformer {
@NotNull
protected static <V extends Value> Frame<V>[] runAnalyzer(
private static <V extends Value> Frame<V>[] runAnalyzer(
@NotNull Analyzer<V> analyzer,
@NotNull String internalClassName,
@NotNull MethodNode node
@@ -42,7 +43,12 @@ public abstract class MethodTransformer {
@NotNull MethodNode node,
@NotNull Interpreter<V> interpreter
) {
return runAnalyzer(new Analyzer<>(interpreter), internalClassName, node);
try {
FastMethodAnalyzer<V> analyser = new FastMethodAnalyzer<>(internalClassName, node, interpreter);
return analyser.analyze();
} catch (Exception e) {
throw ExceptionUtilsKt.rethrow(e);
}
}
public abstract void transform(@NotNull String internalClassName, @NotNull MethodNode methodNode);

View File

@@ -35,6 +35,8 @@ public final class JvmSerializationBindings {
SerializationMappingSlice.create();
public static final SerializationMappingSlice<PropertyDescriptor, Method> SYNTHETIC_METHOD_FOR_PROPERTY =
SerializationMappingSlice.create();
public static final SerializationMappingSlice<PropertyDescriptor, Method> DELEGATE_METHOD_FOR_PROPERTY =
SerializationMappingSlice.create();
public static final class SerializationMappingSlice<K, V> extends BasicWritableSlice<K, V> {
public SerializationMappingSlice() {

View File

@@ -255,12 +255,15 @@ class JvmSerializerExtension @JvmOverloads constructor(
val field = getBinding(FIELD_FOR_PROPERTY, descriptor)
val syntheticMethod = getBinding(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor)
val delegateMethod = getBinding(DELEGATE_METHOD_FOR_PROPERTY, descriptor)
assert(descriptor.isDelegated || delegateMethod == null) { "non-delegated property $descriptor has delegate method" }
val signature = signatureSerializer.propertySignature(
descriptor,
field?.second,
field?.first?.descriptor,
if (syntheticMethod != null) signatureSerializer.methodSignature(null, syntheticMethod) else null,
if (delegateMethod != null) signatureSerializer.methodSignature(null, delegateMethod) else null,
if (getterMethod != null) signatureSerializer.methodSignature(null, getterMethod) else null,
if (setterMethod != null) signatureSerializer.methodSignature(null, setterMethod) else null
)
@@ -359,6 +362,7 @@ class JvmSerializerExtension @JvmOverloads constructor(
fieldName: String?,
fieldDesc: String?,
syntheticMethod: JvmProtoBuf.JvmMethodSignature?,
delegateMethod: JvmProtoBuf.JvmMethodSignature?,
getter: JvmProtoBuf.JvmMethodSignature?,
setter: JvmProtoBuf.JvmMethodSignature?
): JvmProtoBuf.JvmPropertySignature? {
@@ -373,6 +377,10 @@ class JvmSerializerExtension @JvmOverloads constructor(
signature.syntheticMethod = syntheticMethod
}
if (delegateMethod != null) {
signature.delegateMethod = delegateMethod
}
if (getter != null) {
signature.getter = getter
}

View File

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

View File

@@ -12,25 +12,6 @@ val otherCompilerModules = compilerModules.filter { it != path }
val tasksWithWarnings: List<String> by rootProject.extra
val effectSystemEnabled: Boolean by rootProject.extra
val newInferenceEnabled: Boolean by rootProject.extra
configureFreeCompilerArg(effectSystemEnabled, "-Xeffect-system")
configureFreeCompilerArg(newInferenceEnabled, "-Xnew-inference")
configureFreeCompilerArg(true, "-Xuse-mixed-named-arguments")
fun configureFreeCompilerArg(isEnabled: Boolean, compilerArgument: String) {
if (isEnabled) {
allprojects {
tasks.withType<KotlinCompile<*>> {
kotlinOptions {
freeCompilerArgs += listOf(compilerArgument)
}
}
}
}
}
val antLauncherJar by configurations.creating
dependencies {
@@ -85,7 +66,9 @@ if (kotlinBuildProperties.isInJpsBuildIdeaSync) {
idea {
this.module.generatedSourceDirs.add(generationRoot)
}
} else if (!kotlinBuildProperties.useFir && !kotlinBuildProperties.disableWerror) {
}
if (!kotlinBuildProperties.disableWerror) {
allprojects {
tasks.withType<KotlinCompile<*>> {
if (path !in tasksWithWarnings) {

View File

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

View File

@@ -1,6 +1,5 @@
<idea-plugin>
<id>org.jetbrains.kotlin</id>
<version>1.2</version>
<extensionPoints>
<extensionPoint qualifiedName="org.jetbrains.kotlin.analyzeCompleteHandlerExtension"

View File

@@ -1,12 +0,0 @@
<idea-plugin>
<id>org.jetbrains.kotlin</id>
<version>1.2</version>
<!-- Don't add more extension points here! Logic in KotlinCoreEnvironment assumes that there is only one EP. -->
<!-- And this file should be removed once 202 is no longer supported -->
<extensionPoints>
<extensionPoint qualifiedName="com.intellij.psi.classFileDecompiler"
interface="com.intellij.psi.compiled.ClassFileDecompilers$Decompiler"
dynamic="true"/>
</extensionPoints>
</idea-plugin>

View File

@@ -1,10 +0,0 @@
<idea-plugin>
<id>org.jetbrains.kotlin</id>
<version>1.2</version>
<extensionPoints>
<extensionPoint qualifiedName="com.intellij.psi.classFileDecompiler"
interface="com.intellij.psi.compiled.ClassFileDecompilers$Decompiler"
dynamic="true"/>
</extensionPoints>
</idea-plugin>

View File

@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.cli.common.arguments
import com.intellij.util.xmlb.annotations.Transient
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.*
import java.util.*
@@ -82,6 +83,15 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
@Argument(value = "-P", valueDescription = PLUGIN_OPTION_FORMAT, description = "Pass an option to a plugin")
var pluginOptions: Array<String>? by FreezableVar(null)
@Argument(
value = "-opt-in",
// Uncomment after deletion of optInDeprecated
// deprecatedName = "-Xopt-in",
valueDescription = "<fq.name>",
description = "Enable usages of API that requires opt-in with an opt-in requirement marker with the given fully qualified name"
)
var optIn: Array<String>? by FreezableVar(null)
// Advanced options
@Argument(value = "-Xno-inline", description = "Disable method inlining")
@@ -157,13 +167,6 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
var readDeserializedContracts: Boolean by FreezableVar(false)
@Argument(
value = "-Xexperimental",
valueDescription = "<fq.name>",
description = "Enable and propagate usages of experimental API for marker annotation with the given fully qualified name"
)
var experimental: Array<String>? by FreezableVar(null)
@Argument(
value = "-Xuse-experimental",
valueDescription = "<fq.name>",
@@ -171,12 +174,13 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
var useExperimental: Array<String>? by FreezableVar(null)
// NB: we have to keep this flag for some time due to bootstrapping problems
@Argument(
value = "-Xopt-in",
valueDescription = "<fq.name>",
description = "Enable usages of API that requires opt-in with an opt-in requirement marker with the given fully qualified name"
)
var optIn: Array<String>? by FreezableVar(null)
var optInDeprecated: Array<String>? by FreezableVar(null)
@Argument(
value = "-Xproper-ieee754-comparisons",
@@ -365,17 +369,37 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
var extendedCompilerChecks: Boolean by FreezableVar(false)
@Argument(
value = "-Xbuiltins-from-sources",
description = "Compile builtIns from sources"
)
var builtInsFromSources: Boolean by FreezableVar(false)
@Argument(
value = "-Xunrestricted-builder-inference",
description = "Eliminate builder inference restrictions like allowance of returning type variables of a builder inference call"
)
var unrestrictedBuilderInference: Boolean by FreezableVar(false)
open fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap<AnalysisFlag<*>, Any> {
return HashMap<AnalysisFlag<*>, Any>().apply {
put(AnalysisFlags.skipMetadataVersionCheck, skipMetadataVersionCheck)
put(AnalysisFlags.skipPrereleaseCheck, skipPrereleaseCheck || skipMetadataVersionCheck)
put(AnalysisFlags.multiPlatformDoNotCheckActual, noCheckActual)
val experimentalFqNames = experimental?.toList().orEmpty()
if (experimentalFqNames.isNotEmpty()) {
put(AnalysisFlags.experimental, experimentalFqNames)
collector.report(CompilerMessageSeverity.WARNING, "'-Xexperimental' is deprecated and will be removed in a future release")
val useExperimentalFqNames = useExperimental?.toList().orEmpty()
if (useExperimentalFqNames.isNotEmpty()) {
collector.report(
WARNING, "'-Xuse-experimental' is deprecated and will be removed in a future release, please use -opt-in instead"
)
}
put(AnalysisFlags.useExperimental, useExperimental?.toList().orEmpty() + optIn?.toList().orEmpty())
val optInDeprecatedFqNames = optInDeprecated?.toList().orEmpty()
if (optInDeprecatedFqNames.isNotEmpty()) {
// TODO: uncomment this after -opt-in bootstrapping and Gradle script fixing
// collector.report(
// WARNING, "'-Xopt-in' is deprecated and will be removed in a future release, please use -opt-in instead"
// )
}
put(AnalysisFlags.useExperimental, useExperimentalFqNames + optInDeprecatedFqNames + optIn?.toList().orEmpty())
put(AnalysisFlags.expectActualLinker, expectActualLinker)
put(AnalysisFlags.explicitApiVersion, apiVersion != null)
put(AnalysisFlags.allowResultReturnType, allowResultReturnType)
@@ -385,6 +409,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
put(AnalysisFlags.extendedCompilerChecks, extendedCompilerChecks)
put(AnalysisFlags.allowKotlinPackage, allowKotlinPackage)
put(AnalysisFlags.builtInsFromSources, builtInsFromSources)
}
}
@@ -394,6 +419,10 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
put(LanguageFeature.MultiPlatformProjects, LanguageFeature.State.ENABLED)
}
if (unrestrictedBuilderInference) {
put(LanguageFeature.UnrestrictedBuilderInference, LanguageFeature.State.ENABLED)
}
if (newInference) {
put(LanguageFeature.NewInference, LanguageFeature.State.ENABLED)
put(LanguageFeature.SamConversionPerArgument, LanguageFeature.State.ENABLED)

View File

@@ -214,6 +214,12 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
)
var useOldClassFilesReading: Boolean by FreezableVar(false)
@Argument(
value = "-Xuse-fast-jar-file-system",
description = "Use fast implementation on Jar FS. This may speed up compilation time, but currently it's an experimental mode"
)
var useFastJarFileSystem: Boolean by FreezableVar(false)
@Argument(
value = "-Xdump-declarations-to",
valueDescription = "<path>",
@@ -452,9 +458,9 @@ default: `indy-with-constants` for JVM target 9 or greater, `inline` otherwise""
@Argument(
value = "-Xprofile",
valueDescription = "<profilerPath:command:outputDir>",
description = "Debug option: Run compiler with async profiler, save snapshots to outputDir, command is passed to async-profiler on start\n" +
"You'll have to provide async-profiler.jar on classpath to use this\n" +
"profilerPath is a path to libasyncProfiler.so\n" +
description = "Debug option: Run compiler with async profiler and save snapshots to `outputDir`; `command` is passed to async-profiler on start.\n" +
"`profilerPath` is a path to libasyncProfiler.so; async-profiler.jar should be on the compiler classpath.\n" +
"If it's not on the classpath, the compiler will attempt to load async-profiler.jar from the containing directory of profilerPath.\n" +
"Example: -Xprofile=<PATH_TO_ASYNC_PROFILER>/async-profiler/build/libasyncProfiler.so:event=cpu,interval=1ms,threads,start,framebuf=50000000:<SNAPSHOT_DIR_PATH>"
)
var profileCompilerCommand: String? by NullableStringFreezableVar(null)
@@ -499,6 +505,24 @@ default: `indy-with-constants` for JVM target 9 or greater, `inline` otherwise""
)
var typeEnhancementImprovementsInStrictMode: Boolean by FreezableVar(false)
@Argument(
value = "-Xserialize-ir",
description = "Save IR to metadata (EXPERIMENTAL)"
)
var serializeIr: Boolean by FreezableVar(false)
@Argument(
value = "-Xvalidate-ir",
description = "Validate IR before and after lowering"
)
var validateIr: Boolean by FreezableVar(false)
@Argument(
value = "-Xvalidate-bytecode",
description = "Validate generated JVM bytecode before and after optimizations"
)
var validateBytecode: Boolean by FreezableVar(false)
override fun configureAnalysisFlags(collector: MessageCollector, languageVersion: LanguageVersion): MutableMap<AnalysisFlag<*>, Any> {
val result = super.configureAnalysisFlags(collector, languageVersion)
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics

View File

@@ -107,7 +107,7 @@ private fun <A : CommonToolArguments> parsePreprocessedCommandLineArguments(args
return arg.startsWith(argument.value + "=")
}
return argument.value == arg
return argument.value == arg || arg.startsWith(argument.value + "=")
}
val freeArgs = ArrayList<String>()
@@ -160,10 +160,10 @@ private fun <A : CommonToolArguments> parsePreprocessedCommandLineArguments(args
val (property, argument) = argumentField
val value: Any = when {
argumentField.property.returnType.classifier == Boolean::class -> true
argument.isAdvanced && arg.startsWith(argument.value + "=") -> {
arg.startsWith(argument.value + "=") -> {
arg.substring(argument.value.length + 1)
}
argument.isAdvanced && arg.startsWith(argument.deprecatedName + "=") -> {
arg.startsWith(argument.deprecatedName + "=") -> {
arg.substring(argument.deprecatedName.length + 1)
}
i == args.size -> {

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.cli.common.modules;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,7 +30,10 @@ import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.*;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import static org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR;
@@ -59,19 +61,13 @@ public class ModuleXmlParser {
@NotNull String xmlFile,
@NotNull MessageCollector messageCollector
) {
FileInputStream stream = null;
try {
//noinspection IOResourceOpenedButNotSafelyClosed
stream = new FileInputStream(xmlFile);
try (FileInputStream stream = new FileInputStream(xmlFile)) {
return new ModuleXmlParser(messageCollector).parse(new BufferedInputStream(stream));
}
catch (FileNotFoundException e) {
catch (IOException e) {
MessageCollectorUtil.reportException(messageCollector, e);
return ModuleChunk.EMPTY;
}
finally {
StreamUtil.closeStream(stream);
}
}
private final MessageCollector messageCollector;

View File

@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.cli.common.config.addKotlinSourceRoot
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageUtil
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
@@ -39,6 +38,8 @@ import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
import org.jetbrains.kotlin.incremental.js.IncrementalNextRoundChecker
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
import org.jetbrains.kotlin.ir.backend.js.*
import org.jetbrains.kotlin.ir.backend.js.ic.buildCache
import org.jetbrains.kotlin.ir.backend.js.ic.checkCaches
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.declarations.persistent.PersistentIrFactory
import org.jetbrains.kotlin.js.config.*
@@ -48,7 +49,6 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.serialization.js.ModuleKind
import org.jetbrains.kotlin.util.Logger
import org.jetbrains.kotlin.utils.KotlinPaths
import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlin.utils.fileUtils.withReplacedExtensionOrNull
@@ -93,7 +93,7 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
configuration.put(CommonConfigurationKeys.MODULE_NAME, "repl.kts")
val environment = KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForProduction(rootDisposable, configuration)
val projectEnv = KotlinCoreEnvironment.ProjectEnvironment(rootDisposable, environment)
val projectEnv = KotlinCoreEnvironment.ProjectEnvironment(rootDisposable, environment, configuration)
projectEnv.registerExtensionsFromPlugins(configuration)
val scriptingEvaluators = ScriptEvaluationExtension.getInstances(projectEnv.project)
@@ -181,15 +181,42 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
// TODO: Handle non-empty main call arguments
val mainCallArguments = if (K2JsArgumentConstants.NO_CALL == arguments.main) null else emptyList<String>()
val resolvedLibraries = jsResolveLibraries(
libraries,
configuration[JSConfigurationKeys.REPOSITORIES] ?: emptyList(),
messageCollectorLogger(configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY] ?: error("Could not find message collector"))
)
val icCaches = configureLibraries(arguments.cacheDirectories)
val friendAbsolutePaths = friendLibraries.map { File(it).absolutePath }
val friendDependencies = resolvedLibraries.getFullList().filter {
it.libraryFile.absolutePath in friendAbsolutePaths
if (arguments.irBuildCache) {
messageCollector.report(INFO, "")
messageCollector.report(INFO, "Building cache:")
messageCollector.report(INFO, "to: ${outputFilePath}")
messageCollector.report(INFO, arguments.cacheDirectories ?: "")
messageCollector.report(INFO, libraries.toString())
val includes = arguments.includes!!
// TODO: deduplicate
val mainModule = run {
if (sourcesFiles.isNotEmpty()) {
messageCollector.report(ERROR, "Source files are not supported when -Xinclude is present")
}
MainModule.Klib(includes)
}
val start = System.currentTimeMillis()
if (buildCache(
cachePath = outputFilePath,
project = projectJs,
mainModule = mainModule,
analyzer = AnalyzerWithCompilerReport(config.configuration),
configuration = config.configuration,
dependencies = libraries,
friendDependencies = friendLibraries,
icCache = checkCaches(libraries, icCaches, skipLib = mainModule.libPath)
)
) {
messageCollector.report(INFO, "IC cache building duration: ${System.currentTimeMillis() - start}ms")
} else {
messageCollector.report(INFO, "IC cache up-to-date check duration: ${System.currentTimeMillis() - start}ms")
}
return OK
}
if (arguments.irProduceKlibDir || arguments.irProduceKlibFile) {
@@ -202,8 +229,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
files = sourcesFiles,
analyzer = AnalyzerWithCompilerReport(config.configuration),
configuration = config.configuration,
allDependencies = resolvedLibraries,
friendDependencies = friendDependencies,
dependencies = libraries,
friendDependencies = friendLibraries,
irFactory = PersistentIrFactory(), // TODO IrFactoryImpl?
outputKlibPath = outputFile.path,
nopack = arguments.irProduceKlibDir,
@@ -212,6 +239,9 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
}
if (arguments.irProduceJs) {
messageCollector.report(INFO,"Produce executable: $outputFilePath")
messageCollector.report(INFO, arguments.cacheDirectories ?: "")
val phaseConfig = createPhaseConfig(jsPhases, arguments, messageCollector)
val includes = arguments.includes
@@ -220,9 +250,10 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
if (sourcesFiles.isNotEmpty()) {
messageCollector.report(ERROR, "Source files are not supported when -Xinclude is present")
}
val allLibraries = resolvedLibraries.getFullList()
val mainLib = allLibraries.find { it.libraryFile.absolutePath == File(includes).absolutePath }!!
MainModule.Klib(mainLib)
val includesPath = File(includes).canonicalPath
val mainLibPath = libraries.find { File(it).canonicalPath == includesPath }
?: error("No library with name $includes ($includesPath) found")
MainModule.Klib(mainLibPath)
} else {
MainModule.SourceFiles(sourcesFiles)
}
@@ -235,8 +266,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
config.configuration,
PhaseConfig(wasmPhases),
IrFactoryImpl,
allDependencies = resolvedLibraries,
friendDependencies = friendDependencies,
dependencies = libraries,
friendDependencies = friendLibraries,
exportedDeclarations = setOf(FqName("main"))
)
val outputWasmFile = outputFile.withReplacedExtensionOrNull(outputFile.extension, "wasm")!!
@@ -255,6 +286,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
return OK
}
val start = System.currentTimeMillis()
val compiledModule = compile(
projectJs,
mainModule,
@@ -262,8 +295,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
config.configuration,
phaseConfig,
if (arguments.irDceDriven) PersistentIrFactory() else IrFactoryImpl,
allDependencies = resolvedLibraries,
friendDependencies = friendDependencies,
dependencies = libraries,
friendDependencies = friendLibraries,
mainArguments = mainCallArguments,
generateFullJs = !arguments.irDce,
generateDceJs = arguments.irDce,
@@ -282,8 +315,13 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
arguments.irSafeExternalBooleanDiagnostic,
messageCollector
),
lowerPerModule = icCaches.isNotEmpty(),
useStdlibCache = icCaches.isNotEmpty(),
icCache = if (icCaches.isNotEmpty()) checkCaches(libraries, icCaches, skipLib = includes).data else emptyMap(),
)
messageCollector.report(INFO, "Executable production duration: ${System.currentTimeMillis() - start}ms")
val outputs = if (arguments.irDce && !arguments.irDceDriven) compiledModule.outputsAfterDce!! else compiledModule.outputs!!
outputFile.write(outputs)
outputs.dependencies.forEach { (name, content) ->
@@ -476,17 +514,6 @@ fun RuntimeDiagnostic.Companion.resolve(
}
}
fun messageCollectorLogger(collector: MessageCollector) = object : Logger {
override fun warning(message: String) = collector.report(STRONG_WARNING, message)
override fun error(message: String) = collector.report(ERROR, message)
override fun log(message: String) = collector.report(LOGGING, message)
override fun fatal(message: String): Nothing {
collector.report(ERROR, message)
(collector as? GroupingMessageCollector)?.flush()
kotlin.error(message)
}
}
fun loadPluginsForTests(configuration: CompilerConfiguration): ExitCode {
var pluginClasspaths: Iterable<String> = emptyList()
val kotlinPaths = PathUtil.kotlinPathsForCompiler

View File

@@ -1,137 +0,0 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Map;
import java.util.ResourceBundle;
public abstract class DynamicBundle extends AbstractBundle {
private final static Logger LOG = Logger.getInstance(DynamicBundle.class);
protected DynamicBundle(@NotNull String pathToBundle) {
super(pathToBundle);
}
// see BundleUtil
@Override
protected ResourceBundle findBundle(@NotNull String pathToBundle,
@NotNull ClassLoader baseLoader,
@NotNull ResourceBundle.Control control) {
ResourceBundle base = super.findBundle(pathToBundle, baseLoader, control);
LanguageBundleEP langBundle = findLanguageBundle();
if (langBundle == null) return base;
ResourceBundle pluginBundle = super.findBundle(pathToBundle, langBundle.getLoaderForClass(), control);
if (pluginBundle == null) return base;
try {
if (DynamicBundleInternal.SET_PARENT != null) {
DynamicBundleInternal.SET_PARENT.invoke(pluginBundle, base);
}
}
catch (Throwable e) {
LOG.warn(e);
return base;
}
return pluginBundle;
}
/**
* "SET_PARENT" has been temporary moved into the internal class to fix Kotlin compiler.
* It's to be refactored with "ResourceBundleProvider" since 'core-api' module will use java 1.9+
*/
private static class DynamicBundleInternal {
private static final MethodHandle SET_PARENT;
static {
try {
Method method = ResourceBundle.class.getDeclaredMethod("setParent", ResourceBundle.class);
method.setAccessible(true);
SET_PARENT = MethodHandles.lookup().unreflect(method);
}
catch (NoSuchMethodException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
// todo: one language per application
@Nullable
private static LanguageBundleEP findLanguageBundle() {
try {
Application application = ApplicationManager.getApplication();
if (application == null) return null;
if (application.isUnitTestMode() && !application.getExtensionArea().hasExtensionPoint(LanguageBundleEP.EP_NAME)) {
return null;
}
return LanguageBundleEP.EP_NAME.findExtension(LanguageBundleEP.class);
}
catch (ProcessCanceledException e) {
throw e;
}
catch (Exception e) {
LOG.error(e);
return null;
}
}
public static final DynamicBundle INSTANCE = new DynamicBundle("") {
};
@SuppressWarnings("deprecation")
public static class LanguageBundleEP extends com.intellij.openapi.extensions.AbstractExtensionPointBean {
public static final ExtensionPointName<LanguageBundleEP> EP_NAME = ExtensionPointName.create("com.intellij.languageBundle");
}
private static final Map<String, DynamicBundle> ourBundlesForForms = ContainerUtil.createConcurrentSoftValueMap();
/**
* @deprecated used only dy GUI form builder
*/
@Deprecated
public static ResourceBundle getBundle(@NotNull String baseName) {
Class<?> callerClass = ReflectionUtil.findCallerClass(2);
return getBundle(baseName, callerClass == null ? DynamicBundle.class : callerClass);
}
/**
* @deprecated used only dy GUI form builder
*/
@Deprecated
public static ResourceBundle getBundle(@NotNull String baseName, @NotNull Class<?> formClass) {
DynamicBundle dynamic = ourBundlesForForms.computeIfAbsent(baseName, s -> new DynamicBundle(s) {});
ResourceBundle rb = dynamic.getResourceBundle(formClass.getClassLoader());
if (BundleBase.SHOW_LOCALIZED_MESSAGES) {
return new ResourceBundle() {
@Override
protected Object handleGetObject(@NotNull String key) {
Object get = rb.getObject(key);
assert get instanceof String : "Language bundles should contain only strings";
return BundleBase.appendLocalizationMarker((String)get);
}
@NotNull
@Override
public Enumeration<String> getKeys() {
return rb.getKeys();
}
};
}
return rb;
}
}

View File

@@ -0,0 +1,13 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.io;
import org.jetbrains.annotations.NotNull;
import java.nio.channels.FileChannel;
public final class FileChannelUtil {
@NotNull
static FileChannel unInterruptible(@NotNull FileChannel channel) {
return channel;
}
}

View File

@@ -5,9 +5,9 @@
package org.jetbrains.kotlin.cli.common.extensions
import com.intellij.core.JavaCoreProjectEnvironment
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
@@ -22,6 +22,6 @@ interface ScriptEvaluationExtension {
fun eval(
arguments: CommonCompilerArguments,
configuration: CompilerConfiguration,
projectEnvironment: JavaCoreProjectEnvironment
projectEnvironment: KotlinCoreEnvironment.ProjectEnvironment
): ExitCode
}

View File

@@ -5,8 +5,10 @@
package org.jetbrains.kotlin.cli.common.profiling
import java.io.File
import java.lang.invoke.MethodHandles
import java.lang.invoke.MethodType
import java.net.URLClassLoader
interface AsyncProfilerReflected {
fun execute(command: String): String
@@ -14,24 +16,29 @@ interface AsyncProfilerReflected {
val version: String
}
object AsyncProfilerHelper {
private val profilerClass = Class.forName("one.profiler.AsyncProfiler")
private val getInstanceHandle =
MethodHandles.lookup().findStatic(profilerClass, "getInstance", MethodType.methodType(profilerClass, String::class.java))
private val executeHandle =
MethodHandles.lookup().findVirtual(
profilerClass,
"execute",
MethodType.methodType(String::class.java, String::class.java)
)
private val stopHandle =
MethodHandles.lookup().findVirtual(profilerClass, "stop", MethodType.methodType(Void.TYPE))
private val getVersionHandle =
MethodHandles.lookup().findVirtual(profilerClass, "getVersion", MethodType.methodType(String::class.java))
private var instance: AsyncProfilerReflected? = null
fun getInstance(libPath: String?): AsyncProfilerReflected {
// JVM doesn't support loading a native library multiple times even in different class loaders, so we don't attempt to load
// async-profiler again after the first use, which allows to profile the same compiler process multiple times,
// for example in the compiler daemon scenario.
instance?.let { return it }
val profilerClass = loadAsyncProfilerClass(libPath)
val getInstanceHandle =
MethodHandles.lookup().findStatic(profilerClass, "getInstance", MethodType.methodType(profilerClass, String::class.java))
val executeHandle =
MethodHandles.lookup().findVirtual(
profilerClass,
"execute",
MethodType.methodType(String::class.java, String::class.java)
)
val stopHandle =
MethodHandles.lookup().findVirtual(profilerClass, "stop", MethodType.methodType(Void.TYPE))
val getVersionHandle =
MethodHandles.lookup().findVirtual(profilerClass, "getVersion", MethodType.methodType(String::class.java))
val instance = getInstanceHandle.invokeWithArguments(libPath)
return object : AsyncProfilerReflected {
private val boundExecute = executeHandle.bindTo(instance)
@@ -49,6 +56,24 @@ object AsyncProfilerHelper {
override val version: String
get() = boundGetVersion.invokeWithArguments() as String
}.also { this.instance = it }
}
private fun loadAsyncProfilerClass(libPath: String?): Class<*> {
val fqName = "one.profiler.AsyncProfiler"
return try {
Class.forName(fqName)
} catch (e: ClassNotFoundException) {
if (libPath == null) throw e
else {
val directory = File(libPath).parentFile
check(directory.isDirectory) { directory }
val apiJar = directory.resolve("async-profiler.jar")
if (!apiJar.exists())
error("To use async-profiler, either add it to the compiler classpath, or put async-profiler.jar at this path: $apiJar")
val classLoader = URLClassLoader(arrayOf(apiJar.toURI().toURL()), null)
classLoader.loadClass(fqName)
}
}
}
}
}

View File

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

View File

@@ -89,7 +89,8 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
val projectEnvironment =
KotlinCoreEnvironment.ProjectEnvironment(
rootDisposable,
KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForProduction(rootDisposable, configuration)
KotlinCoreEnvironment.getOrCreateApplicationEnvironmentForProduction(rootDisposable, configuration),
configuration
)
projectEnvironment.registerExtensionsFromPlugins(configuration)

View File

@@ -129,4 +129,7 @@ class CliKotlinAsJavaSupport(
PsiSearchScopeUtil.isInScope(searchScope, it)
}.orEmpty()
}
override fun createFacadeForSyntheticFile(facadeClassFqName: FqName, file: KtFile): PsiClass =
error("Should not be called")
}

View File

@@ -5,12 +5,15 @@
package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.VirtualFileSystem
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ProjectScope
import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices
import org.jetbrains.kotlin.asJava.FilteredJvmDiagnostics
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
@@ -18,6 +21,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensionsImpl
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
import org.jetbrains.kotlin.backend.jvm.jvmPhases
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager
import org.jetbrains.kotlin.cli.common.checkKotlinPackageUsage
import org.jetbrains.kotlin.cli.common.fir.FirDiagnosticsCompilerResultsReporter
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
@@ -27,28 +31,38 @@ import org.jetbrains.kotlin.cli.jvm.config.jvmModularRoots
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
import org.jetbrains.kotlin.codegen.CodegenFactory
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.fir.DependencyListForCliModule
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnostic
import org.jetbrains.kotlin.fir.backend.Fir2IrResult
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendExtension
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.fir.session.FirSessionFactory.createSessionWithDependencies
import org.jetbrains.kotlin.load.kotlin.incremental.IncrementalPackagePartProvider
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.modules.Module
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
import org.jetbrains.kotlin.resolve.multiplatform.isCommonSource
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
import org.jetbrains.kotlin.utils.addToStdlib.runIf
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
import java.io.File
import kotlin.collections.set
object FirKotlinToJvmBytecodeCompiler {
fun compileModulesUsingFrontendIR(
@@ -65,61 +79,118 @@ object FirKotlinToJvmBytecodeCompiler {
"ATTENTION!\n This build uses in-dev FIR: \n -Xuse-fir"
)
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
val psiFinderExtensionPoint = PsiElementFinder.EP.getPoint(project)
if (psiFinderExtensionPoint.extensionList.any { it is JavaElementFinder }) {
psiFinderExtensionPoint.unregisterExtension(JavaElementFinder::class.java)
}
val projectConfiguration = environment.configuration
val localFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL)
val outputs = newLinkedHashMapWithExpectedSize<Module, GenerationState>(chunk.size)
val targetIds = environment.configuration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId)
val incrementalComponents = environment.configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS)
val isMultiModuleChunk = chunk.size > 1
for (module in chunk) {
performanceManager?.notifyAnalysisStarted()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val ktFiles = module.getSourceFiles(environment, localFileSystem, chunk.size > 1, buildFile)
if (!checkKotlinPackageUsage(environment, ktFiles)) return false
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, environment.messageCollector).isHasErrors or errorsFound
}
val moduleConfiguration = projectConfiguration.applyModuleProperties(module, buildFile)
val context = CompilationContext(
module,
project,
environment,
moduleConfiguration,
localFileSystem,
isMultiModuleChunk,
buildFile,
performanceManager,
targetIds,
incrementalComponents,
extendedAnalysisMode
)
val generationState = context.compileModule() ?: return false
outputs[module] = generationState
val sourceScope = GlobalSearchScope.filesWithoutLibrariesScope(project, ktFiles.map { it.virtualFile })
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
Disposer.dispose(environment.project)
}
var librariesScope = ProjectScope.getLibrariesScope(project)
val mainClassFqName: FqName? =
if (chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null)
TODO(".jar output is not yet supported for -Xuse-fir: KT-42868")
else null
val providerAndScopeForIncrementalCompilation = run {
if (targetIds == null || incrementalComponents == null) return@run null
val fileSystem = environment.projectEnvironment.environment.localFileSystem
val directoryWithIncrementalPartsFromPreviousCompilation =
moduleConfiguration[JVMConfigurationKeys.OUTPUT_DIRECTORY]
?: return@run null
val previouslyCompiledFiles = directoryWithIncrementalPartsFromPreviousCompilation.walk()
.filter { it.extension == "class" }
.mapNotNull { fileSystem.findFileByIoFile(it) }
.toList()
.takeIf { it.isNotEmpty() }
?: return@run null
val packagePartProvider = IncrementalPackagePartProvider(
environment.createPackagePartProvider(sourceScope),
targetIds.map(incrementalComponents::getIncrementalCache)
)
val incrementalCompilationScope = GlobalSearchScope.filesWithoutLibrariesScope(
project,
previouslyCompiledFiles
)
librariesScope = librariesScope.intersectWith(GlobalSearchScope.notScope(incrementalCompilationScope))
FirSessionFactory.ProviderAndScopeForIncrementalCompilation(packagePartProvider, incrementalCompilationScope)
}
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
}
val languageVersionSettings = moduleConfiguration.languageVersionSettings
val session = createSessionWithDependencies(
Name.identifier(module.getModuleName()),
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices,
externalSessionProvider = null,
private fun CompilationContext.compileModule(): GenerationState? {
performanceManager?.notifyAnalysisStarted()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
val ktFiles = module.getSourceFiles(environment, localFileSystem, isMultiModuleChunk, buildFile)
if (!checkKotlinPackageUsage(environment, ktFiles)) return null
val firAnalyzerFacade = runFrontend(ktFiles).also {
performanceManager?.notifyAnalysisFinished()
} ?: return null
performanceManager?.notifyGenerationStarted()
performanceManager?.notifyIRTranslationStarted()
val extensions = JvmGeneratorExtensionsImpl(moduleConfiguration)
val fir2IrResult = firAnalyzerFacade.convertToIr(extensions)
val session = firAnalyzerFacade.session
performanceManager?.notifyIRTranslationFinished()
val generationState = runBackend(
ktFiles,
fir2IrResult,
extensions,
session
)
performanceManager?.notifyIRGenerationFinished()
performanceManager?.notifyGenerationFinished()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
return generationState
}
private fun CompilationContext.runFrontend(ktFiles: List<KtFile>): FirAnalyzerFacade? {
@Suppress("NAME_SHADOWING")
var ktFiles = ktFiles
val syntaxErrors = ktFiles.fold(false) { errorsFound, ktFile ->
AnalyzerWithCompilerReport.reportSyntaxErrors(ktFile, environment.messageCollector).isHasErrors or errorsFound
}
var sourceScope = GlobalSearchScope.filesWithoutLibrariesScope(project, ktFiles.map { it.virtualFile })
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
var librariesScope = ProjectScope.getLibrariesScope(project)
val providerAndScopeForIncrementalCompilation = createComponentsForIncrementalCompilation(sourceScope)
providerAndScopeForIncrementalCompilation?.scope?.let {
librariesScope = librariesScope.intersectWith(GlobalSearchScope.notScope(it))
}
val languageVersionSettings = moduleConfiguration.languageVersionSettings
val commonKtFiles = ktFiles.filter { it.isCommonSource == true }
val sessionProvider = FirProjectSessionProvider()
fun createSession(
name: String,
platform: TargetPlatform,
analyzerServices: PlatformDependentAnalyzerServices,
sourceScope: GlobalSearchScope,
dependenciesConfigurator: DependencyListForCliModule.Builder.() -> Unit = {}
): FirSession {
return createSessionWithDependencies(
Name.identifier(name),
platform,
analyzerServices,
externalSessionProvider = sessionProvider,
project,
languageVersionSettings,
sourceScope,
@@ -131,6 +202,7 @@ object FirKotlinToJvmBytecodeCompiler {
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
dependenciesConfigurator()
},
sessionConfigurator = {
if (extendedAnalysisMode) {
@@ -138,90 +210,140 @@ object FirKotlinToJvmBytecodeCompiler {
}
}
)
val firAnalyzerFacade = FirAnalyzerFacade(session, languageVersionSettings, ktFiles)
firAnalyzerFacade.runResolution()
val firDiagnostics = firAnalyzerFacade.runCheckers().values.flatten()
val hasErrors = FirDiagnosticsCompilerResultsReporter.reportDiagnostics(firDiagnostics, environment.messageCollector)
performanceManager?.notifyAnalysisFinished()
if (syntaxErrors || hasErrors) {
return false
}
performanceManager?.notifyGenerationStarted()
performanceManager?.notifyIRTranslationStarted()
val extensions = JvmGeneratorExtensionsImpl()
val (moduleFragment, symbolTable, components) = firAnalyzerFacade.convertToIr(extensions)
performanceManager?.notifyIRTranslationFinished()
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
val codegenFactory = JvmIrCodegenFactory(moduleConfiguration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases))
// Create and initialize the module and its dependencies
val container = TopDownAnalyzerFacadeForJVM.createContainer(
project, ktFiles, NoScopeRecordCliBindingTrace(), environment.configuration, environment::createPackagePartProvider,
::FileBasedDeclarationProviderFactory, CompilerEnvironment,
TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, ktFiles), emptyList()
)
val generationState = GenerationState.Builder(
environment.project, ClassBuilderFactories.BINARIES,
container.get(), dummyBindingContext, ktFiles,
moduleConfiguration
).codegenFactory(
codegenFactory
).withModule(
module
).onIndependentPartCompilationEnd(
createOutputFilesFlushingCallbackIfPossible(moduleConfiguration)
).isIrBackend(
true
).jvmBackendClassResolver(
FirJvmBackendClassResolver(components)
).build()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
performanceManager?.notifyIRLoweringStarted()
generationState.beforeCompile()
codegenFactory.generateModuleInFrontendIRMode(
generationState, moduleFragment, symbolTable, extensions, FirJvmBackendExtension(session, components)
) {
performanceManager?.notifyIRLoweringFinished()
performanceManager?.notifyIRGenerationStarted()
}
CodegenFactory.doCheckCancelled(generationState)
generationState.factory.done()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
AnalyzerWithCompilerReport.reportDiagnostics(
FilteredJvmDiagnostics(
generationState.collectedExtraJvmDiagnostics,
dummyBindingContext.diagnostics
),
environment.messageCollector
)
performanceManager?.notifyIRGenerationFinished()
performanceManager?.notifyGenerationFinished()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
outputs[module] = generationState
PsiElementFinder.EP.getPoint(project).unregisterExtension(JavaElementFinder::class.java)
Disposer.dispose(environment.project)
}
val mainClassFqName: FqName? =
if (chunk.size == 1 && projectConfiguration.get(JVMConfigurationKeys.OUTPUT_JAR) != null)
TODO(".jar output is not yet supported for -Xuse-fir: KT-42868")
else null
val commonSession = runIf(
languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects) && commonKtFiles.isNotEmpty()
) {
val commonSourcesScope = GlobalSearchScope.filesWithoutLibrariesScope(project, commonKtFiles.map { it.virtualFile })
sourceScope = sourceScope.intersectWith(GlobalSearchScope.notScope(commonSourcesScope))
ktFiles = ktFiles.filterNot { it.isCommonSource == true }
createSession(
"${module.getModuleName()}-common",
CommonPlatforms.defaultCommonPlatform,
CommonPlatformAnalyzerServices,
commonSourcesScope
)
}
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
val session = createSession(
module.getModuleName(),
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices,
sourceScope
) {
if (commonSession != null) {
sourceDependsOnDependencies(listOf(commonSession.moduleData))
}
friendDependencies(module.getFriendPaths())
}
val commonAnalyzerFacade = commonSession?.let { FirAnalyzerFacade(it, languageVersionSettings, commonKtFiles) }
val firAnalyzerFacade = FirAnalyzerFacade(session, languageVersionSettings, ktFiles)
commonAnalyzerFacade?.runResolution()
val allFirDiagnostics = mutableListOf<FirDiagnostic>()
commonAnalyzerFacade?.runCheckers()?.values?.flattenTo(allFirDiagnostics)
firAnalyzerFacade.runResolution()
firAnalyzerFacade.runCheckers().values.flattenTo(allFirDiagnostics)
val hasErrors = FirDiagnosticsCompilerResultsReporter.reportDiagnostics(allFirDiagnostics, environment.messageCollector)
return firAnalyzerFacade.takeUnless { syntaxErrors || hasErrors }
}
private fun CompilationContext.createComponentsForIncrementalCompilation(
sourceScope: GlobalSearchScope
): FirSessionFactory.ProviderAndScopeForIncrementalCompilation? {
if (targetIds == null || incrementalComponents == null) return null
val fileSystem = environment.projectEnvironment.environment.localFileSystem
val directoryWithIncrementalPartsFromPreviousCompilation =
moduleConfiguration[JVMConfigurationKeys.OUTPUT_DIRECTORY]
?: return null
val previouslyCompiledFiles = directoryWithIncrementalPartsFromPreviousCompilation.walk()
.filter { it.extension == "class" }
.mapNotNull { fileSystem.findFileByIoFile(it) }
.toList()
.takeIf { it.isNotEmpty() }
?: return null
val packagePartProvider = IncrementalPackagePartProvider(
environment.createPackagePartProvider(sourceScope),
targetIds.map(incrementalComponents::getIncrementalCache)
)
val incrementalCompilationScope = GlobalSearchScope.filesWithoutLibrariesScope(
project,
previouslyCompiledFiles
)
return FirSessionFactory.ProviderAndScopeForIncrementalCompilation(packagePartProvider, incrementalCompilationScope)
}
private fun CompilationContext.runBackend(
ktFiles: List<KtFile>,
fir2IrResult: Fir2IrResult,
extensions: JvmGeneratorExtensionsImpl,
session: FirSession
): GenerationState {
val (moduleFragment, symbolTable, components) = fir2IrResult
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
val codegenFactory = JvmIrCodegenFactory(
moduleConfiguration,
moduleConfiguration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases),
jvmGeneratorExtensions = extensions
)
val generationState = GenerationState.Builder(
environment.project, ClassBuilderFactories.BINARIES,
moduleFragment.descriptor, dummyBindingContext, ktFiles,
moduleConfiguration
).codegenFactory(
codegenFactory
).withModule(
module
).onIndependentPartCompilationEnd(
createOutputFilesFlushingCallbackIfPossible(moduleConfiguration)
).isIrBackend(
true
).jvmBackendClassResolver(
FirJvmBackendClassResolver(components)
).build()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
performanceManager?.notifyIRLoweringStarted()
generationState.beforeCompile()
codegenFactory.generateModuleInFrontendIRMode(
generationState, moduleFragment, symbolTable, extensions, FirJvmBackendExtension(session, components)
) {
performanceManager?.notifyIRLoweringFinished()
performanceManager?.notifyIRGenerationStarted()
}
CodegenFactory.doCheckCancelled(generationState)
generationState.factory.done()
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
AnalyzerWithCompilerReport.reportDiagnostics(
FilteredJvmDiagnostics(
generationState.collectedExtraJvmDiagnostics,
dummyBindingContext.diagnostics
),
environment.messageCollector
)
ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
return generationState
}
private class CompilationContext(
val module: Module,
val project: Project,
val environment: KotlinCoreEnvironment,
val moduleConfiguration: CompilerConfiguration,
val localFileSystem: VirtualFileSystem,
val isMultiModuleChunk: Boolean,
val buildFile: File?,
val performanceManager: CommonCompilerPerformanceManager?,
val targetIds: List<TargetId>?,
val incrementalComponents: IncrementalCompilationComponents?,
val extendedAnalysisMode: Boolean
)
}

View File

@@ -1,19 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.openapi.project.DumbUtil
@Suppress("UnstableApiUsage")
class KotlinCoreDumbUtil : DumbUtil {
override fun <T : Any?> filterByDumbAwarenessHonoringIgnoring(collection: Collection<T>): List<T> =
when (collection) {
is List<T> -> collection
else -> ArrayList(collection)
}
override fun mayUseIndices(): Boolean = false
}

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