Compare commits

...

207 Commits

Author SHA1 Message Date
Dmitry Petrov
8b33a50783 JVM skip methods without NEW insns in UninitializedStoresProcessor 2021-07-22 08:23:38 +03:00
Dmitry Petrov
cf7d0a1566 Minor HackedFixStackMethodAnalyzerBase -> FastStackAnalyzer 2021-07-21 16:19:02 +03:00
Dmitry Petrov
8b46dce8a2 JVM use new stack state analyzer in non-local returns preprocessing 2021-07-21 15:28:50 +03:00
Dmitry Petrov
5785e29e32 JVM don't use SPBs in FixStack method analyzer (we don't merge) 2021-07-21 15:28:50 +03:00
Dmitry Petrov
2376033218 JVM don't optimize if there are too many data on exception edges 2021-07-21 15:28:49 +03:00
Dmitry Petrov
ddd1a0a376 JVM skip redundant boxing optimization in methods without boxing 2021-07-21 15:28:49 +03: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
50715 changed files with 21364 additions and 1167810 deletions

View File

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

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

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

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

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

@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.utils.keysToMap
import java.io.File
import java.io.IOException
import java.util.*
import kotlin.system.measureTimeMillis
open class LookupStorage(
targetDataDir: File,
@@ -50,15 +49,11 @@ 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)
@@ -108,7 +103,6 @@ open class LookupStorage(
val id = fileToId[file] ?: continue
idToFile.remove(id)
fileToId.remove(file)
deletedCount++
}
}
@@ -119,7 +113,6 @@ open class LookupStorage(
}
size = 0
deletedCount = 0
super.clean()
}
@@ -127,15 +120,13 @@ 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\n")
}
} finally {
super.flush(memoryCachesOnly)
@@ -152,28 +143,37 @@ 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 removeGarbageForTests() {
for (hash in lookupMap.keys) {
lookupMap[hash] = lookupMap[hash]!!.filter { it in idToFile }.toSet()
}
}
private fun doRemoveGarbage() {
val timeInMillis = measureTimeMillis {
for (hash in lookupMap.keys) {
val dirtyFileIds = lookupMap[hash]!!
val filteredFileIds = dirtyFileIds.filter { it in idToFile }.toSet()
if (dirtyFileIds != filteredFileIds) lookupMap[hash] = filteredFileIds
val oldFileToId = fileToId.toMap()
val oldIdToNewId = HashMap<Int, Int>(oldFileToId.size)
idToFile.clean()
fileToId.clean()
size = 0
for ((file, oldId) in oldFileToId.entries.sortedBy { it.key.path }) {
val newId = addFileIfNeeded(file)
oldIdToNewId[oldId] = newId
}
for (lookup in lookupMap.keys) {
val fileIds = lookupMap[lookup]!!.mapNotNull { oldIdToNewId[it] }.toSet()
if (fileIds.isEmpty()) {
lookupMap.remove(lookup)
} else {
lookupMap[lookup] = fileIds
}
deletedCount = 0
}
LOG.debug(">>Garbage removed in $timeInMillis ms")
}
@TestOnly
fun forceGC() {
removeGarbageIfNeeded(force = true)
removeGarbageForTests()
flush(false)
}

View File

@@ -734,14 +734,6 @@ 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-js-test:test")
}

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

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

@@ -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.
*
@@ -1288,9 +1297,6 @@ 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
@@ -1298,7 +1304,6 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
method.localVariables.clear()
// 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 +1315,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
@@ -1337,14 +1342,32 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
// 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)
}
oldLvtNodeToLatestNewLvtNode[lvtRecord] = node
method.localVariables.add(node)
}
}
}
// Merge consequent LVT records, otherwise, atomicfu goes crazy (KT-47749)
val toRemove = arrayListOf<LocalVariableNode>()
val sortedLVT = method.localVariables.sortedBy { method.instructions.indexOf(it.start) }
for (i in sortedLVT.indices) {
var endIndex = method.instructions.indexOf(sortedLVT[i].end)
for (j in (i + 1) until sortedLVT.size) {
val startIndex = method.instructions.indexOf(sortedLVT[j].start)
if (endIndex < startIndex) break
if (endIndex != startIndex ||
sortedLVT[i].index != sortedLVT[j].index ||
sortedLVT[i].name != sortedLVT[j].name ||
sortedLVT[i].desc != sortedLVT[j].desc
) continue
sortedLVT[i].end = sortedLVT[j].end
endIndex = method.instructions.indexOf(sortedLVT[j].end)
toRemove += sortedLVT[j]
}
}
method.localVariables.removeAll(toRemove)
for (variable in oldLvt) {
// $continuation and $result are dead, but they are used by debugger, as well as fake inliner variables
// For example, $continuation is used to create async stack trace

View File

@@ -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,10 @@ 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 +184,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 +232,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

@@ -17,8 +17,8 @@ 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.fixStack.*
import org.jetbrains.kotlin.codegen.optimization.fixStack.FastStackAnalyzer
import org.jetbrains.kotlin.codegen.optimization.nullCheck.isCheckParameterIsNotNull
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsn
import org.jetbrains.kotlin.config.LanguageFeature
@@ -36,8 +36,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 +55,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()
@@ -273,7 +273,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)
@@ -303,7 +304,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)
@@ -441,7 +442,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))
}
}
@@ -533,33 +534,37 @@ 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
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
}
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
}
}
}
@@ -588,7 +593,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)
}
@@ -742,7 +747,7 @@ class MethodInliner(
ApiVersionCallsPreprocessingMethodTransformer(targetApiVersion).transform("fake", node)
}
val frames = analyzeMethodNodeWithInterpreter(node, BasicInterpreter())
val frames = FastStackAnalyzer("<fake>", node, FixStackInterpreter()).analyze()
val localReturnsNormalizer = LocalReturnsNormalizer()
@@ -831,9 +836,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) {
@@ -878,6 +883,7 @@ class MethodInliner(
}
}
@Suppress("SameParameterValue")
private fun wrapException(originalException: Throwable, node: MethodNode, errorSuffix: String): RuntimeException {
return if (originalException is InlineException) {
InlineException("$errorPrefix: $errorSuffix", originalException)
@@ -890,7 +896,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) {
@@ -901,22 +907,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))
}
}
}
@@ -926,10 +929,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] }
@@ -938,11 +941,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

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

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

@@ -11,8 +11,8 @@ import org.jetbrains.org.objectweb.asm.tree.*
class ControlFlowGraph private constructor(private val insns: InsnList) {
private val successors: Array<MutableList<Int>> = Array(insns.size()) { ArrayList() }
private val predecessors: Array<MutableList<Int>> = Array(insns.size()) { ArrayList() }
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> = successors[index]

View File

@@ -45,7 +45,7 @@ import org.jetbrains.org.objectweb.asm.tree.analysis.Interpreter
import org.jetbrains.org.objectweb.asm.tree.analysis.Value
/**
* @see FlexibleMethodAnalyzer
* @see org.jetbrains.kotlin.codegen.optimization.fixStack.FastStackAnalyzer
*/
@Suppress("DuplicatedCode")
open class FastMethodAnalyzer<V : Value>(

View File

@@ -1,346 +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
/**
* This class is a modified version of `org.objectweb.asm.tree.analysis.Analyzer`
*
* @see FastMethodAnalyzer
*
* @author Eric Bruneton
* @author Dmitry Petrov
*/
@Suppress("DuplicatedCode")
open class FlexibleMethodAnalyzer<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
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
private val singlePredBlock = IntArray(nInsns)
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
checkAssertions()
computeExceptionHandlersForEachInsn()
initSinglePredBlocks()
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 = tcb.handler.indexOf()
if (visitControlFlowExceptionEdge(insn, tcb.handler.indexOf())) {
handler.init(f)
handler.clearStack()
handler.push(interpreter.newValue(exnType))
mergeControlFlowEdge(insn, 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 initSinglePredBlocks() {
markSinglePredBlockEntries()
markSinglePredBlockBodies()
}
private fun markSinglePredBlockEntries() {
// Method entry point is SPB entry point.
var blockId = 0
singlePredBlock[0] = ++blockId
// Every jump target is SPB entry point.
for (insn in insnsArray) {
when (insn) {
is JumpInsnNode -> {
val labelIndex = insn.label.indexOf()
if (singlePredBlock[labelIndex] == 0) {
singlePredBlock[labelIndex] = ++blockId
}
}
is LookupSwitchInsnNode -> {
insn.dflt?.let { dfltLabel ->
val dfltIndex = dfltLabel.indexOf()
if (singlePredBlock[dfltIndex] == 0) {
singlePredBlock[dfltIndex] = ++blockId
}
}
for (label in insn.labels) {
val labelIndex = label.indexOf()
if (singlePredBlock[labelIndex] == 0) {
singlePredBlock[labelIndex] = ++blockId
}
}
}
is TableSwitchInsnNode -> {
insn.dflt?.let { dfltLabel ->
val dfltIndex = dfltLabel.indexOf()
if (singlePredBlock[dfltIndex] == 0) {
singlePredBlock[dfltIndex] = ++blockId
}
}
for (label in insn.labels) {
val labelIndex = label.indexOf()
if (singlePredBlock[labelIndex] == 0) {
singlePredBlock[labelIndex] = ++blockId
}
}
}
}
}
// Every try-catch block handler entry point is SPB entry point
for (tcb in method.tryCatchBlocks) {
val handlerIndex = tcb.handler.indexOf()
if (singlePredBlock[handlerIndex] == 0) {
singlePredBlock[handlerIndex] = ++blockId
}
}
}
private fun markSinglePredBlockBodies() {
var current = 0
for ((i, insn) in insnsArray.withIndex()) {
if (singlePredBlock[i] == 0) {
singlePredBlock[i] = current
} else {
// Entered a new SPB.
current = singlePredBlock[i]
}
// GOTO, ATHROW, *RETURN instructions terminate current SPB.
when (insn.opcode) {
Opcodes.GOTO,
Opcodes.ATHROW,
in Opcodes.IRETURN..Opcodes.RETURN ->
current = 0
}
}
}
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 && insnOpcode != Opcodes.JSR) {
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(insn, 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, 0, current)
}
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 insn = insnsArray[j]
if (!insn.isMeaningful) continue
var insnHandlers: MutableList<TryCatchBlockNode>? = handlers[j]
if (insnHandlers == null) {
insnHandlers = ArrayList<TryCatchBlockNode>()
handlers[j] = insnHandlers
}
insnHandlers.add(tcb)
}
}
}
private fun mergeControlFlowEdge(src: Int, 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
}
dest == src + 1 && singlePredBlock[src] == singlePredBlock[dest] -> {
// Forward jump within a single predecessor block, no need to merge.
oldFrame.init(frame)
true
}
else ->
oldFrame.merge(frame, interpreter)
}
if (changes && !queued[dest]) {
queued[dest] = true
queue[top++] = dest
}
}
}

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 {
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 = 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 && insnOpcode != Opcodes.JSR) {
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.FlexibleMethodAnalyzer
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,8 +89,10 @@ internal class FixStackAnalyzer(
private val analyzer = InternalAnalyzer(owner)
private inner class InternalAnalyzer(owner: String) : FlexibleMethodAnalyzer<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 {
@@ -98,15 +101,15 @@ internal class FixStackAnalyzer(
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

@@ -407,6 +407,7 @@ class GenerationState private constructor(
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_7] = JvmMetadataVersion(1, 7, 0)
check(size == LanguageVersion.values().size) {
"Please add mappings from the missing LanguageVersion instances to the corresponding JvmMetadataVersion " +

View File

@@ -369,6 +369,13 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
var extendedCompilerChecks: Boolean by FreezableVar(false)
@GradleOption(DefaultValues.BooleanFalseDefault::class)
@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"
@@ -403,6 +410,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
put(AnalysisFlags.extendedCompilerChecks, extendedCompilerChecks)
put(AnalysisFlags.allowKotlinPackage, allowKotlinPackage)
put(AnalysisFlags.builtInsFromSources, builtInsFromSources)
}
}

View File

@@ -17,7 +17,14 @@ interface AsyncProfilerReflected {
}
object AsyncProfilerHelper {
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))
@@ -49,7 +56,7 @@ object AsyncProfilerHelper {
override val version: String
get() = boundGetVersion.invokeWithArguments() as String
}
}.also { this.instance = it }
}
private fun loadAsyncProfilerClass(libPath: String?): Class<*> {

View File

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

@@ -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,29 +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.FirJavaElementFinder
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(
@@ -77,149 +90,24 @@ object FirKotlinToJvmBytecodeCompiler {
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 sourceScope = GlobalSearchScope.filesWithoutLibrariesScope(project, ktFiles.map { it.virtualFile })
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
var librariesScope = ProjectScope.getLibrariesScope(project)
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)
}
val languageVersionSettings = moduleConfiguration.languageVersionSettings
val session = createSessionWithDependencies(
Name.identifier(module.getModuleName()),
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices,
externalSessionProvider = null,
val context = CompilationContext(
module,
project,
languageVersionSettings,
sourceScope,
librariesScope,
lookupTracker = environment.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
providerAndScopeForIncrementalCompilation,
getPackagePartProvider = { environment.createPackagePartProvider(it) },
dependenciesConfigurator = {
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
},
sessionConfigurator = {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
}
}
environment,
moduleConfiguration,
localFileSystem,
isMultiModuleChunk,
buildFile,
performanceManager,
targetIds,
incrementalComponents,
extendedAnalysisMode
)
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(projectConfiguration)
val (moduleFragment, symbolTable, components) = firAnalyzerFacade.convertToIr(extensions)
performanceManager?.notifyIRTranslationFinished()
val dummyBindingContext = NoScopeRecordCliBindingTrace().bindingContext
val codegenFactory = JvmIrCodegenFactory(
projectConfiguration,
moduleConfiguration.get(CLIConfigurationKeys.PHASE_CONFIG) ?: PhaseConfig(jvmPhases),
jvmGeneratorExtensions = extensions
)
// 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()
val generationState = context.compileModule() ?: return false
outputs[module] = generationState
Disposer.dispose(environment.project)
@@ -232,4 +120,229 @@ object FirKotlinToJvmBytecodeCompiler {
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
}
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,
librariesScope,
lookupTracker = environment.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER),
providerAndScopeForIncrementalCompilation,
getPackagePartProvider = { environment.createPackagePartProvider(it) },
dependenciesConfigurator = {
dependencies(moduleConfiguration.jvmClasspathRoots.map { it.toPath() })
dependencies(moduleConfiguration.jvmModularRoots.map { it.toPath() })
friendDependencies(moduleConfiguration[JVMConfigurationKeys.FRIEND_PATHS] ?: emptyList())
dependenciesConfigurator()
},
sessionConfigurator = {
if (extendedAnalysisMode) {
registerExtendedCommonCheckers()
}
}
)
}
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
)
}
val session = createSession(
module.getModuleName(),
JvmPlatforms.unspecifiedJvmPlatform,
JvmPlatformAnalyzerServices,
sourceScope
) {
if (commonSession != null) {
sourceDependsOnDependencies(listOf(commonSession.moduleData))
}
}
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

@@ -47,14 +47,32 @@ object KotlinCompilerRunnerUtils {
isDebugEnabled: Boolean,
daemonOptions: DaemonOptions = configureDaemonOptions(),
additionalJvmParams: Array<String> = arrayOf()
): CompileServiceSession? {
val daemonJVMOptions = configureDaemonJVMOptions(
): CompileServiceSession? = newDaemonConnection(
compilerId,
clientAliveFlagFile,
sessionAliveFlagFile,
messageCollector,
isDebugEnabled,
daemonOptions,
configureDaemonJVMOptions(
*additionalJvmParams,
inheritMemoryLimits = true,
inheritOtherJvmOptions = false,
inheritAdditionalProperties = true
)
)
@Synchronized
@JvmStatic
fun newDaemonConnection(
compilerId: CompilerId,
clientAliveFlagFile: File,
sessionAliveFlagFile: File,
messageCollector: MessageCollector,
isDebugEnabled: Boolean,
daemonOptions: DaemonOptions = configureDaemonOptions(),
daemonJVMOptions: DaemonJVMOptions
): CompileServiceSession? {
val daemonReportMessages = ArrayList<DaemonReportMessage>()
val daemonReportingTargets = DaemonReportingTargets(messages = daemonReportMessages)

View File

@@ -53,4 +53,7 @@ object AnalysisFlags {
@JvmStatic
val allowKotlinPackage by AnalysisFlag.Delegates.Boolean
@JvmStatic
val builtInsFromSources by AnalysisFlag.Delegates.Boolean
}

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.daemon.common
import org.jetbrains.kotlin.incremental.ClasspathChanges
import org.jetbrains.kotlin.incremental.IncrementalModuleInfo
import java.io.File
import java.io.Serializable
@@ -52,6 +53,7 @@ class IncrementalCompilationOptions(
val areFileChangesKnown: Boolean,
val modifiedFiles: List<File>?,
val deletedFiles: List<File>?,
val classpathChanges: ClasspathChanges,
val workingDir: File,
compilerMode: CompilerMode,
targetPlatform: CompileService.TargetPlatform,
@@ -87,6 +89,7 @@ class IncrementalCompilationOptions(
"areFileChangesKnown=$areFileChangesKnown, " +
"modifiedFiles=$modifiedFiles, " +
"deletedFiles=$deletedFiles, " +
"classpathChanges=$classpathChanges, " +
"workingDir=$workingDir, " +
"multiModuleICSettings=$multiModuleICSettings, " +
"usePreciseJavaTracking=$usePreciseJavaTracking" +

View File

@@ -601,7 +601,8 @@ abstract class CompileServiceImplBase(
outputFiles = incrementalCompilationOptions.outputFiles,
usePreciseJavaTracking = incrementalCompilationOptions.usePreciseJavaTracking,
modulesApiHistory = modulesApiHistory,
kotlinSourceFilesExtensions = allKotlinExtensions
kotlinSourceFilesExtensions = allKotlinExtensions,
classpathChanges = incrementalCompilationOptions.classpathChanges
)
return try {
compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, changedFiles, projectRoot)

View File

@@ -1,4 +1,4 @@
@R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) public abstract annotation class MyNullable : R|kotlin/Annotation| {
@R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) public final annotation class MyNullable : R|kotlin/Annotation| {
public constructor(): R|MyNullable|
}

View File

@@ -10,7 +10,7 @@
public constructor(): R|A|
}
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class FieldsAreNullable : R|kotlin/Annotation| {
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public final annotation class FieldsAreNullable : R|kotlin/Annotation| {
public constructor(): R|FieldsAreNullable|
}

View File

@@ -6,19 +6,19 @@
public constructor(): R|A|
}
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class ForceFlexibility : R|kotlin/Annotation| {
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public final annotation class ForceFlexibility : R|kotlin/Annotation| {
public constructor(): R|spr/ForceFlexibility|
}
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public final annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|spr/NonNullApi|
}
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public final annotation class Nullable : R|kotlin/Annotation| {
public constructor(): R|spr/Nullable|
}
@R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) public abstract annotation class UnknownNullability : R|kotlin/Annotation| {
@R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) public final annotation class UnknownNullability : R|kotlin/Annotation| {
public constructor(): R|spr/UnknownNullability|
}

View File

@@ -20,15 +20,15 @@ public abstract interface B : R|kotlin/Any| {
public abstract fun foobar(@R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|): R|kotlin/Unit|
}
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class ForceFlexibility : R|kotlin/Annotation| {
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public final annotation class ForceFlexibility : R|kotlin/Annotation| {
public constructor(): R|spr/ForceFlexibility|
}
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public final annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|spr/NonNullApi|
}
@R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) public abstract annotation class UnknownNullability : R|kotlin/Annotation| {
@R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) public final annotation class UnknownNullability : R|kotlin/Annotation| {
public constructor(): R|spr/UnknownNullability|
}

View File

@@ -54,11 +54,11 @@
public constructor(): R|C|
}
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public final annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|NonNullApi|
}
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NullableApi : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public final annotation class NullableApi : R|kotlin/Annotation| {
public constructor(): R|NullableApi|
}

View File

@@ -12,15 +12,15 @@
public constructor(): R|A|
}
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class FieldsAreNullable : R|kotlin/Annotation| {
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public final annotation class FieldsAreNullable : R|kotlin/Annotation| {
public constructor(): R|FieldsAreNullable|
}
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public final annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|NonNullApi|
}
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NullableApi : R|kotlin/Annotation| {
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public final annotation class NullableApi : R|kotlin/Annotation| {
public constructor(): R|NullableApi|
}

View File

@@ -10,11 +10,11 @@
public constructor(): R|A|
}
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public final annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|spr/NonNullApi|
}
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public final annotation class Nullable : R|kotlin/Annotation| {
public constructor(): R|spr/Nullable|
}

View File

@@ -10,11 +10,11 @@ public open class A : R|kotlin/Any| {
public constructor(): R|test/A|
}
@R|kotlin/annotation/Target|(<implicitArrayOf>()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|(<implicitArrayOf>()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public final annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|spr/NonNullApi|
}
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public final annotation class Nullable : R|kotlin/Annotation| {
public constructor(): R|spr/Nullable|
}

View File

@@ -2,7 +2,7 @@ class StringBuilder {
fun append(s: String) {}
}
fun buildString(init: StringBuilder.() -> Unit): String {}
fun buildString(init: StringBuilder.() -> Unit): String {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
interface Template<in X>

View File

@@ -18,10 +18,10 @@ fun test_2(n: Int) {
val y = n + 1
}
fun Int.bar(): Int {}
fun Int.bar(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
fun Int.baz(): Int {}
fun Byte.baz(): Byte {}
fun Int.baz(): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
fun Byte.baz(): Byte {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
fun test_3() {
val x = 1.bar()

View File

@@ -71,162 +71,163 @@ digraph flowFromInplaceLambda_kt {
21 [label="Enter block"];
22 [label="Const: Null(null)"];
23 [label="Check not null: Null(null)!!"];
24 [label="Jump: ^materialize Null(null)!!"];
25 [label="Stub" style="filled" fillcolor=gray];
26 [label="Exit block" style="filled" fillcolor=gray];
24 [label="Stub" style="filled" fillcolor=gray];
25 [label="Jump: ^materialize Null(null)!!" style="filled" fillcolor=gray];
26 [label="Stub" style="filled" fillcolor=gray];
27 [label="Exit block" style="filled" fillcolor=gray];
}
27 [label="Exit function materialize" style="filled" fillcolor=red];
28 [label="Exit function materialize" style="filled" fillcolor=red];
}
20 -> {21};
21 -> {22};
22 -> {23};
23 -> {24};
24 -> {27};
23 -> {28} [label=onUncaughtException];
23 -> {24} [style=dotted];
24 -> {25} [style=dotted];
25 -> {26} [style=dotted];
25 -> {28 26} [style=dotted];
26 -> {27} [style=dotted];
27 -> {28} [style=dotted];
subgraph cluster_8 {
color=red
28 [label="Enter function myRun" style="filled" fillcolor=red];
29 [label="Enter function myRun" style="filled" fillcolor=red];
subgraph cluster_9 {
color=blue
29 [label="Enter block"];
30 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|R|>|()"];
31 [label="Jump: ^myRun R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|R|>|()"];
32 [label="Stub" style="filled" fillcolor=gray];
33 [label="Exit block" style="filled" fillcolor=gray];
30 [label="Enter block"];
31 [label="Function call: R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|R|>|()"];
32 [label="Jump: ^myRun R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|R|>|()"];
33 [label="Stub" style="filled" fillcolor=gray];
34 [label="Exit block" style="filled" fillcolor=gray];
}
34 [label="Exit function myRun" style="filled" fillcolor=red];
35 [label="Exit function myRun" style="filled" fillcolor=red];
}
28 -> {29};
29 -> {30};
30 -> {31};
31 -> {34};
31 -> {32} [style=dotted];
31 -> {32};
32 -> {35};
32 -> {33} [style=dotted];
33 -> {34} [style=dotted];
34 -> {35} [style=dotted];
subgraph cluster_10 {
color=red
35 [label="Enter function test_1" style="filled" fillcolor=red];
36 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_11 {
color=blue
36 [label="Enter block"];
37 [label="Postponed enter to lambda"];
37 [label="Enter block"];
38 [label="Postponed enter to lambda"];
subgraph cluster_12 {
color=blue
45 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
46 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
46 [label="Enter block"];
47 [label="Access variable R|<local>/x|"];
48 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
49 [label="Exit block"];
47 [label="Enter block"];
48 [label="Access variable R|<local>/x|"];
49 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
50 [label="Exit block"];
}
50 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
51 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
38 [label="Call arguments union" style="filled" fillcolor=yellow];
39 [label="Postponed exit from lambda"];
40 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
41 [label="Access variable R|<local>/x|"];
42 [label="Function call: R|/takeInt|(...)"];
43 [label="Exit block"];
39 [label="Call arguments union" style="filled" fillcolor=yellow];
40 [label="Postponed exit from lambda"];
41 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
42 [label="Access variable R|<local>/x|"];
43 [label="Function call: R|/takeInt|(...)"];
44 [label="Exit block"];
}
44 [label="Exit function test_1" style="filled" fillcolor=red];
45 [label="Exit function test_1" style="filled" fillcolor=red];
}
35 -> {36};
36 -> {37};
37 -> {45};
37 -> {39} [color=red];
37 -> {45} [style=dashed];
37 -> {38};
38 -> {46};
38 -> {40} [color=red];
39 -> {40} [color=green];
40 -> {41};
38 -> {46} [style=dashed];
39 -> {41} [color=red];
40 -> {41} [color=green];
41 -> {42};
42 -> {43};
43 -> {44};
45 -> {46};
44 -> {45};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {50};
50 -> {38} [color=red];
50 -> {39} [color=green];
50 -> {51};
51 -> {39} [color=red];
51 -> {40} [color=green];
subgraph cluster_14 {
color=red
51 [label="Enter function test_2" style="filled" fillcolor=red];
52 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_15 {
color=blue
52 [label="Enter block"];
53 [label="Postponed enter to lambda"];
53 [label="Enter block"];
54 [label="Postponed enter to lambda"];
subgraph cluster_16 {
color=blue
74 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
75 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_17 {
color=blue
75 [label="Enter block"];
76 [label="Access variable R|<local>/y|"];
77 [label="Function call: R|<local>/y|.<Unresolved name: inc>#()"];
78 [label="Access variable R|<local>/x|"];
79 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
80 [label="Exit block"];
76 [label="Enter block"];
77 [label="Access variable R|<local>/y|"];
78 [label="Function call: R|<local>/y|.<Unresolved name: inc>#()"];
79 [label="Access variable R|<local>/x|"];
80 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
81 [label="Exit block"];
}
81 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
82 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
54 [label="Postponed exit from lambda"];
55 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
56 [label="Call arguments union" style="filled" fillcolor=yellow];
57 [label="Function call: R|/id|<R|kotlin/Int|>(...)"];
58 [label="Access variable R|<local>/y|"];
59 [label="Type operator: (R|<local>/y| as R|kotlin/Int|)"];
60 [label="Postponed enter to lambda"];
55 [label="Postponed exit from lambda"];
56 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
57 [label="Call arguments union" style="filled" fillcolor=yellow];
58 [label="Function call: R|/id|<R|kotlin/Int|>(...)"];
59 [label="Access variable R|<local>/y|"];
60 [label="Type operator: (R|<local>/y| as R|kotlin/Int|)"];
61 [label="Postponed enter to lambda"];
subgraph cluster_18 {
color=blue
82 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
83 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_19 {
color=blue
83 [label="Enter block"];
84 [label="Access variable R|<local>/x|"];
85 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
86 [label="Access variable R|<local>/y|"];
87 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
88 [label="Const: Int(1)"];
89 [label="Exit block"];
84 [label="Enter block"];
85 [label="Access variable R|<local>/x|"];
86 [label="Function call: R|<local>/x|.R|kotlin/Int.inc|()"];
87 [label="Access variable R|<local>/y|"];
88 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
89 [label="Const: Int(1)"];
90 [label="Exit block"];
}
90 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
91 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
61 [label="Postponed exit from lambda"];
62 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
63 [label="Call arguments union" style="filled" fillcolor=yellow];
64 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
65 [label="Variable declaration: lval a: R|kotlin/Int|"];
66 [label="Access variable R|<local>/x|"];
67 [label="Function call: R|/takeInt|(...)"];
68 [label="Access variable R|<local>/y|"];
69 [label="Function call: R|/takeInt|(...)"];
70 [label="Access variable R|<local>/a|"];
71 [label="Function call: R|/takeInt|(...)"];
72 [label="Exit block"];
62 [label="Postponed exit from lambda"];
63 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
64 [label="Call arguments union" style="filled" fillcolor=yellow];
65 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
66 [label="Variable declaration: lval a: R|kotlin/Int|"];
67 [label="Access variable R|<local>/x|"];
68 [label="Function call: R|/takeInt|(...)"];
69 [label="Access variable R|<local>/y|"];
70 [label="Function call: R|/takeInt|(...)"];
71 [label="Access variable R|<local>/a|"];
72 [label="Function call: R|/takeInt|(...)"];
73 [label="Exit block"];
}
73 [label="Exit function test_2" style="filled" fillcolor=red];
74 [label="Exit function test_2" style="filled" fillcolor=red];
}
51 -> {52};
52 -> {53};
53 -> {74};
53 -> {54} [color=red];
53 -> {74} [style=dashed];
54 -> {55};
53 -> {54};
54 -> {75};
54 -> {55} [color=red];
54 -> {75} [style=dashed];
55 -> {56};
56 -> {57};
57 -> {58};
58 -> {59};
59 -> {60};
60 -> {82};
60 -> {61} [color=red];
60 -> {82} [style=dashed];
61 -> {62};
60 -> {61};
61 -> {83};
61 -> {62} [color=red];
61 -> {83} [style=dashed];
62 -> {63};
63 -> {64};
64 -> {65};
@@ -238,16 +239,16 @@ digraph flowFromInplaceLambda_kt {
70 -> {71};
71 -> {72};
72 -> {73};
74 -> {75};
73 -> {74};
75 -> {76};
76 -> {77};
77 -> {78};
78 -> {79};
79 -> {80};
80 -> {81};
81 -> {56} [color=red];
81 -> {54} [color=green];
82 -> {83};
81 -> {82};
82 -> {57} [color=red];
82 -> {55} [color=green];
83 -> {84};
84 -> {85};
85 -> {86};
@@ -255,79 +256,79 @@ digraph flowFromInplaceLambda_kt {
87 -> {88};
88 -> {89};
89 -> {90};
90 -> {63} [color=red];
90 -> {61} [color=green];
90 -> {91};
91 -> {64} [color=red];
91 -> {62} [color=green];
subgraph cluster_20 {
color=red
91 [label="Enter function test_3" style="filled" fillcolor=red];
92 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_21 {
color=blue
92 [label="Enter block"];
93 [label="Postponed enter to lambda"];
93 [label="Enter block"];
94 [label="Postponed enter to lambda"];
subgraph cluster_22 {
color=blue
111 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
112 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_23 {
color=blue
112 [label="Enter block"];
113 [label="Access variable R|<local>/y|"];
114 [label="Function call: R|<local>/y|.<Unresolved name: inc>#()"];
115 [label="Access variable R|<local>/x|"];
116 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
117 [label="Function call: R|/materialize|<R|kotlin/Int|>()"];
118 [label="Exit block"];
113 [label="Enter block"];
114 [label="Access variable R|<local>/y|"];
115 [label="Function call: R|<local>/y|.<Unresolved name: inc>#()"];
116 [label="Access variable R|<local>/x|"];
117 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
118 [label="Function call: R|/materialize|<R|kotlin/Int|>()"];
119 [label="Exit block"];
}
119 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
120 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
94 [label="Postponed exit from lambda"];
95 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
96 [label="Function call: R|/id|<R|kotlin/Int|>(...)"];
97 [label="Postponed enter to lambda"];
95 [label="Postponed exit from lambda"];
96 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
97 [label="Function call: R|/id|<R|kotlin/Int|>(...)"];
98 [label="Postponed enter to lambda"];
subgraph cluster_24 {
color=blue
120 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
121 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_25 {
color=blue
121 [label="Enter block"];
122 [label="Access variable R|<local>/y|"];
123 [label="Type operator: (R|<local>/y| as R|kotlin/Int|)"];
124 [label="Access variable R|<local>/x|"];
125 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()"];
126 [label="Access variable R|<local>/y|"];
127 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
128 [label="Const: Int(1)"];
129 [label="Exit block"];
122 [label="Enter block"];
123 [label="Access variable R|<local>/y|"];
124 [label="Type operator: (R|<local>/y| as R|kotlin/Int|)"];
125 [label="Access variable R|<local>/x|"];
126 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()"];
127 [label="Access variable R|<local>/y|"];
128 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
129 [label="Const: Int(1)"];
130 [label="Exit block"];
}
130 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
131 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
98 [label="Postponed exit from lambda"];
99 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
100 [label="Call arguments union" style="filled" fillcolor=yellow];
101 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
102 [label="Variable declaration: lval a: R|kotlin/Int|"];
103 [label="Access variable R|<local>/x|"];
104 [label="Function call: R|/takeInt|(...)"];
105 [label="Access variable R|<local>/y|"];
106 [label="Function call: R|/takeInt|(...)"];
107 [label="Access variable R|<local>/a|"];
108 [label="Function call: R|/takeInt|(...)"];
109 [label="Exit block"];
99 [label="Postponed exit from lambda"];
100 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
101 [label="Call arguments union" style="filled" fillcolor=yellow];
102 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
103 [label="Variable declaration: lval a: R|kotlin/Int|"];
104 [label="Access variable R|<local>/x|"];
105 [label="Function call: R|/takeInt|(...)"];
106 [label="Access variable R|<local>/y|"];
107 [label="Function call: R|/takeInt|(...)"];
108 [label="Access variable R|<local>/a|"];
109 [label="Function call: R|/takeInt|(...)"];
110 [label="Exit block"];
}
110 [label="Exit function test_3" style="filled" fillcolor=red];
111 [label="Exit function test_3" style="filled" fillcolor=red];
}
91 -> {92};
92 -> {93};
93 -> {111};
93 -> {94} [color=red];
93 -> {111} [style=dashed];
94 -> {95};
93 -> {94};
94 -> {112};
94 -> {95} [color=red];
94 -> {112} [style=dashed];
95 -> {96};
96 -> {97};
97 -> {120};
97 -> {98} [color=red];
97 -> {120} [style=dashed];
98 -> {99};
97 -> {98};
98 -> {121};
98 -> {99} [color=red];
98 -> {121} [style=dashed];
99 -> {100};
100 -> {101};
101 -> {102};
@@ -339,7 +340,7 @@ digraph flowFromInplaceLambda_kt {
107 -> {108};
108 -> {109};
109 -> {110};
111 -> {112};
110 -> {111};
112 -> {113};
113 -> {114};
114 -> {115};
@@ -347,9 +348,9 @@ digraph flowFromInplaceLambda_kt {
116 -> {117};
117 -> {118};
118 -> {119};
119 -> {100} [color=red];
119 -> {94} [color=green];
120 -> {121};
119 -> {120};
120 -> {101} [color=red];
120 -> {95} [color=green];
121 -> {122};
122 -> {123};
123 -> {124};
@@ -359,77 +360,77 @@ digraph flowFromInplaceLambda_kt {
127 -> {128};
128 -> {129};
129 -> {130};
130 -> {100} [color=red];
130 -> {98} [color=green];
130 -> {131};
131 -> {101} [color=red];
131 -> {99} [color=green];
subgraph cluster_26 {
color=red
131 [label="Enter function test_4" style="filled" fillcolor=red];
132 [label="Enter function test_4" style="filled" fillcolor=red];
subgraph cluster_27 {
color=blue
132 [label="Enter block"];
133 [label="Postponed enter to lambda"];
133 [label="Enter block"];
134 [label="Postponed enter to lambda"];
subgraph cluster_28 {
color=blue
152 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
153 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_29 {
color=blue
153 [label="Enter block"];
154 [label="Access variable R|<local>/y|"];
155 [label="Function call: R|<local>/y|.<Unresolved name: inc>#()"];
156 [label="Access variable R|<local>/x|"];
157 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
158 [label="Exit block"];
154 [label="Enter block"];
155 [label="Access variable R|<local>/y|"];
156 [label="Function call: R|<local>/y|.<Unresolved name: inc>#()"];
157 [label="Access variable R|<local>/x|"];
158 [label="Type operator: (R|<local>/x| as R|kotlin/Int|)"];
159 [label="Exit block"];
}
159 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
160 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
134 [label="Postponed exit from lambda"];
135 [label="Function call: R|/myRun|<R|kotlin/Int|>(...)"];
136 [label="Function call: R|/id|<R|kotlin/Int|>(...)"];
137 [label="Access variable R|<local>/y|"];
138 [label="Type operator: (R|<local>/y| as R|kotlin/Int|)"];
139 [label="Postponed enter to lambda"];
135 [label="Postponed exit from lambda"];
136 [label="Function call: R|/myRun|<R|kotlin/Int|>(...)"];
137 [label="Function call: R|/id|<R|kotlin/Int|>(...)"];
138 [label="Access variable R|<local>/y|"];
139 [label="Type operator: (R|<local>/y| as R|kotlin/Int|)"];
140 [label="Postponed enter to lambda"];
subgraph cluster_30 {
color=blue
160 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
161 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_31 {
color=blue
161 [label="Enter block"];
162 [label="Access variable R|<local>/x|"];
163 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()"];
164 [label="Access variable R|<local>/y|"];
165 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
166 [label="Const: Int(1)"];
167 [label="Exit block"];
162 [label="Enter block"];
163 [label="Access variable R|<local>/x|"];
164 [label="Function call: R|<local>/x|.<Unresolved name: inc>#()"];
165 [label="Access variable R|<local>/y|"];
166 [label="Function call: R|<local>/y|.R|kotlin/Int.inc|()"];
167 [label="Const: Int(1)"];
168 [label="Exit block"];
}
168 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
169 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
140 [label="Postponed exit from lambda"];
141 [label="Function call: R|/myRun|<R|kotlin/Int|>(...)"];
142 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
143 [label="Variable declaration: lval a: R|kotlin/Int|"];
144 [label="Access variable R|<local>/x|"];
145 [label="Function call: <Inapplicable(INAPPLICABLE): /takeInt>#(...)"];
146 [label="Access variable R|<local>/y|"];
147 [label="Function call: R|/takeInt|(...)"];
148 [label="Access variable R|<local>/a|"];
149 [label="Function call: R|/takeInt|(...)"];
150 [label="Exit block"];
141 [label="Postponed exit from lambda"];
142 [label="Function call: R|/myRun|<R|kotlin/Int|>(...)"];
143 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
144 [label="Variable declaration: lval a: R|kotlin/Int|"];
145 [label="Access variable R|<local>/x|"];
146 [label="Function call: <Inapplicable(INAPPLICABLE): /takeInt>#(...)"];
147 [label="Access variable R|<local>/y|"];
148 [label="Function call: R|/takeInt|(...)"];
149 [label="Access variable R|<local>/a|"];
150 [label="Function call: R|/takeInt|(...)"];
151 [label="Exit block"];
}
151 [label="Exit function test_4" style="filled" fillcolor=red];
152 [label="Exit function test_4" style="filled" fillcolor=red];
}
131 -> {132};
132 -> {133};
133 -> {134 152};
133 -> {152} [style=dashed];
134 -> {135};
133 -> {134};
134 -> {135 153};
134 -> {153} [style=dashed];
135 -> {136};
136 -> {137};
137 -> {138};
138 -> {139};
139 -> {140 160};
139 -> {160} [style=dashed];
140 -> {141};
139 -> {140};
140 -> {141 161};
140 -> {161} [style=dashed];
141 -> {142};
142 -> {143};
143 -> {144};
@@ -440,14 +441,14 @@ digraph flowFromInplaceLambda_kt {
148 -> {149};
149 -> {150};
150 -> {151};
152 -> {153};
151 -> {152};
153 -> {154};
154 -> {155};
155 -> {156};
156 -> {157};
157 -> {158};
158 -> {159};
160 -> {161};
159 -> {160};
161 -> {162};
162 -> {163};
163 -> {164};
@@ -455,61 +456,61 @@ digraph flowFromInplaceLambda_kt {
165 -> {166};
166 -> {167};
167 -> {168};
168 -> {169};
subgraph cluster_32 {
color=red
169 [label="Enter function test_5" style="filled" fillcolor=red];
170 [label="Enter function test_5" style="filled" fillcolor=red];
subgraph cluster_33 {
color=blue
170 [label="Enter block"];
171 [label="Postponed enter to lambda"];
171 [label="Enter block"];
172 [label="Postponed enter to lambda"];
subgraph cluster_34 {
color=blue
184 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
185 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_35 {
color=blue
185 [label="Enter block"];
186 [label="Function call: R|/materialize|<R|kotlin/Int|>()"];
187 [label="Exit block"];
186 [label="Enter block"];
187 [label="Function call: R|/materialize|<R|kotlin/Int|>()"];
188 [label="Exit block"];
}
188 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
189 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
172 [label="Postponed exit from lambda"];
173 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
174 [label="Postponed enter to lambda"];
173 [label="Postponed exit from lambda"];
174 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
175 [label="Postponed enter to lambda"];
subgraph cluster_36 {
color=blue
189 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
190 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_37 {
color=blue
190 [label="Enter block"];
191 [label="Function call: R|/materialize|<R|kotlin/Int|>()"];
192 [label="Exit block"];
191 [label="Enter block"];
192 [label="Function call: R|/materialize|<R|kotlin/Int|>()"];
193 [label="Exit block"];
}
193 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
194 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
175 [label="Postponed exit from lambda"];
176 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
177 [label="Call arguments union" style="filled" fillcolor=yellow];
178 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
179 [label="Variable declaration: lval x: R|kotlin/Int|"];
180 [label="Access variable R|<local>/x|"];
181 [label="Function call: R|/takeInt|(...)"];
182 [label="Exit block"];
176 [label="Postponed exit from lambda"];
177 [label="Function call: R|kotlin/run|<R|kotlin/Int|>(...)"];
178 [label="Call arguments union" style="filled" fillcolor=yellow];
179 [label="Function call: R|/select|<R|kotlin/Int|>(...)"];
180 [label="Variable declaration: lval x: R|kotlin/Int|"];
181 [label="Access variable R|<local>/x|"];
182 [label="Function call: R|/takeInt|(...)"];
183 [label="Exit block"];
}
183 [label="Exit function test_5" style="filled" fillcolor=red];
184 [label="Exit function test_5" style="filled" fillcolor=red];
}
169 -> {170};
170 -> {171};
171 -> {184};
171 -> {172} [color=red];
171 -> {184} [style=dashed];
172 -> {173};
171 -> {172};
172 -> {185};
172 -> {173} [color=red];
172 -> {185} [style=dashed];
173 -> {174};
174 -> {189};
174 -> {175} [color=red];
174 -> {189} [style=dashed];
175 -> {176};
174 -> {175};
175 -> {190};
175 -> {176} [color=red];
175 -> {190} [style=dashed];
176 -> {177};
177 -> {178};
178 -> {179};
@@ -517,79 +518,80 @@ digraph flowFromInplaceLambda_kt {
180 -> {181};
181 -> {182};
182 -> {183};
184 -> {185};
183 -> {184};
185 -> {186};
186 -> {187};
187 -> {188};
188 -> {177} [color=red];
188 -> {172} [color=green];
189 -> {190};
188 -> {189};
189 -> {178} [color=red];
189 -> {173} [color=green];
190 -> {191};
191 -> {192};
192 -> {193};
193 -> {177} [color=red];
193 -> {175} [color=green];
193 -> {194};
194 -> {178} [color=red];
194 -> {176} [color=green];
subgraph cluster_38 {
color=red
194 [label="Enter function test_6" style="filled" fillcolor=red];
195 [label="Enter function test_6" style="filled" fillcolor=red];
subgraph cluster_39 {
color=blue
195 [label="Enter block"];
196 [label="Postponed enter to lambda"];
196 [label="Enter block"];
197 [label="Postponed enter to lambda"];
subgraph cluster_40 {
color=blue
203 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
204 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_41 {
color=blue
204 [label="Enter block"];
205 [label="Postponed enter to lambda"];
205 [label="Enter block"];
206 [label="Postponed enter to lambda"];
subgraph cluster_42 {
color=blue
210 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
211 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_43 {
color=blue
211 [label="Enter block"];
212 [label="Function call: R|/materialize|<R|kotlin/String|>()"];
213 [label="Exit block"];
212 [label="Enter block"];
213 [label="Function call: R|/materialize|<R|kotlin/String|>()"];
214 [label="Exit block"];
}
214 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
215 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
206 [label="Postponed exit from lambda"];
207 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)"];
208 [label="Exit block"];
207 [label="Postponed exit from lambda"];
208 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)"];
209 [label="Exit block"];
}
209 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
210 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
197 [label="Postponed exit from lambda"];
198 [label="Function call: R|/myRun|<R|kotlin/String|>(...)"];
199 [label="Function call: R|/id|<R|kotlin/String|>(...)"];
200 [label="Variable declaration: lval x: R|kotlin/String|"];
201 [label="Exit block"];
198 [label="Postponed exit from lambda"];
199 [label="Function call: R|/myRun|<R|kotlin/String|>(...)"];
200 [label="Function call: R|/id|<R|kotlin/String|>(...)"];
201 [label="Variable declaration: lval x: R|kotlin/String|"];
202 [label="Exit block"];
}
202 [label="Exit function test_6" style="filled" fillcolor=red];
203 [label="Exit function test_6" style="filled" fillcolor=red];
}
194 -> {195};
195 -> {196};
196 -> {197 203};
196 -> {203} [style=dashed];
197 -> {198};
196 -> {197};
197 -> {198 204};
197 -> {204} [style=dashed];
198 -> {199};
199 -> {200};
200 -> {201};
201 -> {202};
203 -> {204};
202 -> {203};
204 -> {205};
205 -> {210};
205 -> {206} [color=red];
205 -> {210} [style=dashed];
206 -> {207};
205 -> {206};
206 -> {211};
206 -> {207} [color=red];
206 -> {211} [style=dashed];
207 -> {208};
208 -> {209};
210 -> {211};
209 -> {210};
211 -> {212};
212 -> {213};
213 -> {214};
214 -> {206} [color=green];
214 -> {215};
215 -> {207} [color=green];
}

View File

@@ -11,175 +11,176 @@ digraph inplaceLambdaInControlFlowExpressions_kt {
1 [label="Enter block"];
2 [label="Const: Null(null)"];
3 [label="Check not null: Null(null)!!"];
4 [label="Jump: ^materialize Null(null)!!"];
5 [label="Stub" style="filled" fillcolor=gray];
6 [label="Exit block" style="filled" fillcolor=gray];
4 [label="Stub" style="filled" fillcolor=gray];
5 [label="Jump: ^materialize Null(null)!!" style="filled" fillcolor=gray];
6 [label="Stub" style="filled" fillcolor=gray];
7 [label="Exit block" style="filled" fillcolor=gray];
}
7 [label="Exit function materialize" style="filled" fillcolor=red];
8 [label="Exit function materialize" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {7};
3 -> {8} [label=onUncaughtException];
3 -> {4} [style=dotted];
4 -> {5} [style=dotted];
5 -> {6} [style=dotted];
5 -> {8 6} [style=dotted];
6 -> {7} [style=dotted];
7 -> {8} [style=dotted];
subgraph cluster_2 {
color=red
8 [label="Enter function test_1" style="filled" fillcolor=red];
9 [label="Enter function test_1" style="filled" fillcolor=red];
subgraph cluster_3 {
color=blue
9 [label="Enter block"];
10 [label="Enter block"];
subgraph cluster_4 {
color=blue
10 [label="Enter when"];
11 [label="Enter when"];
subgraph cluster_5 {
color=blue
11 [label="Enter when branch condition "];
12 [label="Const: Boolean(true)"];
13 [label="Exit when branch condition"];
12 [label="Enter when branch condition "];
13 [label="Const: Boolean(true)"];
14 [label="Exit when branch condition"];
}
subgraph cluster_6 {
color=blue
14 [label="Enter when branch condition else"];
15 [label="Exit when branch condition"];
15 [label="Enter when branch condition else"];
16 [label="Exit when branch condition"];
}
16 [label="Enter when branch result"];
17 [label="Enter when branch result"];
subgraph cluster_7 {
color=blue
17 [label="Enter block"];
18 [label="Const: String()"];
19 [label="Exit block"];
18 [label="Enter block"];
19 [label="Const: String()"];
20 [label="Exit block"];
}
20 [label="Exit when branch result"];
21 [label="Enter when branch result"];
21 [label="Exit when branch result"];
22 [label="Enter when branch result"];
subgraph cluster_8 {
color=blue
22 [label="Enter block"];
23 [label="Postponed enter to lambda"];
23 [label="Enter block"];
24 [label="Postponed enter to lambda"];
subgraph cluster_9 {
color=blue
32 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
33 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
33 [label="Enter block"];
34 [label="Function call: R|/materialize|<R|kotlin/String|>()"];
35 [label="Exit block"];
34 [label="Enter block"];
35 [label="Function call: R|/materialize|<R|kotlin/String|>()"];
36 [label="Exit block"];
}
36 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
37 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
24 [label="Postponed exit from lambda"];
25 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)"];
26 [label="Exit block"];
25 [label="Postponed exit from lambda"];
26 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)"];
27 [label="Exit block"];
}
27 [label="Exit when branch result"];
28 [label="Exit when"];
28 [label="Exit when branch result"];
29 [label="Exit when"];
}
29 [label="Variable declaration: lval x: R|kotlin/String|"];
30 [label="Exit block"];
30 [label="Variable declaration: lval x: R|kotlin/String|"];
31 [label="Exit block"];
}
31 [label="Exit function test_1" style="filled" fillcolor=red];
32 [label="Exit function test_1" style="filled" fillcolor=red];
}
8 -> {9};
9 -> {10};
10 -> {11};
11 -> {12};
12 -> {13};
13 -> {21 14};
14 -> {15};
13 -> {14};
14 -> {22 15};
15 -> {16};
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
20 -> {28};
21 -> {22};
20 -> {21};
21 -> {29};
22 -> {23};
23 -> {32};
23 -> {24} [color=red];
23 -> {32} [style=dashed];
24 -> {25};
23 -> {24};
24 -> {33};
24 -> {25} [color=red];
24 -> {33} [style=dashed];
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30};
30 -> {31};
32 -> {33};
31 -> {32};
33 -> {34};
34 -> {35};
35 -> {36};
36 -> {24} [color=green];
36 -> {37};
37 -> {25} [color=green];
subgraph cluster_11 {
color=red
37 [label="Enter function test_2" style="filled" fillcolor=red];
38 [label="Enter function test_2" style="filled" fillcolor=red];
subgraph cluster_12 {
color=blue
38 [label="Enter block"];
39 [label="Enter block"];
subgraph cluster_13 {
color=blue
39 [label="Try expression enter"];
40 [label="Try expression enter"];
subgraph cluster_14 {
color=blue
40 [label="Try main block enter"];
41 [label="Try main block enter"];
subgraph cluster_15 {
color=blue
41 [label="Enter block"];
42 [label="Postponed enter to lambda"];
42 [label="Enter block"];
43 [label="Postponed enter to lambda"];
subgraph cluster_16 {
color=blue
57 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
58 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_17 {
color=blue
58 [label="Enter block"];
59 [label="Function call: R|/materialize|<R|kotlin/String|>()"];
60 [label="Exit block"];
59 [label="Enter block"];
60 [label="Function call: R|/materialize|<R|kotlin/String|>()"];
61 [label="Exit block"];
}
61 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
62 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
43 [label="Postponed exit from lambda"];
44 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)"];
45 [label="Exit block"];
44 [label="Postponed exit from lambda"];
45 [label="Function call: R|kotlin/run|<R|kotlin/String|>(...)"];
46 [label="Exit block"];
}
46 [label="Try main block exit"];
47 [label="Try main block exit"];
}
subgraph cluster_18 {
color=blue
47 [label="Catch enter"];
48 [label="Catch enter"];
subgraph cluster_19 {
color=blue
48 [label="Enter block"];
49 [label="Const: String()"];
50 [label="Exit block"];
49 [label="Enter block"];
50 [label="Const: String()"];
51 [label="Exit block"];
}
51 [label="Catch exit"];
52 [label="Catch exit"];
}
52 [label="Try expression exit"];
53 [label="Try expression exit"];
}
53 [label="Call arguments union" style="filled" fillcolor=yellow];
54 [label="Variable declaration: lval x: R|kotlin/String|"];
55 [label="Exit block"];
54 [label="Call arguments union" style="filled" fillcolor=yellow];
55 [label="Variable declaration: lval x: R|kotlin/String|"];
56 [label="Exit block"];
}
56 [label="Exit function test_2" style="filled" fillcolor=red];
57 [label="Exit function test_2" style="filled" fillcolor=red];
}
37 -> {38};
38 -> {39};
39 -> {40 47};
40 -> {41};
39 -> {40};
40 -> {41 48};
41 -> {42};
42 -> {57};
42 -> {43} [color=red];
42 -> {57} [style=dashed];
43 -> {44};
42 -> {43};
43 -> {58};
43 -> {44} [color=red];
43 -> {58} [style=dashed];
44 -> {45};
45 -> {46};
46 -> {52 47};
47 -> {48};
47 -> {56} [label=onUncaughtException];
46 -> {47};
47 -> {53 48};
48 -> {49};
48 -> {57} [label=onUncaughtException];
49 -> {50};
50 -> {51};
51 -> {52};
@@ -187,56 +188,57 @@ digraph inplaceLambdaInControlFlowExpressions_kt {
53 -> {54};
54 -> {55};
55 -> {56};
57 -> {58};
56 -> {57};
58 -> {59};
59 -> {60};
60 -> {61};
61 -> {53} [color=red];
61 -> {43} [color=green];
61 -> {62};
62 -> {54} [color=red];
62 -> {44} [color=green];
subgraph cluster_20 {
color=red
62 [label="Enter function test_3" style="filled" fillcolor=red];
63 [label="Enter function test_3" style="filled" fillcolor=red];
subgraph cluster_21 {
color=blue
63 [label="Enter block"];
64 [label="Postponed enter to lambda"];
64 [label="Enter block"];
65 [label="Postponed enter to lambda"];
subgraph cluster_22 {
color=blue
72 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
73 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_23 {
color=blue
73 [label="Enter block"];
74 [label="Function call: R|/materialize|<R|kotlin/String?|>()"];
75 [label="Exit block"];
74 [label="Enter block"];
75 [label="Function call: R|/materialize|<R|kotlin/String?|>()"];
76 [label="Exit block"];
}
76 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
77 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
65 [label="Postponed exit from lambda"];
66 [label="Function call: R|kotlin/run|<R|kotlin/String?|>(...)"];
67 [label="Check not null: R|kotlin/run|<R|kotlin/String?|>(...)!!"];
68 [label="Call arguments union" style="filled" fillcolor=yellow];
69 [label="Variable declaration: lval x: R|kotlin/String|"];
70 [label="Exit block"];
66 [label="Postponed exit from lambda"];
67 [label="Function call: R|kotlin/run|<R|kotlin/String?|>(...)"];
68 [label="Check not null: R|kotlin/run|<R|kotlin/String?|>(...)!!"];
69 [label="Call arguments union" style="filled" fillcolor=yellow];
70 [label="Variable declaration: lval x: R|kotlin/String|"];
71 [label="Exit block"];
}
71 [label="Exit function test_3" style="filled" fillcolor=red];
72 [label="Exit function test_3" style="filled" fillcolor=red];
}
62 -> {63};
63 -> {64};
64 -> {72};
64 -> {65} [color=red];
64 -> {72} [style=dashed];
65 -> {66};
64 -> {65};
65 -> {73};
65 -> {66} [color=red];
65 -> {73} [style=dashed];
66 -> {67};
67 -> {68};
68 -> {69};
69 -> {70};
70 -> {71};
72 -> {73};
71 -> {72};
73 -> {74};
74 -> {75};
75 -> {76};
76 -> {68} [color=red];
76 -> {65} [color=green];
76 -> {77};
77 -> {69} [color=red];
77 -> {66} [color=green];
}

View File

@@ -22,5 +22,5 @@ class KClassValue(value: Value) : ConstantValue<KClassValue.Value>(value) {
val (classId, arrayDimensions) = value.value
}
}
}
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
}

View File

@@ -1,14 +1,14 @@
package rest
abstract class Foo<T> {
abstract val x: <!TYPE_ARGUMENTS_NOT_ALLOWED!>T<Int><!>
abstract val x: T<!TYPE_ARGUMENTS_NOT_ALLOWED!><Int><!>
abstract fun foo(): <!TYPE_ARGUMENTS_NOT_ALLOWED!>T<String><!>
abstract fun foo(): T<!TYPE_ARGUMENTS_NOT_ALLOWED!><String><!>
}
fun <T> foo() {
bar<<!TYPE_ARGUMENTS_NOT_ALLOWED!>T<Int><!>>()
bar<List<List<<!TYPE_ARGUMENTS_NOT_ALLOWED!>T<Boolean><!>>>>()
bar<T<!TYPE_ARGUMENTS_NOT_ALLOWED!><Int><!>>()
bar<List<List<T<!TYPE_ARGUMENTS_NOT_ALLOWED!><Boolean><!>>>>()
}
fun <T> bar() {}
@@ -26,9 +26,9 @@ class C<F<!SYNTAX!><<!><!SYNTAX!>Boolean<!><!SYNTAX!>><!><!SYNTAX!>><!> <!SYNTAX
fun <G> gest() {}
fun <T> fest() {
val b: List<<!TYPE_ARGUMENTS_NOT_ALLOWED!>T<Double><!>>
gest<<!TYPE_ARGUMENTS_NOT_ALLOWED!>T<Char><!>>()
val b: List<T<!TYPE_ARGUMENTS_NOT_ALLOWED!><Double><!>>
gest<T<!TYPE_ARGUMENTS_NOT_ALLOWED!><Char><!>>()
gest<T>()
val c: List<List<List<<!TYPE_ARGUMENTS_NOT_ALLOWED!>T<String><!>>>>
gest<List<List<<!TYPE_ARGUMENTS_NOT_ALLOWED!>T<Boolean><!>>>>()
val c: List<List<List<T<!TYPE_ARGUMENTS_NOT_ALLOWED!><String><!>>>>
gest<List<List<T<!TYPE_ARGUMENTS_NOT_ALLOWED!><Boolean><!>>>>()
}

View File

@@ -27,7 +27,7 @@ fun test_2(cond: Boolean?) {
}
fun test_3(cond: Boolean) {
when (cond) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (cond) {
true -> 1
}
}

View File

@@ -27,7 +27,7 @@ fun test_2(enum: SomeEnum?) {
}
fun test_3(enum: SomeEnum) {
when (enum) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (enum) {
SomeEnum.A -> 1
}
}

View File

@@ -44,7 +44,7 @@ fun test_2(base: Base?) {
}
fun test_3(base: Base) {
when (base) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (base) {
is A -> 1
}
}

View File

@@ -1,5 +1,5 @@
class Foo {
operator fun plus(f: Foo): Foo {}
operator fun plus(f: Foo): Foo {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
operator fun plusAssign(f: Foo) {}
}

View File

@@ -38,10 +38,6 @@ FILE: RedundantModalityModifierChecker.kt
public abstract interface Foo : R|kotlin/Any| {
}
public abstract expect class AbstractClass : R|Foo| {
public expect constructor(): R|AbstractClass| {
super<R|kotlin/Any|>()
}
public abstract expect override fun foo(): R|kotlin/Unit|
public abstract expect fun bar(): R|kotlin/Unit|

View File

@@ -2,7 +2,7 @@ fun <T> simpleRun(f: (T) -> Unit): Unit = f(<!RETURN_IN_FUNCTION_WITH_EXPRESSION
fun <T, R> List<T>.simpleMap(f: (T) -> R): R {
}
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
fun <T> simpleWith(t: T, f: T.() -> Unit): Unit = t.f()

View File

@@ -2,10 +2,6 @@ FILE: B.kt
public abstract expect interface Other : R|kotlin/Any| {
}
public final expect class Another : R|kotlin/Any| {
public expect constructor(): R|b/d/Another| {
super<R|kotlin/Any|>()
}
}
public final fun baz(): R|kotlin/Unit| {
}

View File

@@ -32,7 +32,7 @@ class NamedCompilerPhase<in Context : CommonBackendContext, Data>(
}
}
runAfter(phaseConfig, phaserState, context, output)
}
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
private fun runAfter(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, output: Data) {
@@ -40,5 +40,5 @@ class NamedCompilerPhase<in Context : CommonBackendContext, Data>(
private fun runAndProfile(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, source: Data): Data {
}
}
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
}

View File

@@ -33,7 +33,7 @@ public interface Klass extends TypeParametersOwner {
fun List<String>.single(): String = ""
fun List<Int>.single(): Int = 2
fun listOf(): List<String> {}
fun listOf(): List<String> {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
public open class LightMember<D> : Member<D>, Light() {
override fun getName(): String = "Light"

View File

@@ -61,7 +61,9 @@ digraph elvis_kt {
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9 11};
8 -> {9};
8 -> {11} [color=red];
8 -> {13} [color=green];
9 -> {10};
10 -> {11};
11 -> {12};

View File

@@ -469,7 +469,9 @@ digraph returns_kt {
151 -> {152};
152 -> {153};
153 -> {154};
154 -> {155 157};
154 -> {155};
154 -> {157} [color=red];
154 -> {159} [color=green];
155 -> {156};
156 -> {157};
157 -> {158};

View File

@@ -583,7 +583,9 @@ digraph nullability_kt {
194 -> {195 197};
195 -> {196};
196 -> {197};
197 -> {198 200};
197 -> {198};
197 -> {200} [color=red];
197 -> {202} [color=green];
198 -> {199};
199 -> {200};
200 -> {201};

View File

@@ -99,157 +99,158 @@ digraph smartcastToNothing_kt {
31 [label="Enter block"];
32 [label="Const: Null(null)"];
33 [label="Check not null: Null(null)!!"];
34 [label="Jump: ^myListOf Null(null)!!"];
35 [label="Stub" style="filled" fillcolor=gray];
36 [label="Exit block" style="filled" fillcolor=gray];
34 [label="Stub" style="filled" fillcolor=gray];
35 [label="Jump: ^myListOf Null(null)!!" style="filled" fillcolor=gray];
36 [label="Stub" style="filled" fillcolor=gray];
37 [label="Exit block" style="filled" fillcolor=gray];
}
37 [label="Exit function myListOf" style="filled" fillcolor=red];
38 [label="Exit function myListOf" style="filled" fillcolor=red];
}
30 -> {31};
31 -> {32};
32 -> {33};
33 -> {34};
34 -> {37};
33 -> {38} [label=onUncaughtException];
33 -> {34} [style=dotted];
34 -> {35} [style=dotted];
35 -> {36} [style=dotted];
35 -> {38 36} [style=dotted];
36 -> {37} [style=dotted];
37 -> {38} [style=dotted];
subgraph cluster_10 {
color=red
38 [label="Enter function <init>" style="filled" fillcolor=red];
39 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
40 [label="Exit function <init>" style="filled" fillcolor=red];
39 [label="Enter function <init>" style="filled" fillcolor=red];
40 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
41 [label="Exit function <init>" style="filled" fillcolor=red];
}
38 -> {39};
39 -> {40};
40 -> {41};
subgraph cluster_11 {
color=red
41 [label="Enter property" style="filled" fillcolor=red];
42 [label="Const: Int(1)"];
43 [label="Exit property" style="filled" fillcolor=red];
42 [label="Enter property" style="filled" fillcolor=red];
43 [label="Const: Int(1)"];
44 [label="Exit property" style="filled" fillcolor=red];
}
41 -> {42};
42 -> {43};
43 -> {49} [color=green];
43 -> {44};
44 -> {50} [color=green];
subgraph cluster_12 {
color=red
44 [label="Enter property" style="filled" fillcolor=red];
45 [label="Const: Boolean(true)"];
46 [label="Exit property" style="filled" fillcolor=red];
45 [label="Enter property" style="filled" fillcolor=red];
46 [label="Const: Boolean(true)"];
47 [label="Exit property" style="filled" fillcolor=red];
}
44 -> {45};
45 -> {46};
46 -> {50} [color=green];
46 -> {47};
47 -> {51} [color=green];
subgraph cluster_13 {
color=red
47 [label="Enter class A" style="filled" fillcolor=red];
48 [label="Part of class initialization"];
48 [label="Enter class A" style="filled" fillcolor=red];
49 [label="Part of class initialization"];
50 [label="Exit class A" style="filled" fillcolor=red];
50 [label="Part of class initialization"];
51 [label="Exit class A" style="filled" fillcolor=red];
}
47 -> {48} [color=green];
48 -> {49} [style=dotted];
48 -> {41} [color=green];
48 -> {41} [style=dashed];
48 -> {49} [color=green];
49 -> {50} [style=dotted];
49 -> {44} [color=green];
49 -> {44} [style=dashed];
49 -> {42} [color=green];
49 -> {42} [style=dashed];
50 -> {51} [style=dotted];
50 -> {45} [color=green];
50 -> {45} [style=dashed];
subgraph cluster_14 {
color=red
51 [label="Enter function test_0" style="filled" fillcolor=red];
52 [label="Enter function test_0" style="filled" fillcolor=red];
subgraph cluster_15 {
color=blue
52 [label="Enter block"];
53 [label="Const: Null(null)"];
54 [label="Variable declaration: lvar s: R|A?|"];
53 [label="Enter block"];
54 [label="Const: Null(null)"];
55 [label="Variable declaration: lvar s: R|A?|"];
subgraph cluster_16 {
color=blue
55 [label="Enter block"];
56 [label="Access variable R|<local>/results|"];
57 [label="Function call: R|<local>/results|.R|SubstitutionOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<kotlin/Nothing>|>|()"];
58 [label="Variable declaration: lval <iterator>: R|kotlin/collections/Iterator<kotlin/Nothing>|"];
56 [label="Enter block"];
57 [label="Access variable R|<local>/results|"];
58 [label="Function call: R|<local>/results|.R|SubstitutionOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<kotlin/Nothing>|>|()"];
59 [label="Variable declaration: lval <iterator>: R|kotlin/collections/Iterator<kotlin/Nothing>|"];
subgraph cluster_17 {
color=blue
59 [label="Enter while loop"];
60 [label="Enter while loop"];
subgraph cluster_18 {
color=blue
60 [label="Enter loop condition"];
61 [label="Access variable R|<local>/<iterator>|"];
62 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
63 [label="Exit loop condition"];
61 [label="Enter loop condition"];
62 [label="Access variable R|<local>/<iterator>|"];
63 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
64 [label="Exit loop condition"];
}
subgraph cluster_19 {
color=blue
64 [label="Enter loop block"];
65 [label="Enter loop block"];
subgraph cluster_20 {
color=blue
65 [label="Enter block"];
66 [label="Access variable R|<local>/<iterator>|"];
67 [label="Function call: R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|kotlin/Nothing|>|()"];
68 [label="Stub" style="filled" fillcolor=gray];
69 [label="Variable declaration: lval result: R|kotlin/Nothing|" style="filled" fillcolor=gray];
70 [label="Access variable R|<local>/result|" style="filled" fillcolor=gray];
71 [label="Stub" style="filled" fillcolor=gray];
72 [label="Assignment: R|<local>/s|" style="filled" fillcolor=gray];
66 [label="Enter block"];
67 [label="Access variable R|<local>/<iterator>|"];
68 [label="Function call: R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|kotlin/Nothing|>|()"];
69 [label="Stub" style="filled" fillcolor=gray];
70 [label="Variable declaration: lval result: R|kotlin/Nothing|" style="filled" fillcolor=gray];
71 [label="Access variable R|<local>/result|" style="filled" fillcolor=gray];
72 [label="Stub" style="filled" fillcolor=gray];
73 [label="Assignment: R|<local>/s|" style="filled" fillcolor=gray];
subgraph cluster_21 {
color=blue
73 [label="Enter when" style="filled" fillcolor=gray];
74 [label="Enter when" style="filled" fillcolor=gray];
subgraph cluster_22 {
color=blue
74 [label="Enter when branch condition " style="filled" fillcolor=gray];
75 [label="Access variable R|<local>/result|" style="filled" fillcolor=gray];
76 [label="Stub" style="filled" fillcolor=gray];
77 [label="Access variable <Unresolved name: b>#" style="filled" fillcolor=gray];
78 [label="Exit when branch condition" style="filled" fillcolor=gray];
75 [label="Enter when branch condition " style="filled" fillcolor=gray];
76 [label="Access variable R|<local>/result|" style="filled" fillcolor=gray];
77 [label="Stub" style="filled" fillcolor=gray];
78 [label="Access variable <Unresolved name: b>#" style="filled" fillcolor=gray];
79 [label="Exit when branch condition" style="filled" fillcolor=gray];
}
79 [label="Synthetic else branch" style="filled" fillcolor=gray];
80 [label="Enter when branch result" style="filled" fillcolor=gray];
80 [label="Synthetic else branch" style="filled" fillcolor=gray];
81 [label="Enter when branch result" style="filled" fillcolor=gray];
subgraph cluster_23 {
color=blue
81 [label="Enter block" style="filled" fillcolor=gray];
82 [label="Jump: break@@@[R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()] " style="filled" fillcolor=gray];
83 [label="Stub" style="filled" fillcolor=gray];
84 [label="Exit block" style="filled" fillcolor=gray];
82 [label="Enter block" style="filled" fillcolor=gray];
83 [label="Jump: break@@@[R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()] " style="filled" fillcolor=gray];
84 [label="Stub" style="filled" fillcolor=gray];
85 [label="Exit block" style="filled" fillcolor=gray];
}
85 [label="Exit when branch result" style="filled" fillcolor=gray];
86 [label="Exit when" style="filled" fillcolor=gray];
86 [label="Exit when branch result" style="filled" fillcolor=gray];
87 [label="Exit when" style="filled" fillcolor=gray];
}
87 [label="Exit block" style="filled" fillcolor=gray];
88 [label="Exit block" style="filled" fillcolor=gray];
}
88 [label="Exit loop block" style="filled" fillcolor=gray];
89 [label="Exit loop block" style="filled" fillcolor=gray];
}
89 [label="Exit whileloop"];
90 [label="Exit whileloop"];
}
90 [label="Exit block"];
91 [label="Exit block"];
}
91 [label="Access variable R|<local>/s|"];
92 [label="Enter safe call"];
93 [label="Postponed enter to lambda"];
92 [label="Access variable R|<local>/s|"];
93 [label="Enter safe call"];
94 [label="Postponed enter to lambda"];
subgraph cluster_24 {
color=blue
100 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
101 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_25 {
color=blue
101 [label="Enter block"];
102 [label="Access variable R|<local>/it|"];
103 [label="Access variable R|/A.a|"];
104 [label="Exit block"];
102 [label="Enter block"];
103 [label="Access variable R|<local>/it|"];
104 [label="Access variable R|/A.a|"];
105 [label="Exit block"];
}
105 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
106 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
94 [label="Call arguments union" style="filled" fillcolor=yellow];
95 [label="Postponed exit from lambda"];
96 [label="Function call: $subj$.R|kotlin/let|<R|A|, R|kotlin/Int|>(...)"];
97 [label="Exit safe call"];
98 [label="Exit block"];
95 [label="Call arguments union" style="filled" fillcolor=yellow];
96 [label="Postponed exit from lambda"];
97 [label="Function call: $subj$.R|kotlin/let|<R|A|, R|kotlin/Int|>(...)"];
98 [label="Exit safe call"];
99 [label="Exit block"];
}
99 [label="Exit function test_0" style="filled" fillcolor=red];
100 [label="Exit function test_0" style="filled" fillcolor=red];
}
51 -> {52};
52 -> {53};
53 -> {54};
54 -> {55};
@@ -261,53 +262,54 @@ digraph smartcastToNothing_kt {
60 -> {61};
61 -> {62};
62 -> {63};
63 -> {89 64};
64 -> {65};
63 -> {64};
64 -> {90 65};
65 -> {66};
66 -> {67};
67 -> {99} [label=onUncaughtException];
67 -> {68} [style=dotted];
67 -> {68};
68 -> {100} [label=onUncaughtException];
68 -> {69} [style=dotted];
69 -> {70} [style=dotted];
70 -> {71} [style=dotted];
70 -> {99} [style=dotted] [label=onUncaughtException];
71 -> {72} [style=dotted];
71 -> {100} [style=dotted] [label=onUncaughtException];
72 -> {73} [style=dotted];
73 -> {74} [style=dotted];
74 -> {75} [style=dotted];
75 -> {76} [style=dotted];
75 -> {99} [style=dotted] [label=onUncaughtException];
76 -> {77} [style=dotted];
76 -> {100} [style=dotted] [label=onUncaughtException];
77 -> {78} [style=dotted];
78 -> {80 79} [style=dotted];
79 -> {86} [style=dotted];
80 -> {81} [style=dotted];
78 -> {79} [style=dotted];
79 -> {81 80} [style=dotted];
80 -> {87} [style=dotted];
81 -> {82} [style=dotted];
82 -> {89 83} [style=dotted];
83 -> {84} [style=dotted];
82 -> {83} [style=dotted];
83 -> {90 84} [style=dotted];
84 -> {85} [style=dotted];
85 -> {86} [style=dotted];
86 -> {87} [style=dotted];
87 -> {88} [style=dotted];
88 -> {60} [color=green style=dotted];
89 -> {90};
88 -> {89} [style=dotted];
89 -> {61} [color=green style=dotted];
90 -> {91};
91 -> {92 97};
92 -> {93};
93 -> {100};
93 -> {95} [color=red];
93 -> {100} [style=dashed];
91 -> {92};
92 -> {93 98};
93 -> {94};
94 -> {101};
94 -> {96} [color=red];
95 -> {96} [color=green];
96 -> {97};
94 -> {101} [style=dashed];
95 -> {97} [color=red];
96 -> {97} [color=green];
97 -> {98};
98 -> {99};
100 -> {101};
99 -> {100};
101 -> {102};
102 -> {103};
103 -> {104};
104 -> {105};
105 -> {94} [color=red];
105 -> {95} [color=green];
105 -> {106};
106 -> {95} [color=red];
106 -> {96} [color=green];
}

View File

@@ -9,9 +9,9 @@ abstract class My<T : Some> {
abstract fun foo(arg: T)
abstract val y: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>My.T<!>
abstract val y: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>My<!>.T
abstract val z: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>test.My.T<!>
abstract val z: test.<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>My<!>.T
class Some : <!SUPERTYPE_NOT_A_CLASS_OR_INTERFACE, UNRESOLVED_REFERENCE!>T<!>()
}

View File

@@ -8,7 +8,7 @@ typealias TA = A<CharSequence>
fun bar(): TA = TODO()
fun foo() {
when (val a = bar()) {
<!NON_EXHAUSTIVE_WHEN_STATEMENT!>when<!> (val a = bar()) {
is A.B -> a.x.length
}
}

View File

@@ -10,4 +10,4 @@ class A<T1, T2> {
fun <R1, R2, R3> foo(c: A<R1, R1>.B<R2, R2>.C<R3, R3>) {}
fun <R3> foo(c: <!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>A.B.C<R3, R3><!>) {}
fun <R3> foo(c: A.<!WRONG_NUMBER_OF_TYPE_ARGUMENTS!>B<!>.C<R3, R3>) {}

View File

@@ -7,7 +7,7 @@ import java.nio.file.Files
fun detectDirsWithTestsMapFileOnly(file: File): List<String> {
Files.walk(file.toPath()).filter(Files::isRegularFile)
}
<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
interface A
fun foo(x: A, vararg strings: String) {}

View File

@@ -3,7 +3,7 @@ fun interface MySam {
}
class A {
fun bar(x: String): Int {}
fun bar(x: String): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
}
fun foo(x: MySam) {}

View File

@@ -1,5 +1,5 @@
class A {
fun bar(x: String): Int {}
fun bar(x: String): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
}
fun foo(x: (A, String) -> Int) {}

View File

@@ -1,5 +1,5 @@
class A {
fun bar(x: String): Int {}
fun bar(x: String): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
}
fun foo(x: (String) -> Int) {}

View File

@@ -1,6 +1,6 @@
fun foo(x: (String) -> Int) {}
fun bar(x: String): Int {}
fun bar(x: String): Int {<!NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY!>}<!>
fun main() {
foo(::bar)

View File

@@ -27,223 +27,225 @@ digraph delegateWithAnonymousObject_kt {
6 [label="Enter block"];
7 [label="Const: Null(null)"];
8 [label="Check not null: Null(null)!!"];
9 [label="Jump: ^delegate Null(null)!!"];
10 [label="Stub" style="filled" fillcolor=gray];
11 [label="Exit block" style="filled" fillcolor=gray];
9 [label="Stub" style="filled" fillcolor=gray];
10 [label="Jump: ^delegate Null(null)!!" style="filled" fillcolor=gray];
11 [label="Stub" style="filled" fillcolor=gray];
12 [label="Exit block" style="filled" fillcolor=gray];
}
12 [label="Exit function delegate" style="filled" fillcolor=red];
13 [label="Exit function delegate" style="filled" fillcolor=red];
}
5 -> {6};
6 -> {7};
7 -> {8};
8 -> {9};
9 -> {12};
8 -> {13} [label=onUncaughtException];
8 -> {9} [style=dotted];
9 -> {10} [style=dotted];
10 -> {11} [style=dotted];
10 -> {13 11} [style=dotted];
11 -> {12} [style=dotted];
12 -> {13} [style=dotted];
subgraph cluster_4 {
color=red
13 [label="Enter function <init>" style="filled" fillcolor=red];
14 [label="Delegated constructor call: super<R|DelegateProvider<IssueListView>|>()"];
15 [label="Exit function <init>" style="filled" fillcolor=red];
14 [label="Enter function <init>" style="filled" fillcolor=red];
15 [label="Delegated constructor call: super<R|DelegateProvider<IssueListView>|>()"];
16 [label="Exit function <init>" style="filled" fillcolor=red];
}
13 -> {14};
14 -> {15};
15 -> {16};
subgraph cluster_5 {
color=red
16 [label="Enter function updateFrom" style="filled" fillcolor=red];
17 [label="Enter function updateFrom" style="filled" fillcolor=red];
subgraph cluster_6 {
color=blue
17 [label="Enter block"];
18 [label="Exit block"];
18 [label="Enter block"];
19 [label="Exit block"];
}
19 [label="Exit function updateFrom" style="filled" fillcolor=red];
20 [label="Exit function updateFrom" style="filled" fillcolor=red];
}
16 -> {17};
17 -> {18};
18 -> {19};
19 -> {20};
subgraph cluster_7 {
color=red
20 [label="Enter class IssueListView" style="filled" fillcolor=red];
21 [label="Exit class IssueListView" style="filled" fillcolor=red];
21 [label="Enter class IssueListView" style="filled" fillcolor=red];
22 [label="Exit class IssueListView" style="filled" fillcolor=red];
}
20 -> {21} [color=green];
21 -> {22} [color=green];
subgraph cluster_8 {
color=red
22 [label="Enter function <init>" style="filled" fillcolor=red];
23 [label="Delegated constructor call: super<R|DelegateProvider<IssuesListUserProfile>|>()"];
24 [label="Exit function <init>" style="filled" fillcolor=red];
23 [label="Enter function <init>" style="filled" fillcolor=red];
24 [label="Delegated constructor call: super<R|DelegateProvider<IssuesListUserProfile>|>()"];
25 [label="Exit function <init>" style="filled" fillcolor=red];
}
22 -> {23};
23 -> {24};
24 -> {25};
subgraph cluster_9 {
color=red
33 [label="Enter function <init>" style="filled" fillcolor=red];
34 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
35 [label="Exit function <init>" style="filled" fillcolor=red];
34 [label="Enter function <init>" style="filled" fillcolor=red];
35 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
36 [label="Exit function <init>" style="filled" fillcolor=red];
}
33 -> {34};
34 -> {35};
35 -> {36};
subgraph cluster_10 {
color=red
36 [label="Enter function getValue" style="filled" fillcolor=red];
37 [label="Enter function getValue" style="filled" fillcolor=red];
subgraph cluster_11 {
color=blue
37 [label="Enter block"];
38 [label="Function call: R|/IssueListView.IssueListView|()"];
39 [label="Jump: ^getValue R|/IssueListView.IssueListView|()"];
40 [label="Stub" style="filled" fillcolor=gray];
41 [label="Exit block" style="filled" fillcolor=gray];
38 [label="Enter block"];
39 [label="Function call: R|/IssueListView.IssueListView|()"];
40 [label="Jump: ^getValue R|/IssueListView.IssueListView|()"];
41 [label="Stub" style="filled" fillcolor=gray];
42 [label="Exit block" style="filled" fillcolor=gray];
}
42 [label="Exit function getValue" style="filled" fillcolor=red];
43 [label="Exit function getValue" style="filled" fillcolor=red];
}
36 -> {37};
37 -> {38};
38 -> {39};
39 -> {42};
39 -> {40} [style=dotted];
39 -> {40};
40 -> {43};
40 -> {41} [style=dotted];
41 -> {42} [style=dotted];
42 -> {43} [style=dotted];
subgraph cluster_12 {
color=red
43 [label="Enter function setValue" style="filled" fillcolor=red];
44 [label="Enter function setValue" style="filled" fillcolor=red];
subgraph cluster_13 {
color=blue
44 [label="Enter block"];
45 [label="Function call: R|/IssueListView.IssueListView|()"];
46 [label="Access variable R|<local>/value|"];
47 [label="Function call: R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(...)"];
48 [label="Jump: ^setValue R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(R|<local>/value|)"];
49 [label="Stub" style="filled" fillcolor=gray];
50 [label="Exit block" style="filled" fillcolor=gray];
45 [label="Enter block"];
46 [label="Function call: R|/IssueListView.IssueListView|()"];
47 [label="Access variable R|<local>/value|"];
48 [label="Function call: R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(...)"];
49 [label="Jump: ^setValue R|/IssueListView.IssueListView|().R|/IssueListView.updateFrom|(R|<local>/value|)"];
50 [label="Stub" style="filled" fillcolor=gray];
51 [label="Exit block" style="filled" fillcolor=gray];
}
51 [label="Exit function setValue" style="filled" fillcolor=red];
52 [label="Exit function setValue" style="filled" fillcolor=red];
}
43 -> {44};
44 -> {45};
45 -> {46};
46 -> {47};
47 -> {48};
48 -> {51};
48 -> {49} [style=dotted];
48 -> {49};
49 -> {52};
49 -> {50} [style=dotted];
50 -> {51} [style=dotted];
51 -> {52} [style=dotted];
subgraph cluster_14 {
color=red
52 [label="Enter function getter" style="filled" fillcolor=red];
53 [label="Enter function getter" style="filled" fillcolor=red];
subgraph cluster_15 {
color=blue
53 [label="Enter block"];
54 [label="Access variable D|/IssuesListUserProfile.issueListView|"];
55 [label="Access variable this@R|/IssuesListUserProfile|"];
56 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride<kotlin/properties/ReadWriteProperty.getValue: R|IssueListView|>|(...)"];
57 [label="Jump: ^ this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride<kotlin/properties/ReadWriteProperty.getValue: R|IssueListView|>|(this@R|/IssuesListUserProfile|, ::R|/IssuesListUserProfile.issueListView|)"];
58 [label="Stub" style="filled" fillcolor=gray];
59 [label="Exit block" style="filled" fillcolor=gray];
54 [label="Enter block"];
55 [label="Access variable D|/IssuesListUserProfile.issueListView|"];
56 [label="Access variable this@R|/IssuesListUserProfile|"];
57 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride<kotlin/properties/ReadWriteProperty.getValue: R|IssueListView|>|(...)"];
58 [label="Jump: ^ this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride<kotlin/properties/ReadWriteProperty.getValue: R|IssueListView|>|(this@R|/IssuesListUserProfile|, ::R|/IssuesListUserProfile.issueListView|)"];
59 [label="Stub" style="filled" fillcolor=gray];
60 [label="Exit block" style="filled" fillcolor=gray];
}
60 [label="Exit function getter" style="filled" fillcolor=red];
61 [label="Exit function getter" style="filled" fillcolor=red];
}
52 -> {53};
53 -> {54};
54 -> {55};
55 -> {56};
56 -> {57};
57 -> {60};
57 -> {58} [style=dotted];
57 -> {58};
58 -> {61};
58 -> {59} [style=dotted];
59 -> {60} [style=dotted];
60 -> {61} [style=dotted];
subgraph cluster_16 {
color=red
61 [label="Enter function setter" style="filled" fillcolor=red];
62 [label="Enter function setter" style="filled" fillcolor=red];
subgraph cluster_17 {
color=blue
62 [label="Enter block"];
63 [label="Access variable D|/IssuesListUserProfile.issueListView|"];
64 [label="Access variable this@R|/IssuesListUserProfile|"];
65 [label="Access variable R|<local>/issueListView|"];
66 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride<kotlin/properties/ReadWriteProperty.setValue: R|kotlin/Unit|>|(...)"];
67 [label="Exit block"];
63 [label="Enter block"];
64 [label="Access variable D|/IssuesListUserProfile.issueListView|"];
65 [label="Access variable this@R|/IssuesListUserProfile|"];
66 [label="Access variable R|<local>/issueListView|"];
67 [label="Function call: this@R|/IssuesListUserProfile|.D|/IssuesListUserProfile.issueListView|.R|SubstitutionOverride<kotlin/properties/ReadWriteProperty.setValue: R|kotlin/Unit|>|(...)"];
68 [label="Exit block"];
}
68 [label="Exit function setter" style="filled" fillcolor=red];
69 [label="Exit function setter" style="filled" fillcolor=red];
}
61 -> {62};
62 -> {63};
63 -> {64};
64 -> {65};
65 -> {66};
66 -> {67};
67 -> {68};
68 -> {69};
subgraph cluster_18 {
color=red
69 [label="Enter property" style="filled" fillcolor=red];
70 [label="Postponed enter to lambda"];
71 [label="Postponed exit from lambda"];
72 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...)"];
73 [label="Access variable this@R|/IssuesListUserProfile|"];
74 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...).<Unresolved name: provideDelegate>#(...)"];
75 [label="Postponed enter to lambda"];
70 [label="Enter property" style="filled" fillcolor=red];
71 [label="Postponed enter to lambda"];
72 [label="Postponed exit from lambda"];
73 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...)"];
74 [label="Access variable this@R|/IssuesListUserProfile|"];
75 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...).<Unresolved name: provideDelegate>#(...)"];
76 [label="Postponed enter to lambda"];
subgraph cluster_19 {
color=blue
25 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
26 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_20 {
color=blue
26 [label="Enter block"];
27 [label="Exit anonymous object"];
28 [label="Exit anonymous object expression"];
29 [label="Exit block"];
27 [label="Enter block"];
28 [label="Exit anonymous object"];
29 [label="Exit anonymous object expression"];
30 [label="Exit block"];
}
30 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
31 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
subgraph cluster_21 {
color=blue
31 [label="Enter class <anonymous object>" style="filled" fillcolor=red];
32 [label="Exit class <anonymous object>" style="filled" fillcolor=red];
32 [label="Enter class <anonymous object>" style="filled" fillcolor=red];
33 [label="Exit class <anonymous object>" style="filled" fillcolor=red];
}
76 [label="Postponed exit from lambda"];
77 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...)"];
78 [label="Exit property" style="filled" fillcolor=red];
77 [label="Postponed exit from lambda"];
78 [label="Function call: this@R|/IssuesListUserProfile|.R|/delegate|<R|IssuesListUserProfile|, R|IssuesListUserProfile|, R|IssueListView|>(...)"];
79 [label="Exit property" style="filled" fillcolor=red];
}
69 -> {70};
70 -> {71};
70 -> {} [style=dashed];
71 -> {72};
71 -> {} [style=dashed];
72 -> {73};
73 -> {74};
74 -> {75};
75 -> {76 25};
75 -> {25} [style=dashed];
76 -> {77};
75 -> {76};
76 -> {77 26};
76 -> {26} [style=dashed];
77 -> {78};
78 -> {81} [color=green];
25 -> {26};
78 -> {79};
79 -> {82} [color=green];
26 -> {27};
26 -> {33 36 43} [color=red];
27 -> {28};
27 -> {33 36 43 31} [color=green];
27 -> {33 36 43 31} [style=dashed];
27 -> {34 37 44} [color=red];
28 -> {29};
28 -> {34 37 44 32} [color=green];
28 -> {34 37 44 32} [style=dashed];
29 -> {30};
31 -> {32} [color=green];
30 -> {31};
32 -> {33} [color=green];
subgraph cluster_22 {
color=red
79 [label="Enter class IssuesListUserProfile" style="filled" fillcolor=red];
80 [label="Part of class initialization"];
81 [label="Exit class IssuesListUserProfile" style="filled" fillcolor=red];
80 [label="Enter class IssuesListUserProfile" style="filled" fillcolor=red];
81 [label="Part of class initialization"];
82 [label="Exit class IssuesListUserProfile" style="filled" fillcolor=red];
}
79 -> {80} [color=green];
80 -> {81} [style=dotted];
80 -> {69} [color=green];
80 -> {69} [style=dashed];
80 -> {81} [color=green];
81 -> {82} [style=dotted];
81 -> {70} [color=green];
81 -> {70} [style=dashed];
}

View File

@@ -11,151 +11,153 @@ digraph plusAssignWithLambdaInRhs_kt {
1 [label="Enter block"];
2 [label="Const: Null(null)"];
3 [label="Check not null: Null(null)!!"];
4 [label="Variable declaration: lval list: R|kotlin/collections/MutableList<kotlin/Function1<kotlin/String, kotlin/String>>|"];
5 [label="Access variable R|<local>/list|"];
6 [label="Postponed enter to lambda"];
4 [label="Stub" style="filled" fillcolor=gray];
5 [label="Variable declaration: lval list: R|kotlin/collections/MutableList<kotlin/Function1<kotlin/String, kotlin/String>>|" style="filled" fillcolor=gray];
6 [label="Access variable R|<local>/list|" style="filled" fillcolor=gray];
7 [label="Postponed enter to lambda" style="filled" fillcolor=gray];
subgraph cluster_2 {
color=blue
11 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
12 [label="Enter function anonymousFunction" style="filled" fillcolor=red style="filled" fillcolor=gray];
subgraph cluster_3 {
color=blue
12 [label="Enter block"];
13 [label="Access variable R|<local>/it|"];
14 [label="Exit block"];
13 [label="Enter block" style="filled" fillcolor=gray];
14 [label="Access variable R|<local>/it|" style="filled" fillcolor=gray];
15 [label="Exit block" style="filled" fillcolor=gray];
}
15 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
16 [label="Exit function anonymousFunction" style="filled" fillcolor=red style="filled" fillcolor=gray];
}
7 [label="Postponed exit from lambda"];
8 [label="Function call: R|<local>/list|.R|kotlin/collections/plusAssign|<R|(kotlin/String) -> kotlin/String|>(...)"];
9 [label="Exit block"];
8 [label="Postponed exit from lambda" style="filled" fillcolor=gray];
9 [label="Function call: R|<local>/list|.R|kotlin/collections/plusAssign|<R|(kotlin/String) -> kotlin/String|>(...)" style="filled" fillcolor=gray];
10 [label="Exit block" style="filled" fillcolor=gray];
}
10 [label="Exit function test" style="filled" fillcolor=red];
11 [label="Exit function test" style="filled" fillcolor=red];
}
0 -> {1};
1 -> {2};
2 -> {3};
3 -> {4};
4 -> {5};
5 -> {6};
6 -> {11};
6 -> {7} [color=red];
6 -> {11} [style=dashed];
7 -> {8};
8 -> {9};
9 -> {10};
11 -> {15 12};
12 -> {13};
13 -> {14};
14 -> {15};
15 -> {7} [color=green];
15 -> {11} [color=green style=dashed];
3 -> {11} [label=onUncaughtException];
3 -> {4} [style=dotted];
4 -> {5} [style=dotted];
5 -> {6} [style=dotted];
6 -> {7} [style=dotted];
7 -> {8 12} [style=dotted];
7 -> {12} [style=dashed];
8 -> {9} [style=dotted];
9 -> {10} [style=dotted];
10 -> {11} [style=dotted];
12 -> {16 13} [style=dotted];
13 -> {14} [style=dotted];
14 -> {15} [style=dotted];
15 -> {16} [style=dotted];
16 -> {8} [style=dotted];
16 -> {12} [color=green style=dotted];
subgraph cluster_4 {
color=red
16 [label="Enter function <init>" style="filled" fillcolor=red];
17 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
18 [label="Exit function <init>" style="filled" fillcolor=red];
17 [label="Enter function <init>" style="filled" fillcolor=red];
18 [label="Delegated constructor call: super<R|kotlin/Any|>()"];
19 [label="Exit function <init>" style="filled" fillcolor=red];
}
16 -> {17};
17 -> {18};
18 -> {19};
subgraph cluster_5 {
color=red
19 [label="Enter property" style="filled" fillcolor=red];
20 [label="Access variable R|<local>/executor|"];
21 [label="Exit property" style="filled" fillcolor=red];
20 [label="Enter property" style="filled" fillcolor=red];
21 [label="Access variable R|<local>/executor|"];
22 [label="Exit property" style="filled" fillcolor=red];
}
19 -> {20};
20 -> {21};
21 -> {24} [color=green];
21 -> {22};
22 -> {25} [color=green];
subgraph cluster_6 {
color=red
22 [label="Enter class A" style="filled" fillcolor=red];
23 [label="Part of class initialization"];
24 [label="Exit class A" style="filled" fillcolor=red];
23 [label="Enter class A" style="filled" fillcolor=red];
24 [label="Part of class initialization"];
25 [label="Exit class A" style="filled" fillcolor=red];
}
22 -> {23} [color=green];
23 -> {24} [style=dotted];
23 -> {19} [color=green];
23 -> {19} [style=dashed];
23 -> {24} [color=green];
24 -> {25} [style=dotted];
24 -> {20} [color=green];
24 -> {20} [style=dashed];
subgraph cluster_7 {
color=red
25 [label="Enter function postpone" style="filled" fillcolor=red];
26 [label="Enter function postpone" style="filled" fillcolor=red];
subgraph cluster_8 {
color=blue
26 [label="Enter block"];
27 [label="Function call: R|kotlin/collections/mutableListOf|<R|() -> kotlin/Unit|>()"];
28 [label="Variable declaration: lval queue: R|kotlin/collections/MutableList<kotlin/Function0<kotlin/Unit>>|"];
29 [label="Postponed enter to lambda"];
27 [label="Enter block"];
28 [label="Function call: R|kotlin/collections/mutableListOf|<R|() -> kotlin/Unit|>()"];
29 [label="Variable declaration: lval queue: R|kotlin/collections/MutableList<kotlin/Function0<kotlin/Unit>>|"];
30 [label="Postponed enter to lambda"];
subgraph cluster_9 {
color=blue
36 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
37 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_10 {
color=blue
37 [label="Enter block"];
38 [label="Access variable R|<local>/queue|"];
39 [label="Postponed enter to lambda"];
38 [label="Enter block"];
39 [label="Access variable R|<local>/queue|"];
40 [label="Postponed enter to lambda"];
subgraph cluster_11 {
color=blue
44 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
45 [label="Enter function anonymousFunction" style="filled" fillcolor=red];
subgraph cluster_12 {
color=blue
45 [label="Enter block"];
46 [label="Function call: R|<local>/computation|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()"];
47 [label="Function call: R|<local>/resolve|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(...)"];
48 [label="Exit block"];
46 [label="Enter block"];
47 [label="Function call: R|<local>/computation|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|()"];
48 [label="Function call: R|<local>/resolve|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(...)"];
49 [label="Exit block"];
}
49 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
50 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
40 [label="Postponed exit from lambda"];
41 [label="Function call: R|<local>/queue|.R|kotlin/collections/plusAssign|<R|() -> kotlin/Unit|>(...)"];
42 [label="Exit block"];
41 [label="Postponed exit from lambda"];
42 [label="Function call: R|<local>/queue|.R|kotlin/collections/plusAssign|<R|() -> kotlin/Unit|>(...)"];
43 [label="Exit block"];
}
43 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
44 [label="Exit function anonymousFunction" style="filled" fillcolor=red];
}
30 [label="Postponed exit from lambda"];
31 [label="Function call: R|/A.A|<R|T|>(...)"];
32 [label="Jump: ^postpone R|/A.A|<R|T|>(<L> = A@fun <anonymous>(resolve: R|(T) -> kotlin/Unit|): R|kotlin/Unit| <inline=NoInline> {
31 [label="Postponed exit from lambda"];
32 [label="Function call: R|/A.A|<R|T|>(...)"];
33 [label="Jump: ^postpone R|/A.A|<R|T|>(<L> = A@fun <anonymous>(resolve: R|(T) -> kotlin/Unit|): R|kotlin/Unit| <inline=NoInline> {
R|<local>/queue|.R|kotlin/collections/plusAssign|<R|() -> kotlin/Unit|>(A@fun <anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
R|<local>/resolve|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/computation|.R|SubstitutionOverride<kotlin/Function0.invoke: R|T|>|())
}
)
}
)"];
33 [label="Stub" style="filled" fillcolor=gray];
34 [label="Exit block" style="filled" fillcolor=gray];
34 [label="Stub" style="filled" fillcolor=gray];
35 [label="Exit block" style="filled" fillcolor=gray];
}
35 [label="Exit function postpone" style="filled" fillcolor=red];
36 [label="Exit function postpone" style="filled" fillcolor=red];
}
25 -> {26};
26 -> {27};
27 -> {28};
28 -> {29};
29 -> {30 36};
29 -> {36} [style=dashed];
30 -> {31};
29 -> {30};
30 -> {31 37};
30 -> {37} [style=dashed];
31 -> {32};
32 -> {35};
32 -> {33} [style=dotted];
32 -> {33};
33 -> {36};
33 -> {34} [style=dotted];
34 -> {35} [style=dotted];
36 -> {37};
35 -> {36} [style=dotted];
37 -> {38};
38 -> {39};
39 -> {44};
39 -> {40} [color=red];
39 -> {44} [style=dashed];
40 -> {41};
39 -> {40};
40 -> {45};
40 -> {41} [color=red];
40 -> {45} [style=dashed];
41 -> {42};
42 -> {43};
44 -> {49 45};
45 -> {46};
43 -> {44};
45 -> {50 46};
46 -> {47};
47 -> {48};
48 -> {49};
49 -> {40} [color=green];
49 -> {44} [color=green style=dashed];
49 -> {50};
50 -> {41} [color=green];
50 -> {45} [color=green style=dashed];
}

View File

@@ -1,10 +1,6 @@
Module: m1-common
FILE: common.kt
public final expect class MyList : R|kotlin/Any| {
public expect constructor(): R|MyList| {
super<R|kotlin/Any|>()
}
public final expect fun get(i: R|kotlin/Int|): R|kotlin/Int|
}

View File

@@ -1761,6 +1761,272 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/annotations/parameters")
@TestDataPath("$PROJECT_ROOT")
public class Parameters {
@Test
public void testAllFilesPresentInParameters() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/annotations/parameters"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("byte.kt")
public void testByte() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/byte.kt");
}
@Test
@TestMetadata("char.kt")
public void testChar() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/char.kt");
}
@Test
@TestMetadata("double.kt")
public void testDouble() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/double.kt");
}
@Test
@TestMetadata("float.kt")
public void testFloat() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/float.kt");
}
@Test
@TestMetadata("int.kt")
public void testInt() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/int.kt");
}
@Test
@TestMetadata("long.kt")
public void testLong() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/long.kt");
}
@Test
@TestMetadata("short.kt")
public void testShort() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/short.kt");
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/annotations/parameters/expressions")
@TestDataPath("$PROJECT_ROOT")
public class Expressions {
@Test
public void testAllFilesPresentInExpressions() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/annotations/parameters/expressions"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("andAnd.kt")
public void testAndAnd() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/andAnd.kt");
}
@Test
@TestMetadata("boolean.kt")
public void testBoolean() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/boolean.kt");
}
@Test
@TestMetadata("char.kt")
public void testChar() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/char.kt");
}
@Test
@TestMetadata("compositeCallBinary.kt")
public void testCompositeCallBinary() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/compositeCallBinary.kt");
}
@Test
@TestMetadata("divide.kt")
public void testDivide() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/divide.kt");
}
@Test
@TestMetadata("double.kt")
public void testDouble() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/double.kt");
}
@Test
@TestMetadata("eqeq.kt")
public void testEqeq() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/eqeq.kt");
}
@Test
@TestMetadata("escapedString.kt")
public void testEscapedString() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/escapedString.kt");
}
@Test
@TestMetadata("float.kt")
public void testFloat() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/float.kt");
}
@Test
@TestMetadata("gt.kt")
public void testGt() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/gt.kt");
}
@Test
@TestMetadata("gteq.kt")
public void testGteq() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/gteq.kt");
}
@Test
@TestMetadata("intrincics.kt")
public void testIntrincics() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/intrincics.kt");
}
@Test
@TestMetadata("labeled.kt")
public void testLabeled() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/labeled.kt");
}
@Test
@TestMetadata("long.kt")
public void testLong() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/long.kt");
}
@Test
@TestMetadata("lt.kt")
public void testLt() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/lt.kt");
}
@Test
@TestMetadata("lteq.kt")
public void testLteq() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/lteq.kt");
}
@Test
@TestMetadata("maxValue.kt")
public void testMaxValue() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/maxValue.kt");
}
@Test
@TestMetadata("maxValueByte.kt")
public void testMaxValueByte() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/maxValueByte.kt");
}
@Test
@TestMetadata("maxValueInt.kt")
public void testMaxValueInt() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/maxValueInt.kt");
}
@Test
@TestMetadata("miltiply.kt")
public void testMiltiply() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/miltiply.kt");
}
@Test
@TestMetadata("minus.kt")
public void testMinus() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/minus.kt");
}
@Test
@TestMetadata("mod.kt")
public void testMod() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/mod.kt");
}
@Test
@TestMetadata("multilineString.kt")
public void testMultilineString() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/multilineString.kt");
}
@Test
@TestMetadata("not.kt")
public void testNot() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/not.kt");
}
@Test
@TestMetadata("noteq.kt")
public void testNoteq() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/noteq.kt");
}
@Test
@TestMetadata("orOr.kt")
public void testOrOr() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/orOr.kt");
}
@Test
@TestMetadata("paranthesized.kt")
public void testParanthesized() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/paranthesized.kt");
}
@Test
@TestMetadata("plus.kt")
public void testPlus() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/plus.kt");
}
@Test
@TestMetadata("simpleCallBinary.kt")
public void testSimpleCallBinary() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/simpleCallBinary.kt");
}
@Test
@TestMetadata("stringPlusInt.kt")
public void testStringPlusInt() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/stringPlusInt.kt");
}
@Test
@TestMetadata("stringTemplate.kt")
public void testStringTemplate() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/stringTemplate.kt");
}
@Test
@TestMetadata("strings.kt")
public void testStrings() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/strings.kt");
}
@Test
@TestMetadata("unaryMinus.kt")
public void testUnaryMinus() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/unaryMinus.kt");
}
@Test
@TestMetadata("unaryPlus.kt")
public void testUnaryPlus() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/unaryPlus.kt");
}
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/annotations/rendering")
@TestDataPath("$PROJECT_ROOT")
@@ -1870,6 +2136,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/annotations/typeUse/kt46173.kt");
}
@Test
@TestMetadata("kt47772.kt")
public void testKt47772() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/typeUse/kt47772.kt");
}
@Test
@TestMetadata("kt8325.kt")
public void testKt8325() throws Exception {
@@ -12722,6 +12994,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("kt47744.kt")
public void testKt47744() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/kt47744.kt");
}
@Test
@TestMetadata("labaledCall.kt")
public void testLabaledCall() throws Exception {
@@ -13962,6 +14240,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reifiedParameterWithRecursiveBound.kt");
}
@Test
@TestMetadata("reportImplicitNothingOnlyForOwnTypeParameters.kt")
public void testReportImplicitNothingOnlyForOwnTypeParameters() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reportImplicitNothingOnlyForOwnTypeParameters.kt");
}
@Test
@TestMetadata("specialCallWithMaterializeAndExpectedType.kt")
public void testSpecialCallWithMaterializeAndExpectedType() throws Exception {
@@ -19605,6 +19889,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/numbers/kt47447.kt");
}
@Test
@TestMetadata("kt47729.kt")
public void testKt47729() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt47729.kt");
}
@Test
@TestMetadata("kt47729_parenthesis.kt")
public void testKt47729_parenthesis() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt47729_parenthesis.kt");
}
@Test
@TestMetadata("literalReceiverWithIntegerValueType.kt")
public void testLiteralReceiverWithIntegerValueType() throws Exception {
@@ -31385,6 +31681,18 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.kt");
}
@Test
@TestMetadata("nonExhaustiveWhenStatement_1_6.kt")
public void testNonExhaustiveWhenStatement_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.kt");
}
@Test
@TestMetadata("nonExhaustiveWhenStatement_1_7.kt")
public void testNonExhaustiveWhenStatement_1_7() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.kt");
}
@Test
@TestMetadata("NonExhaustiveWithNullabilityCheck.kt")
public void testNonExhaustiveWithNullabilityCheck() throws Exception {

View File

@@ -1761,6 +1761,272 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/annotations/parameters")
@TestDataPath("$PROJECT_ROOT")
public class Parameters {
@Test
public void testAllFilesPresentInParameters() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/annotations/parameters"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("byte.kt")
public void testByte() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/byte.kt");
}
@Test
@TestMetadata("char.kt")
public void testChar() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/char.kt");
}
@Test
@TestMetadata("double.kt")
public void testDouble() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/double.kt");
}
@Test
@TestMetadata("float.kt")
public void testFloat() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/float.kt");
}
@Test
@TestMetadata("int.kt")
public void testInt() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/int.kt");
}
@Test
@TestMetadata("long.kt")
public void testLong() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/long.kt");
}
@Test
@TestMetadata("short.kt")
public void testShort() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/short.kt");
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/annotations/parameters/expressions")
@TestDataPath("$PROJECT_ROOT")
public class Expressions {
@Test
public void testAllFilesPresentInExpressions() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/annotations/parameters/expressions"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("andAnd.kt")
public void testAndAnd() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/andAnd.kt");
}
@Test
@TestMetadata("boolean.kt")
public void testBoolean() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/boolean.kt");
}
@Test
@TestMetadata("char.kt")
public void testChar() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/char.kt");
}
@Test
@TestMetadata("compositeCallBinary.kt")
public void testCompositeCallBinary() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/compositeCallBinary.kt");
}
@Test
@TestMetadata("divide.kt")
public void testDivide() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/divide.kt");
}
@Test
@TestMetadata("double.kt")
public void testDouble() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/double.kt");
}
@Test
@TestMetadata("eqeq.kt")
public void testEqeq() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/eqeq.kt");
}
@Test
@TestMetadata("escapedString.kt")
public void testEscapedString() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/escapedString.kt");
}
@Test
@TestMetadata("float.kt")
public void testFloat() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/float.kt");
}
@Test
@TestMetadata("gt.kt")
public void testGt() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/gt.kt");
}
@Test
@TestMetadata("gteq.kt")
public void testGteq() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/gteq.kt");
}
@Test
@TestMetadata("intrincics.kt")
public void testIntrincics() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/intrincics.kt");
}
@Test
@TestMetadata("labeled.kt")
public void testLabeled() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/labeled.kt");
}
@Test
@TestMetadata("long.kt")
public void testLong() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/long.kt");
}
@Test
@TestMetadata("lt.kt")
public void testLt() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/lt.kt");
}
@Test
@TestMetadata("lteq.kt")
public void testLteq() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/lteq.kt");
}
@Test
@TestMetadata("maxValue.kt")
public void testMaxValue() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/maxValue.kt");
}
@Test
@TestMetadata("maxValueByte.kt")
public void testMaxValueByte() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/maxValueByte.kt");
}
@Test
@TestMetadata("maxValueInt.kt")
public void testMaxValueInt() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/maxValueInt.kt");
}
@Test
@TestMetadata("miltiply.kt")
public void testMiltiply() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/miltiply.kt");
}
@Test
@TestMetadata("minus.kt")
public void testMinus() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/minus.kt");
}
@Test
@TestMetadata("mod.kt")
public void testMod() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/mod.kt");
}
@Test
@TestMetadata("multilineString.kt")
public void testMultilineString() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/multilineString.kt");
}
@Test
@TestMetadata("not.kt")
public void testNot() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/not.kt");
}
@Test
@TestMetadata("noteq.kt")
public void testNoteq() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/noteq.kt");
}
@Test
@TestMetadata("orOr.kt")
public void testOrOr() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/orOr.kt");
}
@Test
@TestMetadata("paranthesized.kt")
public void testParanthesized() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/paranthesized.kt");
}
@Test
@TestMetadata("plus.kt")
public void testPlus() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/plus.kt");
}
@Test
@TestMetadata("simpleCallBinary.kt")
public void testSimpleCallBinary() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/simpleCallBinary.kt");
}
@Test
@TestMetadata("stringPlusInt.kt")
public void testStringPlusInt() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/stringPlusInt.kt");
}
@Test
@TestMetadata("stringTemplate.kt")
public void testStringTemplate() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/stringTemplate.kt");
}
@Test
@TestMetadata("strings.kt")
public void testStrings() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/strings.kt");
}
@Test
@TestMetadata("unaryMinus.kt")
public void testUnaryMinus() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/unaryMinus.kt");
}
@Test
@TestMetadata("unaryPlus.kt")
public void testUnaryPlus() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/parameters/expressions/unaryPlus.kt");
}
}
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/annotations/rendering")
@TestDataPath("$PROJECT_ROOT")
@@ -1870,6 +2136,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/annotations/typeUse/kt46173.kt");
}
@Test
@TestMetadata("kt47772.kt")
public void testKt47772() throws Exception {
runTest("compiler/testData/diagnostics/tests/annotations/typeUse/kt47772.kt");
}
@Test
@TestMetadata("kt8325.kt")
public void testKt8325() throws Exception {
@@ -12722,6 +12994,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/builderInference"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("kt47744.kt")
public void testKt47744() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/kt47744.kt");
}
@Test
@TestMetadata("labaledCall.kt")
public void testLabaledCall() throws Exception {
@@ -13962,6 +14240,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reifiedParameterWithRecursiveBound.kt");
}
@Test
@TestMetadata("reportImplicitNothingOnlyForOwnTypeParameters.kt")
public void testReportImplicitNothingOnlyForOwnTypeParameters() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/reportImplicitNothingOnlyForOwnTypeParameters.kt");
}
@Test
@TestMetadata("specialCallWithMaterializeAndExpectedType.kt")
public void testSpecialCallWithMaterializeAndExpectedType() throws Exception {
@@ -19605,6 +19889,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/numbers/kt47447.kt");
}
@Test
@TestMetadata("kt47729.kt")
public void testKt47729() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt47729.kt");
}
@Test
@TestMetadata("kt47729_parenthesis.kt")
public void testKt47729_parenthesis() throws Exception {
runTest("compiler/testData/diagnostics/tests/numbers/kt47729_parenthesis.kt");
}
@Test
@TestMetadata("literalReceiverWithIntegerValueType.kt")
public void testLiteralReceiverWithIntegerValueType() throws Exception {
@@ -31385,6 +31681,18 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/tests/when/NonExhaustiveWarningNull.kt");
}
@Test
@TestMetadata("nonExhaustiveWhenStatement_1_6.kt")
public void testNonExhaustiveWhenStatement_1_6() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_6.kt");
}
@Test
@TestMetadata("nonExhaustiveWhenStatement_1_7.kt")
public void testNonExhaustiveWhenStatement_1_7() throws Exception {
runTest("compiler/testData/diagnostics/tests/when/nonExhaustiveWhenStatement_1_7.kt");
}
@Test
@TestMetadata("NonExhaustiveWithNullabilityCheck.kt")
public void testNonExhaustiveWithNullabilityCheck() throws Exception {

View File

@@ -7,6 +7,7 @@ plugins {
dependencies {
implementation(project(":compiler:fir:tree"))
implementation(project(":compiler:fir:tree:tree-generator"))
implementation(project(":compiler:resolution.common"))
implementation(project(":kotlin-reflect"))
implementation(project(":kotlin-reflect-api"))

View File

@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.checkers.generator.diagnostics.model.*
import org.jetbrains.kotlin.fir.declarations.*
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
import org.jetbrains.kotlin.types.Variance
import kotlin.properties.PropertyDelegateProvider
import kotlin.properties.ReadOnlyProperty
@@ -446,12 +448,15 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val TYPE_ARGUMENTS_NOT_ALLOWED by error<PsiElement>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error<PsiElement> {
parameter<Int>("expectedCount")
parameter<FirClassLikeSymbol<*>>("classifier")
parameter<FirRegularClassSymbol>("classifier")
}
val NO_TYPE_ARGUMENTS_ON_RHS by error<PsiElement> {
parameter<Int>("expectedCount")
parameter<FirClassLikeSymbol<*>>("classifier")
}
val OUTER_CLASS_ARGUMENTS_REQUIRED by error<PsiElement> {
parameter<FirRegularClassSymbol>("outer")
}
val TYPE_PARAMETERS_IN_OBJECT by error<PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error<PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error<PsiElement>()
@@ -782,7 +787,6 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val ABSTRACT_PROPERTY_WITH_SETTER by error<KtPropertyAccessor>()
val PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY by error<KtModifierListOwner>(PositioningStrategy.PRIVATE_MODIFIER)
val PRIVATE_SETTER_FOR_OPEN_PROPERTY by error<KtModifierListOwner>(PositioningStrategy.PRIVATE_MODIFIER)
val EXPECTED_PRIVATE_DECLARATION by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
val VAL_WITH_SETTER by error<KtPropertyAccessor>()
val CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT by error<KtElement>(PositioningStrategy.CONST_MODIFIER)
val CONST_VAL_WITH_GETTER by error<KtElement>()
@@ -812,11 +816,56 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val MPP_PROJECTS by object : DiagnosticGroup("Multi-platform projects") {
val EXPECTED_DECLARATION_WITH_BODY by error<KtDeclaration>(PositioningStrategy.DECLARATION_SIGNATURE)
val EXPECTED_CLASS_CONSTRUCTOR_DELEGATION_CALL by error<KtConstructorDelegationCall>()
val EXPECTED_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER by error<KtParameter>()
val EXPECTED_ENUM_CONSTRUCTOR by error<KtConstructor<*>>()
val EXPECTED_ENUM_ENTRY_WITH_BODY by error<KtEnumEntry>()
val EXPECTED_PROPERTY_INITIALIZER by error<KtExpression>()
// TODO: need to cover `by` as well as delegate expression
val EXPECTED_DELEGATED_PROPERTY by error<KtExpression>()
val EXPECTED_LATEINIT_PROPERTY by error<KtModifierListOwner>(PositioningStrategy.LATEINIT_MODIFIER)
val SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS by error<PsiElement>()
val EXPECTED_PRIVATE_DECLARATION by error<KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
val IMPLEMENTATION_BY_DELEGATION_IN_EXPECT_CLASS by error<KtDelegatedSuperTypeEntry>()
val ACTUAL_TYPE_ALIAS_NOT_TO_CLASS by error<KtTypeAlias>(PositioningStrategy.DECLARATION_SIGNATURE)
val ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE by error<KtTypeAlias>(PositioningStrategy.DECLARATION_SIGNATURE)
val ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE by error<KtTypeAlias>(PositioningStrategy.DECLARATION_SIGNATURE)
val ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION by error<KtTypeAlias>(PositioningStrategy.DECLARATION_SIGNATURE)
val ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS by error<PsiElement>()
val ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE by error<PsiElement> {
parameter<FirVariableSymbol<*>>("parameter")
}
val EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND by error<PsiElement>()
val NO_ACTUAL_FOR_EXPECT by error<KtNamedDeclaration>(PositioningStrategy.INCOMPATIBLE_DECLARATION) {
parameter<Symbol>("declaration")
parameter<FirModuleData>("module")
parameter<Map<Incompatible<Symbol>, Collection<Symbol>>>("compatibility")
}
val ACTUAL_WITHOUT_EXPECT by error<KtNamedDeclaration> {
parameter<Symbol>("declaration")
parameter<Map<Incompatible<Symbol>, Collection<Symbol>>>("compatibility")
}
val AMBIGUOUS_ACTUALS by error<KtNamedDeclaration>(PositioningStrategy.INCOMPATIBLE_DECLARATION) {
parameter<Symbol>("declaration")
parameter<Collection<Symbol>>("candidates")
}
val AMBIGUOUS_EXPECTS by error<KtNamedDeclaration>(PositioningStrategy.INCOMPATIBLE_DECLARATION) {
parameter<Symbol>("declaration")
parameter<Collection<FirModuleData>>("modules")
}
val NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME) {
parameter<Symbol>("declaration")
parameter<List<Pair<Symbol, Map<Incompatible<Symbol>, Collection<Symbol>>>>>("members")
}
val ACTUAL_MISSING by error<KtNamedDeclaration>(PositioningStrategy.ACTUAL_DECLARATION_NAME)
}
val DESTRUCTING_DECLARATION by object : DiagnosticGroup("Destructuring declaration") {
@@ -927,6 +976,10 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val NO_ELSE_IN_WHEN by error<KtWhenExpression>(PositioningStrategy.WHEN_EXPRESSION) {
parameter<List<WhenMissingCase>>("missingWhenCases")
}
val NON_EXHAUSTIVE_WHEN_STATEMENT by warning<KtWhenExpression>(PositioningStrategy.WHEN_EXPRESSION) {
parameter<String>("type")
parameter<List<WhenMissingCase>>("missingWhenCases")
}
val INVALID_IF_AS_EXPRESSION by error<KtIfExpression>(PositioningStrategy.IF_EXPRESSION)
val ELSE_MISPLACED_IN_WHEN by error<KtWhenEntry>(PositioningStrategy.ELSE_ENTRY)
val ILLEGAL_DECLARATION_IN_WHEN_SUBJECT by error<KtElement> {
@@ -1033,6 +1086,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
val RETURNS by object : DiagnosticGroup("Returns") {
val RETURN_NOT_ALLOWED by error<KtReturnExpression>(PositioningStrategy.RETURN_WITH_LABEL)
val RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY by error<KtReturnExpression>(PositioningStrategy.RETURN_WITH_LABEL)
val NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY by error<KtDeclarationWithBody>(PositioningStrategy.DECLARATION_WITH_BODY)
val ANONYMOUS_INITIALIZER_IN_INTERFACE by error<KtAnonymousInitializer>(PositioningStrategy.DECLARATION_SIGNATURE)
}
val INLINE by object : DiagnosticGroup("Inline") {

View File

@@ -76,6 +76,9 @@ enum class PositioningStrategy(private val strategy: String? = null) {
IMPORT_LAST_NAME,
DATA_MODIFIER,
SPREAD_OPERATOR,
DECLARATION_WITH_BODY,
INCOMPATIBLE_DECLARATION,
ACTUAL_DECLARATION_NAME,
;

View File

@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.analysis.diagnostics.SourceElementPositioningStrategies
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.expressions.FirExpression
@@ -34,15 +35,21 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.psi.KtAnonymousInitializer
import org.jetbrains.kotlin.psi.KtArrayAccessExpression
import org.jetbrains.kotlin.psi.KtBinaryExpression
import org.jetbrains.kotlin.psi.KtBinaryExpressionWithTypeRHS
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtConstructor
import org.jetbrains.kotlin.psi.KtConstructorDelegationCall
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtIfExpression
@@ -65,6 +72,7 @@ import org.jetbrains.kotlin.psi.KtWhenCondition
import org.jetbrains.kotlin.psi.KtWhenEntry
import org.jetbrains.kotlin.psi.KtWhenExpression
import org.jetbrains.kotlin.resolve.ForbiddenNamedArgumentsTarget
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible
import org.jetbrains.kotlin.types.Variance
/*
@@ -295,8 +303,9 @@ object FirErrors {
val UPPER_BOUND_VIOLATED by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
val UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION by error2<PsiElement, ConeKotlinType, ConeKotlinType>()
val TYPE_ARGUMENTS_NOT_ALLOWED by error0<PsiElement>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2<PsiElement, Int, FirClassLikeSymbol<*>>()
val WRONG_NUMBER_OF_TYPE_ARGUMENTS by error2<PsiElement, Int, FirRegularClassSymbol>()
val NO_TYPE_ARGUMENTS_ON_RHS by error2<PsiElement, Int, FirClassLikeSymbol<*>>()
val OUTER_CLASS_ARGUMENTS_REQUIRED by error1<PsiElement, FirRegularClassSymbol>()
val TYPE_PARAMETERS_IN_OBJECT by error0<PsiElement>()
val ILLEGAL_PROJECTION_USAGE by error0<PsiElement>()
val TYPE_PARAMETERS_IN_ENUM by error0<PsiElement>()
@@ -423,7 +432,6 @@ object FirErrors {
val ABSTRACT_PROPERTY_WITH_SETTER by error0<KtPropertyAccessor>()
val PRIVATE_SETTER_FOR_ABSTRACT_PROPERTY by error0<KtModifierListOwner>(SourceElementPositioningStrategies.PRIVATE_MODIFIER)
val PRIVATE_SETTER_FOR_OPEN_PROPERTY by error0<KtModifierListOwner>(SourceElementPositioningStrategies.PRIVATE_MODIFIER)
val EXPECTED_PRIVATE_DECLARATION by error0<KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val VAL_WITH_SETTER by error0<KtPropertyAccessor>()
val CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT by error0<KtElement>(SourceElementPositioningStrategies.CONST_MODIFIER)
val CONST_VAL_WITH_GETTER by error0<KtElement>()
@@ -441,9 +449,29 @@ object FirErrors {
// Multi-platform projects
val EXPECTED_DECLARATION_WITH_BODY by error0<KtDeclaration>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val EXPECTED_CLASS_CONSTRUCTOR_DELEGATION_CALL by error0<KtConstructorDelegationCall>()
val EXPECTED_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER by error0<KtParameter>()
val EXPECTED_ENUM_CONSTRUCTOR by error0<KtConstructor<*>>()
val EXPECTED_ENUM_ENTRY_WITH_BODY by error0<KtEnumEntry>()
val EXPECTED_PROPERTY_INITIALIZER by error0<KtExpression>()
val EXPECTED_DELEGATED_PROPERTY by error0<KtExpression>()
val EXPECTED_LATEINIT_PROPERTY by error0<KtModifierListOwner>(SourceElementPositioningStrategies.LATEINIT_MODIFIER)
val SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS by error0<PsiElement>()
val EXPECTED_PRIVATE_DECLARATION by error0<KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val IMPLEMENTATION_BY_DELEGATION_IN_EXPECT_CLASS by error0<KtDelegatedSuperTypeEntry>()
val ACTUAL_TYPE_ALIAS_NOT_TO_CLASS by error0<KtTypeAlias>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE by error0<KtTypeAlias>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE by error0<KtTypeAlias>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION by error0<KtTypeAlias>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
val ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS by error0<PsiElement>()
val ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE by error1<PsiElement, FirVariableSymbol<*>>()
val EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND by error0<PsiElement>()
val NO_ACTUAL_FOR_EXPECT by error3<KtNamedDeclaration, FirBasedSymbol<*>, FirModuleData, Map<Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>(SourceElementPositioningStrategies.INCOMPATIBLE_DECLARATION)
val ACTUAL_WITHOUT_EXPECT by error2<KtNamedDeclaration, FirBasedSymbol<*>, Map<Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>()
val AMBIGUOUS_ACTUALS by error2<KtNamedDeclaration, FirBasedSymbol<*>, Collection<FirBasedSymbol<*>>>(SourceElementPositioningStrategies.INCOMPATIBLE_DECLARATION)
val AMBIGUOUS_EXPECTS by error2<KtNamedDeclaration, FirBasedSymbol<*>, Collection<FirModuleData>>(SourceElementPositioningStrategies.INCOMPATIBLE_DECLARATION)
val NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS by error2<KtNamedDeclaration, FirBasedSymbol<*>, List<Pair<FirBasedSymbol<*>, Map<Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>>>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
val ACTUAL_MISSING by error0<KtNamedDeclaration>(SourceElementPositioningStrategies.ACTUAL_DECLARATION_NAME)
// Destructuring declaration
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<KtDestructuringDeclaration>()
@@ -488,6 +516,7 @@ object FirErrors {
// When expressions
val EXPECTED_CONDITION by error0<KtWhenCondition>()
val NO_ELSE_IN_WHEN by error1<KtWhenExpression, List<WhenMissingCase>>(SourceElementPositioningStrategies.WHEN_EXPRESSION)
val NON_EXHAUSTIVE_WHEN_STATEMENT by warning2<KtWhenExpression, String, List<WhenMissingCase>>(SourceElementPositioningStrategies.WHEN_EXPRESSION)
val INVALID_IF_AS_EXPRESSION by error0<KtIfExpression>(SourceElementPositioningStrategies.IF_EXPRESSION)
val ELSE_MISPLACED_IN_WHEN by error0<KtWhenEntry>(SourceElementPositioningStrategies.ELSE_ENTRY)
val ILLEGAL_DECLARATION_IN_WHEN_SUBJECT by error1<KtElement, String>()
@@ -545,6 +574,8 @@ object FirErrors {
// Returns
val RETURN_NOT_ALLOWED by error0<KtReturnExpression>(SourceElementPositioningStrategies.RETURN_WITH_LABEL)
val RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY by error0<KtReturnExpression>(SourceElementPositioningStrategies.RETURN_WITH_LABEL)
val NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY by error0<KtDeclarationWithBody>(SourceElementPositioningStrategies.DECLARATION_WITH_BODY)
val ANONYMOUS_INITIALIZER_IN_INTERFACE by error0<KtAnonymousInitializer>(SourceElementPositioningStrategies.DECLARATION_SIGNATURE)
// Inline
val USAGE_IS_NOT_INLINABLE by error1<KtElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCE_BY_QUALIFIED)

View File

@@ -30,13 +30,15 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirInfixFunctionDeclarationChecker,
FirExposedVisibilityDeclarationChecker,
FirCyclicTypeBoundsChecker,
FirExpectActualDeclarationChecker
)
override val functionCheckers: Set<FirFunctionChecker>
get() = setOf(
FirContractChecker,
FirFunctionParameterChecker,
FirInlineDeclarationChecker
FirInlineDeclarationChecker,
FirFunctionReturnChecker,
)
override val simpleFunctionCheckers: Set<FirSimpleFunctionChecker>
@@ -88,6 +90,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirFunInterfaceDeclarationChecker,
FirNestedClassChecker,
FirInlineClassDeclarationChecker,
FirOuterClassArgumentsRequiredChecker
)
override val constructorCheckers: Set<FirConstructorChecker>
@@ -137,4 +140,9 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
FirAnonymousFunctionParametersChecker,
FirAnonymousFunctionSyntaxChecker,
)
override val anonymousInitializerCheckers: Set<FirAnonymousInitializerChecker>
get() = setOf(
FirAnonymousInitializerInInterfaceChecker
)
}

View File

@@ -58,6 +58,7 @@ interface FirDeclarationPresenter {
is ConeKotlinType -> {
appendRepresentation(it)
}
is ConeKotlinTypeConflictingProjection -> {}
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.findClosestClassOrObject
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirAnonymousInitializer
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
object FirAnonymousInitializerInInterfaceChecker : FirAnonymousInitializerChecker() {
override fun check(declaration: FirAnonymousInitializer, context: CheckerContext, reporter: DiagnosticReporter) {
val clazz = context.findClosestClassOrObject() ?: return
if (clazz.isInterface) {
reporter.reportOn(declaration.source, FirErrors.ANONYMOUS_INITIALIZER_IN_INTERFACE, context)
}
}
}

View File

@@ -197,6 +197,7 @@ object FirConflictsChecker : FirBasicDeclarationChecker() {
}
}
}
else -> {}
}
if (declarationName != null) {
session.lookupTracker?.recordLookup(

View File

@@ -0,0 +1,242 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirMemberDeclaration
import org.jetbrains.kotlin.fir.declarations.utils.isActual
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.toSymbol
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.*
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
@Suppress("DuplicatedCode")
object FirExpectActualDeclarationChecker : FirBasicDeclarationChecker() {
override fun check(declaration: FirDeclaration, context: CheckerContext, reporter: DiagnosticReporter) {
if (!context.session.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) return
if (declaration !is FirMemberDeclaration) return
if (declaration.isActual) {
checkActualDeclarationHasExpected(declaration, context, reporter)
}
}
private fun <T> checkActualDeclarationHasExpected(
declaration: T,
context: CheckerContext,
reporter: DiagnosticReporter,
checkActual: Boolean = true
) where T : FirDeclaration, T : FirMemberDeclaration {
val scopeSession = ScopeSession()
val symbol = declaration.symbol
val compatibilityToMembersMap = FirExpectActualResolver.findExpectForActual(symbol, context.session, scopeSession) ?: return
val session = context.session
checkAmbiguousExpects(symbol, compatibilityToMembersMap, symbol, context, reporter)
val source = declaration.source
if (!declaration.isActual) {
if (compatibilityToMembersMap.allStrongIncompatibilities()) return
if (Compatible in compatibilityToMembersMap) {
if (checkActual && requireActualModifier(symbol, session)) {
reporter.reportOn(source, FirErrors.ACTUAL_MISSING, context)
}
return
}
}
val singleIncompatibility = compatibilityToMembersMap.keys.singleOrNull()
when {
singleIncompatibility is Incompatible.ClassScopes -> {
assert(symbol is FirRegularClassSymbol || symbol is FirTypeAliasSymbol) {
"Incompatible.ClassScopes is only possible for a class or a typealias: $declaration"
}
// Do not report "expected members have no actual ones" for those expected members, for which there's a clear
// (albeit maybe incompatible) single actual suspect, declared in the actual class.
// This is needed only to reduce the number of errors. Incompatibility errors for those members will be reported
// later when this checker is called for them
fun hasSingleActualSuspect(
expectedWithIncompatibility: Pair<FirBasedSymbol<*>, Map<Incompatible<FirBasedSymbol<*>>, Collection<FirBasedSymbol<*>>>>
): Boolean {
val (expectedMember, incompatibility) = expectedWithIncompatibility
val actualMember = incompatibility.values.singleOrNull()?.singleOrNull()
return actualMember != null &&
actualMember.isExplicitActualDeclaration() &&
!incompatibility.allStrongIncompatibilities() &&
FirExpectActualResolver.findExpectForActual(
actualMember,
session,
scopeSession
)?.values?.singleOrNull()?.singleOrNull() == expectedMember
}
val nonTrivialUnfulfilled = singleIncompatibility.unfulfilled.filterNot(::hasSingleActualSuspect)
if (nonTrivialUnfulfilled.isNotEmpty()) {
reporter.reportOn(source, FirErrors.NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS, symbol, nonTrivialUnfulfilled, context)
}
}
Compatible !in compatibilityToMembersMap -> {
reporter.reportOn(source, FirErrors.ACTUAL_WITHOUT_EXPECT, symbol, compatibilityToMembersMap.cast(), context)
}
else -> {
val expected = compatibilityToMembersMap[Compatible]!!.first()
if (expected is FirRegularClassSymbol && expected.classKind == ClassKind.ANNOTATION_CLASS) {
val klass = symbol.expandedClass(session)
val actualConstructor = klass?.declarationSymbols?.firstIsInstanceOrNull<FirConstructorSymbol>()
val expectedConstructor = expected.declarationSymbols.firstIsInstanceOrNull<FirConstructorSymbol>()
if (expectedConstructor != null && actualConstructor != null) {
checkAnnotationConstructors(source, expectedConstructor, actualConstructor, context, reporter)
}
}
}
}
}
@Suppress("UNUSED_PARAMETER")
private fun checkAnnotationConstructors(
source: FirSourceElement?,
expected: FirConstructorSymbol,
actual: FirConstructorSymbol,
context: CheckerContext,
reporter: DiagnosticReporter
) {
for (expectedValueParameter in expected.valueParameterSymbols) {
// Actual parameter with the same name is guaranteed to exist because this method is only called for compatible annotations
val actualValueDescriptor = actual.valueParameterSymbols.first { it.name == expectedValueParameter.name }
if (expectedValueParameter.hasDefaultValue && actualValueDescriptor.hasDefaultValue) {
// TODO
// val expectedParameter =
// DescriptorToSourceUtils.descriptorToDeclaration(expectedValueParameter) as? KtParameter ?: continue
//
// val expectedValue = trace.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expectedParameter.defaultValue)
// ?.toConstantValue(expectedValueParameter.type)
//
// val actualValue =
// getActualAnnotationParameterValue(actualValueDescriptor, trace.bindingContext, expectedValueParameter.type)
// if (expectedValue != actualValue) {
// val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(actualValueDescriptor)
// val target = (ktParameter as? KtParameter)?.defaultValue ?: (reportOn as? KtTypeAlias)?.nameIdentifier ?: reportOn
// trace.report(Errors.ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE.on(target, actualValueDescriptor))
// }
}
}
}
private fun checkAmbiguousExpects(
actualDeclaration: FirBasedSymbol<*>,
compatibility: Map<ExpectActualCompatibility<FirBasedSymbol<*>>, List<FirBasedSymbol<*>>>,
symbol: FirBasedSymbol<*>,
context: CheckerContext,
reporter: DiagnosticReporter
) {
val filesWithAtLeastWeaklyCompatibleExpects = compatibility.asSequence()
.filter { (compatibility, _) ->
compatibility.isCompatibleOrWeakCompatible()
}
.map { (_, members) -> members }
.flatten()
.map { it.moduleData }
.sortedBy { it.name.asString() }
.toList()
if (filesWithAtLeastWeaklyCompatibleExpects.size > 1) {
reporter.reportOn(
actualDeclaration.source,
FirErrors.AMBIGUOUS_EXPECTS,
symbol,
filesWithAtLeastWeaklyCompatibleExpects,
context
)
}
}
fun Map<out ExpectActualCompatibility<*>, *>.allStrongIncompatibilities(): Boolean {
return keys.all { it is Incompatible && it.kind == IncompatibilityKind.STRONG }
}
private fun ExpectActualCompatibility<FirBasedSymbol<*>>.isCompatibleOrWeakCompatible(): Boolean {
return this is Compatible ||
this is Incompatible && kind == IncompatibilityKind.WEAK
}
// we don't require `actual` modifier on
// - annotation constructors, because annotation classes can only have one constructor
// - inline class primary constructors, because inline class must have primary constructor
// - value parameter inside primary constructor of inline class, because inline class must have one value parameter
private fun requireActualModifier(declaration: FirBasedSymbol<*>, session: FirSession): Boolean {
return !declaration.isAnnotationConstructor(session) &&
!declaration.isPrimaryConstructorOfInlineClass(session) &&
!isUnderlyingPropertyOfInlineClass(declaration)
}
@Suppress("UNUSED_PARAMETER")
private fun isUnderlyingPropertyOfInlineClass(declaration: FirBasedSymbol<*>): Boolean {
// TODO
// return declaration is PropertyDescriptor && declaration.isUnderlyingPropertyOfInlineClass()
return false
}
private fun FirBasedSymbol<*>.isExplicitActualDeclaration(): Boolean {
// return when (this) {
// is FirConstructor -> DescriptorToSourceUtils.getSourceFromDescriptor(this) is KtConstructor<*>
// is FirCallableMemberDeclaration<*> -> kind == CallableMemberDescriptor.Kind.DECLARATION
// else -> true
// }
return true
}
}
fun FirBasedSymbol<*>.isAnnotationConstructor(session: FirSession): Boolean {
if (this !is FirConstructorSymbol) return false
return getConstructedClass(session)?.classKind == ClassKind.ANNOTATION_CLASS
}
fun FirBasedSymbol<*>.isEnumConstructor(session: FirSession): Boolean {
if (this !is FirConstructorSymbol) return false
return getConstructedClass(session)?.classKind == ClassKind.ENUM_CLASS
}
fun FirBasedSymbol<*>.isPrimaryConstructorOfInlineClass(session: FirSession): Boolean {
if (this !is FirConstructorSymbol) return false
return getConstructedClass(session)?.isInlineOrValueClass() == true && this.isPrimary
}
fun FirConstructorSymbol.getConstructedClass(session: FirSession): FirRegularClassSymbol? {
return resolvedReturnTypeRef.coneType
.fullyExpandedType(session)
.toSymbol(session) as? FirRegularClassSymbol?
}
fun FirBasedSymbol<*>.expandedClass(session: FirSession): FirRegularClassSymbol? {
return when (this) {
is FirTypeAliasSymbol -> resolvedExpandedTypeRef.coneType.fullyExpandedType(session).toSymbol(session) as? FirRegularClassSymbol
is FirRegularClassSymbol -> this
else -> null
}
}

View File

@@ -0,0 +1,658 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.checkers.collectEnumEntries
import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.resolve.*
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutorByMap
import org.jetbrains.kotlin.fir.resolve.substitution.chain
import org.jetbrains.kotlin.fir.scopes.*
import org.jetbrains.kotlin.fir.scopes.impl.FirPackageMemberScope
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.keysToMap
object FirExpectActualResolver {
@OptIn(ExperimentalStdlibApi::class)
fun findExpectForActual(
actualSymbol: FirBasedSymbol<*>,
useSiteSession: FirSession,
scopeSession: ScopeSession
): Map<ExpectActualCompatibility<FirBasedSymbol<*>>, List<FirBasedSymbol<*>>>? {
return when (actualSymbol) {
is FirCallableSymbol<*> -> {
val callableId = actualSymbol.callableId
val classId = callableId.classId
var parentSubstitutor: ConeSubstitutor? = null
var expectContainingClass: FirRegularClassSymbol? = null
var actualContainingClass: FirRegularClassSymbol? = null
val candidates = when {
classId != null -> {
expectContainingClass = useSiteSession.dependenciesSymbolProvider.getClassLikeSymbolByFqName(classId)?.let {
it.fullyExpandedClass(it.moduleData.session)
}
actualContainingClass = useSiteSession.symbolProvider.getClassLikeSymbolByFqName(classId)
?.fullyExpandedClass(useSiteSession)
val expectTypeParameters = expectContainingClass?.typeParameterSymbols.orEmpty()
val actualTypeParameters = actualContainingClass
?.typeParameterSymbols
.orEmpty()
parentSubstitutor = createTypeParameterSubstitutor(expectTypeParameters, actualTypeParameters, useSiteSession)
when (actualSymbol) {
is FirConstructorSymbol -> expectContainingClass?.getConstructors(scopeSession)
else -> expectContainingClass?.getMembers(callableId.callableName, scopeSession)
}.orEmpty()
}
callableId.isLocal -> return null
else -> {
val scope = FirPackageMemberScope(callableId.packageName, useSiteSession, useSiteSession.dependenciesSymbolProvider)
mutableListOf<FirCallableSymbol<*>>().apply {
scope.processFunctionsByName(callableId.callableName) { add(it) }
scope.processPropertiesByName(callableId.callableName) { add(it) }
}
}
}
candidates.filter { expectSymbol ->
actualSymbol != expectSymbol && expectSymbol.isExpect
}.groupBy { expectDeclaration ->
areCompatibleCallables(
expectDeclaration,
actualSymbol,
useSiteSession,
parentSubstitutor,
expectContainingClass,
actualContainingClass
)
}
}
is FirClassLikeSymbol<*> -> {
val expectClassSymbol = useSiteSession.dependenciesSymbolProvider
.getClassLikeSymbolByFqName(actualSymbol.classId) as? FirRegularClassSymbol ?: return null
val compatibility = areCompatibleClassifiers(expectClassSymbol, actualSymbol, useSiteSession, scopeSession)
mapOf(compatibility to listOf(expectClassSymbol))
}
else -> null
}
}
private fun areCompatibleClassifiers(
expectClassSymbol: FirRegularClassSymbol,
actualClassLikeSymbol: FirClassLikeSymbol<*>,
actualSession: FirSession,
scopeSession: ScopeSession
): ExpectActualCompatibility<FirBasedSymbol<*>> {
// Can't check FQ names here because nested expected class may be implemented via actual typealias's expansion with the other FQ name
assert(expectClassSymbol.classId.shortClassName == actualClassLikeSymbol.classId.shortClassName) {
"This function should be invoked only for declarations with the same name: $expectClassSymbol, $actualClassLikeSymbol"
}
val actualClass = when (actualClassLikeSymbol) {
is FirRegularClassSymbol -> actualClassLikeSymbol
is FirTypeAliasSymbol -> actualClassLikeSymbol.resolvedExpandedTypeRef.coneType.fullyExpandedType(actualSession)
.toSymbol(actualSession) as? FirRegularClassSymbol
?: return ExpectActualCompatibility.Compatible // do not report extra error on erroneous typealias
else -> throw IllegalArgumentException("Incorrect actual classifier for $expectClassSymbol: $actualClassLikeSymbol")
}
if (expectClassSymbol.classKind != actualClass.classKind) return ExpectActualCompatibility.Incompatible.ClassKind
if (!equalBy(expectClassSymbol, actualClass) { listOf(it.isCompanion, it.isInner, it.isInline /*|| it.isValue*/) }) {
return ExpectActualCompatibility.Incompatible.ClassModifiers
}
val expectTypeParameterSymbols = expectClassSymbol.typeParameterSymbols
val actualTypeParameterSymbols = actualClass.typeParameterSymbols
if (expectTypeParameterSymbols.size != actualTypeParameterSymbols.size) {
return ExpectActualCompatibility.Incompatible.TypeParameterCount
}
if (!areCompatibleModalities(expectClassSymbol.modality, actualClass.modality)) {
return ExpectActualCompatibility.Incompatible.Modality
}
if (expectClassSymbol.visibility != actualClass.visibility) {
return ExpectActualCompatibility.Incompatible.Visibility
}
val substitutor = createTypeParameterSubstitutor(expectTypeParameterSymbols, actualTypeParameterSymbols, actualSession)
val expectSession = expectClassSymbol.moduleData.session
areCompatibleTypeParameters(expectTypeParameterSymbols, actualTypeParameterSymbols, actualSession, expectSession, substitutor).let {
if (it != ExpectActualCompatibility.Compatible) {
return it
}
}
// Subtract kotlin.Any from supertypes because it's implicitly added if no explicit supertype is specified,
// and not added if an explicit supertype _is_ specified
val expectSupertypes = expectClassSymbol.superConeTypes.filterNot { it.classId == actualSession.builtinTypes.anyType.id }
val actualSupertypes = actualClass.superConeTypes.filterNot { it.classId == actualSession.builtinTypes.anyType.id }
if (
expectSupertypes.map(substitutor::substituteOrSelf).any { expectSupertype ->
actualSupertypes.none { actualSupertype ->
areCompatibleTypes(expectSupertype, actualSupertype, expectSession, actualSession)
}
}
) {
return ExpectActualCompatibility.Incompatible.Supertypes
}
areCompatibleClassScopes(expectClassSymbol, actualClass, actualSession, scopeSession, substitutor).let {
if (it != ExpectActualCompatibility.Compatible) {
return it
}
}
return ExpectActualCompatibility.Compatible
}
private fun areCompatibleClassScopes(
expectClassSymbol: FirRegularClassSymbol,
actualClassSymbol: FirRegularClassSymbol,
actualSession: FirSession,
scopeSession: ScopeSession,
substitutor: ConeSubstitutor
): ExpectActualCompatibility<FirBasedSymbol<*>> {
val unfulfilled =
mutableListOf<Pair<FirBasedSymbol<*>, Map<ExpectActualCompatibility.Incompatible<FirBasedSymbol<*>>, MutableCollection<FirBasedSymbol<*>>>>>()
val allActualMembers = actualClassSymbol.getMembers(scopeSession, actualSession)
val actualMembersByName = allActualMembers.groupBy { it.name }
val actualConstructors = allActualMembers.filterIsInstance<FirConstructorSymbol>()
outer@ for (expectMember in expectClassSymbol.getMembers(scopeSession)) {
// if (expectMember is CallableMemberDescriptor && !expectMember.kind.isReal) continue
val actualMembers = when (expectMember) {
is FirConstructorSymbol -> actualConstructors
else -> actualMembersByName[expectMember.name]?.filter { actualMember ->
expectMember is FirRegularClassSymbol && actualMember is FirRegularClassSymbol ||
expectMember is FirCallableSymbol<*> && actualMember is FirCallableSymbol<*>
}.orEmpty()
}
val mapping = actualMembers.keysToMap { actualMember ->
when (expectMember) {
is FirCallableSymbol<*> ->
areCompatibleCallables(
expectMember,
actualMember as FirCallableSymbol<*>,
actualSession,
substitutor,
expectClassSymbol,
actualClassSymbol
)
is FirRegularClassSymbol ->
areCompatibleClassifiers(expectMember, actualMember as FirRegularClassSymbol, actualSession, scopeSession)
else -> throw UnsupportedOperationException("Unsupported declaration: $expectMember ($actualMembers)")
}
}
if (mapping.values.any { it == ExpectActualCompatibility.Compatible }) continue
val incompatibilityMap =
mutableMapOf<ExpectActualCompatibility.Incompatible<FirBasedSymbol<*>>, MutableCollection<FirBasedSymbol<*>>>()
for ((declaration, compatibility) in mapping) {
when (compatibility) {
ExpectActualCompatibility.Compatible -> continue@outer
is ExpectActualCompatibility.Incompatible -> incompatibilityMap.getOrPut(compatibility) { SmartList() }.add(declaration)
}
}
unfulfilled.add(expectMember to incompatibilityMap)
}
if (expectClassSymbol.classKind == ClassKind.ENUM_CLASS) {
val expectEntries = expectClassSymbol.collectEnumEntries().map { it.name }
val actualEntries = actualClassSymbol.collectEnumEntries().map { it.name }
if (!actualEntries.containsAll(expectEntries)) {
return ExpectActualCompatibility.Incompatible.EnumEntries
}
}
// TODO: check static scope?
if (unfulfilled.isEmpty()) return ExpectActualCompatibility.Compatible
return ExpectActualCompatibility.Incompatible.ClassScopes(unfulfilled)
}
private fun areCompatibleCallables(
expectDeclaration: FirCallableSymbol<*>,
actualDeclaration: FirCallableSymbol<*>,
actualSession: FirSession,
parentSubstitutor: ConeSubstitutor?,
expectContainingClass: FirRegularClassSymbol?,
actualContainingClass: FirRegularClassSymbol?,
): ExpectActualCompatibility<FirBasedSymbol<*>> {
assert(
(expectDeclaration is FirConstructorSymbol && actualDeclaration is FirConstructorSymbol) ||
expectDeclaration.callableId.callableName == actualDeclaration.callableId.callableName
) {
"This function should be invoked only for declarations with the same name: $expectDeclaration, $actualDeclaration"
}
assert((expectDeclaration.dispatchReceiverType == null) == (actualDeclaration.dispatchReceiverType == null)) {
"This function should be invoked only for declarations in the same kind of container (both members or both top level): $expectDeclaration, $actualDeclaration"
}
val expectSession = expectDeclaration.moduleData.session
if (
expectDeclaration is FirConstructorSymbol &&
actualDeclaration is FirConstructorSymbol &&
expectContainingClass?.classKind == ClassKind.ENUM_CLASS &&
actualContainingClass?.classKind == ClassKind.ENUM_CLASS
) {
return ExpectActualCompatibility.Compatible
}
if (expectDeclaration is FirNamedFunctionSymbol != actualDeclaration is FirNamedFunctionSymbol) {
return ExpectActualCompatibility.Incompatible.CallableKind
}
val expectedReceiverType = expectDeclaration.resolvedReceiverTypeRef
val actualReceiverType = actualDeclaration.resolvedReceiverTypeRef
if ((expectedReceiverType != null) != (actualReceiverType != null)) {
return ExpectActualCompatibility.Incompatible.ParameterShape
}
val expectedValueParameters = expectDeclaration.valueParameterSymbols
val actualValueParameters = actualDeclaration.valueParameterSymbols
if (!valueParametersCountCompatible(expectDeclaration, actualDeclaration, expectedValueParameters, actualValueParameters)) {
return ExpectActualCompatibility.Incompatible.ParameterCount
}
val expectedTypeParameters = expectDeclaration.typeParameterSymbols
val actualTypeParameters = actualDeclaration.typeParameterSymbols
if (expectedTypeParameters.size != actualTypeParameters.size) {
return ExpectActualCompatibility.Incompatible.TypeParameterCount
}
val substitutor = createTypeParameterSubstitutor(expectedTypeParameters, actualTypeParameters, actualSession, parentSubstitutor)
if (
!areCompatibleTypeLists(
expectedValueParameters.toTypeList(substitutor),
actualValueParameters.toTypeList(ConeSubstitutor.Empty),
expectSession,
actualSession
) ||
!areCompatibleTypes(
expectedReceiverType?.coneType?.let { substitutor.substituteOrSelf(it) },
actualReceiverType?.coneType,
expectSession,
actualSession
)
) {
return ExpectActualCompatibility.Incompatible.ParameterTypes
}
if (
!areCompatibleTypes(
substitutor.substituteOrSelf(expectDeclaration.resolvedReturnTypeRef.coneType),
actualDeclaration.resolvedReturnTypeRef.coneType,
expectSession,
actualSession
)
) {
return ExpectActualCompatibility.Incompatible.ReturnType
}
// TODO: implement hasStableParameterNames calculation
// if (actualDeclaration.hasStableParameterNames() && !equalsBy(expectedValueParameters, actualValueParameters, ValueParameterDescriptor::getName)) return Incompatible.ParameterNames
if (!equalsBy(expectedTypeParameters, actualTypeParameters) { it.name }) {
return ExpectActualCompatibility.Incompatible.TypeParameterNames
}
if (
!areCompatibleModalities(
expectDeclaration.modality,
actualDeclaration.modality,
(expectDeclaration.dispatchReceiverType?.toSymbol(expectSession) as? FirRegularClassSymbol)?.modality,
actualContainingClass?.modality
)
) {
return ExpectActualCompatibility.Incompatible.Modality
}
if (!areDeclarationsWithCompatibleVisibilities(expectDeclaration.resolvedStatus, actualDeclaration.resolvedStatus)) {
return ExpectActualCompatibility.Incompatible.Visibility
}
areCompatibleTypeParameters(expectedTypeParameters, actualTypeParameters, actualSession, expectSession, substitutor).let {
if (it != ExpectActualCompatibility.Compatible) {
return it
}
}
if (!equalsBy(expectedValueParameters, actualValueParameters) { it.isVararg }) {
return ExpectActualCompatibility.Incompatible.ValueParameterVararg
}
// Adding noinline/crossinline to parameters is disallowed, except if the expected declaration was not inline at all
if (expectDeclaration is FirNamedFunctionSymbol && expectDeclaration.isInline) {
if (expectedValueParameters.indices.any { i -> !expectedValueParameters[i].isNoinline && actualValueParameters[i].isNoinline }) {
return ExpectActualCompatibility.Incompatible.ValueParameterNoinline
}
if (expectedValueParameters.indices.any { i -> !expectedValueParameters[i].isCrossinline && actualValueParameters[i].isCrossinline }) {
return ExpectActualCompatibility.Incompatible.ValueParameterCrossinline
}
}
when {
expectDeclaration is FirNamedFunctionSymbol && actualDeclaration is FirNamedFunctionSymbol -> areCompatibleFunctions(
expectDeclaration,
actualDeclaration
).let { if (it != ExpectActualCompatibility.Compatible) return it }
expectDeclaration is FirConstructorSymbol && actualDeclaration is FirConstructorSymbol -> areCompatibleFunctions(
expectDeclaration,
actualDeclaration
).let { if (it != ExpectActualCompatibility.Compatible) return it }
expectDeclaration is FirPropertySymbol && actualDeclaration is FirPropertySymbol -> areCompatibleProperties(
expectDeclaration,
actualDeclaration
).let { if (it != ExpectActualCompatibility.Compatible) return it }
else -> throw AssertionError("Unsupported declarations: $expectDeclaration, $actualDeclaration")
}
return ExpectActualCompatibility.Compatible
}
private fun createTypeParameterSubstitutor(
expectedTypeParameters: List<FirTypeParameterSymbol>,
actualTypeParameters: List<FirTypeParameterSymbol>,
useSiteSession: FirSession,
parentSubstitutor: ConeSubstitutor? = null
): ConeSubstitutor {
val substitution = expectedTypeParameters.zip(actualTypeParameters).associate { (expectedParameterSymbol, actualParameterSymbol) ->
expectedParameterSymbol to actualParameterSymbol.toLookupTag().constructType(emptyArray(), isNullable = false)
}
val substitutor = ConeSubstitutorByMap(
substitution,
useSiteSession
)
if (parentSubstitutor == null) {
return substitutor
}
return substitutor.chain(parentSubstitutor)
}
private fun valueParametersCountCompatible(
expectDeclaration: FirCallableSymbol<*>,
actualDeclaration: FirCallableSymbol<*>,
expectValueParameters: List<FirValueParameterSymbol>,
actualValueParameters: List<FirValueParameterSymbol>
): Boolean {
if (expectValueParameters.size == actualValueParameters.size) return true
return if (
expectDeclaration.isAnnotationConstructor(expectDeclaration.moduleData.session) &&
actualDeclaration.isAnnotationConstructor(actualDeclaration.moduleData.session)
) {
expectValueParameters.isEmpty() && actualValueParameters.all { it.hasDefaultValue }
} else {
false
}
}
private fun areCompatibleTypeLists(
expectedTypes: List<ConeKotlinType?>,
actualTypes: List<ConeKotlinType?>,
expectSession: FirSession,
actualSession: FirSession
): Boolean {
for (i in expectedTypes.indices) {
if (!areCompatibleTypes(expectedTypes[i], actualTypes[i], expectSession, actualSession)) {
return false
}
}
return true
}
private fun areCompatibleTypes(
expectedType: ConeKotlinType?,
actualType: ConeKotlinType?,
expectSession: FirSession,
actualSession: FirSession
): Boolean {
if (expectedType == null) return actualType == null
if (actualType == null) return false
val typeCheckerContext = ConeInferenceContextForExpectActual(expectSession, actualSession).newBaseTypeCheckerContext(
errorTypesEqualToAnything = false,
stubTypesEqualToAnything = true
)
return AbstractTypeChecker.equalTypes(
typeCheckerContext,
expectedType,
actualType
)
}
private fun areCompatibleModalities(
expectModality: Modality?,
actualModality: Modality?,
expectContainingClassModality: Modality? = null,
actualContainingClassModality: Modality? = null
): Boolean {
val result = (expectModality == actualModality) ||
(expectModality == Modality.FINAL && (actualModality == Modality.OPEN || actualModality == Modality.ABSTRACT))
if (result) return true
if (expectContainingClassModality == null || actualContainingClassModality == null) return result
return expectModality == expectContainingClassModality && actualModality == actualContainingClassModality
}
private fun areDeclarationsWithCompatibleVisibilities(
expectStatus: FirDeclarationStatus,
actualStatus: FirDeclarationStatus
): Boolean {
val compare = Visibilities.compare(expectStatus.visibility, actualStatus.visibility)
return if (expectStatus.modality != Modality.FINAL) {
// For overridable declarations visibility should match precisely, see KT-19664
compare == 0
} else {
// For non-overridable declarations actuals are allowed to have more permissive visibility
compare != null && compare <= 0
}
}
private fun areCompatibleTypeParameters(
expectTypeParameterSymbols: List<FirTypeParameterSymbol>,
actualTypeParameterSymbols: List<FirTypeParameterSymbol>,
actualSession: FirSession,
expectSession: FirSession,
substitutor: ConeSubstitutor
): ExpectActualCompatibility<FirBasedSymbol<*>> {
for (i in expectTypeParameterSymbols.indices) {
val expectBounds = expectTypeParameterSymbols[i].resolvedBounds.map { it.coneType }
val actualBounds = actualTypeParameterSymbols[i].resolvedBounds.map { it.coneType }
if (
expectBounds.size != actualBounds.size ||
!areCompatibleTypeLists(expectBounds.map(substitutor::substituteOrSelf), actualBounds, expectSession, actualSession)
) {
return ExpectActualCompatibility.Incompatible.TypeParameterUpperBounds
}
}
if (!equalsBy(expectTypeParameterSymbols, actualTypeParameterSymbols) { it.variance }) {
return ExpectActualCompatibility.Incompatible.TypeParameterVariance
}
// Removing "reified" from an expected function's type parameter is fine
if (
expectTypeParameterSymbols.indices.any { i ->
!expectTypeParameterSymbols[i].isReified && actualTypeParameterSymbols[i].isReified
}
) {
return ExpectActualCompatibility.Incompatible.TypeParameterReified
}
return ExpectActualCompatibility.Compatible
}
private fun areCompatibleFunctions(
expectFunction: FirCallableSymbol<*>,
actualFunction: FirCallableSymbol<*>
): ExpectActualCompatibility<FirBasedSymbol<*>> {
if (!equalBy(expectFunction, actualFunction) { f -> f.isSuspend }) {
return ExpectActualCompatibility.Incompatible.FunctionModifiersDifferent
}
if (
expectFunction.isExternal && !actualFunction.isExternal ||
expectFunction.isInfix && !actualFunction.isInfix ||
expectFunction.isInline && !actualFunction.isInline ||
expectFunction.isOperator && !actualFunction.isOperator ||
expectFunction.isTailRec && !actualFunction.isTailRec
) {
return ExpectActualCompatibility.Incompatible.FunctionModifiersNotSubset
}
return ExpectActualCompatibility.Compatible
}
private fun areCompatibleProperties(a: FirPropertySymbol, b: FirPropertySymbol): ExpectActualCompatibility<FirBasedSymbol<*>> {
if (!equalBy(a, b) { p -> p.isVar }) {
return ExpectActualCompatibility.Incompatible.PropertyKind
}
if (!equalBy(a, b) { p -> listOf(p.isConst, p.isLateInit) }) {
return ExpectActualCompatibility.Incompatible.PropertyModifiers
}
return ExpectActualCompatibility.Compatible
}
// ---------------------------------------- Utils ----------------------------------------
private class ConeInferenceContextForExpectActual(val expectSession: FirSession, val actualSession: FirSession) : ConeInferenceContext {
override val session: FirSession
get() = actualSession
override fun areEqualTypeConstructors(c1: TypeConstructorMarker, c2: TypeConstructorMarker): Boolean {
if (c1 !is ConeClassifierLookupTag || c2 !is ConeClassifierLookupTag) {
return c1 == c2
}
return isExpectedClassAndActualTypeAlias(c1, c2) ||
isExpectedClassAndActualTypeAlias(c2, c1) ||
c1 == c2
}
// For example, expectedTypeConstructor may be the expected class kotlin.text.StringBuilder, while actualTypeConstructor
// is java.lang.StringBuilder. For the purposes of type compatibility checking, we must consider these types equal here.
// Note that the case of an "actual class" works as expected though, because the actual class by definition has the same FQ name
// as the corresponding expected class, so their type constructors are equal as per AbstractClassTypeConstructor#equals
private fun isExpectedClassAndActualTypeAlias(
expectLookupTag: ConeClassifierLookupTag,
actualLookupTag: ConeClassifierLookupTag
): Boolean {
val expectDeclaration = expectLookupTag.toClassLikeDeclaration(expectSession) ?: return false
val actualDeclaration = actualLookupTag.toClassLikeDeclaration(actualSession) ?: return false
if (!expectDeclaration.isExpect) return false
val expectClassId = when (expectDeclaration) {
is FirRegularClassSymbol -> expectDeclaration.classId
is FirTypeAliasSymbol -> expectDeclaration.resolvedExpandedTypeRef.coneType.classId
else -> null
} ?: return false
return expectClassId == actualDeclaration.classId
}
private fun ConeClassifierLookupTag.toClassLikeDeclaration(session: FirSession): FirClassLikeSymbol<*>? {
return this.toSymbol(session) as? FirClassLikeSymbol<*>
}
}
private fun List<FirValueParameterSymbol>.toTypeList(substitutor: ConeSubstitutor): List<ConeKotlinType> {
return this.map { substitutor.substituteOrSelf(it.resolvedReturnTypeRef.coneType) }
}
private val FirCallableSymbol<*>.valueParameterSymbols: List<FirValueParameterSymbol>
get() = (this as? FirFunctionSymbol<*>)?.valueParameterSymbols ?: emptyList()
private inline fun <T, K> equalsBy(first: List<T>, second: List<T>, selector: (T) -> K): Boolean {
for (i in first.indices) {
if (selector(first[i]) != selector(second[i])) return false
}
return true
}
private inline fun <T, K> equalBy(first: T, second: T, selector: (T) -> K): Boolean =
selector(first) == selector(second)
private fun FirClassSymbol<*>.getMembers(
scopeSession: ScopeSession,
session: FirSession = moduleData.session
): Collection<FirBasedSymbol<*>> {
val scope = defaultType().scope(useSiteSession = session, scopeSession, FakeOverrideTypeCalculator.DoNothing)
?: return emptyList()
return mutableListOf<FirBasedSymbol<*>>().apply {
for (name in scope.getCallableNames()) {
scope.getMembersTo(this, name)
}
for (name in declarationSymbols.mapNotNull { (it as? FirRegularClassSymbol)?.classId?.shortClassName }) {
addIfNotNull(scope.getSingleClassifier(name) as? FirRegularClassSymbol)
}
getConstructorsTo(this, scope)
}
}
private fun FirClassSymbol<*>.getConstructors(
scopeSession: ScopeSession,
session: FirSession = moduleData.session
): Collection<FirConstructorSymbol> {
return mutableListOf<FirConstructorSymbol>().apply {
getConstructorsTo(this, unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false))
}
}
private fun getConstructorsTo(destination: MutableList<in FirConstructorSymbol>, scope: FirTypeScope) {
scope.getDeclaredConstructors().mapTo(destination) { it }
}
private fun FirClassSymbol<*>.getMembers(name: Name, scopeSession: ScopeSession): Collection<FirCallableSymbol<*>> {
val scope = defaultType().scope(useSiteSession = moduleData.session, scopeSession, FakeOverrideTypeCalculator.DoNothing)
?: return emptyList()
return mutableListOf<FirCallableSymbol<*>>().apply {
scope.getMembersTo(this, name)
}
}
@OptIn(ExperimentalStdlibApi::class)
private fun FirTypeScope.getMembersTo(
destination: MutableList<in FirCallableSymbol<*>>,
name: Name,
) {
processFunctionsByName(name) { destination.add(it) }
processPropertiesByName(name) { destination.add(it) }
}
private val FirBasedSymbol<*>.name: Name
get() = when (this) {
is FirCallableSymbol<*> -> name
is FirRegularClassSymbol -> classId.shortClassName
else -> error("Should not be here")
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.hasBody
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.BlockExitNode
import org.jetbrains.kotlin.fir.resolve.dfa.controlFlowGraph
import org.jetbrains.kotlin.fir.types.isNothing
import org.jetbrains.kotlin.fir.types.isUnit
object FirFunctionReturnChecker : FirFunctionChecker() {
override fun check(declaration: FirFunction, context: CheckerContext, reporter: DiagnosticReporter) {
checkHasReturnIfBlock(declaration, reporter, context)
}
private fun checkHasReturnIfBlock(
declaration: FirFunction,
reporter: DiagnosticReporter,
context: CheckerContext
) {
if (declaration is FirPropertyAccessor && declaration.isSetter) return
if (declaration is FirConstructor) return
if (declaration is FirAnonymousFunction && declaration.isLambda) return
if (declaration.returnTypeRef.isUnit || declaration.returnTypeRef.isNothing) return
val graph = declaration.controlFlowGraphReference?.controlFlowGraph ?: return
val blockExitNode = graph.exitNode.previousNodes.lastOrNull { it is BlockExitNode } ?: return
if (!blockExitNode.isDead) {
reporter.reportOn(declaration.source, FirErrors.NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY, context)
}
}
}

View File

@@ -130,6 +130,7 @@ object FirInlineClassDeclarationChecker : FirRegularClassChecker() {
}
}
}
else -> {}
}
}

View File

@@ -37,6 +37,7 @@ object FirNestedClassChecker : FirRegularClassChecker() {
reporter.reportOn(declaration.source, NESTED_CLASS_NOT_ALLOWED, declaration.description, context)
}
}
else -> {}
}
}

View File

@@ -0,0 +1,66 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
import org.jetbrains.kotlin.fir.analysis.checkers.extractArgumentTypeRefAndSource
import org.jetbrains.kotlin.fir.analysis.checkers.getContainingClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.resolve.isValidTypeParameterFromOuterClass
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.resolve.toTypeProjections
import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.types.*
object FirOuterClassArgumentsRequiredChecker : FirRegularClassChecker() {
override fun check(declaration: FirRegularClass, context: CheckerContext, reporter: DiagnosticReporter) {
// Checking the rest super types that weren't resolved on the first OUTER_CLASS_ARGUMENTS_REQUIRED check in FirTypeResolver
for (superTypeRef in declaration.superTypeRefs) {
checkOuterClassArgumentsRequired(superTypeRef, declaration, context, reporter)
}
}
}
private fun checkOuterClassArgumentsRequired(
typeRef: FirTypeRef,
declaration: FirRegularClass?,
context: CheckerContext,
reporter: DiagnosticReporter
) {
if (typeRef !is FirResolvedTypeRef || typeRef is FirErrorTypeRef) {
return
}
val type: ConeKotlinType = typeRef.type
val delegatedTypeRef = typeRef.delegatedTypeRef
if (delegatedTypeRef is FirUserTypeRef && type is ConeClassLikeType) {
val symbol = type.lookupTag.toSymbol(context.session)
if (symbol is FirRegularClassSymbol) {
val typeArguments = delegatedTypeRef.qualifier.toTypeProjections()
val typeParameters = symbol.typeParameterSymbols
for (index in typeArguments.size until typeParameters.size) {
val typeParameter = typeParameters[index]
if (!isValidTypeParameterFromOuterClass(typeParameter, declaration, context.session)) {
val outerClass = typeParameter.containingDeclarationSymbol as FirRegularClassSymbol
reporter.reportOn(typeRef.source, FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED, outerClass, context)
break
}
}
}
}
for (index in type.typeArguments.indices) {
val firTypeRefSource = extractArgumentTypeRefAndSource(typeRef, index) ?: continue
firTypeRefSource.typeRef?.let { checkOuterClassArgumentsRequired(it, declaration, context, reporter) }
}
}

View File

@@ -39,6 +39,7 @@ object FirProjectionRelationChecker : FirBasicDeclarationChecker() {
}
is FirTypeAlias ->
checkTypeRef(declaration.expandedTypeRef, context, reporter)
else -> {}
}
}

View File

@@ -6,29 +6,76 @@
package org.jetbrains.kotlin.fir.analysis.checkers.expression
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.fir.FirSourceElement
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.utils.modality
import org.jetbrains.kotlin.fir.expressions.ExhaustivenessStatus
import org.jetbrains.kotlin.fir.expressions.FirWhenExpression
import org.jetbrains.kotlin.fir.expressions.impl.FirElseIfTrueCondition
import org.jetbrains.kotlin.fir.expressions.isExhaustive
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.types.isBooleanOrNullableBoolean
object FirExhaustiveWhenChecker : FirWhenExpressionChecker() {
override fun check(expression: FirWhenExpression, context: CheckerContext, reporter: DiagnosticReporter) {
if (expression.usedAsExpression && !expression.isExhaustive) {
val source = expression.source ?: return
reportNotExhaustive(expression, context, reporter)
reportElseMisplaced(expression, reporter, context)
}
private fun reportNotExhaustive(whenExpression: FirWhenExpression, context: CheckerContext, reporter: DiagnosticReporter) {
if (whenExpression.isExhaustive) return
val source = whenExpression.source ?: return
if (whenExpression.usedAsExpression) {
if (source.isIfExpression) {
reporter.reportOn(source, FirErrors.INVALID_IF_AS_EXPRESSION, context)
return
} else if (source.isWhenExpression) {
val missingCases = (expression.exhaustivenessStatus as ExhaustivenessStatus.NotExhaustive).reasons
reporter.reportOn(source, FirErrors.NO_ELSE_IN_WHEN, missingCases, context)
reporter.reportOn(source, FirErrors.NO_ELSE_IN_WHEN, whenExpression.missingCases, context)
}
} else {
val subjectType = whenExpression.subject?.typeRef?.coneType ?: return
val subjectClassSymbol = subjectType.fullyExpandedType(context.session).toRegularClassSymbol(context.session) ?: return
val kind = when {
subjectClassSymbol.modality == Modality.SEALED -> AlgebraicTypeKind.Sealed
subjectClassSymbol.classKind == ClassKind.ENUM_CLASS -> AlgebraicTypeKind.Enum
subjectType.isBooleanOrNullableBoolean -> AlgebraicTypeKind.Boolean
else -> return
}
if (context.session.languageVersionSettings.supportsFeature(LanguageFeature.ProhibitNonExhaustiveWhenOnAlgebraicTypes)) {
reporter.reportOn(source, FirErrors.NO_ELSE_IN_WHEN, whenExpression.missingCases, context)
} else {
reporter.reportOn(source, FirErrors.NON_EXHAUSTIVE_WHEN_STATEMENT, kind.displayName, whenExpression.missingCases, context)
}
}
}
private val FirWhenExpression.missingCases: List<WhenMissingCase>
get() = (exhaustivenessStatus as ExhaustivenessStatus.NotExhaustive).reasons
private enum class AlgebraicTypeKind(val displayName: String) {
Sealed("sealed class/interface"),
Enum("enum"),
Boolean("Boolean")
}
private fun reportElseMisplaced(
expression: FirWhenExpression,
reporter: DiagnosticReporter,
context: CheckerContext
) {
val branchesCount = expression.branches.size
for (indexedValue in expression.branches.withIndex()) {
val branch = indexedValue.value

View File

@@ -48,6 +48,7 @@ object FirReturnAllowedChecker : FirReturnExpressionChecker() {
}
is FirProperty -> if (!containingDeclaration.isLocal) return false
is FirValueParameter -> return true
else -> {}
}
}
return true

View File

@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers.extended
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirPropertyChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
@@ -21,7 +22,7 @@ object RedundantSetterParameterTypeChecker : FirPropertyChecker() {
val propertyTypeSource = declaration.returnTypeRef.source
val setterParameterTypeSource = valueParameter.returnTypeRef.source ?: return
if (setterParameterTypeSource != propertyTypeSource) {
if (setterParameterTypeSource.kind !is FirFakeSourceElementKind && setterParameterTypeSource != propertyTypeSource) {
reporter.reportOn(setterParameterTypeSource, REDUNDANT_SETTER_PARAMETER_TYPE, context)
}
}

View File

@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.analysis.checkers.type
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.context.findClosest
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirDeprecationChecker
@@ -17,11 +18,11 @@ import org.jetbrains.kotlin.fir.types.coneTypeSafe
object FirDeprecatedTypeChecker : FirTypeRefChecker() {
override fun check(typeRef: FirTypeRef, context: CheckerContext, reporter: DiagnosticReporter) {
if (context.findClosest<FirPropertyAccessor>() != null) return
val source = typeRef.source ?: return
if (source.kind is FirFakeSourceElementKind) return
val resolved = typeRef.coneTypeSafe<ConeClassLikeType>() ?: return
val symbol = resolved.lookupTag.toSymbol(context.session) ?: return
FirDeprecationChecker.reportDeprecationIfNeeded(typeRef.source, symbol, null, context, reporter)
FirDeprecationChecker.reportDeprecationIfNeeded(source, symbol, null, context, reporter)
}
}

View File

@@ -13,10 +13,13 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.AMBI
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.DECLARATION_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FIR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FQ_NAMES_IN_TYPES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.COLLECTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.MODULE_DATA
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.FUNCTION_PARAMETERS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NOT_RENDERED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.NULLABLE_STRING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_CLASS_OR_OBJECT_NAME
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_COLLECTION_OF_TYPES
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.RENDER_TYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticRenderers.SYMBOL
@@ -37,6 +40,16 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_PROPERTY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_PROPERTY_WITH_SETTER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ABSTRACT_SUPER_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACCESSOR_FOR_DELEGATED_PROPERTY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_MISSING
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_NOT_TO_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ACTUAL_WITHOUT_EXPECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_ACTUALS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.AMBIGUOUS_EXPECTS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_ARGUMENT_MUST_BE_CONST
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_CLASS_CONSTRUCTOR_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_CLASS_MEMBER
@@ -44,6 +57,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_ON_SUP
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_PARAMETER_DEFAULT_VALUE_MUST_BE_CONSTANT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANNOTATION_USED_AS_ANNOTATION_ARGUMENT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_FUNCTION_PARAMETER_WITH_DEFAULT_VALUE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ANONYMOUS_INITIALIZER_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_PASSED_TWICE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARGUMENT_TYPE_MISMATCH
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ARRAY_EQUALITY_OPERATOR_CAN_BE_REPLACED_WITH_EQUALS
@@ -123,9 +137,14 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EQUALITY_NOT_APPL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ERROR_FROM_JAVA_RESOLUTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ERROR_IN_CONTRACT_DESCRIPTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPANDED_TYPE_CANNOT_BE_INHERITED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_CLASS_CONSTRUCTOR_DELEGATION_CALL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_CONDITION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_DECLARATION_WITH_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_DELEGATED_PROPERTY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_ENUM_CONSTRUCTOR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_ENUM_ENTRY_WITH_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_LATEINIT_PROPERTY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_PRIVATE_DECLARATION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_PROPERTY_INITIALIZER
@@ -170,6 +189,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_CONST_EXP
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_KOTLIN_VERSION_STRING_VALUE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_SELECTOR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ILLEGAL_UNDERSCORE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.IMPLEMENTATION_BY_DELEGATION_IN_EXPECT_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_CANDIDATE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_FILE_TARGET
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.INAPPLICABLE_INFIX_MODIFIER
@@ -229,6 +249,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NEWER_VERSION_IN_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NEXT_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NONE_APPLICABLE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_ABSTRACT_FUNCTION_WITH_NO_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_EXHAUSTIVE_WHEN_STATEMENT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_IN_FINAL_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_IN_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED
@@ -243,9 +264,12 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_LOOP_LABEL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_A_SUPERTYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ACTUAL_FOR_EXPECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_COMPANION_OBJECT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_ELSE_IN_WHEN
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_GET_METHOD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_SET_METHOD
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_THIS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NO_VALUE_FOR_PARAMETER
@@ -255,6 +279,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NULLABLE_TYPE_OF_
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ONLY_ONE_CLASS_BOUND_ALLOWED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OPERATOR_RENAMED_ON_IMPORT
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OTHER_ERROR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OUTER_CLASS_ARGUMENTS_REQUIRED
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERLOAD_RESOLUTION_AMBIGUITY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.OVERRIDING_FINAL_MEMBER
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.PACKAGE_CANNOT_BE_IMPORTED
@@ -318,6 +343,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SPREAD_OF_NULLABL
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERCLASS_NOT_ACCESSIBLE_FROM_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPES_FOR_ANNOTATION_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_APPEARS_TWICE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_IN_INTERFACE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_INITIALIZED_WITHOUT_PRIMARY_CONSTRUCTOR
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.SUPERTYPE_IS_EXTENSION_FUNCTION_TYPE
@@ -715,7 +741,12 @@ class FirDefaultErrorMessages {
WRONG_NUMBER_OF_TYPE_ARGUMENTS,
"{0,choice,0#No type arguments|1#One type argument|1<{0,number,integer} type arguments} expected for {1}",
null,
SYMBOL
RENDER_CLASS_OR_OBJECT_NAME
)
map.put(
OUTER_CLASS_ARGUMENTS_REQUIRED,
"Type arguments should be specified for an outer {0}. Use full class name to specify them",
RENDER_CLASS_OR_OBJECT_NAME
)
map.put(TYPE_PARAMETERS_IN_OBJECT, "Type parameters are not allowed for objects")
// map.put(ILLEGAL_PROJECTION_USAGE, ...) // &
@@ -807,6 +838,8 @@ class FirDefaultErrorMessages {
map.put(TYPE_PARAMETER_OF_PROPERTY_NOT_USED_IN_RECEIVER, "Type parameter of a property must be used in its receiver type")
map.put(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY, "A 'return' expression required in a function with a block body ('{...}')")
map.put(RETURN_TYPE_MISMATCH, "Return type mismatch: expected {0}, actual {1}", RENDER_TYPE, RENDER_TYPE, NOT_RENDERED)
map.put(CYCLIC_GENERIC_UPPER_BOUND, "Type parameter has cyclic upper bounds")
@@ -1124,10 +1157,30 @@ class FirDefaultErrorMessages {
// Multi-platform projects
map.put(EXPECTED_DECLARATION_WITH_BODY, "Expected declaration must not have a body")
map.put(EXPECTED_CLASS_CONSTRUCTOR_DELEGATION_CALL, "Explicit delegation call for constructor of an expected class is not allowed")
map.put(EXPECTED_CLASS_CONSTRUCTOR_PROPERTY_PARAMETER, "Expected class constructor cannot have a property parameter")
map.put(EXPECTED_ENUM_CONSTRUCTOR, "Expected enum class cannot have a constructor")
map.put(EXPECTED_ENUM_ENTRY_WITH_BODY, "Expected enum entry cannot have a body")
map.put(EXPECTED_PROPERTY_INITIALIZER, "Expected property cannot have an initializer")
map.put(EXPECTED_DELEGATED_PROPERTY, "Expected property cannot be delegated")
map.put(EXPECTED_PRIVATE_DECLARATION, "Expected declaration cannot be private")
map.put(EXPECTED_LATEINIT_PROPERTY, "Expected property cannot be lateinit")
map.put(EXPECTED_PRIVATE_DECLARATION, "Expected declaration cannot be private")
map.put(SUPERTYPE_INITIALIZED_IN_EXPECTED_CLASS, "Expected classes cannot initialize supertypes")
map.put(EXPECTED_PRIVATE_DECLARATION, "Expected declaration cannot be private")
map.put(IMPLEMENTATION_BY_DELEGATION_IN_EXPECT_CLASS, "Implementation by delegation in expected classes is prohibited")
map.put(ACTUAL_TYPE_ALIAS_NOT_TO_CLASS, "Right-hand side of actual type alias should be a class, not another type alias")
map.put(ACTUAL_TYPE_ALIAS_TO_CLASS_WITH_DECLARATION_SITE_VARIANCE, "Aliased class should not have type parameters with declaration-site variance")
map.put(ACTUAL_TYPE_ALIAS_WITH_USE_SITE_VARIANCE, "Right-hand side of actual type alias cannot contain use-site variance or star projections")
map.put(ACTUAL_TYPE_ALIAS_WITH_COMPLEX_SUBSTITUTION, "Type arguments in the right-hand side of actual type alias should be its type parameters in the same order, e.g. 'actual typealias Foo<A, B> = Bar<A, B>'")
map.put(ACTUAL_FUNCTION_WITH_DEFAULT_ARGUMENTS, "Actual function cannot have default argument values, they should be declared in the expected function")
map.put(ACTUAL_ANNOTATION_CONFLICTING_DEFAULT_ARGUMENT_VALUE, "Parameter ''{0}'' has conflicting values in the expected and actual annotation", SYMBOL)
map.put(EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND, "Expected function source is not found, therefore it's impossible to generate default argument values declared there. Please add the corresponding file to compilation sources")
map.put(NO_ACTUAL_FOR_EXPECT, "Expected {0} has no actual declaration in module {1}{2}", SYMBOL, MODULE_DATA, FirPlatformIncompatibilityDiagnosticRenderer.TEXT)
map.put(ACTUAL_WITHOUT_EXPECT, "{0} has no corresponding expected declaration{1}", SYMBOL, FirPlatformIncompatibilityDiagnosticRenderer.TEXT)
map.put(AMBIGUOUS_ACTUALS, "{0} has several compatible actual declarations in modules {1}", SYMBOL, SYMBOLS)
map.put(AMBIGUOUS_EXPECTS, "{0} has several compatible expect declarations in modules {1}", SYMBOL, COLLECTION(MODULE_DATA))
map.put(NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS, "Actual class ''{0}'' has no corresponding members for expected class members:{1}", SYMBOL, FirIncompatibleExpectedActualClassScopesRenderer.TEXT)
map.put(ACTUAL_MISSING, "Declaration must be marked with 'actual'")
// Destructuring declaration
map.put(INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION, "Initializer required for destructuring declaration")
@@ -1232,6 +1285,12 @@ class FirDefaultErrorMessages {
map.put(EXPECTED_CONDITION, "Expected condition of type Boolean")
map.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", WHEN_MISSING_CASES)
map.put(INVALID_IF_AS_EXPRESSION, "'if' must have both main and 'else' branches if used as an expression")
map.put(
NON_EXHAUSTIVE_WHEN_STATEMENT,
"Non exhaustive ''when'' statements on {0} will be prohibited in 1.7, add {1}",
TO_STRING,
WHEN_MISSING_CASES
)
// Context tracking
map.put(TYPE_PARAMETER_IS_NOT_AN_EXPRESSION, "Type parameter ''{0}'' is not an expression", SYMBOL)
@@ -1315,6 +1374,7 @@ class FirDefaultErrorMessages {
RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY,
"Returns are not allowed for functions with expression body. Use block body in '{...}'"
)
map.put(ANONYMOUS_INITIALIZER_IN_INTERFACE, "Anonymous initializers are not allowed in interfaces")
// Inline
map.put(

View File

@@ -8,12 +8,16 @@ package org.jetbrains.kotlin.fir.analysis.diagnostics
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.diagnostics.WhenMissingCase
import org.jetbrains.kotlin.diagnostics.rendering.ContextIndependentParameterRenderer
import org.jetbrains.kotlin.diagnostics.rendering.Renderer
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.dfa.cfg.isLocalClassOrAnonymousObject
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.*
@@ -32,11 +36,7 @@ object FirDiagnosticRenderers {
}
}
val SYMBOLS = Renderer { symbols: Collection<FirBasedSymbol<*>> ->
symbols.joinToString(prefix = "[", postfix = "]", separator = ", ", limit = 3, truncated = "...") { symbol ->
SYMBOL.render(symbol)
}
}
val SYMBOLS = COLLECTION(SYMBOL)
val RENDER_COLLECTION_OF_TYPES = Renderer { types: Collection<ConeKotlinType> ->
types.joinToString(separator = ", ") { type ->
@@ -79,6 +79,25 @@ object FirDiagnosticRenderers {
"$classOrObject $name"
}
val RENDER_CLASS_OR_OBJECT_NAME = Renderer { firClassLike: FirClassLikeSymbol<*> ->
val name = firClassLike.classId.relativeClassName.shortName().asString()
val prefix = when (firClassLike) {
is FirTypeAliasSymbol -> "typealias"
is FirRegularClassSymbol -> {
when {
firClassLike.isCompanion -> "companion object"
firClassLike.isInterface -> "interface"
firClassLike.isEnumClass -> "enum class"
firClassLike.isFromEnumClass -> "enum entry"
firClassLike.isLocalClassOrAnonymousObject -> "object"
else -> "class"
}
}
else -> AssertionError("Unexpected class: $firClassLike")
}
"$prefix '$name'"
}
val RENDER_TYPE = Renderer { t: ConeKotlinType ->
// TODO: need a way to tune granuality, e.g., without parameter names in functional types.
t.render()
@@ -112,4 +131,17 @@ object FirDiagnosticRenderers {
}
val FUNCTION_PARAMETERS = Renderer { hasValueParameters: Boolean -> if (hasValueParameters) "..." else "" }
val MODULE_DATA = Renderer<FirModuleData> {
"Module ${it.name}"
}
@Suppress("FunctionName")
fun <T> COLLECTION(renderer: ContextIndependentParameterRenderer<T>): ContextIndependentParameterRenderer<Collection<T>> {
return Renderer { list ->
list.joinToString(prefix = "[", postfix = "]", separator = ", ", limit = 3, truncated = "...") {
renderer.render(it)
}
}
}
}

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