Compare commits

...

200 Commits

Author SHA1 Message Date
Alexander Udalov
2e4e2f67bb Make inline+reified functions synthetic instead of private in bytecode
#KT-18563 Fixed

(cherry picked from commit f9d61f2dc7)
2019-05-28 16:18:32 +02:00
Alexander Udalov
dab23322fd Minor, restructure InlineOnly-related utilities
(cherry picked from commit a645b36688)
2019-05-28 16:18:06 +02:00
Alexander Udalov
7c00d2ba82 Restructure bytecode listing tests on InlineOnly/inline+reified
(cherry picked from commit b42adcd73d)
2019-05-28 16:18:05 +02:00
Sergey Rostov
14aab280c2 Gradle, JS: support exotic versions while converting to semver
#KT-31563
2019-05-28 16:41:31 +03:00
Ilmir Usmanov
489d80c249 Wrap result method node with max stack calculator in inliner
#KT-31347 Fixed
2019-05-28 16:38:25 +03:00
Nikolay Krasko
ef50f25db1 Refactoring: drop unused AbstractKotlinReferenceContributor.kt 2019-05-28 16:17:13 +03:00
Nikolay Krasko
a3dfa28374 Don't produce references for Kotlin block 2019-05-28 16:17:13 +03:00
Nikolay Krasko
95cdc94fbb Get Kotlin references through Kotlin contributors only (KT-31129)
Speed up getting references and protect Kotlin from slow
references contributors.

 #KT-31129 Fixed
2019-05-28 16:17:12 +03:00
Nikolay Krasko
ffa298ea34 Minor: move KotlinDefaultAnnotationMethodImplicitReferenceContributor.kt
Need this move to reference contributor from reference provider service.
2019-05-28 16:17:12 +03:00
Natalia Selezneva
ba00df846e Pass environment variables resolving script dependencies
There is no option in UI to enable/disable passing those variables,
but during Gradle Sync environment variables are passed by default
Also Gradle expect that gradleOptions are passed but there is also no option in UI
(during Gradle Sync IDEA add some options but they shouldn't affect dependencies resolution process)
see GradleExeSettings.resolverExtension.getExtraCommandLineArgs

gradleWithConnection was removed because it isn't used by gradle because they need to manage the TAPI project directory

projectRoot was fixed to externalProjectPath because it can be overrided in settings.gradle

^KT-30974 Fixed

(cherry picked from commit b5dbdc53d1)
2019-05-28 16:08:14 +03:00
Eduard Wolf
b8cb533b39 KT-31639: Fix Iterables.drop integer overflow
(cherry picked from commit c885cadde4)
2019-05-28 15:49:12 +03:00
Andrey Uskov
8b6096f312 Fix exception during mpp run task creation due to usage of deprecated api
#KT-31482 Fixed
2019-05-28 15:22:46 +03:00
Andrey Uskov
19f01b98df Fix ClassCastException during search of overriders
#EA-115095 Fixed
2019-05-28 15:21:56 +03:00
Andrey Uskov
cf8184e9c9 Do not show UI dialog from a write action during work of intention
#EA-100676 Fixed
2019-05-28 15:21:18 +03:00
Mikhail Zarechenskiy
eb813678fc Fix debugger tests for new-inference
There is new child of `VariableAsFunctionResolvedCall` in
 new-inference: `NewVariableAsFunctionResolvedCallImpl`. So, in order to
 support both versions, just use parent class
2019-05-28 14:49:34 +03:00
Igor Yakovlev
8c96111e16 Fix render of classpath log message for UL-classes 2019-05-28 14:26:48 +03:00
Alexander Udalov
02fc21b7ff Support fake Java property overrides in function equality in bridges
A synthetic property descriptor created for `B.value` (see the added
test) should not be equal to the normal descriptor created by the fake
override construction algorithm. Otherwise we can't reach this synthetic
non-abstract descriptor when building bridges in `C`, which results in
exception.

 #KT-31367 Fixed

(cherry picked from commit 082c337faa)
2019-05-28 11:51:37 +02:00
Ilya Matveev
f3be367962 Gradle, native: Rename test binary class: Test -> TestExecutable 2019-05-28 10:50:38 +03:00
Ilya Matveev
6d62f21d60 Gradle, native: Don't treat test output as stacktrace
Currently native test runner reports stacktraces using TC
service messages.
2019-05-28 10:50:37 +03:00
Ilya Matveev
54698544d9 Gradle, native: Introduce separate binary type for tests
Earlier native tests were represented by the same binary type as product
executables. We also used to create test tasks in the same manner as run
tasks for product executables. Such tasks could be obtained used a property
of an executable binary with type Exec.

But now we have a separate class for test tasks. Also we probably will want
to create several tasks for the same test. So we cannot use the same run task
property for both test and product executables. Also representing test and
product executables by the same binary type leads to the fact that assemble
task execution causes building not only product binaries but also the test
ones.

This patch solves the issues described above by introducing a separate binary
type for tests. Such a test binary can be created in the same manner as other
binaries:

    kotlin.macosX64 {
        binaries {
            test("integration") { ... }
        }
    }

One test binary and a task executing it is created by the plugin out of the box.
This test binary replaces a test executable used to be created earlier.

Issue #KT-31609 Fixed
2019-05-28 10:50:37 +03:00
Mikhail Zarechenskiy
9365ff6dcf Fix compilation against bootstrap compiler 2019-05-27 17:37:30 +03:00
Mikhail Zarechenskiy
200dde8cb4 [NI] Don't consider Any!-constraint from upper bounds as more specific
#KT-31624 Fixed
2019-05-27 17:37:28 +03:00
Mikhail Zarechenskiy
da06af2fee Duplicate test for NI and OI to avoid mismatch of diagnostics
There is a problem with different order of diagnostics for NI and OI,
 so, in order to fix this test, it was duplicated
2019-05-27 17:37:27 +03:00
Mikhail Zarechenskiy
e3fa388dfe [NI] Avoid forcing resolve for array access expression
#KT-31606 Fixed
 #EA-126523 Fixed
2019-05-27 17:37:25 +03:00
Mikhail Zarechenskiy
9434babe9f [NI] Don't apply SAM-conversion for type that is subtype of function
Plus, don't get synthetic candidates as all candidates are creating
 by conversion

 #KT-31503 Fixed
2019-05-27 17:37:23 +03:00
Mikhail Zarechenskiy
61f48da6e8 [NI] Fix assertion: KotlinTypeMarker -> KotlinType 2019-05-27 01:02:05 +03:00
Mikhail Zarechenskiy
46420d60f0 [NI] Approximate components of raw types separately
This is needed as components can have different type arguments
2019-05-26 21:42:43 +03:00
Mikhail Zarechenskiy
cb3371ba2e [NI] Implement various optimizations for incorporation algorithm
Mostly, these optimisations are picked from the old inference.
 Also, remove exponential complexity for flexible types in approximation,
 note that more correct fix for this would be to introduce new types
 that corresponds just to platform types to avoid nullability problems,
 but due to complexity it will be done later

 #KT-31415 Fixed
2019-05-26 21:35:52 +03:00
Mikhail Zarechenskiy
6b660fe466 Fix exception on star import from typealias
#KT-30983 Fixed
2019-05-26 21:35:50 +03:00
Mikhail Zarechenskiy
d0231351ec Add tests to preserve current behavior for upcoming changes
##KT-30983 In Progress
2019-05-26 21:35:48 +03:00
Mikhail Zarechenskiy
ec8e8cb23c [NI] More accurate handle of capture types from subtyping
#KT-31520 Fixed
2019-05-26 21:35:46 +03:00
Mikhail Zarechenskiy
c0c63bdc98 [NI] Don't loose inference session during property resolve
#KT-31620 Fixed
2019-05-26 21:35:45 +03:00
Toshiaki Kameyama
0786555650 Redundant 'suspend' modifier inspection: don't report when function has suspend operator invoke
#KT-25465 Fixed

(cherry picked from commit 354f8f0bf1)
2019-05-24 23:05:16 +03:00
Ilya Chernikov
b11e31d275 Fix scripting-compiler tests, add them to the global scriptingTest task 2019-05-24 13:43:03 +02:00
Dmitriy Novozhilov
15d28a75a9 Fix compiler testdata broken in d2d603b 2019-05-24 11:02:55 +03:00
Ilya Chernikov
62dcae008c [minor] fixes after review 2019-05-24 08:26:41 +02:00
Ilya Chernikov
fbeded85e6 Implement test run on embeddable jars for jsr223 and scripting host tests...
also:
- add missing tests to the global scriptingTests task
- extract jsr223 tests into separate project
- fix dependency in jsr223 embeddable jar
2019-05-24 08:26:41 +02:00
Ilya Chernikov
5e4ff87244 Refactor default JSR-223 engine implementation:
- rename classes for clarity
- sort out dependencies
- move common pars to jvm-host jar
- switch to configurations only customization
2019-05-24 08:26:41 +02:00
Ilya Chernikov
560c65c50f Add evaluation context passing to the evaluation config refiners 2019-05-24 08:26:40 +02:00
Ilya Chernikov
a23fb03bd9 Fix dependencies to compiler in scripting modules 2019-05-24 08:26:40 +02:00
Ilya Chernikov
b96fcce096 Move scripting jvm host tests to a separate project...
to solve problems with testing with direct dependency on proguarded compiler
2019-05-24 08:26:40 +02:00
Ilya Chernikov
503a042b29 Drop dependencies to script-util from new scripting infrastructure 2019-05-24 08:26:40 +02:00
Ilya Chernikov
649b74ab7f Convert JvmGetScriptingClass to object to simplify (de)serialization 2019-05-24 08:26:40 +02:00
Ilya Chernikov
623c7673e1 Add a link to hostConfiguration from compilation and evaluation ones
also add possibility to supply functional defaults for keys in PropertiesCollection
2019-05-24 08:26:40 +02:00
Ilya Chernikov
76b7dcfdaf Get rid of UsefulTestCase to avoid dependencies, parallelize tests 2019-05-24 08:26:40 +02:00
Ilya Chernikov
73e3cfe3a4 [minor] fix some warnings 2019-05-24 08:26:40 +02:00
Ilya Chernikov
45cbd792ac Add missing scripting tests to the global task, make them parallel 2019-05-24 08:26:39 +02:00
Ilya Chernikov
ebaca7a4d8 Fix main-kts script classpath calculation 2019-05-24 08:26:39 +02:00
Ilya Chernikov
8e45f79a0e Implement JSR-223 functionality on top of the "new" REPL 2019-05-24 08:26:39 +02:00
Ilya Chernikov
d91881acf4 Implement "legacy" REPL wrappers on top of the "new" scripting infrastructure 2019-05-24 08:26:39 +02:00
Ilya Chernikov
206d53d35a Create core environment in test mode properly 2019-05-24 08:26:39 +02:00
Ilya Chernikov
8585f69b27 Prepare scripting infrastructure for REPL:
- refactor script compiler to simplify extending it for repl
- add repl snippet compilation functions to the new scripting compiler
- extract util functions into appropriate files
- extract repl part into separate class
- extract bridge definition and related definitions into separate file
2019-05-24 08:26:39 +02:00
Ilya Chernikov
738108e9c9 Replace message collector with reporting lambda
to simplify usages and slightly reduce dependencies
2019-05-24 08:26:39 +02:00
Ilya Chernikov
c84a4e8640 Add another method for fetching classpath from classloader, refactor 2019-05-24 08:26:38 +02:00
Ilya Gorbunov
0526298b37 Unmute tests for JVM_IR that pass after making assertFailsWith inline
(cherry picked from commit 0a3ebb5780)
2019-05-23 19:40:24 +03:00
Ilya Gorbunov
7e766a1413 Add hidden methods to keep binary compatibility in kotlin-test for JVM
(cherry picked from commit 6632cf5b1d)
2019-05-23 19:40:23 +03:00
Ilya Gorbunov
bb77d673a0 Make assertFails(With) inline-only functions
So that the lambda passed to these functions can capture suspend
function calls.

#KT-31194 Fixed

(cherry picked from commit 22694fa6b0)
2019-05-23 19:40:23 +03:00
Ilya Gorbunov
ed85927abf Remove internal visibility suppressions in kotlin.test
Internal visibility works fine in MPP, so they are no longer required.

(partially cherry picked from commit 18f9b20610)
2019-05-23 19:40:06 +03:00
Benjamin Orsini
690b84e2e8 Add map() documentation sample
* docs: add map() sample
* docs: add samples for Map and CharSequence
* docs: add another sample for Maps.map()

(cherry picked from commit 3e39f26379)
2019-05-23 19:39:33 +03:00
Ivan Gavrilovic
2bba568dd6 If incremental KAPT is disabled, do not analyze classpath
When incremental apt mode in KAPT is disabled, do not analyze
classpath to determine the type of the annotation processors. Instead,
just mark them all as non-incremental.

(cherry picked from commit 72fdc648ff)
2019-05-23 19:19:21 +03:00
Peter Xu
d432ea7df5 Revert obsolete code introduced in KT-12402
The classes being filtered have been renamed months ago. The change
committed in KT-12402 is no longer relevant as the underlying issue has
been fixed.

(cherry picked from commit a639607821)
2019-05-23 19:19:20 +03:00
Ivan Gavrilovic
81f4a090f6 Handle return result of dir creation/deletion in kapt
#KT-31322

(cherry picked from commit b609fe529c)
2019-05-23 19:19:20 +03:00
Ivan Gavrilovic
7a17bccf23 Remove generated sources and classes for full KAPT build
When running incremental annotation processing in KAPT,
even if incremental flag is enabled, and full rebuild should
be performed (e.g. in presence of dynamic non-incremental APs),
make sure generated sources and classes are removed.

 #KT-31322 fixed

(cherry picked from commit f60bfc34c0)
2019-05-23 19:19:19 +03:00
Vladimir Krivosheev
6528826ea7 Do not use constructor injection for app level extension KotlinClassWithDelegatedPropertyRenderer (KT-31266)
(cherry picked from commit 757b4b3910)
2019-05-23 19:19:19 +03:00
Yan Zhulanow
902dfe0815 Revert "Kapt: Always use raw types for annotation parameter types (KT-30346)"
This reverts commit 66754e62

(cherry picked from commit a0778ad703)
2019-05-23 19:19:18 +03:00
Yan Zhulanow
207bd4e1b9 Pill: Recognize 'embedded' configuration as 'compile' in JPS 2019-05-23 19:19:18 +03:00
Dmitriy Novozhilov
d2d603b3bd Add wrappers on KotlinType in EffectSystem
Also that commit removes usages of builtins inside
  effect system and starts refactoring of functor
  composition via composition instead of inheritance.

There are some changes in testdata related to inference of recursive
  functions with implicit return types.

After this commit they all are marked as unresolved. It happens because
  those functions have DeferredType as return type, and computing this
  type produces recursive exception, which provides “typechecker
  recursive problem” diagnostic.

Before this commit, function call was completed successfully, because
  call completer didn’t computed that type, and computation of DeferredType
  were triggered only in `DataFlowAnalyzer.checkType`.
Now, effect system tries to compute that type while wrapping KotlinTypes
  into ESTypes, and effect system itself is triggered in in call completer,
  so, call completion doesn’t finish and function call is marked as unresolved.

#KT-31364
2019-05-23 19:19:17 +03:00
Dmitriy Novozhilov
536e135c66 [NI] Fix recursion in contract declaration analysis.
#KT-30410 Fixed
2019-05-23 19:19:17 +03:00
Dmitriy Novozhilov
56768ff7ea [NI] Add check for non-null argument type in arguments check
#KT-31461 Fixed
2019-05-23 19:19:16 +03:00
Dmitriy Novozhilov
6f05bafeb3 [NI] Remove deep types in commosn super type for recursive types
#KT-30411 Fixed
2019-05-23 19:19:16 +03:00
Dmitriy Novozhilov
ec852452b0 [NI] Fix error type approximation in ILTApproximatorConfiguration
#KT-31441 Fixed
2019-05-23 19:19:15 +03:00
Sergey Rostov
61ba1c875a Gradle, js: fix js test frameworks DSL for groovy
#KT-31566 Fixed
2019-05-23 19:19:15 +03:00
Sergey Rostov
15f9895088 Gradle, test reports: NewMultiplatformIT.testJavaSupportInJvmTargets
"check" task, now creates aggregate report for all gradle versions,
so this test is affected too
2019-05-23 19:19:15 +03:00
Sergey Rostov
95d338db0d Gradle, tests: introduce kotlin.tests.individualTaskReports
This property required for getting individual junit.xml files that is
currently used in test run assertions.
2019-05-23 19:19:14 +03:00
Sergey Rostov
ca065eedce Gradle, js, single platform projects: create single test aggregator
Extract KotlinTestsRegistry service for customizing aggregated test tasks
naming.
2019-05-23 19:19:14 +03:00
Sergey Rostov
61fcc1cbd2 Gradle, js, tests: always create a jsTest task for compatibility
This requires runnable aggregate test task even if there are not tests in it.
That, in turn, requires support aggregate test tasks hierarchy.
Also TestReport integrated in aggregate for all gradle versions (was for 5 only).

#KT-31527 Fixed
2019-05-23 19:19:13 +03:00
Sergey Rostov
0e480fd040 Gradle, libWithTests test: check js tests running, add test results assertion 2019-05-23 19:19:13 +03:00
Sergey Rostov
c8788d93a3 Gradle, testing test execution: support asserting reports from multiple tasks at once 2019-05-23 19:19:12 +03:00
Sergey Rostov
7c24ed6152 Gradle, js, webpack: fix compatibility with older gradle version 2019-05-23 19:19:12 +03:00
Sergey Rostov
d666d2b186 Gradle, js, npm: try fixing project version to semver
JS package managers requires it.

#KT-31563 Fixed
2019-05-23 19:19:11 +03:00
victor.petukhov
91da355f49 Actualize spec tests 2019-05-23 19:19:11 +03:00
victor.petukhov
bdb7683887 Report warning about implicitly inferred nothing only for return position
^KT-31535 Fixed
2019-05-23 19:19:10 +03:00
Ilmir Usmanov
066ce5464a Do not generate $$forInline suffix for enclosing method
in OUTERCLASS field.

The inliner generates two versions of suspend functions/lambdas in
inline functions: with state-machine and without. The former is used
to call the function from Java or via reflection and have ordinary
name, while the latter is used by inliner and have $$forInline suffix.
The inliner throws the state-machine version away, duplicates
$$forInline version and then call state-machine generator.

If these suspend functions/lambdas are not going to be inlined,
$$forInline version is not generated. However, all objects, which are
used in these suspend functions/lambdas, have $$forInline version
written to OUTERCLASS field. This leads to errors by proguard.
Since they are used in both state-machine version and for-inline ones,
we can simply remove $$forInline suffix from OUTERCLASS field and this
fixes the issue.

 #KT-31242 Fixed
2019-05-23 19:19:10 +03:00
Ilmir Usmanov
7bc607c851 Fix Java interop of inline suspend functions with suspend parameters
In 1.3.31 I fixed Java interop for inline function with coroutines
(TL;DR: when we need a state machine, generate two methods: one with
normal name, and the other one with $$forInline suffix, for the inliner
to use, just like inline suspend functions), however, I forgot a case
with inline suspend function with inline suspend function parameter.
In this case, the compiler a generated two functions, as needed, but,
neither of them had a state-machine. This change adds the state-machine
for the method with normal name. Note, that suspend inline functions
with crossinline parameter, which are also supported by the change,
did not cause incorrect behaviour, since until now they were generated
as synthetic.

 #KT-31354 Fixed
2019-05-23 19:19:09 +03:00
Ilmir Usmanov
e12c7c8f59 Remove redundant continuation classes and INNERCLASS nodes
#KT-31339 Fixed
2019-05-23 19:19:09 +03:00
Ilya Matveev
3b2272ce6a Gradle plugin: remove old native binary APIs
This patch removes APIs for native binary configuring
introduced in 1.3.0 and deprecated in 1.3.30.

Issue #KT-31229 Fixed
2019-05-23 19:19:08 +03:00
Sergey Rostov
5c998b7a33 Gradle, js, npm: skip KotlinProjectExtensions from different class loaders 2019-05-23 19:19:08 +03:00
Sergey Rostov
cfbc44f97f Gradle, js: fix supporting sub targets DSL in build.gradle.kts 2019-05-23 19:19:08 +03:00
Sergey Rostov
224360aa2d Gradle, js, npm: skip old Kotlin2JsPlugin compilations 2019-05-23 19:19:07 +03:00
Sergey Rostov
aef162b1d2 Gradle, js: create run task only when project evaluated
As it may be created after js target configuration by java application plugin
2019-05-23 19:19:07 +03:00
Sergey Rostov
2f7eedd568 Gradle, js, npm: fix case when resolver visits dependents projects first 2019-05-23 19:19:06 +03:00
Sergey Rostov
b22102d252 Gradle, js: implement NpmSimpleLinker for cases when there are no npm dependencies 2019-05-23 19:19:06 +03:00
Sergey Rostov
e20fbee48c Gradle, js: fix task input annotations 2019-05-23 19:19:05 +03:00
Sergey Rostov
3ee7134540 Gradle, tests: don't use gradle testing internals by default 2019-05-23 19:19:05 +03:00
Sergey Rostov
462c5dea53 Gradle, tests: fix cleanAllTests task name 2019-05-23 19:19:04 +03:00
Sergey Rostov
0c13f4b1fc Gradle, js: update npm packages versions 2019-05-23 19:19:04 +03:00
Sergey Rostov
9975ec9d0d Gradle: introduce "target" DSL function for single platform plugins 2019-05-23 19:19:04 +03:00
Sergey Rostov
ecb56ebedc Gradle, js: introduce commonJs() dsl function 2019-05-23 19:19:03 +03:00
Sergey Rostov
eb2e37f8d2 Gradle, js, webpack: report progress
#KT-31013
2019-05-23 19:19:03 +03:00
Sergey Rostov
d9e46fef61 Gradle, js, yarn: split into workspaces and simple implementations
#KT-31018
	#KT-31017
2019-05-23 19:19:02 +03:00
Sergey Rostov
1ebb5145de Gradle, js, npm: store imported packages as yarn workspaces
#KT-30530
2019-05-23 19:19:02 +03:00
Sergey Rostov
1db0643460 Gradle, tests: fix type in "prepend" 2019-05-23 19:19:01 +03:00
Sergey Rostov
46ea87217f Gradle, js, karma: source maps support
#KT-31478
	#KT-31011
	#KT-30573
2019-05-23 19:19:01 +03:00
Sergey Rostov
0cc405a02f Gradle, js, tests: don't add prefix if platform and/or sub target name is null 2019-05-23 19:19:00 +03:00
Sergey Rostov
a102cbe469 Gradle, js: create npm packages per compilation
#KT-30530
2019-05-23 19:19:00 +03:00
Sergey Rostov
78b02e5efa Gradle, js: resolve npm dependencies without task only during IDEA import
#KT-30530
2019-05-23 19:18:59 +03:00
Sergey Rostov
277694a733 Gradle, js: create one npmResolve per build (share between subprojects)
#KT-30530
2019-05-23 19:18:59 +03:00
Sergey Rostov
4f0128f3ca Gradle, js, npm: remove hoisted gradle node modules. Split results collection from shared cache.
#KT-30530
2019-05-23 19:18:58 +03:00
Sergey Rostov
5ee77a02ea Gradle, js, npm: resolver between projects
#KT-30530
2019-05-23 19:18:58 +03:00
Sergey Rostov
7146f79bc9 Gradle, js: use project.whenEvaluated instead of project.afterEvaluate 2019-05-23 19:18:57 +03:00
Sergey Rostov
56310ae159 Gradle, js, dsl: use ConfigureUtil.configure for Groovy compatibility 2019-05-23 19:18:57 +03:00
Sergey Rostov
fe72bc494e Gradle, js, krama: use web pack config directory
#KT-31011
2019-05-23 19:18:56 +03:00
Sergey Rostov
4ac8a18367 Gradle, js: don't use any subtarget by default 2019-05-23 19:18:55 +03:00
Sergey Rostov
db7b4e29c4 Gradle, js, run: fix run dependencies on browserRun and nodeRun 2019-05-23 19:18:55 +03:00
Sergey Rostov
9b1d498663 Gradle, js, test: add basic @Input for test frameworks settings 2019-05-23 19:18:54 +03:00
Sergey Rostov
19656f7884 Gradle, js: aggregate jsTest task should work the same way as all tests aggregator
E.g: individual test tasks should not fail build, aggregate reports should be created.
Also this task should not be included in check (as all tests should be already executed
from the all tests aggregated task).
2019-05-23 19:18:54 +03:00
Sergey Rostov
64556720e1 Gradle, js, karma: show output as progress 2019-05-23 19:18:53 +03:00
Sergey Rostov
fa240df089 Gradle, js, yarn: remove outdated warning about yarn workspaces
#KT-31018
	#KT-31017
2019-05-23 19:18:53 +03:00
Sergey Rostov
79dc998331 Gradle, js: fixes for groovy dsl 2019-05-23 19:18:52 +03:00
Sergey Rostov
1c8580109b Gradle, js, browser: best effort for parsing karma suite names
#KT-31011
2019-05-23 19:18:52 +03:00
Sergey Rostov
6d579d59d9 Gradle, js, browser: fix karma.conf.js writer
#KT-31011
2019-05-23 19:18:51 +03:00
Sergey Rostov
93209bf67b Gradle, js, browser: fix run 2019-05-23 19:18:50 +03:00
Sergey Rostov
6c3ab15b03 Gradle, js: fix resolving required dependencies
#KT-31011
2019-05-23 19:18:50 +03:00
Sergey Rostov
3ee521700e Gradle, nodeJs: fix tests 2019-05-23 19:18:49 +03:00
Sergey Rostov
e8a30fb648 Gradle, js: revert to storing compile output inside node_modules
#KT-30530
Currently kotlin JS compiler generated `require('a.js')` for test -> main
dependencies. This is not worked in layout with compile output at project
work dir (will work if compiler will generate `require('a_test.js')`).
2019-05-23 19:18:49 +03:00
Sergey Rostov
734c894d37 Gradle, js: extract NpmProjectModules to separate file
#KT-30530
2019-05-23 19:18:48 +03:00
Sergey Rostov
b5a8258bef Gradle, js, node: fix source map support configuration
#KT-30573 Fixed
2019-05-23 19:18:48 +03:00
Sergey Rostov
4247ecba2e Gradle, js: fix nodejs run target 2019-05-23 19:18:47 +03:00
Sergey Rostov
0aa9edd833 Gradle, js: restore umd by default 2019-05-23 19:18:47 +03:00
Sergey Rostov
57bf604350 Gradle, js: fix karma.conf.js by wrapping config in function
#KT-31011
2019-05-23 19:18:46 +03:00
Sergey Rostov
5102c5b820 Gradle, js: implement resolving node modules according to https://nodejs.org/api/modules.html
#KT-30530
2019-05-23 19:18:46 +03:00
Sergey Rostov
666b23dc92 Gradle, js: fix requiredDependencies resolve 2019-05-23 19:18:45 +03:00
Sergey Rostov
302be0a5d2 Gradle, js: fix NodeJsExec 2019-05-23 19:18:45 +03:00
Sergey Rostov
a4d9f4c112 Gradle, js: use js compilation only after target configuration 2019-05-23 19:18:45 +03:00
Sergey Rostov
299cdf79cd Gradle, JS: make KotlinWebpack.configDirectory optional
#KT-31013
2019-05-23 19:18:44 +03:00
Sergey Rostov
543eabbd5f Gradle, JS: resolve NPM dependencies inside task when possible
#KT-30530
2019-05-23 19:18:44 +03:00
Sergey Rostov
50c25e2852 Gradle, JS: introduce RequiresNpmDependencies
#KT-30530
2019-05-23 19:18:43 +03:00
Sergey Rostov
9e327b932c Gradle, JS: extract npm package constants
#KT-30530
2019-05-23 19:18:42 +03:00
Sergey Rostov
988ee456f5 Gradle, JS: introduce inner browser and nodejs inner targets
#KT-30747 Fixed
2019-05-23 19:18:42 +03:00
Sergey Rostov
a9d32b17ff Gradle, JS: nodejs target 2019-05-23 19:18:41 +03:00
Sergey Rostov
e3429c7997 Gradle, JS, webpack: source maps support
#KT-31013
2019-05-23 19:18:41 +03:00
Sergey Rostov
55a7ae6acb Gradle, JS: new nodejs project layout
#KT-30530
2019-05-23 19:18:40 +03:00
Sergey Rostov
73cead421e Gradle, JS: webpack support
#KT-31013
2019-05-23 19:18:40 +03:00
Sergey Rostov
899917585b Gradle, tests: clean should depend on cleanAllTests 2019-05-23 19:18:39 +03:00
Sergey Rostov
d3fd16a491 Gradle, testsL fix ijListenTestTask 2019-05-23 19:18:39 +03:00
Sergey Rostov
a19790c16a Gradle, npm: resolve node_modules at parents, return local NodeJsExtension at NodeJsPlugin.apply 2019-05-23 19:18:38 +03:00
Sergey Rostov
3d6579e5a5 Gradle, yarn: get recursively resolved dependencies
#KT-31018 Fixed
	#KT-31016 Fixed
	#KT-31017 Fixed
2019-05-23 19:18:38 +03:00
Sergey Rostov
eaca460d80 Gradle: improve tasks registration API, fix test tasks registration
Previously test tasks may be created inside other registration task
lambda which may be called lazily. This is illegal in Gradle.

Also let introduce Project.createOrRegisterTask on Project receiver
and reified type parameter.
2019-05-23 19:18:37 +03:00
Sergey Rostov
686bc8af83 Gradle: webpack
#KT-31013 Fixed
	#KT-31014 Fixed
2019-05-23 19:18:37 +03:00
Sergey Rostov
6c539e6b73 Gradle, tests: remove "Task" suffix from KotlinTest tasks (as for jvm) 2019-05-23 19:18:36 +03:00
Sergey Rostov
8be1aba2c8 Gradle, js: karma
#KT-31011 fixed
2019-05-23 19:18:35 +03:00
Sergey Rostov
b27b22e30f Gradle, js: mocha
#KT-31010 Fixed
2019-05-23 19:18:35 +03:00
Sergey Rostov
2946237005 Gradle, npm: disable manageNodeModules by default
#KT-30530
2019-05-23 19:18:34 +03:00
Sergey Rostov
de242623d7 Gradle, js: run tests using the new project-wide node_modules
#KT-30530
2019-05-23 19:18:34 +03:00
Sergey Rostov
b5dcfb2c5a Gradle: npm integration using yarn
#KT-31018 Fixed
2019-05-23 19:18:33 +03:00
Sergey Rostov
c6d560b2e6 Gradle, Tests runner: update tests, fix tests on Windows 2019-05-23 19:18:33 +03:00
Sergey Rostov
02e38b6e22 Gradle, Native: don't capture output if treatOutputAsStracktrace enabled
#KT-30529
2019-05-23 19:18:32 +03:00
Sergey Rostov
7b662a2fe3 Gradle, tests: cleanAllTests task
#KT-29946
2019-05-23 19:18:31 +03:00
Sergey Rostov
99b6ee5ee3 Gradle, tests: show test results in IDE
#KT-29946
2019-05-23 19:18:31 +03:00
Sergey Rostov
b653d81bfe Gradle: Kotlin/Native stack trace parser
#KT-30526
	#KT-30529
2019-05-23 19:18:30 +03:00
Sergey Rostov
97084112b3 Gradle: JS stack trace parser
#KT-30526
2019-05-23 19:18:29 +03:00
Sergey Rostov
8a54ab3dd2 Gradle, test: allTests task, same class and method names for jvm, js and native
#KT-30691 Fixed
	#KT-31448 Fixed
2019-05-23 19:18:29 +03:00
Elena Lepilkina
ee74bdacc0 New Kotlin/Native version 2019-05-22 18:19:03 +03:00
Vyacheslav Gerasimov
c12b784e5b Build: Fix cache redirector configuration for all projects
Since we forcing project evaluation in root build script cache redirector
should be configured before we do so, otherwise `afterEvaluate` is not called

(cherry picked from commit 40e9f48bd0)
2019-05-20 15:18:25 +03:00
nikita.movshin
f0555ab5df Fix changelog for 1.3.40 2019-05-17 20:59:49 +03:00
nikita.movshin
cac8f3ace3 Add changelog for 1.3.40 2019-05-17 20:57:41 +03:00
Elena Lepilkina
d331c7d376 New EAP buikd of Kotlin/Native 2019-05-17 10:17:53 +03:00
Roman Artemev
ad4671ed5f [IR BE] Delegate coroutine naming strategy to platform part
(cherry picked from commit 02d84bf061)
2019-05-16 19:20:41 +03:00
Alexey Tsvetkov
7cc4c606a1 Do not expose paths with placeholders in JS IC caches
#KT-31310 Fixed
2019-05-16 04:07:14 +03:00
Elena Lepilkina
009e33ed72 Changed Kotlin/Native version (EAP1) 2019-05-15 12:09:26 +03:00
Dmitry Gridin
2d83ceb980 Fix "Unused import" for 'provideDelegate'
#KT-31319 Fixed

(cherry picked from commit eee8d0263d)
2019-05-14 22:02:23 +07:00
Dmitry Gridin
966dd3ee24 Don't delete import from stdlib if alias exists and used
#KT-31414 Fixed

(cherry picked from commit 3914530fa8)
2019-05-14 22:02:07 +07:00
Dmitry Gridin
efdb19772b Optimize Imports shouldn't delete imports with unresolved parts
#KT-10512 Fixed

(cherry picked from commit 32298522dd)
2019-05-14 22:01:42 +07:00
Ilya Gorbunov
7accee269b Add simplified overloads of String<->ByteArray/CharArray conversions
These overloads cover the most common cases of conversion of the entire
String or Byte/CharArray, avoiding extra index check and branching.

#KT-24810, KT-29265

(cherry picked from commit 2c26dc3af6)
2019-05-14 17:54:13 +03:00
Mikhail Glukhikh
012b8f76a0 Fix .inspection file for ConvertNaNEquality tests
(cherry picked from commit 2d5f41cfe3)
2019-05-14 16:50:51 +03:00
Matthew Runo
01551d1bad Migrate RetentionPolicy arguments in deprecated Java quick-fix
#KT-29666 Fixed

(cherry picked from commit 39f576d75c)
2019-05-14 09:28:49 +03:00
Toshiaki Kameyama
be2c670c09 Implicit Nothing? type: don't report when declaration overrides nullable nothing type
#KT-30481 Fixed

(cherry picked from commit 14259ca9e0)
2019-05-14 09:28:23 +03:00
Dereck Bridie
a3ebd0751c KT-26629 Inspection to replace equality check with NaN with isNaN call
(cherry picked from commit 574178882a)
2019-05-14 09:27:58 +03:00
Mikhail Glukhikh
9d013254a4 Add name to argument: support old-style comment deletion
(cherry picked from commit b4a63794e5)
2019-05-14 09:27:36 +03:00
Mikhail Glukhikh
15045d2512 Use candidate descriptor to determine parameter name stability in IDEA
#KT-31349 Fixed

(cherry picked from commit b0d294b50c)
2019-05-14 09:27:12 +03:00
Mikhail Glukhikh
fa9cf694dd Apply "unnamed boolean literal" to idea & J2K + other style fixes
(cherry picked from commit d517276a06)
2019-05-14 09:26:51 +03:00
Mikhail Glukhikh
d849bde003 Introduce "add parameter names to following arguments"
This commit also refactors relevant intentions & inspections,
like "add name to argument", "add names to call arguments",
"unnamed boolean literal argument"

#KT-30622 Fixed

(cherry picked from commit 955bfd6e7b)
2019-05-14 09:26:25 +03:00
Sergey Igushkin
5694726f04 Introduce Java support in JVM MPP targets (KT-26256)
Deprecate the `jvmWithJava` preset, add warning.

Add a function `withJava()` to JVM MPP targets which applies the 'java'
plugin and sets up the Kotlin & Java interoperation.

Issue #KT-26256 Fixed

Signed-off-by: Sergey Igushkin <hotkeytlt@gmail.com>
(cherry picked from commit be05095df5)
2019-05-13 18:11:04 +03:00
Mikhail Zarechenskiy
d277ddb38c [NI] Complete call if return type contains only "good" type variables 2019-05-13 16:21:01 +03:00
Mikhail Zarechenskiy
3d6c735538 [NI] Complete call if return type has proper lower or equal constraints
There was a silly bug: equal constraint is actually a lower and an upper
 constraint, but we checked only presence of lower constraints.

 Test is important as here we have one equal constraint and should
 complete inner call `foo<Int>()` without propagating it to `bar` to
 avoid using `NoInfer` annotation multiple times
2019-05-13 16:20:52 +03:00
Mikhail Zarechenskiy
8165d07346 [NI] Use original implicit receiver for DSL violation check
There is an inconsistency between old and new inference for storing
 receivers of resolved calls. In new inference, for captured types,
 receiver will be changed and to preserve behavior of the old inference,
 we use original one during important checks.
 This is more a workaround than a solution and should be revisited.

 #KT-31356 Fixed
 #KT-29948 Fixed
 #KT-31360 Fixed
2019-05-13 16:20:43 +03:00
Mikhail Zarechenskiy
2a58d137e2 [NI] Preserve annotations during type substitution
#KT-31346 Fixed
2019-05-13 16:20:34 +03:00
Toshiaki Kameyama
b6f2cc125a "Redundant 'requireNotNull' or 'checkNotNull' call": don't remove first argument if function is used as expression
#KT-31404 Fixed

(cherry picked from commit cf4471ba53)
2019-05-13 17:05:02 +07:00
Dmitry Gridin
40f2823278 Fix incorrect quickfix "Replace with Kotlin analog" for conversion to an extension
where the first argument is an expression with an operation
 #KT-31341 Fixed

(cherry picked from commit 07e908f15f)
2019-05-13 17:04:49 +07:00
Natalia Selezneva
aa6d3c3fbe Fix NPE in SLRUMap in ScriptDefinitionsManager
EA-138364 - NPE: LinkedHashMap$Entry.access$

(cherry picked from commit e158875a14)
2019-05-13 12:39:50 +03:00
Natalia Selezneva
469230016e Do not provide 'add dependency' quick fix for unresolved references for non-project files
EA-126105 - NPE: JavaFileManagerImpl$LibSrcExcludingScope.<init> (KotlinAddOrderEntryActionFactory)

(cherry picked from commit 2a2fe6b428)
2019-05-13 12:39:13 +03:00
Natalia Selezneva
ce55ae31b5 Fix 'Invalid file' Exception during script definition search (EA-125840)
EA-125840 - assert: FileManagerImpl.findFile

(cherry picked from commit ba7d66eb4b)
2019-05-13 12:38:49 +03:00
Natalia Selezneva
703dd28553 Do not use canonical paths in OutsidersPsiFileSupportUtils (EA-135551)
EA-135551 - IOE: OutsidersPsiFileSupportUtils$getOutsiderFileOrigin$.invoke

(cherry picked from commit 836006b3f3)
2019-05-13 12:38:28 +03:00
Natalia Selezneva
3249a82f33 Fix notification about highlighting for diff view in build.gradle.kts (KT-30638)
(cherry picked from commit 98235952ad)

^KT-30638 Fixed
2019-05-13 12:38:02 +03:00
Natalia Selezneva
c5d590cbfd Fix highlighting for scripts in diff view (KT-30690)
(cherry picked from commit 495d98f997)

^KT-30690 Fixed
2019-05-13 12:37:00 +03:00
Natalia Selezneva
1fe369bf84 Minor: extract common parts
(cherry picked from commit 88c6ecbbdf)
2019-05-13 12:36:28 +03:00
Natalia Selezneva
33246782dc Run indexes update after typing in script if needed
(cherry picked from commit 89bf7f991a)
2019-05-13 12:36:02 +03:00
Natalia Selezneva
49c539eb39 Refactoring: add isApplicable method to ScriptDependenciesLoader
(cherry picked from commit 9e51f82248)
2019-05-13 12:35:32 +03:00
Natalia Selezneva
1a8dbc07ed Do not start script dependencies update if dependencies are already cached
(cherry picked from commit e990c61b55)
2019-05-13 12:35:08 +03:00
LepilkinaElena
6c0750e975 Version of K/N for MPP is set to EAP0 version 2019-05-07 14:50:59 +03:00
693 changed files with 15505 additions and 12243 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -114,8 +114,7 @@ open class IncrementalJsCache(
fun nonDirtyPackageParts(): Map<File, TranslationResultValue> =
hashMapOf<File, TranslationResultValue>().apply {
for (path in translationResults.keys()) {
val file = File(path)
for (file in translationResults.keys()) {
if (file !in dirtySources) {
put(file, translationResults[file]!!)
}
@@ -167,8 +166,8 @@ private class TranslationResultMap(
operator fun get(sourceFile: File): TranslationResultValue? =
storage[pathConverter.toPath(sourceFile)]
fun keys(): Collection<String> =
storage.keys
fun keys(): Collection<File> =
storage.keys.map { pathConverter.toFile(it) }
fun remove(sourceFile: File, changesCollector: ChangesCollector) {
val path = pathConverter.toPath(sourceFile)

View File

@@ -155,10 +155,10 @@ extra["versions.org.springframework"] = "4.2.0.RELEASE"
extra["versions.jflex"] = "1.7.0"
extra["versions.markdown"] = "0.1.25"
extra["versions.trove4j"] = "1.0.20181211"
extra["versions.kotlin-native-shared"] = "1.0-dev-50"
extra["versions.kotlin-native-shared"] = "1.0-dev-89"
if (!project.hasProperty("versions.kotlin-native")) {
extra["versions.kotlin-native"] = "1.3-dev-9780"
extra["versions.kotlin-native"] = "1.3-eap-10240"
}
val isTeamcityBuild = project.hasProperty("teamcity") || System.getenv("TEAMCITY_VERSION") != null
@@ -381,6 +381,11 @@ allprojects {
dependencies.add(it.name, files(bootstrapCompilerClasspath))
}
}
if (cacheRedirectorEnabled()) {
logger.info("Redirecting repositories for $displayName")
repositories.redirect()
}
}
}
@@ -489,7 +494,12 @@ tasks {
create("scriptingTest") {
dependsOn("dist")
dependsOn(":kotlin-script-util:test")
dependsOn(":kotlin-scripting-jvm-host:test")
dependsOn(":kotlin-scripting-compiler:test")
dependsOn(":kotlin-scripting-jvm-host-test:test")
dependsOn(":kotlin-scripting-jsr223-test:test")
dependsOn(":kotlin-scripting-jvm-host-test:embeddableTest")
dependsOn(":kotlin-scripting-jsr223-test:embeddableTest")
dependsOn(":kotlin-main-kts-test:test")
}
create("compilerTest") {
@@ -730,12 +740,3 @@ tasks.create("findShadowJarsInClasspath").doLast {
project.checkConfig("testCompileClasspath")
}
}
allprojects {
afterEvaluate {
if (cacheRedirectorEnabled()) {
logger.info("Redirecting repositories for $displayName")
repositories.redirect()
}
}
}

View File

@@ -130,7 +130,7 @@ fun parse(project: Project, libraries: List<PLibrary>, context: ParserContext):
*/
private val CONFIGURATION_MAPPING = mapOf(
listOf("runtime") to Scope.RUNTIME,
listOf("compile") to Scope.COMPILE,
listOf("compile", "embedded") to Scope.COMPILE,
listOf("compileOnly") to Scope.PROVIDED
)

View File

@@ -65,7 +65,8 @@ import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isToArrayFromCollection
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isEffectivelyInlineOnly;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineOnlyPrivateInBytecode;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineWithReified;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmSyntheticAnnotation;
@@ -388,7 +389,8 @@ public class AsmUtil {
flags |= getVarargsFlag(functionDescriptor);
flags |= getDeprecatedAccessFlag(functionDescriptor);
if (deprecationResolver.isDeprecatedHidden(functionDescriptor) ||
(functionDescriptor.isSuspend()) && functionDescriptor.getVisibility().equals(Visibilities.PRIVATE)) {
isInlineWithReified(functionDescriptor) ||
functionDescriptor.isSuspend() && functionDescriptor.getVisibility().equals(Visibilities.PRIVATE)) {
flags |= ACC_SYNTHETIC;
}
return flags;
@@ -526,7 +528,7 @@ public class AsmUtil {
return ACC_PRIVATE;
}
if (isEffectivelyInlineOnly(memberDescriptor)) {
if (isInlineOnlyPrivateInBytecode(memberDescriptor)) {
return ACC_PRIVATE;
}

View File

@@ -76,6 +76,7 @@ import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isEffectivelyInlineOnly;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineOnlyPrivateInBytecode;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.InlineClassManglingRulesKt.shouldHideConstructorDueToInlineClassTypeValueParameters;
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
@@ -1153,10 +1154,10 @@ public class FunctionCodegen {
// $default methods are never private to be accessible from other class files (e.g. inner) without the need of synthetic accessors
// $default methods are never protected to be accessible from subclass nested classes
int visibilityFlag = Visibilities.isPrivate(functionDescriptor.getVisibility()) ||
isEffectivelyInlineOnly(functionDescriptor) ?
AsmUtil.NO_FLAG_PACKAGE_PRIVATE : Opcodes.ACC_PUBLIC;
int flags = visibilityFlag | getDeprecatedAccessFlag(functionDescriptor) | ACC_SYNTHETIC;
int visibilityFlag =
Visibilities.isPrivate(functionDescriptor.getVisibility()) || isInlineOnlyPrivateInBytecode(functionDescriptor)
? AsmUtil.NO_FLAG_PACKAGE_PRIVATE : Opcodes.ACC_PUBLIC;
int flags = visibilityFlag | getDeprecatedAccessFlag(functionDescriptor) | ACC_SYNTHETIC;
if (!(functionDescriptor instanceof ConstructorDescriptor &&
!InlineClassesUtilsKt.isInlineClass(functionDescriptor.getContainingDeclaration()))
) {

View File

@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaForKotlinOverridePropertyDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
import org.jetbrains.kotlin.resolve.jvm.annotations.hasPlatformDependentAnnotation
@@ -42,18 +44,27 @@ class DescriptorBasedFunctionHandleForJvm(
override val mightBeIncorrectCode: Boolean
get() = state.classBuilderMode.mightBeIncorrectCode
override fun hashCode(): Int = descriptor.containerEntityForEqualityAndHashCode().hashCode() + 31 * asmMethod.hashCode()
override fun equals(other: Any?): Boolean {
if (other !is DescriptorBasedFunctionHandleForJvm) return false
override fun hashCode(): Int =
(descriptor.containerEntityForEqualityAndHashCode().hashCode() * 31 +
descriptor.isJavaForKotlinOverrideProperty.hashCode()) * 31 +
asmMethod.hashCode()
return asmMethod == other.asmMethod &&
descriptor.containerEntityForEqualityAndHashCode() == other.descriptor.containerEntityForEqualityAndHashCode()
override fun equals(other: Any?): Boolean {
if (this === other) return true
return other is DescriptorBasedFunctionHandleForJvm &&
asmMethod == other.asmMethod &&
descriptor.containerEntityForEqualityAndHashCode() == other.descriptor.containerEntityForEqualityAndHashCode() &&
descriptor.isJavaForKotlinOverrideProperty == other.descriptor.isJavaForKotlinOverrideProperty
}
}
private fun FunctionDescriptor.containerEntityForEqualityAndHashCode(): Any =
(containingDeclaration as? ClassDescriptor)?.typeConstructor ?: containingDeclaration
private val FunctionDescriptor.isJavaForKotlinOverrideProperty: Boolean
get() = this is PropertyAccessorDescriptor && correspondingProperty is JavaForKotlinOverridePropertyDescriptor
private fun CallableMemberDescriptor.isJvmDefaultOrPlatformDependent() =
hasJvmDefaultAnnotation() || hasPlatformDependentAnnotation()

View File

@@ -27,7 +27,7 @@ import java.util.*;
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isEffectivelyInlineOnly;
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineOnlyPrivateInBytecode;
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.isCallableMemberWithJvmDefaultAnnotation;
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
@@ -693,7 +693,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
boolean withinInline,
boolean isSuperCall
) {
if (isEffectivelyInlineOnly(unwrappedDescriptor)) return false;
if (isInlineOnlyPrivateInBytecode(unwrappedDescriptor)) return false;
return isSuperCall && withinInline ||
(accessFlag & ACC_PRIVATE) != 0 ||

View File

@@ -30,7 +30,7 @@ open class SuspendFunctionGenerationStrategy(
state: GenerationState,
protected val originalSuspendDescriptor: FunctionDescriptor,
protected val declaration: KtFunction,
private val containingClassInternalName: String,
protected val containingClassInternalName: String,
private val constructorCallNormalizationMode: JVMConstructorCallNormalizationMode,
protected val functionCodegen: FunctionCodegen
) : FunctionGenerationStrategy.CodegenBased(state) {
@@ -53,16 +53,7 @@ open class SuspendFunctionGenerationStrategy(
override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor {
if (access and Opcodes.ACC_ABSTRACT != 0) return mv
val stateMachineBuilder = CoroutineTransformerMethodVisitor(
mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState,
isForNamedFunction = true,
element = declaration,
diagnostics = state.diagnostics,
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
languageVersionSettings = languageVersionSettings
)
val stateMachineBuilder = createStateMachineBuilder(mv, access, name, desc)
val forInline = state.bindingContext[CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA, originalSuspendDescriptor] == true
// Both capturing and inline functions share the same suffix, however, inline functions can also be capturing
@@ -95,6 +86,24 @@ open class SuspendFunctionGenerationStrategy(
) else stateMachineBuilder
}
protected fun createStateMachineBuilder(
mv: MethodVisitor,
access: Int,
name: String,
desc: String
): CoroutineTransformerMethodVisitor {
return CoroutineTransformerMethodVisitor(
mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState,
isForNamedFunction = true,
element = declaration,
diagnostics = state.diagnostics,
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
languageVersionSettings = languageVersionSettings
)
}
private fun containingClassInternalNameOrNull() =
originalSuspendDescriptor.containingDeclaration.safeAs<ClassDescriptor>()?.let(state.typeMapper::mapClass)?.internalName

View File

@@ -5,20 +5,30 @@
package org.jetbrains.kotlin.codegen.coroutines
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.FunctionCodegen
import org.jetbrains.kotlin.codegen.FunctionGenerationStrategy
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.codegen.inline.coroutines.findReceiverOfInvoke
import org.jetbrains.kotlin.codegen.inline.coroutines.surroundInvokesWithSuspendMarkers
import org.jetbrains.kotlin.codegen.inline.isInvokeOnLambda
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter
// For named suspend function we generate two methods:
// 1) to use as noinline function, which have state machine
@@ -44,7 +54,10 @@ class SuspendInlineFunctionGenerationStrategy(
if (access and Opcodes.ACC_ABSTRACT != 0) return mv
return MethodNodeCopyingMethodVisitor(
super.wrapMethodVisitor(mv, access, name, desc), access, name, desc,
SurroundSuspendParameterCallsWithSuspendMarkersMethodVisitor(
createStateMachineBuilder(mv, access, name, desc),
access, name, desc, containingClassInternalName, originalSuspendDescriptor.valueParameters
), access, name, desc,
newMethod = { origin, newAccess, newName, newDesc ->
functionCodegen.newMethod(origin, newAccess, newName, newDesc, null, null)
}, keepAccess = false
@@ -78,3 +91,39 @@ class MethodNodeCopyingMethodVisitor(
else access or Opcodes.ACC_PRIVATE and Opcodes.ACC_PUBLIC.inv() and Opcodes.ACC_PROTECTED.inv()
}
}
private class SurroundSuspendParameterCallsWithSuspendMarkersMethodVisitor(
delegate: MethodVisitor,
access: Int,
name: String,
desc: String,
private val thisName: String,
private val valueParameters: List<ValueParameterDescriptor>
): TransformationMethodVisitor(delegate, access, name, desc, null, null) {
override fun performTransformations(methodNode: MethodNode) {
fun AbstractInsnNode.index() = methodNode.instructions.indexOf(this)
fun AbstractInsnNode.isInlineSuspendParameter(): Boolean {
if (this !is VarInsnNode) return false
val index = `var` - (if (methodNode.access and Opcodes.ACC_STATIC != 0) 0 else 1)
return opcode == Opcodes.ALOAD && index < valueParameters.size && InlineUtil.isInlineParameter(valueParameters[index]) &&
valueParameters[index].type.isSuspendFunctionType
}
FixStackMethodTransformer().transform(thisName, methodNode)
val sourceFrames = MethodTransformer.analyze(thisName, methodNode, SourceInterpreter())
val noinlineInvokes = arrayListOf<Pair<AbstractInsnNode, AbstractInsnNode>>()
for (insn in methodNode.instructions.asSequence()) {
if (insn.opcode != Opcodes.INVOKEINTERFACE) continue
insn as MethodInsnNode
if (!isInvokeOnLambda(insn.owner, insn.name)) continue
val frame = sourceFrames[insn.index()] ?: continue
val aload = findReceiverOfInvoke(frame, insn).takeIf { it?.isInlineSuspendParameter() == true } as? VarInsnNode ?: continue
noinlineInvokes.add(insn to aload)
}
surroundInvokesWithSuspendMarkers(methodNode, noinlineInvokes)
}
}

View File

@@ -10,7 +10,9 @@ import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.coroutines.DEBUG_METADATA_ANNOTATION_ASM_TYPE
import org.jetbrains.kotlin.codegen.coroutines.isCapturedSuspendLambda
import org.jetbrains.kotlin.codegen.coroutines.isCoroutineSuperClass
import org.jetbrains.kotlin.codegen.coroutines.isResumeImplMethodName
import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.codegen.serialization.JvmCodegenStringTable
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
@@ -141,7 +143,7 @@ class AnonymousObjectTransformer(
superClassName,
allCapturedParamBuilder.listCaptured()
)
loop@for (next in methodsToTransform) {
loop@ for (next in methodsToTransform) {
val deferringVisitor =
when {
coroutineTransformer.shouldSkip(next) -> continue@loop
@@ -162,9 +164,15 @@ class AnonymousObjectTransformer(
}
deferringMethods.forEach { method ->
val continuationToRemove = CoroutineTransformer.findFakeContinuationConstructorClassName(method.intermediate)
val oldContinuationName = coroutineTransformer.oldContinuationFrom(method.intermediate)
coroutineTransformer.replaceFakesWithReals(method.intermediate)
removeFinallyMarkers(method.intermediate)
method.visitEnd()
if (continuationToRemove != null && coroutineTransformer.safeToRemoveContinuationClass(method.intermediate)) {
transformationResult.addClassToRemove(continuationToRemove)
innerClassNodes.removeIf { it.name == oldContinuationName }
}
}
SourceMapper.flushToClassBuilder(sourceMapper, classBuilder)
@@ -238,7 +246,14 @@ class AnonymousObjectTransformer(
private fun writeOuterInfo(visitor: ClassVisitor) {
val info = inliningContext.callSiteInfo
visitor.visitOuterClass(info.ownerClassName, info.functionName, info.functionDesc)
// Since $$forInline functions are not generated if retransformation is the last one (i.e. call site is not inline)
// link to the function in OUTERCLASS field becomes invalid. However, since $$forInline function always has no-inline
// companion without the suffix, use it.
if (info.isSuspend && info.isInlineOrInsideInline) {
visitor.visitOuterClass(info.ownerClassName, info.functionName?.removeSuffix(FOR_INLINE_SUFFIX), info.functionDesc)
} else {
visitor.visitOuterClass(info.ownerClassName, info.functionName, info.functionDesc)
}
}
private fun inlineMethodAndUpdateGlobalResult(
@@ -282,7 +297,8 @@ class AnonymousObjectTransformer(
transformationInfo.oldClassName,
sourceNode.name,
if (isConstructor) transformationInfo.newConstructorDescriptor else sourceNode.desc,
inliningContext.callSiteInfo.isInlineOrInsideInline
inliningContext.callSiteInfo.isInlineOrInsideInline,
isSuspendFunctionOrLambda(sourceNode)
), null
)
@@ -292,6 +308,12 @@ class AnonymousObjectTransformer(
return result
}
private fun isSuspendFunctionOrLambda(sourceNode: MethodNode): Boolean =
(sourceNode.desc.endsWith(";Lkotlin/coroutines/Continuation;)Ljava/lang/Object;") ||
sourceNode.desc.endsWith(";Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;")) &&
(CoroutineTransformer.findFakeContinuationConstructorClassName(sourceNode) != null ||
languageVersionSettings.isResumeImplMethodName(sourceNode.name.removeSuffix(FOR_INLINE_SUFFIX)))
private fun generateConstructorAndFields(
classBuilder: ClassBuilder,
allCapturedBuilder: ParametersBuilder,

View File

@@ -1,19 +1,14 @@
/*
* Copyright 2010-2016 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.
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.codegen.inline
class InlineCallSiteInfo(val ownerClassName: String, val functionName: String?, val functionDesc: String?, val isInlineOrInsideInline: Boolean)
class InlineCallSiteInfo(
val ownerClassName: String,
val functionName: String?,
val functionDesc: String?,
val isInlineOrInsideInline: Boolean,
val isSuspend: Boolean
)

View File

@@ -153,7 +153,7 @@ class MethodInliner(
LocalVariablesSorter(
resultNode.access,
resultNode.desc,
resultNode
wrapWithMaxLocalCalc(resultNode)
), AsmTypeRemapper(remapper, result)
)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2019 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.
*/
@@ -122,7 +122,11 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
val signature = codegen.state.typeMapper.mapSignatureSkipGeneric(context.functionDescriptor, context.contextKind)
return InlineCallSiteInfo(
parentCodegen.className, signature.asmMethod.name, signature.asmMethod.descriptor, compilationContextFunctionDescriptor.isInlineOrInsideInline()
parentCodegen.className,
signature.asmMethod.name,
signature.asmMethod.descriptor,
compilationContextFunctionDescriptor.isInlineOrInsideInline(),
compilationContextFunctionDescriptor.isSuspend
)
}

View File

@@ -215,6 +215,13 @@ class CoroutineTransformer(
fun unregisterClassBuilder(continuationClassName: String) =
(inliningContext as RegeneratedClassContext).continuationBuilders.remove(continuationClassName)
// If tail-call optimization took place, we do not need continuation class anymore, unless it is used by $$forInline method
fun safeToRemoveContinuationClass(method: MethodNode): Boolean = !generateForInline && !isStateMachine(method)
fun oldContinuationFrom(method: MethodNode): String? =
methods.find { it.name == method.name + FOR_INLINE_SUFFIX && it.desc == method.desc }
?.let { findFakeContinuationConstructorClassName(it) }
companion object {
fun findFakeContinuationConstructorClassName(node: MethodNode): String? {
val marker = node.instructions.asSequence().firstOrNull(::isBeforeFakeContinuationConstructorCallMarker) ?: return null

View File

@@ -96,5 +96,11 @@ open class AggregatedReplStageState<T1, T2>(val state1: IReplStageState<T1>, val
override fun getNextLineNo() = state1.getNextLineNo()
override val currentGeneration: Int get() = state1.currentGeneration
override fun dispose() {
state2.dispose()
state1.dispose()
super.dispose()
}
}

View File

@@ -60,18 +60,21 @@ open class BasicReplStageHistory<T>(override val lock: ReentrantReadWriteLock =
override fun resetTo(id: ILineId): Iterable<ILineId> {
lock.write {
val idx = indexOfFirst { it.id == id }
if (idx < 0) throw java.util.NoSuchElementException("Cannot rest to inexistent line ${id.no}")
return if (idx < lastIndex) {
val removed = asSequence().drop(idx + 1).map { it.id }.toList()
removeRange(idx + 1, size)
currentGeneration.incrementAndGet()
removed
}
else {
currentGeneration.incrementAndGet()
emptyList()
}
return tryResetTo(id) ?: throw NoSuchElementException("Cannot reset to non-existent line ${id.no}")
}
}
protected fun tryResetTo(id: ILineId): List<ILineId>? {
val idx = indexOfFirst { it.id == id }
if (idx < 0) return null
return if (idx < lastIndex) {
val removed = asSequence().drop(idx + 1).map { it.id }.toList()
removeRange(idx + 1, size)
currentGeneration.incrementAndGet()
removed
} else {
currentGeneration.incrementAndGet()
emptyList()
}
}
}

View File

@@ -20,13 +20,11 @@ import java.io.File
import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.write
class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
baseClasspath: Iterable<File>,
baseClassloader: ClassLoader? = Thread.currentThread().contextClassLoader,
private val fallbackScriptArgs: ScriptArgsWithTypes? = null,
repeatingMode: ReplRepeatingMode = ReplRepeatingMode.REPEAT_ONLY_MOST_RECENT
open class GenericReplCompilingEvaluatorBase(
val compiler: ReplCompiler,
val evaluator: ReplEvaluator,
private val fallbackScriptArgs: ScriptArgsWithTypes? = null
) : ReplFullEvaluator {
private val evaluator = GenericReplEvaluator(baseClasspath, baseClassloader, fallbackScriptArgs, repeatingMode)
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = AggregatedReplStageState(compiler.createState(lock), evaluator.createState(lock), lock)
@@ -75,7 +73,7 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
}
override fun eval(state: IReplStageState<*>, compileResult: ReplCompileResult.CompiledClasses, scriptArgs: ScriptArgsWithTypes?, invokeWrapper: InvokeWrapper?): ReplEvalResult =
evaluator.eval(state, compileResult, scriptArgs, invokeWrapper)
evaluator.eval(state, compileResult, scriptArgs, invokeWrapper)
override fun check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult = compiler.check(state, codeLine)
@@ -93,12 +91,24 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
private val evaluator: ReplEvaluator,
private val defaultScriptArgs: ScriptArgsWithTypes?) : Evaluable {
override fun eval(scriptArgs: ScriptArgsWithTypes?, invokeWrapper: InvokeWrapper?): ReplEvalResult =
evaluator.eval(state, compiledCode, scriptArgs ?: defaultScriptArgs, invokeWrapper)
evaluator.eval(state, compiledCode, scriptArgs ?: defaultScriptArgs, invokeWrapper)
}
}
class GenericReplCompilingEvaluator(
compiler: ReplCompiler,
baseClasspath: Iterable<File>,
baseClassloader: ClassLoader? = Thread.currentThread().contextClassLoader,
fallbackScriptArgs: ScriptArgsWithTypes? = null,
repeatingMode: ReplRepeatingMode = ReplRepeatingMode.REPEAT_ONLY_MOST_RECENT
) : GenericReplCompilingEvaluatorBase(
compiler,
GenericReplEvaluator(baseClasspath, baseClassloader, fallbackScriptArgs, repeatingMode),
fallbackScriptArgs
)
private fun AggregatedReplStageState<*, *>.adjustHistories(): Iterable<ILineId>? =
state2.history.peek()?.let {
state1.history.resetTo(it.id)
}
state2.history.peek()?.let {
state1.history.resetTo(it.id)
}
?: state1.history.reset()

View File

@@ -90,7 +90,8 @@ sealed class ReplCompileResult : Serializable {
val classes: List<CompiledClassData>,
val hasResult: Boolean,
val classpathAddendum: List<File>,
val type: String?
val type: String?,
val data: Any? // TODO: temporary; migration to new scripting infrastructure
) : ReplCompileResult() {
companion object { private val serialVersionUID: Long = 2L }
}

View File

@@ -61,6 +61,9 @@ interface IReplStageState<T> {
fun <StateT : IReplStageState<*>> asState(target: Class<out StateT>): StateT =
if (target.isAssignableFrom(this::class.java)) this as StateT
else throw IllegalArgumentException("$this is not an expected instance of IReplStageState")
fun dispose() {
}
}

View File

@@ -300,7 +300,7 @@ class Fir2IrDeclarationStorage(
startOffset, endOffset, origin, symbol,
constructor.name, constructor.visibility,
constructor.returnTypeRef.toIrType(session, this),
false, false, isPrimary
isInline = false, isExternal = false, isPrimary = isPrimary
).bindAndDeclareParameters(constructor, descriptor, setParent, shouldLeaveScope)
}
}

View File

@@ -167,18 +167,18 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
callableName,
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
Flags.IS_EXPECT_PROPERTY.get(flags),
false,
false,
Flags.IS_CONST.get(flags),
Flags.IS_LATEINIT.get(flags),
proto.receiverType(c.typeTable)?.toTypeRef(local),
returnTypeRef,
Flags.IS_VAR.get(flags),
null,
FirDefaultPropertyGetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags))),
FirDefaultPropertySetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags))),
null
isExpect = Flags.IS_EXPECT_PROPERTY.get(flags),
isActual = false,
isOverride = false,
isConst = Flags.IS_CONST.get(flags),
isLateInit = Flags.IS_LATEINIT.get(flags),
receiverTypeRef = proto.receiverType(c.typeTable)?.toTypeRef(local),
returnTypeRef = returnTypeRef,
isVar = Flags.IS_VAR.get(flags),
initializer = null,
getter = FirDefaultPropertyGetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags))),
setter = FirDefaultPropertySetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags))),
delegate = null
).apply {
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.firUnsafe() }
annotations += c.annotationDeserializer.loadPropertyAnnotations(proto, local.nameResolver)
@@ -209,16 +209,16 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
Flags.IS_EXPECT_FUNCTION.get(flags),
false,
false,
Flags.IS_OPERATOR.get(flags),
Flags.IS_INFIX.get(flags),
Flags.IS_INLINE.get(flags),
Flags.IS_TAILREC.get(flags),
Flags.IS_EXTERNAL_FUNCTION.get(flags),
Flags.IS_SUSPEND.get(flags),
proto.receiverType(local.typeTable)?.toTypeRef(local),
proto.returnType(local.typeTable).toTypeRef(local)
isActual = false,
isOverride = false,
isOperator = Flags.IS_OPERATOR.get(flags),
isInfix = Flags.IS_INFIX.get(flags),
isInline = Flags.IS_INLINE.get(flags),
isTailRec = Flags.IS_TAILREC.get(flags),
isExternal = Flags.IS_EXTERNAL_FUNCTION.get(flags),
isSuspend = Flags.IS_SUSPEND.get(flags),
receiverTypeRef = proto.receiverType(local.typeTable)?.toTypeRef(local),
returnTypeRef = proto.returnType(local.typeTable).toTypeRef(local)
).apply {
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.firUnsafe() }
valueParameters += local.memberDeserializer.valueParameters(proto.valueParameterList)

View File

@@ -158,9 +158,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
}
*/
val simpleType = this.asSimpleType() ?: return false
repeat(simpleType.argumentsCount()) { index ->
val argument = simpleType.getArgument(index)
repeat(argumentsCount()) { index ->
val argument = getArgument(index)
if (!argument.isStarProjection() && argument.getType().containsInternal(predicate, visited)) return true
}

View File

@@ -22,7 +22,11 @@ interface SyntheticSymbol : ConeSymbol
class SyntheticPropertySymbol(callableId: CallableId) : FirPropertySymbol(callableId), SyntheticSymbol
class FirSyntheticPropertiesScope(val session: FirSession, val baseScope: FirScope, val typeCalculator: ReturnTypeCalculator) : FirScope {
class FirSyntheticPropertiesScope(
val session: FirSession,
private val baseScope: FirScope,
private val typeCalculator: ReturnTypeCalculator
) : FirScope {
val synthetic: MutableMap<ConeCallableSymbol, ConeVariableSymbol> = mutableMapOf()
@@ -47,18 +51,18 @@ class FirSyntheticPropertiesScope(val session: FirSession, val baseScope: FirSco
name,
fir.visibility,
fir.modality,
false,
false,
false,
false,
false,
null,
returnTypeRef,
true,
null,
FirDefaultPropertyGetter(session, null, returnTypeRef, fir.visibility),
FirDefaultPropertySetter(session, null, returnTypeRef, fir.visibility),
null
isExpect = false,
isActual = false,
isOverride = false,
isConst = false,
isLateInit = false,
receiverTypeRef = null,
returnTypeRef = returnTypeRef,
isVar = true,
initializer = null,
getter = FirDefaultPropertyGetter(session, null, returnTypeRef, fir.visibility),
setter = FirDefaultPropertySetter(session, null, returnTypeRef, fir.visibility),
delegate = null
)
return processor(synthetic)
}

View File

@@ -169,9 +169,9 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider
relativeClassName.shortName(),
Visibilities.PUBLIC,
Modality.OPEN,
false,
false,
ClassKind.CLASS,
isExpect = false,
isActual = false,
classKind = ClassKind.CLASS,
isInner = false,
isCompanion = false,
isData = false,

View File

@@ -435,10 +435,10 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
null,
Name.identifier("it"),
FirResolvedTypeRefImpl(session, null, parameters.single(), emptyList()),
null,
false,
false,
false
defaultValue = null,
isCrossinline = false,
isNoinline = false,
isVararg = false
)
else -> null
}

View File

@@ -144,13 +144,13 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext {
return typeConstructor
}
override fun SimpleTypeMarker.argumentsCount(): Int {
override fun KotlinTypeMarker.argumentsCount(): Int {
require(this is ConeKotlinType)
return this.typeArguments.size
}
override fun SimpleTypeMarker.getArgument(index: Int): TypeArgumentMarker {
override fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker {
require(this is ConeKotlinType)
return this.typeArguments.getOrNull(index)

View File

@@ -1704,6 +1704,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/callableReference/parsingPriorityOfGenericArgumentsVsLess.kt");
}
@TestMetadata("rewriteAtSliceOnGetOperator.kt")
public void testRewriteAtSliceOnGetOperator() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/rewriteAtSliceOnGetOperator.kt");
}
@TestMetadata("sam.kt")
public void testSam() throws Exception {
runTest("compiler/testData/diagnostics/tests/callableReference/sam.kt");
@@ -9703,6 +9708,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/inference/possibleCycleOnConstraints.kt");
}
@TestMetadata("recursiveTypes.kt")
public void testRecursiveTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/recursiveTypes.kt");
}
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/reportAboutUnresolvedReferenceAsUnresolved.kt");
@@ -10004,6 +10014,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/constraints"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("constraintFromVariantTypeWithNestedProjection.kt")
public void testConstraintFromVariantTypeWithNestedProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/constraints/constraintFromVariantTypeWithNestedProjection.kt");
}
@TestMetadata("constraintOnFunctionLiteral.kt")
public void testConstraintOnFunctionLiteral() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/constraints/constraintOnFunctionLiteral.kt");
@@ -10044,6 +10059,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/inference/constraints/kt8879.kt");
}
@TestMetadata("manyConstraintsDueToFlexibleRawTypes.kt")
public void testManyConstraintsDueToFlexibleRawTypes() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/constraints/manyConstraintsDueToFlexibleRawTypes.kt");
}
@TestMetadata("manyConstraintsDueToRecursiveFlexibleTypesWithWildcards.kt")
public void testManyConstraintsDueToRecursiveFlexibleTypesWithWildcards() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/constraints/manyConstraintsDueToRecursiveFlexibleTypesWithWildcards.kt");
}
@TestMetadata("notNullConstraintOnNullableType.kt")
public void testNotNullConstraintOnNullableType() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/constraints/notNullConstraintOnNullableType.kt");
@@ -10189,6 +10214,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
public void testNothingWithCallableReference() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/nothingWithCallableReference.kt");
}
@TestMetadata("platformNothingAsUsefulConstraint.kt")
public void testPlatformNothingAsUsefulConstraint() throws Exception {
runTest("compiler/testData/diagnostics/tests/inference/nothingType/platformNothingAsUsefulConstraint.kt");
}
}
@TestMetadata("compiler/testData/diagnostics/tests/inference/recursiveCalls")
@@ -12358,6 +12388,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/j+k/sam/privateCandidatesWithWrongArguments.kt");
}
@TestMetadata("recursiveSamsAndInvoke.kt")
public void testRecursiveSamsAndInvoke() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/recursiveSamsAndInvoke.kt");
}
@TestMetadata("samOnTypeParameter.kt")
public void testSamOnTypeParameter() throws Exception {
runTest("compiler/testData/diagnostics/tests/j+k/sam/samOnTypeParameter.kt");
@@ -17470,6 +17505,21 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.kt");
}
@TestMetadata("kt29948.kt")
public void testKt29948() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.kt");
}
@TestMetadata("kt31360.kt")
public void testKt31360() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.kt");
}
@TestMetadata("markedReceiverWithCapturedTypeArgument.kt")
public void testMarkedReceiverWithCapturedTypeArgument() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.kt");
}
@TestMetadata("markersIntersection.kt")
public void testMarkersIntersection() throws Exception {
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/markersIntersection.kt");
@@ -22203,9 +22253,9 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/typeParameters/implicitNothingAsTypeParameter.kt");
}
@TestMetadata("implicitNothingAsTypeParameterNI.kt")
public void testImplicitNothingAsTypeParameterNI() throws Exception {
runTest("compiler/testData/diagnostics/tests/typeParameters/implicitNothingAsTypeParameterNI.kt");
@TestMetadata("implicitNothingOnDelegates.kt")
public void testImplicitNothingOnDelegates() throws Exception {
runTest("compiler/testData/diagnostics/tests/typeParameters/implicitNothingOnDelegates.kt");
}
@TestMetadata("misplacedConstraints.kt")
@@ -22346,6 +22396,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/typealias/importFromTypeAliasObject.kt");
}
@TestMetadata("importMemberFromJavaViaAlias.kt")
public void testImportMemberFromJavaViaAlias() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/importMemberFromJavaViaAlias.kt");
}
@TestMetadata("inGenerics.kt")
public void testInGenerics() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/inGenerics.kt");
@@ -22516,6 +22571,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/typealias/simpleTypeAlias.kt");
}
@TestMetadata("starImportOnTypeAlias.kt")
public void testStarImportOnTypeAlias() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/starImportOnTypeAlias.kt");
}
@TestMetadata("starProjection.kt")
public void testStarProjection() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/starProjection.kt");
@@ -22681,6 +22741,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasShouldExpandToClass.kt");
}
@TestMetadata("typeAliasesInImportDirectives.kt")
public void testTypeAliasesInImportDirectives() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasesInImportDirectives.kt");
}
@TestMetadata("typeAliasesInQualifiers.kt")
public void testTypeAliasesInQualifiers() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasesInQualifiers.kt");
}
@TestMetadata("typealiasRhsAnnotations.kt")
public void testTypealiasRhsAnnotations() throws Exception {
runTest("compiler/testData/diagnostics/tests/typealias/typealiasRhsAnnotations.kt");

View File

@@ -1,19 +0,0 @@
/*
* Copyright 2010-2016 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.
*/
package org.jetbrains.kotlin.resolve.jvm
interface GlobalSearchScopeWithModuleSources

View File

@@ -44,7 +44,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.asJava.KtLightClassMarker;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.load.java.JavaClassFinder;
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl;
import org.jetbrains.kotlin.load.java.structure.JavaClass;
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl;
import org.jetbrains.kotlin.name.ClassId;
@@ -126,30 +125,7 @@ public class KotlinJavaPsiFacade {
}
else {
PsiClass aClass = finder.findClass(qualifiedName, scope);
if (aClass != null) {
if (scope instanceof JavaClassFinderImpl.FilterOutKotlinSourceFilesScope) {
GlobalSearchScope baseScope = ((JavaClassFinderImpl.FilterOutKotlinSourceFilesScope) scope).getBase();
boolean isSourcesScope = baseScope instanceof GlobalSearchScopeWithModuleSources;
if (!isSourcesScope) {
Object originalFinder = (finder instanceof KotlinPsiElementFinderWrapperImpl)
? ((KotlinPsiElementFinderWrapperImpl) finder).getOriginal()
: finder;
// Temporary fix for #KT-12402
boolean isAndroidDataBindingClassWriter = originalFinder.getClass().getName()
.equals("com.android.tools.idea.databinding.DataBindingClassFinder");
boolean isAndroidDataBindingComponentClassWriter = originalFinder.getClass().getName()
.equals("com.android.tools.idea.databinding.DataBindingComponentClassFinder");
if (isAndroidDataBindingClassWriter || isAndroidDataBindingComponentClassWriter) {
continue;
}
}
}
return createJavaClass(classId, aClass);
}
if (aClass != null) return createJavaClass(classId, aClass);
}
}
@@ -341,10 +317,6 @@ public class KotlinJavaPsiFacade {
this.finder = finder;
}
public PsiElementFinder getOriginal() {
return finder;
}
@Override
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
return finder.findClass(qualifiedName, scope);

View File

@@ -60,8 +60,7 @@ class SamAdapterFunctionsScope(
private val deprecationResolver: DeprecationResolver,
private val lookupTracker: LookupTracker
) : SyntheticScope.Default() {
private val samViaSyntheticScopeDisabled = languageVersionSettings.supportsFeature(LanguageFeature.NewInference) &&
languageVersionSettings.supportsFeature(LanguageFeature.SamConversionForKotlinFunctions)
private val samViaSyntheticScopeDisabled = languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
private val extensionForFunction =
storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function ->

View File

@@ -508,7 +508,7 @@ class ControlFlowInformationProvider private constructor(
}
}
if (descriptor == null) {
val descriptors = trace.get(BindingContext.AMBIGUOUS_REFERENCE_TARGET, operationReference) ?: emptyList()
val descriptors = trace.get(AMBIGUOUS_REFERENCE_TARGET, operationReference) ?: emptyList<DeclarationDescriptor>()
for (referenceDescriptor in descriptors) {
if ((referenceDescriptor as? FunctionDescriptor)?.returnType?.let { KotlinBuiltIns.isUnit(it) } == true) {
hasReassignMethodReturningUnit = true

View File

@@ -67,7 +67,7 @@ private fun ESValue.toDataFlowValue(builtIns: KotlinBuiltIns): DataFlowValue? =
is ESDataFlowValue -> dataFlowValue
is ESConstant -> when (constantReference) {
ConstantReference.NULL -> DataFlowValue.nullValue(builtIns)
else -> DataFlowValue(IdentifierInfo.NO, type)
else -> DataFlowValue(IdentifierInfo.NO, type.toKotlinType(builtIns))
}
else -> null
}

View File

@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.contracts.model.Computation
import org.jetbrains.kotlin.contracts.model.ESComponents
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.contracts.model.MutableContextInfo
import org.jetbrains.kotlin.contracts.model.functors.EqualsFunctor
@@ -46,13 +45,6 @@ class EffectSystem(
val dataFlowValueFactory: DataFlowValueFactory,
val builtIns: KotlinBuiltIns
) {
// Lazy because this code is executed when the container is set up (before any resolution starts),
// so builtins are not fully functional yet at that moment
val components: ESComponents by lazy(LazyThreadSafetyMode.NONE) { ESComponents(builtIns) }
val constants: ESConstants
get() = components.constants
fun getDataFlowInfoForFinishedCall(
resolvedCall: ResolvedCall<*>,
bindingTrace: BindingTrace,
@@ -64,7 +56,7 @@ class EffectSystem(
val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return DataFlowInfo.EMPTY
if (callExpression is KtDeclaration) return DataFlowInfo.EMPTY
val resultContextInfo = getContextInfoWhen(ESReturns(constants.wildcard), callExpression, bindingTrace, moduleDescriptor)
val resultContextInfo = getContextInfoWhen(ESReturns(ESConstants.wildcard), callExpression, bindingTrace, moduleDescriptor)
return resultContextInfo.toDataFlowInfo(languageVersionSettings, builtIns)
}
@@ -83,10 +75,10 @@ class EffectSystem(
val rightComputation =
getNonTrivialComputation(rightExpression, bindingTrace, moduleDescriptor) ?: return ConditionalDataFlowInfo.EMPTY
val effects = EqualsFunctor(constants, false).invokeWithArguments(leftComputation, rightComputation)
val effects = EqualsFunctor(false).invokeWithArguments(leftComputation, rightComputation)
val equalsContextInfo = InfoCollector(ESReturns(constants.trueValue), constants).collectFromSchema(effects)
val notEqualsContextInfo = InfoCollector(ESReturns(constants.falseValue), constants).collectFromSchema(effects)
val equalsContextInfo = InfoCollector(ESReturns(ESConstants.trueValue), builtIns).collectFromSchema(effects)
val notEqualsContextInfo = InfoCollector(ESReturns(ESConstants.falseValue), builtIns).collectFromSchema(effects)
return ConditionalDataFlowInfo(
equalsContextInfo.toDataFlowInfo(languageVersionSettings, builtIns),
@@ -101,7 +93,7 @@ class EffectSystem(
val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return
if (callExpression is KtDeclaration) return
val resultingContextInfo = getContextInfoWhen(ESReturns(constants.wildcard), callExpression, bindingTrace, moduleDescriptor)
val resultingContextInfo = getContextInfoWhen(ESReturns(ESConstants.wildcard), callExpression, bindingTrace, moduleDescriptor)
for (effect in resultingContextInfo.firedEffects) {
val callsEffect = effect as? ESCalls ?: continue
val lambdaExpression = (callsEffect.callable as? ESLambda)?.lambda ?: continue
@@ -118,7 +110,7 @@ class EffectSystem(
if (!languageVersionSettings.supportsFeature(LanguageFeature.UseReturnsEffect)) return DataFlowInfo.EMPTY
if (condition == null) return DataFlowInfo.EMPTY
return getContextInfoWhen(ESReturns(constants.booleanValue(value)), condition, bindingTrace, moduleDescriptor)
return getContextInfoWhen(ESReturns(ESConstants.booleanValue(value)), condition, bindingTrace, moduleDescriptor)
.toDataFlowInfo(languageVersionSettings, moduleDescriptor.builtIns)
}
@@ -133,11 +125,11 @@ class EffectSystem(
}
if (isInContractBlock) return MutableContextInfo.EMPTY
val computation = getNonTrivialComputation(expression, bindingTrace, moduleDescriptor) ?: return MutableContextInfo.EMPTY
return InfoCollector(observedEffect, constants).collectFromSchema(computation.effects)
return InfoCollector(observedEffect, builtIns).collectFromSchema(computation.effects)
}
private fun getNonTrivialComputation(expression: KtExpression, trace: BindingTrace, moduleDescriptor: ModuleDescriptor): Computation? {
val visitor = EffectsExtractingVisitor(trace, moduleDescriptor, dataFlowValueFactory, constants, languageVersionSettings)
val visitor = EffectsExtractingVisitor(trace, moduleDescriptor, dataFlowValueFactory, languageVersionSettings)
return visitor.extractOrGetCached(expression).takeUnless { it == UNKNOWN_COMPUTATION }
}
}

View File

@@ -25,10 +25,8 @@ import org.jetbrains.kotlin.contracts.model.ConditionalEffect
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.contracts.model.Functor
import org.jetbrains.kotlin.contracts.model.functors.*
import org.jetbrains.kotlin.contracts.model.structure.CallComputation
import org.jetbrains.kotlin.contracts.model.structure.ESConstants
import org.jetbrains.kotlin.contracts.model.structure.UNKNOWN_COMPUTATION
import org.jetbrains.kotlin.contracts.model.structure.isReturns
import org.jetbrains.kotlin.contracts.model.structure.*
import org.jetbrains.kotlin.contracts.model.visitors.Reducer
import org.jetbrains.kotlin.contracts.parsing.isEqualsDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
@@ -58,10 +56,10 @@ class EffectsExtractingVisitor(
private val trace: BindingTrace,
private val moduleDescriptor: ModuleDescriptor,
private val dataFlowValueFactory: DataFlowValueFactory,
private val constants: ESConstants,
private val languageVersionSettings: LanguageVersionSettings
) : KtVisitor<Computation, Unit>() {
private val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns
private val reducer: Reducer = Reducer(builtIns)
fun extractOrGetCached(element: KtElement): Computation {
trace[BindingContext.EXPRESSION_EFFECTS, element]?.let { return it }
@@ -77,17 +75,20 @@ class EffectsExtractingVisitor(
val descriptor = resolvedCall.resultingDescriptor
return when {
descriptor.isEqualsDescriptor() -> CallComputation(
builtIns.booleanType,
EqualsFunctor(constants, false).invokeWithArguments(arguments)
ESBooleanType,
EqualsFunctor(false).invokeWithArguments(arguments, reducer)
)
descriptor is ValueDescriptor -> ESVariableWithDataFlowValue(
descriptor,
(element as KtExpression).createDataFlowValue() ?: return UNKNOWN_COMPUTATION
)
descriptor is FunctionDescriptor -> CallComputation(
descriptor.returnType,
descriptor.getFunctor()?.invokeWithArguments(arguments) ?: emptyList()
)
descriptor is FunctionDescriptor -> {
val esType = descriptor.returnType?.toESType()
CallComputation(
esType,
descriptor.getFunctor()?.invokeWithArguments(arguments, reducer) ?: emptyList()
)
}
else -> UNKNOWN_COMPUTATION
}
}
@@ -111,18 +112,18 @@ class EffectsExtractingVisitor(
val value: Any? = compileTimeConstant.getValue(type)
return when (value) {
is Boolean -> constants.booleanValue(value)
null -> constants.nullValue
is Boolean -> ESConstants.booleanValue(value)
null -> ESConstants.nullValue
else -> UNKNOWN_COMPUTATION
}
}
override fun visitIsExpression(expression: KtIsExpression, data: Unit): Computation {
val rightType: KotlinType = trace[BindingContext.TYPE, expression.typeReference] ?: return UNKNOWN_COMPUTATION
val rightType = trace[BindingContext.TYPE, expression.typeReference]?.toESType() ?: return UNKNOWN_COMPUTATION
val arg = extractOrGetCached(expression.leftHandSide)
return CallComputation(
builtIns.booleanType,
IsFunctor(constants, rightType, expression.isNegated).invokeWithArguments(listOf(arg))
ESBooleanType,
IsFunctor(rightType, expression.isNegated).invokeWithArguments(listOf(arg), reducer)
)
}
@@ -134,7 +135,7 @@ class EffectsExtractingVisitor(
// null bypassing function's contract, so we have to filter them out
fun ESEffect.containsReturnsNull(): Boolean =
isReturns { value == constants.nullValue } || this is ConditionalEffect && this.simpleEffect.containsReturnsNull()
isReturns { value == ESConstants.nullValue } || this is ConditionalEffect && this.simpleEffect.containsReturnsNull()
val effectsWithoutReturnsNull = computation.effects.filter { !it.containsReturnsNull() }
return CallComputation(computation.type, effectsWithoutReturnsNull)
@@ -147,10 +148,10 @@ class EffectsExtractingVisitor(
val args = listOf(left, right)
return when (expression.operationToken) {
KtTokens.EXCLEQ -> CallComputation(builtIns.booleanType, EqualsFunctor(constants, true).invokeWithArguments(args))
KtTokens.EQEQ -> CallComputation(builtIns.booleanType, EqualsFunctor(constants, false).invokeWithArguments(args))
KtTokens.ANDAND -> CallComputation(builtIns.booleanType, AndFunctor(constants).invokeWithArguments(args))
KtTokens.OROR -> CallComputation(builtIns.booleanType, OrFunctor(constants).invokeWithArguments(args))
KtTokens.EXCLEQ -> CallComputation(ESBooleanType, EqualsFunctor(true).invokeWithArguments(args, reducer))
KtTokens.EQEQ -> CallComputation(ESBooleanType, EqualsFunctor(false).invokeWithArguments(args, reducer))
KtTokens.ANDAND -> CallComputation(ESBooleanType, AndFunctor().invokeWithArguments(args, reducer))
KtTokens.OROR -> CallComputation(ESBooleanType, OrFunctor().invokeWithArguments(args, reducer))
else -> UNKNOWN_COMPUTATION
}
}
@@ -158,7 +159,7 @@ class EffectsExtractingVisitor(
override fun visitUnaryExpression(expression: KtUnaryExpression, data: Unit): Computation {
val arg = extractOrGetCached(expression.baseExpression ?: return UNKNOWN_COMPUTATION)
return when (expression.operationToken) {
KtTokens.EXCL -> CallComputation(builtIns.booleanType, NotFunctor(constants).invokeWithArguments(arg))
KtTokens.EXCL -> CallComputation(ESBooleanType, NotFunctor().invokeWithArguments(arg))
else -> UNKNOWN_COMPUTATION
}
}

View File

@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.calls.CallResolver;
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
@@ -303,7 +304,9 @@ public class BodyResolver {
if (delegateExpression != null) {
LexicalScope scope = scopeForConstructor == null ? scopeForMemberResolution : scopeForConstructor;
KotlinType expectedType = supertype != null ? supertype : NO_EXPECTED_TYPE;
typeInferrer.getType(scope, delegateExpression, expectedType, outerDataFlowInfo, trace);
typeInferrer.getType(
scope, delegateExpression, expectedType, outerDataFlowInfo, InferenceSession.Companion.getDefault(), trace
);
}
if (descriptor.isExpect()) {
@@ -660,7 +663,8 @@ public class BodyResolver {
PreliminaryDeclarationVisitor.Companion.createForDeclaration(
(KtDeclaration) anonymousInitializer.getParent().getParent(), trace, languageVersionSettings);
expressionTypingServices.getTypeInfo(
scopeForInitializers, body, NO_EXPECTED_TYPE, outerDataFlowInfo, trace, /*isStatement = */true
scopeForInitializers, body, NO_EXPECTED_TYPE, outerDataFlowInfo,
InferenceSession.Companion.getDefault(), trace, /*isStatement = */true
);
}
processModifiersOnInitializer(anonymousInitializer, scopeForInitializers);
@@ -864,6 +868,7 @@ public class BodyResolver {
propertyDescriptor,
delegateExpression,
propertyHeaderScope,
InferenceSession.Companion.getDefault(),
trace);
}
@@ -878,7 +883,7 @@ public class BodyResolver {
KotlinType expectedTypeForInitializer = property.getTypeReference() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
if (propertyDescriptor.getCompileTimeInitializer() == null) {
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer,
outerDataFlowInfo, trace);
outerDataFlowInfo, InferenceSession.Companion.getDefault(), trace);
}
}

View File

@@ -53,14 +53,14 @@ class DelegatedPropertyInferenceSession(
?: builtIns.nullableNothingType
val valueParameterForThis = descriptor.valueParameters.getOrNull(0) ?: return
val substitutedType = substitutor.substituteKeepAnnotations(valueParameterForThis.type.unwrap())
val substitutedType = substitutor.safeSubstitute(valueParameterForThis.type.unwrap())
commonSystem.addSubtypeConstraint(typeOfThis.unwrap(), substitutedType, DelegatedPropertyConstraintPosition(atom))
}
private fun ResolvedCallAtom.addConstraintsForGetValueMethod(commonSystem: ConstraintSystemBuilder) {
if (expectedType != null) {
val unsubstitutedReturnType = candidateDescriptor.returnType?.unwrap() ?: return
val substitutedReturnType = substitutor.substituteKeepAnnotations(unsubstitutedReturnType)
val substitutedReturnType = substitutor.safeSubstitute(unsubstitutedReturnType)
commonSystem.addSubtypeConstraint(substitutedReturnType, expectedType, DelegatedPropertyConstraintPosition(atom))
}
@@ -71,7 +71,7 @@ class DelegatedPropertyInferenceSession(
private fun ResolvedCallAtom.addConstraintsForSetValueMethod(commonSystem: ConstraintSystemBuilder) {
if (expectedType != null) {
val unsubstitutedParameterType = candidateDescriptor.valueParameters.getOrNull(2)?.type?.unwrap() ?: return
val substitutedParameterType = substitutor.substituteKeepAnnotations(unsubstitutedParameterType)
val substitutedParameterType = substitutor.safeSubstitute(unsubstitutedParameterType)
commonSystem.addSubtypeConstraint(expectedType, substitutedParameterType, DelegatedPropertyConstraintPosition(atom))
}

View File

@@ -72,6 +72,7 @@ class DelegatedPropertyResolver(
variableDescriptor: VariableDescriptorWithAccessors,
delegateExpression: KtExpression,
propertyHeaderScope: LexicalScope,
inferenceSession: InferenceSession,
trace: BindingTrace
) {
property.getter?.let { getter ->
@@ -86,8 +87,9 @@ class DelegatedPropertyResolver(
ScopeUtils.makeScopeForPropertyInitializer(propertyHeaderScope, variableDescriptor)
else propertyHeaderScope
val byExpressionType =
resolveDelegateExpression(delegateExpression, property, variableDescriptor, initializerScope, trace, outerDataFlowInfo)
val byExpressionType =resolveDelegateExpression(
delegateExpression, property, variableDescriptor, initializerScope, trace, outerDataFlowInfo, inferenceSession
)
resolveProvideDelegateMethod(variableDescriptor, delegateExpression, byExpressionType, trace, initializerScope, outerDataFlowInfo)
val delegateType = getResolvedDelegateType(variableDescriptor, delegateExpression, byExpressionType, trace)
@@ -455,7 +457,8 @@ class DelegatedPropertyResolver(
variableDescriptor: VariableDescriptorWithAccessors,
scopeForDelegate: LexicalScope,
trace: BindingTrace,
dataFlowInfo: DataFlowInfo
dataFlowInfo: DataFlowInfo,
inferenceSession: InferenceSession
): KotlinType {
val traceToResolveDelegatedProperty = TemporaryBindingTrace.create(trace, "Trace to resolve delegated property")
@@ -475,12 +478,13 @@ class DelegatedPropertyResolver(
}
val delegatedPropertyTypeFromNI =
resolveWithNewInference(delegateExpression, variableDescriptor, scopeForDelegate, trace, dataFlowInfo)
resolveWithNewInference(delegateExpression, variableDescriptor, scopeForDelegate, trace, dataFlowInfo, inferenceSession)
val delegateType = expressionTypingServices.safeGetType(
scopeForDelegate,
delegateExpression,
delegatedPropertyTypeFromNI ?: NO_EXPECTED_TYPE,
dataFlowInfo,
inferenceSession,
traceToResolveDelegatedProperty
)
@@ -494,7 +498,8 @@ class DelegatedPropertyResolver(
variableDescriptor: VariableDescriptorWithAccessors,
scopeForDelegate: LexicalScope,
trace: BindingTrace,
dataFlowInfo: DataFlowInfo
dataFlowInfo: DataFlowInfo,
inferenceSession: InferenceSession
): KotlinType? {
if (!languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) return null
@@ -503,7 +508,7 @@ class DelegatedPropertyResolver(
val traceToResolveDelegatedProperty = TemporaryBindingTrace.create(trace, "Trace to resolve delegated property")
val delegateTypeInfo = expressionTypingServices.getTypeInfo(
scopeForDelegate, delegateExpression, NO_EXPECTED_TYPE, dataFlowInfo,
scopeForDelegate, delegateExpression, NO_EXPECTED_TYPE, dataFlowInfo, inferenceSession,
traceToResolveDelegatedProperty, false, delegateExpression, ContextDependency.DEPENDENT
)

View File

@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory;
@@ -798,7 +799,8 @@ public class DescriptorResolver {
@NotNull LexicalScope scopeForInitializerResolution,
@NotNull KtDestructuringDeclarationEntry entry,
@NotNull BindingTrace trace,
@NotNull DataFlowInfo dataFlowInfo
@NotNull DataFlowInfo dataFlowInfo,
@NotNull InferenceSession inferenceSession
) {
KtDestructuringDeclaration destructuringDeclaration = (KtDestructuringDeclaration) entry.getParent();
KtExpression initializer = destructuringDeclaration.getInitializer();
@@ -819,6 +821,7 @@ public class DescriptorResolver {
entry,
trace,
dataFlowInfo,
inferenceSession,
VariableAsPropertyInfo.Companion.createFromDestructuringDeclarationEntry(componentType));
}
@@ -842,7 +845,8 @@ public class DescriptorResolver {
@NotNull LexicalScope scopeForInitializerResolution,
@NotNull KtProperty property,
@NotNull BindingTrace trace,
@NotNull DataFlowInfo dataFlowInfo
@NotNull DataFlowInfo dataFlowInfo,
@NotNull InferenceSession inferenceSession
) {
return resolveAsPropertyDescriptor(
containingDeclaration,
@@ -851,6 +855,7 @@ public class DescriptorResolver {
property,
trace,
dataFlowInfo,
inferenceSession,
VariableAsPropertyInfo.Companion.createFromProperty(property));
}
@@ -862,6 +867,7 @@ public class DescriptorResolver {
@NotNull KtVariableDeclaration variableDeclaration,
@NotNull BindingTrace trace,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull InferenceSession inferenceSession,
@NotNull VariableAsPropertyInfo propertyInfo
) {
KtModifierList modifierList = variableDeclaration.getModifierList();
@@ -962,7 +968,8 @@ public class DescriptorResolver {
KotlinType propertyType = propertyInfo.getVariableType();
KotlinType typeIfKnown = propertyType != null ? propertyType : variableTypeAndInitializerResolver.resolveTypeNullable(
propertyDescriptor, scopeForInitializer,
variableDeclaration, dataFlowInfo, /* local = */ trace, false
variableDeclaration, dataFlowInfo, inferenceSession,
trace, /* local = */ false
);
PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(
@@ -980,7 +987,7 @@ public class DescriptorResolver {
assert type != null : "At least getter type must be initialized via resolvePropertyGetterDescriptor";
variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(
propertyDescriptor, scopeForInitializer, variableDeclaration, dataFlowInfo, type, trace
propertyDescriptor, scopeForInitializer, variableDeclaration, dataFlowInfo, type, inferenceSession, trace
);
propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(container), receiverDescriptor);

View File

@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPsiUtil
import org.jetbrains.kotlin.psi.KtVariableDeclaration
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
@@ -74,7 +75,8 @@ class LocalVariableResolver(
context.trace.report(LOCAL_VARIABLE_WITH_SETTER.on(setter))
}
val propertyDescriptor = resolveLocalVariableDescriptor(scope, property, context.dataFlowInfo, context.trace)
val propertyDescriptor =
resolveLocalVariableDescriptor(scope, property, context.dataFlowInfo, context.inferenceSession, context.trace)
val delegateExpression = property.delegateExpression
if (delegateExpression != null) {
@@ -94,6 +96,7 @@ class LocalVariableResolver(
propertyDescriptor,
delegateExpression,
typingContext.scope,
typingContext.inferenceSession,
typingContext.trace
)
propertyDescriptor.getter?.updateAccessorFlagsFromResolvedCallForDelegatedProperty(typingContext.trace)
@@ -153,6 +156,7 @@ class LocalVariableResolver(
scope: LexicalScope,
variable: KtVariableDeclaration,
dataFlowInfo: DataFlowInfo,
inferenceSession: InferenceSession,
trace: BindingTrace
): VariableDescriptor {
val containingDeclaration = scope.ownerDescriptor
@@ -176,7 +180,9 @@ class LocalVariableResolver(
variable is KtProperty && variable.hasDelegate()
)
// For a local variable the type must not be deferred
type = variableTypeAndInitializerResolver.resolveType(propertyDescriptor, scope, variable, dataFlowInfo, trace, local = true)
type = variableTypeAndInitializerResolver.resolveType(
propertyDescriptor, scope, variable, dataFlowInfo, inferenceSession, trace, local = true
)
val receiverParameter = (containingDeclaration as ScriptDescriptor).thisAsReceiverParameter
propertyDescriptor.setType(type, emptyList<TypeParameterDescriptor>(), receiverParameter, null)
@@ -186,11 +192,14 @@ class LocalVariableResolver(
} else {
val variableDescriptor = resolveLocalVariableDescriptorWithType(scope, variable, null, trace)
// For a local variable the type must not be deferred
type = variableTypeAndInitializerResolver.resolveType(variableDescriptor, scope, variable, dataFlowInfo, trace, local = true)
type = variableTypeAndInitializerResolver.resolveType(
variableDescriptor, scope, variable, dataFlowInfo, inferenceSession, trace, local = true
)
variableDescriptor.setOutType(type)
result = variableDescriptor
}
variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(result, scope, variable, dataFlowInfo, type, trace)
variableTypeAndInitializerResolver
.setConstantForVariableIfNeeded(result, scope, variable, dataFlowInfo, type, inferenceSession, trace)
// Type annotations also should be resolved
ForceResolveUtil.forceResolveAllContents(type.annotations)
return result

View File

@@ -231,7 +231,7 @@ class QualifiedExpressionResolver {
val packageOrClassDescriptor = resolveToPackageOrClass(
path, moduleDescriptor, trace, packageFragmentForCheck,
scopeForFirstPart = null, position = QualifierPosition.IMPORT
) ?: return null
).classDescriptorFromTypeAlias() ?: return null
if (packageOrClassDescriptor is ClassDescriptor && packageOrClassDescriptor.kind.isSingleton && lastPart.expression != null) {
trace.report(
@@ -249,6 +249,10 @@ class QualifiedExpressionResolver {
}
}
private fun DeclarationDescriptor?.classDescriptorFromTypeAlias(): DeclarationDescriptor? {
return if (this is TypeAliasDescriptor) classDescriptor else this
}
private fun computePackageFragmentToCheck(
containingFile: KtFile,
packageFragmentForVisibilityCheck: PackageFragmentDescriptor?

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2010-2019 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.resolve
import org.jetbrains.kotlin.contracts.description.ContractProviderKey
import org.jetbrains.kotlin.contracts.description.LazyContractProvider
import org.jetbrains.kotlin.contracts.parsing.isContractCallDescriptor
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.psi.Call
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.psiUtil.isContractDescriptionCallPsiCheck
import org.jetbrains.kotlin.psi.psiUtil.isFirstStatement
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
/*
* See KT-26386 and KT-30410
*/
fun disableContractsInsideContractsBlock(call: Call, descriptor: CallableDescriptor?, scope: LexicalScope, trace: BindingTrace) {
call.callElement.safeAs<KtExpression>()?.let { callExpression ->
if (callExpression.isFirstStatement() && callExpression.isContractDescriptionCallPsiCheck()) {
if (descriptor?.isContractCallDescriptor() != true) {
scope.ownerDescriptor
.safeAs<FunctionDescriptor>()
?.getUserData(ContractProviderKey)
?.safeAs<LazyContractProvider>()
?.setContractDescription(null)
} else {
trace.record(BindingContext.IS_CONTRACT_DECLARATION_BLOCK, callExpression, true)
}
}
}
}

View File

@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtVariableDeclaration
import org.jetbrains.kotlin.resolve.DescriptorResolver.transformAnonymousTypeIfNeeded
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
@@ -44,10 +45,13 @@ class VariableTypeAndInitializerResolver(
scopeForInitializer: LexicalScope,
variable: KtVariableDeclaration,
dataFlowInfo: DataFlowInfo,
inferenceSession: InferenceSession,
trace: BindingTrace,
local: Boolean
): KotlinType {
resolveTypeNullable(variableDescriptor, scopeForInitializer, variable, dataFlowInfo, trace, local)?.let { return it }
resolveTypeNullable(
variableDescriptor, scopeForInitializer, variable, dataFlowInfo, inferenceSession, trace, local
)?.let { return it }
if (local) {
trace.report(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER.on(variable))
@@ -61,6 +65,7 @@ class VariableTypeAndInitializerResolver(
scopeForInitializer: LexicalScope,
variable: KtVariableDeclaration,
dataFlowInfo: DataFlowInfo,
inferenceSession: InferenceSession,
trace: BindingTrace,
local: Boolean
): KotlinType? {
@@ -70,7 +75,9 @@ class VariableTypeAndInitializerResolver(
!variable.hasInitializer() && variable is KtProperty && variableDescriptor is VariableDescriptorWithAccessors &&
variable.hasDelegateExpression() ->
resolveDelegatedPropertyType(variable, variableDescriptor, scopeForInitializer, dataFlowInfo, trace, local)
resolveDelegatedPropertyType(
variable, variableDescriptor, scopeForInitializer, dataFlowInfo, inferenceSession, trace, local
)
variable.hasInitializer() -> when {
!local ->
@@ -81,12 +88,13 @@ class VariableTypeAndInitializerResolver(
variable, trace,
expressionTypingServices.languageVersionSettings
)
val initializerType =
resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
val initializerType = resolveInitializerType(
scopeForInitializer, variable.initializer!!, dataFlowInfo, inferenceSession, trace, local
)
transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace, anonymousTypeTransformers)
}
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, inferenceSession, trace, local)
}
else -> null
@@ -99,6 +107,7 @@ class VariableTypeAndInitializerResolver(
variable: KtVariableDeclaration,
dataFlowInfo: DataFlowInfo,
variableType: KotlinType,
inferenceSession: InferenceSession,
trace: BindingTrace
) {
if (!variable.hasInitializer() || variable.isVar) return
@@ -111,7 +120,8 @@ class VariableTypeAndInitializerResolver(
)) return@computeInitializer null
val initializer = variable.initializer
val initializerType = expressionTypingServices.safeGetType(scope, initializer!!, variableType, dataFlowInfo, trace)
val initializerType =
expressionTypingServices.safeGetType(scope, initializer!!, variableType, dataFlowInfo, inferenceSession, trace)
val constant = constantExpressionEvaluator.evaluateExpression(initializer, trace, initializerType)
?: return@computeInitializer null
@@ -131,12 +141,13 @@ class VariableTypeAndInitializerResolver(
variableDescriptor: VariableDescriptorWithAccessors,
scopeForInitializer: LexicalScope,
dataFlowInfo: DataFlowInfo,
inferenceSession: InferenceSession,
trace: BindingTrace,
local: Boolean
) = wrappedTypeFactory.createRecursionIntolerantDeferredType(trace) {
val delegateExpression = property.delegateExpression!!
val type = delegatedPropertyResolver.resolveDelegateExpression(
delegateExpression, property, variableDescriptor, scopeForInitializer, trace, dataFlowInfo
delegateExpression, property, variableDescriptor, scopeForInitializer, trace, dataFlowInfo, inferenceSession
)
val getterReturnType = delegatedPropertyResolver.getGetValueMethodReturnType(
@@ -153,10 +164,13 @@ class VariableTypeAndInitializerResolver(
scope: LexicalScope,
initializer: KtExpression,
dataFlowInfo: DataFlowInfo,
inferenceSession: InferenceSession,
trace: BindingTrace,
local: Boolean
): KotlinType {
val inferredType = expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace)
val inferredType = expressionTypingServices.safeGetType(
scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, inferenceSession, trace
)
val approximatedType = approximateType(inferredType, local)
return declarationReturnTypeSanitizer.sanitizeReturnType(approximatedType, wrappedTypeFactory, trace, languageVersionSettings)
}

View File

@@ -135,19 +135,7 @@ class CallCompleter(
context: BasicCallResolutionContext,
tracing: TracingStrategy
) {
context.call.callElement.safeAs<KtExpression>()?.let { callExpression ->
if (callExpression.isFirstStatement() && callExpression.isContractDescriptionCallPsiCheck()) {
if (resolvedCall?.resultingDescriptor?.isContractCallDescriptor() != true) {
context.scope.ownerDescriptor
.safeAs<FunctionDescriptor>()
?.getUserData(ContractProviderKey)
?.safeAs<LazyContractProvider>()
?.setContractDescription(null)
} else {
context.trace.record(BindingContext.IS_CONTRACT_DECLARATION_BLOCK, callExpression, true)
}
}
}
disableContractsInsideContractsBlock(context.call, resolvedCall?.resultingDescriptor, context.scope, context.trace)
if (resolvedCall == null || resolvedCall.isCompleted || resolvedCall.constraintSystem == null) {
completeArguments(context, results)

View File

@@ -350,7 +350,7 @@ public class CallResolver {
);
}
KotlinType calleeType = expressionTypingServices.safeGetType(
context.scope, calleeExpression, expectedType, context.dataFlowInfo, context.trace);
context.scope, calleeExpression, expectedType, context.dataFlowInfo, context.inferenceSession, context.trace);
ExpressionReceiver expressionReceiver = ExpressionReceiver.Companion.create(calleeExpression, calleeType, context.trace.getBindingContext());
Call call = new CallTransformer.CallForImplicitInvoke(context.call.getExplicitReceiver(), expressionReceiver, context.call,

View File

@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.resolve.calls
import com.intellij.psi.util.PsiUtil
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.INVOKE_ON
import org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.NON_KOTLIN_FUNCTION
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isNull
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
@@ -128,6 +130,17 @@ class DiagnosticReporterByTrackingStrategy(
trace.report(UNRESOLVED_REFERENCE.on(it.callableReference, it.callableReference))
}
}
ArgumentTypeMismatchDiagnostic::class.java -> {
require(diagnostic is ArgumentTypeMismatchDiagnostic)
reportIfNonNull(callArgument.safeAs<PSIKotlinCallArgument>()?.valueArgument?.getArgumentExpression()) {
if (it.isNull()) {
trace.report(NULL_FOR_NONNULL_TYPE.on(it, diagnostic.expectedType))
} else {
trace.report(TYPE_MISMATCH.on(it, diagnostic.expectedType, diagnostic.actualType))
}
}
}
}
}

View File

@@ -31,7 +31,12 @@ object DslScopeViolationCallChecker : CallChecker {
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.DslMarkersSupport)) return
val callImplicitReceivers = resolvedCall.getImplicitReceivers()
for (callImplicitReceiver in callImplicitReceivers) {
val originalReceivers = if (context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference))
callImplicitReceivers.map { it.original }
else
callImplicitReceivers
for (callImplicitReceiver in originalReceivers) {
checkCallImplicitReceiver(callImplicitReceiver, resolvedCall, reportOn, context)
}
}

View File

@@ -9,8 +9,11 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.types.DeferredType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils
import org.jetbrains.kotlin.types.typeUtil.isNothing
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
private val SPECIAL_FUNCTION_NAMES = ControlStructureTypingUtils.ResolveConstruct.values().map { it.specialFunctionName }.toSet()
@@ -32,16 +35,21 @@ object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
* }
*/
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
if (resolvedCall.candidateDescriptor.name !in SPECIAL_FUNCTION_NAMES && resolvedCall.call.typeArguments.isEmpty()) {
val resultingDescriptor = resolvedCall.resultingDescriptor
val inferredReturnType = resultingDescriptor.returnType
if (inferredReturnType is DeferredType)
return
if (resultingDescriptor.name !in SPECIAL_FUNCTION_NAMES && resolvedCall.call.typeArguments.isEmpty()) {
val lambdasFromArgumentsReturnTypes =
resolvedCall.candidateDescriptor.valueParameters.filter { it.type.isFunctionType }
.map { it.returnType?.arguments?.last()?.type }.toSet()
val unsubstitutedReturnType = resultingDescriptor.original.returnType
val expectedType = context.resolutionContext.expectedType
val hasImplicitNothing = inferredReturnType?.isNothing() == true &&
unsubstitutedReturnType?.isTypeParameter() == true &&
(TypeUtils.noExpectedType(expectedType) || !expectedType.isNothing())
val hasImplicitNothingExceptLambdaReturnTypes = resolvedCall.typeArguments.any { (unsubstitutedType, resultingType) ->
resultingType.isNothing() && unsubstitutedType.defaultType !in lambdasFromArgumentsReturnTypes
}
if (hasImplicitNothingExceptLambdaReturnTypes) {
if (hasImplicitNothing && unsubstitutedReturnType !in lambdasFromArgumentsReturnTypes) {
context.trace.report(Errors.IMPLICIT_NOTHING_AS_TYPE_PARAMETER.on(reportOn))
}
}

View File

@@ -91,6 +91,7 @@ class KotlinResolutionCallbacksImpl(
receiverType: UnwrappedType?,
parameters: List<UnwrappedType>,
expectedReturnType: UnwrappedType?,
annotations: Annotations,
stubsForPostponedVariables: Map<NewTypeVariable, StubType>
): Pair<List<KotlinCallArgument>, InferenceSession?> {
val psiCallArgument = lambdaArgument.psiCallArgument as PSIFunctionKotlinCallArgument
@@ -130,7 +131,7 @@ class KotlinResolutionCallbacksImpl(
val builtIns = outerCallContext.scope.ownerDescriptor.builtIns
val expectedType = createFunctionType(
builtIns, Annotations.EMPTY, receiverType, parameters, null,
builtIns, annotations, receiverType, parameters, null,
lambdaInfo.expectedType, isSuspend
)
@@ -264,4 +265,10 @@ class KotlinResolutionCallbacksImpl(
trace.record(BindingContext.CAST_TYPE_USED_AS_EXPECTED_TYPE, binaryParent)
return resultType
}
override fun disableContractsIfNecessary(resolvedAtom: ResolvedCallAtom) {
val atom = resolvedAtom.atom as? PSIKotlinCall ?: return
val context = topLevelCallContext ?: return
disableContractsInsideContractsBlock(atom.psiCall, resolvedAtom.candidateDescriptor, context.scope, trace)
}
}

View File

@@ -191,8 +191,8 @@ class ResolvedAtomCompleter(
val substitutedFunctionalType = createFunctionType(
builtIns,
existingLambdaType.annotations,
lambda.receiver?.let { resultSubstitutor.substituteKeepAnnotations(it) },
lambda.parameters.map { resultSubstitutor.substituteKeepAnnotations(it) },
lambda.receiver?.let { resultSubstitutor.safeSubstitute(it) },
lambda.parameters.map { resultSubstitutor.safeSubstitute(it) },
null, // parameter names transforms to special annotations, so they are already taken from parameter types
returnType,
lambda.isSuspend
@@ -208,7 +208,7 @@ class ResolvedAtomCompleter(
}
val valueType = receiver.value.type.unwrap()
val newValueType = resultSubstitutor.substituteKeepAnnotations(valueType)
val newValueType = resultSubstitutor.safeSubstitute(valueType)
if (valueType !== newValueType) {
val newReceiverValue = receiver.value.replaceType(newValueType)

View File

@@ -181,7 +181,9 @@ class InlineAnalyzerExtension(
}
if (hasInlineArgs) return
if (functionDescriptor.isInlineOnlyOrReifiable() || functionDescriptor.isExpect || functionDescriptor.isSuspend) return
if (functionDescriptor.isInlineWithReified() || functionDescriptor.isInlineOnly() || functionDescriptor.isExpect ||
functionDescriptor.isSuspend
) return
if (reasonableInlineRules.any { it.isInlineReasonable(functionDescriptor, function, trace.bindingContext) }) return

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2019 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.
*/
@@ -14,17 +14,30 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
private val INLINE_ONLY_ANNOTATION_FQ_NAME = FqName("kotlin.internal.InlineOnly")
fun MemberDescriptor.isInlineOnlyOrReifiable(): Boolean =
this is CallableMemberDescriptor && (isReifiable() || DescriptorUtils.getDirectMember(this).isReifiable() || isInlineOnly())
/**
* @return true if it's impossible to observe a call instruction referencing this member in the bytecode.
*/
fun MemberDescriptor.isEffectivelyInlineOnly(): Boolean =
isInlineOnlyOrReifiable() || (this is FunctionDescriptor && isSuspend && isInline &&
(valueParameters.any { it.isCrossinline } || visibility == Visibilities.PRIVATE))
isInlineWithReified() || isInlineOnlyPrivateInBytecode()
/**
* @return true if this member should be private in bytecode because it's effectively inline-only.
*/
fun MemberDescriptor.isInlineOnlyPrivateInBytecode(): Boolean =
isInlineOnly() || isPrivateInlineSuspend()
fun MemberDescriptor.isInlineOnly(): Boolean =
this is FunctionDescriptor && isInline &&
(hasInlineOnlyAnnotation() || DescriptorUtils.getDirectMember(this).hasInlineOnlyAnnotation())
private fun CallableMemberDescriptor.isReifiable() = typeParameters.any { it.isReified }
private fun MemberDescriptor.isPrivateInlineSuspend(): Boolean =
this is FunctionDescriptor && isSuspend && isInline && visibility == Visibilities.PRIVATE
private fun CallableMemberDescriptor.hasInlineOnlyAnnotation() = annotations.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)
fun MemberDescriptor.isInlineWithReified(): Boolean =
this is CallableMemberDescriptor && (hasReifiedParameters() || DescriptorUtils.getDirectMember(this).hasReifiedParameters())
private fun CallableMemberDescriptor.hasReifiedParameters(): Boolean =
typeParameters.any { it.isReified }
private fun CallableMemberDescriptor.hasInlineOnlyAnnotation(): Boolean =
annotations.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)

View File

@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
import org.jetbrains.kotlin.resolve.lazy.LazyClassContext
import org.jetbrains.kotlin.resolve.lazy.declarations.AbstractPsiBasedDeclarationProvider
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProvider
@@ -129,7 +130,8 @@ protected constructor(
getScopeForInitializerResolution(propertyDeclaration),
propertyDeclaration,
trace,
c.declarationScopeProvider.getOuterDataFlowInfoForDeclaration(propertyDeclaration)
c.declarationScopeProvider.getOuterDataFlowInfoForDeclaration(propertyDeclaration),
InferenceSession.default
)
result.add(propertyDescriptor)
}
@@ -141,7 +143,8 @@ protected constructor(
getScopeForInitializerResolution(entry),
entry,
trace,
c.declarationScopeProvider.getOuterDataFlowInfoForDeclaration(entry)
c.declarationScopeProvider.getOuterDataFlowInfoForDeclaration(entry),
InferenceSession.default
)
result.add(propertyDescriptor)
}

View File

@@ -1717,15 +1717,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
context, call, arrayAccessExpression, isGet ? OperatorNameConventions.GET : OperatorNameConventions.SET);
List<KtExpression> indices = arrayAccessExpression.getIndexExpressions();
// The accumulated data flow info of all index expressions is saved on the last index
KotlinTypeInfo resultTypeInfo = arrayTypeInfo;
if (!indices.isEmpty()) {
resultTypeInfo = facade.getTypeInfo(indices.get(indices.size() - 1), context);
}
if (!isGet) {
resultTypeInfo = facade.getTypeInfo(rightHandSide, context);
}
KotlinTypeInfo resultTypeInfo =
computeAccumulatedInfoForArrayAccessExpression(arrayTypeInfo, indices, rightHandSide, isGet, context, facade);
if ((isImplicit && !functionResults.isSuccess()) || !functionResults.isSingleResult()) {
traceForResolveResult.report(isGet ? NO_GET_METHOD.on(arrayAccessExpression) : NO_SET_METHOD.on(arrayAccessExpression));
@@ -1735,4 +1729,40 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
functionResults.getResultingCall());
return resultTypeInfo.replaceType(functionResults.getResultingDescriptor().getReturnType());
}
private static KotlinTypeInfo computeAccumulatedInfoForArrayAccessExpression(
@NotNull KotlinTypeInfo arrayTypeInfo,
@NotNull List<KtExpression> indices,
@Nullable KtExpression rightHandSide,
boolean isGet,
@NotNull ExpressionTypingContext context,
@NotNull ExpressionTypingInternals facade
) {
KotlinTypeInfo accumulatedTypeInfo = null;
boolean forceResolve = !context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference);
// The accumulated data flow info of all index expressions is saved on the last index
if (!indices.isEmpty()) {
accumulatedTypeInfo = getTypeInfo(indices.get(indices.size() - 1), facade, context, forceResolve);
}
if (!isGet && rightHandSide != null) {
accumulatedTypeInfo = getTypeInfo(rightHandSide, facade, context, forceResolve);
}
return accumulatedTypeInfo != null ? accumulatedTypeInfo : arrayTypeInfo;
}
private static KotlinTypeInfo getTypeInfo(
@NotNull KtExpression expression,
@NotNull ExpressionTypingInternals facade,
@NotNull ExpressionTypingContext context,
boolean forceExpressionResolve
) {
if (forceExpressionResolve) {
return facade.getTypeInfo(expression, context);
} else {
return BindingContextUtils.getRecordedTypeInfo(expression, context.trace.getBindingContext());
}
}
}

View File

@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession;
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency;
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
@@ -71,9 +72,10 @@ public class ExpressionTypingServices {
@NotNull KtExpression expression,
@NotNull KotlinType expectedType,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull InferenceSession inferenceSession,
@NotNull BindingTrace trace
) {
KotlinType type = getType(scope, expression, expectedType, dataFlowInfo, trace);
KotlinType type = getType(scope, expression, expectedType, dataFlowInfo, inferenceSession, trace);
return type != null ? type : ErrorUtils.createErrorType("Type for " + expression.getText());
}
@@ -84,10 +86,14 @@ public class ExpressionTypingServices {
@NotNull KtExpression expression,
@NotNull KotlinType expectedType,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull InferenceSession inferenceSession,
@NotNull BindingTrace trace,
boolean isStatement
) {
return getTypeInfo(scope, expression, expectedType, dataFlowInfo, trace, isStatement, expression, ContextDependency.INDEPENDENT);
return getTypeInfo(
scope, expression, expectedType, dataFlowInfo, inferenceSession,
trace, isStatement, expression, ContextDependency.INDEPENDENT
);
}
@NotNull
@@ -96,6 +102,7 @@ public class ExpressionTypingServices {
@NotNull KtExpression expression,
@NotNull KotlinType expectedType,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull InferenceSession inferenceSession,
@NotNull BindingTrace trace,
boolean isStatement,
@NotNull KtExpression contextExpression,
@@ -103,7 +110,7 @@ public class ExpressionTypingServices {
) {
ExpressionTypingContext context = ExpressionTypingContext.newContext(
trace, scope, dataFlowInfo, expectedType, contextDependency, statementFilter, getLanguageVersionSettings(),
expressionTypingComponents.dataFlowValueFactory
expressionTypingComponents.dataFlowValueFactory, inferenceSession
);
if (contextExpression != expression) {
context = context.replaceExpressionContextProvider(arg -> arg == expression ? contextExpression : null);
@@ -122,9 +129,10 @@ public class ExpressionTypingServices {
@NotNull KtExpression expression,
@NotNull KotlinType expectedType,
@NotNull DataFlowInfo dataFlowInfo,
@NotNull InferenceSession inferenceSession,
@NotNull BindingTrace trace
) {
return getTypeInfo(scope, expression, expectedType, dataFlowInfo, trace, false).getType();
return getTypeInfo(scope, expression, expectedType, dataFlowInfo, inferenceSession, trace, false).getType();
}
/////////////////////////////////////////////////////////

View File

@@ -33,7 +33,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
protected abstract val stateMachineMethodName: Name
protected abstract fun getCoroutineBaseClass(function: IrFunction): IrClassSymbol
protected abstract fun nameForCoroutineClass(function: IrFunction): Name
protected abstract fun buildStateMachine(
originalBody: IrBody, stateMachineFunction: IrFunction,
@@ -258,8 +258,6 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
val stateMachineFunction: IrFunction
)
private var coroutineId = 0
private inner class CoroutineBuilder(val irFunction: IrFunction, val functionReference: IrFunctionReference?) {
private val startOffset = irFunction.startOffset
@@ -273,7 +271,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
startOffset, endOffset,
DECLARATION_ORIGIN_COROUTINE_IMPL,
IrClassSymbolImpl(d),
"${irFunction.name}COROUTINE\$${coroutineId++}".synthesizedName,
nameForCoroutineClass(irFunction),
ClassKind.CLASS,
irFunction.visibility,
Modality.FINAL,

View File

@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.backend.js.lower.coroutines
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.common.ir.isSuspend
import org.jetbrains.kotlin.backend.common.lower.AbstractSuspendFunctionsLowering
import org.jetbrains.kotlin.ir.IrElement
@@ -34,10 +35,13 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
private val coroutineImplResultSymbolSetter = ctx.coroutineImplResultSymbolSetter
private var exceptionTrapId = -1
private var coroutineId = 0
override val stateMachineMethodName = Name.identifier("doResume")
override fun getCoroutineBaseClass(function: IrFunction) = context.ir.symbols.coroutineImpl
override fun nameForCoroutineClass(function: IrFunction) = "${function.name}COROUTINE\$${coroutineId++}".synthesizedName
override fun buildStateMachine(
originalBody: IrBody,
stateMachineFunction: IrFunction,

View File

@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 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.
* Copyright 2010-2019 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.backend.jvm.codegen
@@ -66,7 +55,7 @@ class IrSourceCompilerForInline(
get() = OwnerKind.getMemberOwnerKind(callElement.descriptor.containingDeclaration)
override val inlineCallSiteInfo: InlineCallSiteInfo
get() = InlineCallSiteInfo("TODO", null, null, false)
get() = InlineCallSiteInfo("TODO", null, null, false, false)
override val lazySourceMapper: DefaultSourceMapper
get() = codegen.classCodegen.getOrCreateSourceMapper()

View File

@@ -417,7 +417,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
override fun getOwnMethods(): List<KtLightMethod> = if (tooComplex) super.getOwnMethods() else _ownMethods
private fun asJavaMethods(ktFunction: KtFunction, forceStatic: Boolean, forcePrivate: Boolean = false): Collection<KtLightMethod> {
if (ktFunction.hasAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME)) return emptyList()
if (ktFunction.hasAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME) || ktFunction.hasReifiedParameters()) return emptyList()
val basicMethod = asJavaMethod(ktFunction, forceStatic, forcePrivate)
@@ -540,7 +540,6 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
private fun KtDeclaration.isInlineOnly(): Boolean {
if (this !is KtCallableDeclaration || !hasModifier(INLINE_KEYWORD)) return false
if (typeParameters.any { it.hasModifier(REIFIED_KEYWORD) }) return true
if (annotationEntries.isEmpty()) return false
val descriptor = resolve() as? CallableMemberDescriptor ?: return false
@@ -588,7 +587,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
private fun propertyAccessors(declaration: KtCallableDeclaration, mutable: Boolean, onlyJvmStatic: Boolean): List<KtLightMethod> {
val propertyName = declaration.name ?: return emptyList()
if (declaration.isConstOrJvmField()) return emptyList()
if (declaration.isConstOrJvmField() || declaration.hasReifiedParameters()) return emptyList()
val ktGetter = (declaration as? KtProperty)?.getter
val ktSetter = (declaration as? KtProperty)?.setter
@@ -654,6 +653,9 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
!declaration.hasModifier(ABSTRACT_KEYWORD)
}
private fun KtCallableDeclaration.hasReifiedParameters(): Boolean =
typeParameters.any { it.hasModifier(REIFIED_KEYWORD) }
override fun getInitializers(): Array<PsiClassInitializer> = emptyArray()
override fun getContainingClass(): PsiClass? =

View File

@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.kdoc.psi.impl
import com.intellij.lang.ASTNode
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiReference
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
import org.jetbrains.kotlin.psi.KtElementImpl
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
class KDocLink(node: ASTNode) : KtElementImpl(node) {
@@ -42,7 +39,4 @@ class KDocLink(node: ASTNode) : KtElementImpl(node) {
val tag = getStrictParentOfType<KDocTag>()
return if (tag != null && tag.getSubjectLink() == this) tag else null
}
override fun getReferences(): Array<out PsiReference> =
ReferenceProvidersRegistry.getReferencesFromProviders(this)
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.psi
import com.intellij.openapi.components.ServiceManager
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
open class KotlinReferenceProvidersService {
open fun getReferences(psiElement: PsiElement): Array<PsiReference> = PsiReference.EMPTY_ARRAY
companion object {
private val NO_REFERENCES_SERVICE = KotlinReferenceProvidersService()
@JvmStatic
fun getInstance(): KotlinReferenceProvidersService {
return ServiceManager.getService(KotlinReferenceProvidersService::class.java) ?: NO_REFERENCES_SERVICE
}
@JvmStatic
fun getReferencesFromProviders(psiElement: PsiElement): Array<PsiReference> {
return getInstance().getReferences(psiElement)
}
}
}

View File

@@ -18,8 +18,9 @@ package org.jetbrains.kotlin.psi;
import com.intellij.lang.Language;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiModifiableCodeBlock;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.LazyParseablePsiElement;
import com.intellij.psi.util.PsiUtilCore;
@@ -94,14 +95,6 @@ public class KtBlockExpression extends LazyParseablePsiElement implements KtElem
super.delete();
}
@Override
@SuppressWarnings("deprecation")
public PsiReference getReference() {
PsiReference[] references = getReferences();
if (references.length == 1) return references[0];
else return null;
}
@Override
@NotNull
public PsiElement[] getChildren() {
@@ -118,12 +111,6 @@ public class KtBlockExpression extends LazyParseablePsiElement implements KtElem
return result == null ? PsiElement.EMPTY_ARRAY : PsiUtilCore.toPsiElementArray(result);
}
@NotNull
@Override
public PsiReference[] getReferences() {
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
}
@NotNull
@Override
public KtElement getPsiOrParent() {

View File

@@ -19,8 +19,10 @@ package org.jetbrains.kotlin.psi;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.KotlinLanguage;
@@ -92,7 +94,7 @@ public class KtElementImpl extends ASTWrapperPsiElement implements KtElement {
@NotNull
@Override
public PsiReference[] getReferences() {
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
return KotlinReferenceProvidersService.getReferencesFromProviders(this);
}
@NotNull

View File

@@ -20,7 +20,6 @@ import com.intellij.extapi.psi.StubBasedPsiElementBase;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.stubs.IStubElementType;
import com.intellij.psi.stubs.StubElement;
import com.intellij.util.IncorrectOperationException;
@@ -109,7 +108,7 @@ public class KtElementImplStub<T extends StubElement<?>> extends StubBasedPsiEle
@NotNull
@Override
public PsiReference[] getReferences() {
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
return KotlinReferenceProvidersService.getReferencesFromProviders(this);
}
@NotNull

View File

@@ -17,10 +17,7 @@
package org.jetbrains.kotlin.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.ElementManipulators;
import com.intellij.psi.LiteralTextEscaper;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.*;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
@@ -28,7 +25,8 @@ import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub;
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
public class KtStringTemplateExpression extends KtElementImplStub<KotlinPlaceHolderStub<KtStringTemplateExpression>> implements KtExpression, PsiLanguageInjectionHost {
public class KtStringTemplateExpression extends KtElementImplStub<KotlinPlaceHolderStub<KtStringTemplateExpression>>
implements KtExpression, PsiLanguageInjectionHost, ContributedReferenceHost {
private static final TokenSet CLOSE_QUOTE_TOKEN_SET = TokenSet.create(KtTokens.CLOSING_QUOTE);
public KtStringTemplateExpression(@NotNull ASTNode node) {

View File

@@ -25,10 +25,13 @@ import com.intellij.psi.impl.source.tree.TreeUtil
import com.intellij.psi.search.PsiSearchScopeUtil
import com.intellij.psi.search.SearchScope
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import java.util.*
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
// NOTE: in this file we collect only LANGUAGE INDEPENDENT methods working with PSI and not modifying it
@@ -477,3 +480,11 @@ fun LazyParseablePsiElement.getContainingKtFile(): KtFile {
val fileString = if (file != null && file.isValid) file.text else ""
throw IllegalStateException("KtElement not inside KtFile: $file with text \"$fileString\" for element $this of type ${this::class.java} node = ${this.node}")
}
@UseExperimental(ExperimentalContracts::class)
fun KtExpression.isNull(): Boolean {
contract {
returns(true) implies (this@isNull is KtConstantExpression)
}
return this is KtConstantExpression && this.node.elementType == KtNodeTypes.NULL
}

View File

@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.contracts.description
import org.jetbrains.kotlin.contracts.interpretation.ContractInterpretationDispatcher
import org.jetbrains.kotlin.contracts.model.ESComponents
import org.jetbrains.kotlin.contracts.model.Functor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
@@ -40,12 +39,11 @@ open class ContractDescription(
val ownerFunction: FunctionDescriptor,
storageManager: StorageManager
) {
private val computeFunctor = storageManager.createMemoizedFunctionWithNullableValues<ModuleDescriptor, Functor> { module ->
val components = ESComponents(module.builtIns)
ContractInterpretationDispatcher(components).convertContractDescriptorToFunctor(this)
private val computeFunctor = storageManager.createNullableLazyValue {
ContractInterpretationDispatcher().convertContractDescriptorToFunctor(this)
}
fun getFunctor(usageModule: ModuleDescriptor): Functor? = computeFunctor(usageModule)
fun getFunctor(usageModule: ModuleDescriptor): Functor? = computeFunctor.invoke()
}
interface ContractDescriptionElement {

View File

@@ -25,33 +25,31 @@ import org.jetbrains.kotlin.contracts.model.structure.*
internal class ConditionInterpreter(
private val dispatcher: ContractInterpretationDispatcher
) : ContractDescriptionVisitor<ESExpression?, Unit> {
private val constants = dispatcher.components.constants
override fun visitLogicalOr(logicalOr: LogicalOr, data: Unit): ESExpression? {
val left = logicalOr.left.accept(this, data) ?: return null
val right = logicalOr.right.accept(this, data) ?: return null
return ESOr(constants, left, right)
return ESOr(left, right)
}
override fun visitLogicalAnd(logicalAnd: LogicalAnd, data: Unit): ESExpression? {
val left = logicalAnd.left.accept(this, data) ?: return null
val right = logicalAnd.right.accept(this, data) ?: return null
return ESAnd(constants, left, right)
return ESAnd(left, right)
}
override fun visitLogicalNot(logicalNot: LogicalNot, data: Unit): ESExpression? {
val arg = logicalNot.arg.accept(this, data) ?: return null
return ESNot(constants, arg)
return ESNot(arg)
}
override fun visitIsInstancePredicate(isInstancePredicate: IsInstancePredicate, data: Unit): ESExpression? {
val esVariable = dispatcher.interpretVariable(isInstancePredicate.arg) ?: return null
return ESIs(esVariable, IsFunctor(constants, isInstancePredicate.type, isInstancePredicate.isNegated))
return ESIs(esVariable, IsFunctor(isInstancePredicate.type.toESType(), isInstancePredicate.isNegated))
}
override fun visitIsNullPredicate(isNullPredicate: IsNullPredicate, data: Unit): ESExpression? {
val variable = dispatcher.interpretVariable(isNullPredicate.arg) ?: return null
return ESEqual(constants, variable, constants.nullValue, isNullPredicate.isNegated)
return ESEqual(variable, ESConstants.nullValue, isNullPredicate.isNegated)
}
override fun visitBooleanConstantDescriptor(booleanConstantDescriptor: BooleanConstantReference, data: Unit): ESExpression? =

View File

@@ -22,12 +22,12 @@ import org.jetbrains.kotlin.contracts.model.structure.ESConstant
import org.jetbrains.kotlin.contracts.model.structure.ESConstants
internal class ConstantValuesInterpreter {
fun interpretConstant(constantReference: ConstantReference, constants: ESConstants): ESConstant? = when (constantReference) {
BooleanConstantReference.TRUE -> constants.trueValue
BooleanConstantReference.FALSE -> constants.falseValue
ConstantReference.NULL -> constants.nullValue
ConstantReference.NOT_NULL -> constants.notNullValue
ConstantReference.WILDCARD -> constants.wildcard
fun interpretConstant(constantReference: ConstantReference): ESConstant? = when (constantReference) {
BooleanConstantReference.TRUE -> ESConstants.trueValue
BooleanConstantReference.FALSE -> ESConstants.falseValue
ConstantReference.NULL -> ESConstants.nullValue
ConstantReference.NOT_NULL -> ESConstants.notNullValue
ConstantReference.WILDCARD -> ESConstants.wildcard
else -> null
}
}

View File

@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.contracts.description.ContractDescription
import org.jetbrains.kotlin.contracts.description.EffectDeclaration
import org.jetbrains.kotlin.contracts.description.expressions.ConstantReference
import org.jetbrains.kotlin.contracts.description.expressions.VariableReference
import org.jetbrains.kotlin.contracts.model.ESComponents
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.contracts.model.ESExpression
import org.jetbrains.kotlin.contracts.model.Functor
@@ -33,7 +32,7 @@ import org.jetbrains.kotlin.contracts.model.structure.ESVariable
/**
* This class manages conversion of [ContractDescription] to [Functor]
*/
class ContractInterpretationDispatcher(val components: ESComponents) {
class ContractInterpretationDispatcher {
private val constantsInterpreter = ConstantValuesInterpreter()
private val conditionInterpreter = ConditionInterpreter(this)
private val conditionalEffectInterpreter = ConditionalEffectInterpreter(this)
@@ -51,7 +50,7 @@ class ContractInterpretationDispatcher(val components: ESComponents) {
}
}
return SubstitutingFunctor(components, resultingClauses, contractDescription.ownerFunction)
return SubstitutingFunctor(resultingClauses, contractDescription.ownerFunction)
}
internal fun interpretEffect(effectDeclaration: EffectDeclaration): ESEffect? {
@@ -60,7 +59,7 @@ class ContractInterpretationDispatcher(val components: ESComponents) {
}
internal fun interpretConstant(constantReference: ConstantReference): ESConstant? =
constantsInterpreter.interpretConstant(constantReference, components.constants)
constantsInterpreter.interpretConstant(constantReference)
internal fun interpretCondition(booleanExpression: BooleanExpression): ESExpression? =
booleanExpression.accept(conditionInterpreter, Unit)

View File

@@ -16,7 +16,7 @@
package org.jetbrains.kotlin.contracts.model
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.contracts.model.structure.ESType
/**
* Generic abstraction of static information about some part of program.
@@ -27,7 +27,7 @@ interface Computation {
* If type is unknown or computation doesn't have a type (e.g. if
* it is some construction, like "for"-loop), then type is 'null'
*/
val type: KotlinType?
val type: ESType?
/**
* List of all possible effects of this computation.

View File

@@ -1,15 +0,0 @@
/*
* Copyright 2010-2018 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.contracts.model
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.contracts.model.structure.ESConstants
class ESComponents(
val builtIns: KotlinBuiltIns
) {
val constants: ESConstants = ESConstants(builtIns)
}

View File

@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.contracts.model
import org.jetbrains.kotlin.contracts.model.visitors.Reducer
/**
* An abstraction of effect-generating nature of some computation.
*
@@ -25,5 +27,13 @@ package org.jetbrains.kotlin.contracts.model
* values, it takes effects and returns effects.
*/
interface Functor {
fun invokeWithArguments(arguments: List<Computation>): List<ESEffect>
fun invokeWithArguments(arguments: List<Computation>, reducer: Reducer): List<ESEffect>
}
abstract class AbstractFunctor : Functor {
override fun invokeWithArguments(arguments: List<Computation>, reducer: Reducer): List<ESEffect> =
reducer.reduceEffects(doInvocation(arguments, reducer))
protected abstract fun doInvocation(arguments: List<Computation>, reducer: Reducer): List<ESEffect>
}

View File

@@ -16,14 +16,12 @@
package org.jetbrains.kotlin.contracts.model.functors
import org.jetbrains.kotlin.contracts.model.Computation
import org.jetbrains.kotlin.contracts.model.ConditionalEffect
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.contracts.model.ESExpression
import org.jetbrains.kotlin.contracts.model.*
import org.jetbrains.kotlin.contracts.model.structure.*
import org.jetbrains.kotlin.contracts.model.visitors.Reducer
abstract class AbstractBinaryFunctor(constants: ESConstants) : AbstractReducingFunctor(constants) {
override fun doInvocation(arguments: List<Computation>): List<ESEffect> {
abstract class AbstractBinaryFunctor : AbstractFunctor() {
override fun doInvocation(arguments: List<Computation>, reducer: Reducer): List<ESEffect> {
assert(arguments.size == 2) { "Wrong size of arguments list for Binary functor: expected 2, got ${arguments.size}" }
return invokeWithArguments(arguments[0], arguments[1])
}
@@ -49,7 +47,7 @@ abstract class AbstractBinaryFunctor(constants: ESConstants) : AbstractReducingF
if (list.isEmpty())
null
else
list.map { it.condition }.reduce { acc, condition -> ESOr(constants, acc, condition) }
list.map { it.condition }.reduce { acc, condition -> ESOr(acc, condition) }
protected abstract fun invokeWithConstant(computation: Computation, constant: ESConstant): List<ESEffect>

View File

@@ -1,36 +0,0 @@
/*
* Copyright 2010-2017 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.
*/
package org.jetbrains.kotlin.contracts.model.functors
import org.jetbrains.kotlin.contracts.model.Computation
import org.jetbrains.kotlin.contracts.model.ESComponents
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.contracts.model.Functor
import org.jetbrains.kotlin.contracts.model.structure.ESConstants
import org.jetbrains.kotlin.contracts.model.visitors.Reducer
/**
* Abstract implementation of Functor with some routine house-holding
* automatically performed. *
*/
abstract class AbstractReducingFunctor(internal val constants: ESConstants) : Functor {
private val reducer = Reducer(constants)
override fun invokeWithArguments(arguments: List<Computation>): List<ESEffect> = reducer.reduceEffects(doInvocation(arguments))
protected abstract fun doInvocation(arguments: List<Computation>): List<ESEffect>
}

View File

@@ -16,12 +16,10 @@
package org.jetbrains.kotlin.contracts.model.functors
import org.jetbrains.kotlin.contracts.model.Computation
import org.jetbrains.kotlin.contracts.model.ConditionalEffect
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.contracts.model.structure.ESConstants
import org.jetbrains.kotlin.contracts.model.*
import org.jetbrains.kotlin.contracts.model.structure.isReturns
import org.jetbrains.kotlin.contracts.model.structure.isWildcard
import org.jetbrains.kotlin.contracts.model.visitors.Reducer
/**
* Unary functor that has sequential semantics, i.e. it won't apply to
@@ -30,8 +28,8 @@ import org.jetbrains.kotlin.contracts.model.structure.isWildcard
* It provides [applyToFinishingClauses] method for successors, which is guaranteed to
* be called only on clauses that haven't failed before reaching functor transformation.
*/
abstract class AbstractUnaryFunctor(constants: ESConstants) : AbstractReducingFunctor(constants) {
override fun doInvocation(arguments: List<Computation>): List<ESEffect> {
abstract class AbstractUnaryFunctor : AbstractFunctor() {
override fun doInvocation(arguments: List<Computation>, reducer: Reducer): List<ESEffect> {
assert(arguments.size == 1) { "Wrong size of arguments list for Unary operator: expected 1, got ${arguments.size}" }
return invokeWithArguments(arguments[0])
}

View File

@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.contracts.model.ConditionalEffect
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.contracts.model.structure.*
class AndFunctor(constants: ESConstants) : AbstractBinaryFunctor(constants) {
class AndFunctor : AbstractBinaryFunctor() {
override fun invokeWithConstant(computation: Computation, constant: ESConstant): List<ESEffect> = when {
constant.isTrue -> computation.effects
constant.isFalse -> emptyList()
@@ -48,20 +48,20 @@ class AndFunctor(constants: ESConstants) : AbstractBinaryFunctor(constants) {
// Even if one of 'Returns(true)' is missing, we still can argue that other condition
// *must* be true when whole functor returns true
val conditionWhenTrue = applyWithDefault(whenLeftReturnsTrue, whenRightReturnsTrue) { l, r -> ESAnd(constants, l, r) }
val conditionWhenTrue = applyWithDefault(whenLeftReturnsTrue, whenRightReturnsTrue) { l, r -> ESAnd(l, r) }
// When whole And-functor returns false, we can only argue that one of arguments was false, and to do so we
// have to know *both* 'Returns(false)'-conditions
val conditionWhenFalse = applyIfBothNotNull(whenLeftReturnsFalse, whenRightReturnsFalse) { l, r -> ESOr(constants, l, r) }
val conditionWhenFalse = applyIfBothNotNull(whenLeftReturnsFalse, whenRightReturnsFalse) { l, r -> ESOr(l, r) }
val result = mutableListOf<ConditionalEffect>()
if (conditionWhenTrue != null) {
result.add(ConditionalEffect(conditionWhenTrue, ESReturns(constants.trueValue)))
result.add(ConditionalEffect(conditionWhenTrue, ESReturns(ESConstants.trueValue)))
}
if (conditionWhenFalse != null) {
result.add(ConditionalEffect(conditionWhenFalse, ESReturns(constants.falseValue)))
result.add(ConditionalEffect(conditionWhenFalse, ESReturns(ESConstants.falseValue)))
}
return result

View File

@@ -16,14 +16,11 @@
package org.jetbrains.kotlin.contracts.model.functors
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.contracts.model.Computation
import org.jetbrains.kotlin.contracts.model.ConditionalEffect
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.contracts.model.ESValue
import org.jetbrains.kotlin.contracts.model.*
import org.jetbrains.kotlin.contracts.model.structure.*
import org.jetbrains.kotlin.contracts.model.visitors.Reducer
class EqualsFunctor(constants: ESConstants, val isNegated: Boolean) : AbstractReducingFunctor(constants) {
class EqualsFunctor(val isNegated: Boolean) : AbstractFunctor() {
/*
Equals is a bit tricky case to produce clauses, because e.g. if we want to emit "Returns(true)"-clause,
then we have to guarantee that we know *all* cases when 'true' could've been returned, and join
@@ -41,7 +38,7 @@ class EqualsFunctor(constants: ESConstants, val isNegated: Boolean) : AbstractRe
We don't want to code here fair analysis for general cases, because it's too complex. Instead, we just
check some specific cases, which are useful enough in practice
*/
override fun doInvocation(arguments: List<Computation>): List<ESEffect> {
override fun doInvocation(arguments: List<Computation>, reducer: Reducer): List<ESEffect> {
assert(arguments.size == 2) { "Equals functor expected 2 arguments, got ${arguments.size}" }
// TODO: AnnotationConstructorCaller kills this with implicit receiver. Investigate, how.
@@ -77,16 +74,15 @@ class EqualsFunctor(constants: ESConstants, val isNegated: Boolean) : AbstractRe
}
if (effect.simpleEffect.value == constant) {
val trueClause = ConditionalEffect(effect.condition, ESReturns(constants.booleanValue(isNegated.not())))
val trueClause = ConditionalEffect(effect.condition, ESReturns(ESConstants.booleanValue(isNegated.not())))
resultingClauses.add(trueClause)
}
if (effect.simpleEffect.value != constant && effect.simpleEffect.value is ESConstant && isSafeToProduceFalse(
call,
effect.simpleEffect.value,
constant
)) {
val falseClause = ConditionalEffect(effect.condition, ESReturns(constants.booleanValue(isNegated)))
call, effect.simpleEffect.value, constant
)
) {
val falseClause = ConditionalEffect(effect.condition, ESReturns(ESConstants.booleanValue(isNegated)))
resultingClauses.add(falseClause)
}
}
@@ -96,11 +92,15 @@ class EqualsFunctor(constants: ESConstants, val isNegated: Boolean) : AbstractRe
// It is safe to produce false if we're comparing types which are isomorphic to Boolean. For such types we can be sure, that
// if leftConstant != rightConstant, then this is the only way to produce 'false'.
private fun isSafeToProduceFalse(leftCall: Computation, leftConstant: ESConstant, rightConstant: ESConstant): Boolean = when {
// Comparison of Boolean
KotlinBuiltIns.isBoolean(rightConstant.type) && leftCall.type != null && KotlinBuiltIns.isBoolean(leftCall.type!!) -> true
private fun isSafeToProduceFalse(
leftCall: Computation,
leftConstant: ESConstant,
rightConstant: ESConstant
): Boolean = when {
// Comparison of Boolean
rightConstant.type.isBoolean() && leftCall.type.isBoolean() -> true
// Comparison of NULL/NOT_NULL, which is essentially Boolean
// Comparison of NULL/NOT_NULL, which is essentially Boolean
leftConstant.isNullConstant() && rightConstant.isNullConstant() -> true
else -> false
@@ -108,8 +108,8 @@ class EqualsFunctor(constants: ESConstants, val isNegated: Boolean) : AbstractRe
private fun equateValues(left: ESValue, right: ESValue): List<ESEffect> {
return listOf(
ConditionalEffect(ESEqual(constants, left, right, isNegated), ESReturns(constants.trueValue)),
ConditionalEffect(ESEqual(constants, left, right, isNegated.not()), ESReturns(constants.falseValue))
ConditionalEffect(ESEqual(left, right, isNegated), ESReturns(ESConstants.trueValue)),
ConditionalEffect(ESEqual(left, right, isNegated.not()), ESReturns(ESConstants.falseValue))
)
}
}

View File

@@ -16,17 +16,15 @@
package org.jetbrains.kotlin.contracts.model.functors
import org.jetbrains.kotlin.contracts.model.Computation
import org.jetbrains.kotlin.contracts.model.ConditionalEffect
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.contracts.model.ESValue
import org.jetbrains.kotlin.contracts.model.*
import org.jetbrains.kotlin.contracts.model.structure.ESConstants
import org.jetbrains.kotlin.contracts.model.structure.ESIs
import org.jetbrains.kotlin.contracts.model.structure.ESReturns
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.contracts.model.structure.ESType
import org.jetbrains.kotlin.contracts.model.visitors.Reducer
class IsFunctor(constants: ESConstants, val type: KotlinType, val isNegated: Boolean) : AbstractReducingFunctor(constants) {
override fun doInvocation(arguments: List<Computation>): List<ESEffect> {
class IsFunctor(val type: ESType, val isNegated: Boolean) : AbstractFunctor() {
override fun doInvocation(arguments: List<Computation>, reducer: Reducer): List<ESEffect> {
assert(arguments.size == 1) { "Wrong size of arguments list for Unary operator: expected 1, got ${arguments.size}" }
return invokeWithArguments(arguments[0])
}
@@ -40,10 +38,10 @@ class IsFunctor(constants: ESConstants, val type: KotlinType, val isNegated: Boo
private fun invokeWithValue(value: ESValue): List<ConditionalEffect> {
val trueIs = ESIs(value, this)
val falseIs = ESIs(value, IsFunctor(constants, type, isNegated.not()))
val falseIs = ESIs(value, IsFunctor(type, isNegated.not()))
val trueResult = ConditionalEffect(trueIs, ESReturns(constants.trueValue))
val falseResult = ConditionalEffect(falseIs, ESReturns(constants.falseValue))
val trueResult = ConditionalEffect(trueIs, ESReturns(ESConstants.trueValue))
val falseResult = ConditionalEffect(falseIs, ESReturns(ESConstants.falseValue))
return listOf(trueResult, falseResult)
}
}

View File

@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.contracts.model.structure.ESReturns
import org.jetbrains.kotlin.contracts.model.structure.isFalse
import org.jetbrains.kotlin.contracts.model.structure.isTrue
class NotFunctor(constants: ESConstants) : AbstractUnaryFunctor(constants) {
class NotFunctor : AbstractUnaryFunctor() {
override fun invokeWithReturningEffects(list: List<ConditionalEffect>): List<ConditionalEffect> = list.mapNotNull {
val outcome = it.simpleEffect
@@ -31,8 +31,8 @@ class NotFunctor(constants: ESConstants) : AbstractUnaryFunctor(constants) {
val returnValue = (outcome as ESReturns).value
when {
returnValue.isTrue -> ConditionalEffect(it.condition, ESReturns(constants.falseValue))
returnValue.isFalse -> ConditionalEffect(it.condition, ESReturns(constants.trueValue))
returnValue.isTrue -> ConditionalEffect(it.condition, ESReturns(ESConstants.falseValue))
returnValue.isFalse -> ConditionalEffect(it.condition, ESReturns(ESConstants.trueValue))
else -> null
}
}

View File

@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.contracts.model.ConditionalEffect
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.contracts.model.structure.*
class OrFunctor(constants: ESConstants) : AbstractBinaryFunctor(constants) {
class OrFunctor : AbstractBinaryFunctor() {
override fun invokeWithConstant(computation: Computation, constant: ESConstant): List<ESEffect> = when {
constant.isFalse -> computation.effects
constant.isTrue -> emptyList()
@@ -48,20 +48,20 @@ class OrFunctor(constants: ESConstants) : AbstractBinaryFunctor(constants) {
// When whole Or-functor returns true, all we know is that one of arguments was true.
// So, to make a correct clause we have to know *both* 'Returns(true)'-conditions
val conditionWhenTrue = applyIfBothNotNull(whenLeftReturnsTrue, whenRightReturnsTrue) { l, r -> ESOr(constants, l, r) }
val conditionWhenTrue = applyIfBothNotNull(whenLeftReturnsTrue, whenRightReturnsTrue) { l, r -> ESOr(l, r) }
// Even if one of 'Returns(false)' is missing, we still can argue that other condition
// *must* be false when whole OR-functor returns false
val conditionWhenFalse = applyWithDefault(whenLeftReturnsFalse, whenRightReturnsFalse) { l, r -> ESAnd(constants, l, r) }
val conditionWhenFalse = applyWithDefault(whenLeftReturnsFalse, whenRightReturnsFalse) { l, r -> ESAnd(l, r) }
val result = mutableListOf<ConditionalEffect>()
if (conditionWhenTrue != null) {
result.add(ConditionalEffect(conditionWhenTrue, ESReturns(constants.trueValue)))
result.add(ConditionalEffect(conditionWhenTrue, ESReturns(ESConstants.trueValue)))
}
if (conditionWhenFalse != null) {
result.add(ConditionalEffect(conditionWhenFalse, ESReturns(constants.falseValue)))
result.add(ConditionalEffect(conditionWhenFalse, ESReturns(ESConstants.falseValue)))
}
return result

View File

@@ -18,17 +18,17 @@ package org.jetbrains.kotlin.contracts.model.functors
import org.jetbrains.kotlin.contracts.model.*
import org.jetbrains.kotlin.contracts.model.structure.*
import org.jetbrains.kotlin.contracts.model.visitors.Reducer
import org.jetbrains.kotlin.contracts.model.visitors.Substitutor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.utils.addIfNotNull
class SubstitutingFunctor(
private val components: ESComponents,
private val basicEffects: List<ESEffect>,
private val ownerFunction: FunctionDescriptor
) : AbstractReducingFunctor(components.constants) {
override fun doInvocation(arguments: List<Computation>): List<ESEffect> {
) : AbstractFunctor() {
override fun doInvocation(arguments: List<Computation>, reducer: Reducer): List<ESEffect> {
if (basicEffects.isEmpty()) return emptyList()
val receiver =
@@ -40,7 +40,7 @@ class SubstitutingFunctor(
}
val substitutions = parameters.zip(arguments).toMap()
val substitutor = Substitutor(substitutions, components.builtIns)
val substitutor = Substitutor(substitutions, reducer)
val substitutedClauses = mutableListOf<ESEffect>()
effectsLoop@ for (effect in basicEffects) {

View File

@@ -18,11 +18,10 @@ package org.jetbrains.kotlin.contracts.model.structure
import org.jetbrains.kotlin.contracts.model.Computation
import org.jetbrains.kotlin.contracts.model.ESEffect
import org.jetbrains.kotlin.types.KotlinType
class CallComputation(override val type: KotlinType?, override val effects: List<ESEffect>) : Computation
class CallComputation(override val type: ESType?, override val effects: List<ESEffect>) : Computation
object UNKNOWN_COMPUTATION : Computation {
override val type: KotlinType? = null
override val type: ESType? = null
override val effects: List<ESEffect> = emptyList()
}

View File

@@ -22,18 +22,18 @@ import org.jetbrains.kotlin.contracts.model.ESOperator
import org.jetbrains.kotlin.contracts.model.ESValue
import org.jetbrains.kotlin.contracts.model.functors.*
class ESAnd(val constants: ESConstants, val left: ESExpression, val right: ESExpression) : ESOperator {
override val functor: AndFunctor = AndFunctor(constants)
class ESAnd(val left: ESExpression, val right: ESExpression) : ESOperator {
override val functor: AndFunctor = AndFunctor()
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitAnd(this)
}
class ESOr(val constants: ESConstants, val left: ESExpression, val right: ESExpression) : ESOperator {
override val functor: OrFunctor = OrFunctor(constants)
class ESOr(val left: ESExpression, val right: ESExpression) : ESOperator {
override val functor: OrFunctor = OrFunctor()
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitOr(this)
}
class ESNot(val constants: ESConstants, val arg: ESExpression) : ESOperator {
override val functor = NotFunctor(constants)
class ESNot(val arg: ESExpression) : ESOperator {
override val functor = NotFunctor()
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitNot(this)
}
@@ -42,13 +42,13 @@ class ESIs(val left: ESValue, override val functor: IsFunctor) : ESOperator {
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitIs(this)
}
class ESEqual(val constants: ESConstants, val left: ESValue, val right: ESValue, isNegated: Boolean) : ESOperator {
override val functor: EqualsFunctor = EqualsFunctor(constants, isNegated)
class ESEqual(val left: ESValue, val right: ESValue, isNegated: Boolean) : ESOperator {
override val functor: EqualsFunctor = EqualsFunctor(isNegated)
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitEqual(this)
}
fun ESExpression.and(other: ESExpression?, constants: ESConstants): ESExpression =
if (other == null) this else ESAnd(constants, this, other)
fun ESExpression.and(other: ESExpression?): ESExpression =
if (other == null) this else ESAnd(this, other)
fun ESExpression.or(other: ESExpression?, constants: ESConstants): ESExpression =
if (other == null) this else ESOr(constants, this, other)
fun ESExpression.or(other: ESExpression?): ESExpression =
if (other == null) this else ESOr(this, other)

View File

@@ -0,0 +1,51 @@
/*
* Copyright 2010-2019 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.contracts.model.structure
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.types.KotlinType
sealed class ESType {
abstract fun toKotlinType(builtIns: KotlinBuiltIns): KotlinType
}
abstract class ESBuiltInType : ESType()
object ESAnyType : ESBuiltInType() {
override fun toKotlinType(builtIns: KotlinBuiltIns): KotlinType = builtIns.anyType
}
object ESNullableAnyType : ESBuiltInType() {
override fun toKotlinType(builtIns: KotlinBuiltIns): KotlinType = builtIns.nullableAnyType
}
object ESNullableNothingType : ESBuiltInType() {
override fun toKotlinType(builtIns: KotlinBuiltIns): KotlinType = builtIns.nullableNothingType
}
object ESNothingType : ESBuiltInType() {
override fun toKotlinType(builtIns: KotlinBuiltIns): KotlinType = builtIns.nothingType
}
object ESBooleanType : ESType() {
override fun toKotlinType(builtIns: KotlinBuiltIns): KotlinType = builtIns.booleanType
}
class ESKotlinType(val type: KotlinType) : ESType() {
override fun toKotlinType(builtIns: KotlinBuiltIns): KotlinType = type
}
fun KotlinType.toESType() = when {
KotlinBuiltIns.isBoolean(this) -> ESBooleanType
KotlinBuiltIns.isAny(this) -> ESAnyType
KotlinBuiltIns.isNullableAny(this) -> ESNullableAnyType
KotlinBuiltIns.isNothing(this) -> ESNothingType
KotlinBuiltIns.isNullableNothing(this) -> ESNullableNothingType
else -> ESKotlinType(this)
}
fun ESType?.isBoolean(): Boolean = this is ESBooleanType

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.contracts.model.structure
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.contracts.description.expressions.BooleanConstantReference
import org.jetbrains.kotlin.contracts.description.expressions.ConstantReference
import org.jetbrains.kotlin.contracts.model.ESEffect
@@ -25,7 +24,6 @@ import org.jetbrains.kotlin.contracts.model.ESExpressionVisitor
import org.jetbrains.kotlin.contracts.model.ESValue
import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
@@ -36,7 +34,7 @@ interface ESReceiver : ESValue {
}
abstract class AbstractESValue(override val type: KotlinType?) : ESValue {
abstract class AbstractESValue(override val type: ESType?) : ESValue {
override val effects: List<ESEffect> = listOf()
}
@@ -57,7 +55,7 @@ open class ESReceiverValue(override val receiverValue: ReceiverValue) : Abstract
*
* [ESVariable] at points 2 and 3 must has consistent equality according to using them as keys
*/
open class ESVariable(val descriptor: ValueDescriptor) : AbstractESValue(descriptor.type) {
open class ESVariable(val descriptor: ValueDescriptor) : AbstractESValue(descriptor.type.toESType()) {
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitVariable(this)
override fun equals(other: Any?): Boolean {
@@ -82,7 +80,7 @@ open class ESVariable(val descriptor: ValueDescriptor) : AbstractESValue(descrip
*
* There is only few constants are supported (@see [ESConstant.Companion])
*/
class ESConstant internal constructor(val constantReference: ConstantReference, override val type: KotlinType) : AbstractESValue(type) {
class ESConstant internal constructor(val constantReference: ConstantReference, override val type: ESType) : AbstractESValue(type) {
override fun <T> accept(visitor: ESExpressionVisitor<T>): T = visitor.visitConstant(this)
override fun equals(other: Any?): Boolean = other is ESConstant && constantReference == other.constantReference
@@ -95,12 +93,12 @@ class ESConstant internal constructor(val constantReference: ConstantReference,
constantReference == ConstantReference.NULL || constantReference == ConstantReference.NOT_NULL
}
class ESConstants internal constructor(builtIns: KotlinBuiltIns) {
val trueValue = ESConstant(BooleanConstantReference.TRUE, builtIns.booleanType)
val falseValue = ESConstant(BooleanConstantReference.FALSE, builtIns.booleanType)
val nullValue = ESConstant(ConstantReference.NULL, builtIns.nullableNothingType)
val notNullValue = ESConstant(ConstantReference.NOT_NULL, builtIns.anyType)
val wildcard = ESConstant(ConstantReference.WILDCARD, builtIns.nullableAnyType)
object ESConstants {
val trueValue = ESConstant(BooleanConstantReference.TRUE, ESBooleanType)
val falseValue = ESConstant(BooleanConstantReference.FALSE, ESBooleanType)
val nullValue = ESConstant(ConstantReference.NULL, ESNullableNothingType)
val notNullValue = ESConstant(ConstantReference.NOT_NULL, ESAnyType)
val wildcard = ESConstant(ConstantReference.WILDCARD, ESNullableAnyType)
fun booleanValue(value: Boolean) =
if (value) trueValue else falseValue

View File

@@ -23,10 +23,7 @@ import org.jetbrains.kotlin.contracts.model.ESExpressionVisitor
import org.jetbrains.kotlin.contracts.model.MutableContextInfo
import org.jetbrains.kotlin.contracts.model.structure.*
class InfoCollector(
private val observedEffect: ESEffect,
private val constants: ESConstants
) : ESExpressionVisitor<MutableContextInfo> {
class InfoCollector(private val observedEffect: ESEffect, private val builtIns: KotlinBuiltIns) : ESExpressionVisitor<MutableContextInfo> {
private var isInverted: Boolean = false
fun collectFromSchema(schema: List<ESEffect>): MutableContextInfo =
@@ -41,18 +38,19 @@ class InfoCollector(
// Check for information from conditional effects
return when (observedEffect.isImplies(effect.simpleEffect)) {
// observed effect implies clause's effect => clause's effect was fired => clause's condition is true
// observed effect implies clause's effect => clause's effect was fired => clause's condition is true
true -> effect.condition.accept(this)
// Observed effect *may* or *doesn't* implies clause's - no useful information
// Observed effect *may* or *doesn't* implies clause's - no useful information
null, false -> null
}
}
override fun visitIs(isOperator: ESIs): MutableContextInfo = with(isOperator) {
if (functor.isNegated != isInverted) MutableContextInfo.EMPTY.notSubtype(left, type) else MutableContextInfo.EMPTY.subtype(
val isType = type.toKotlinType(builtIns)
if (functor.isNegated != isInverted) MutableContextInfo.EMPTY.notSubtype(left, isType) else MutableContextInfo.EMPTY.subtype(
left,
type
isType
)
}
@@ -76,10 +74,10 @@ class InfoCollector(
}
override fun visitVariable(esVariable: ESVariable): MutableContextInfo =
if (esVariable.type.let { it == null || !KotlinBuiltIns.isBoolean(it) })
if (esVariable.type.let { !it.isBoolean() })
MutableContextInfo.EMPTY
else
MutableContextInfo.EMPTY.equal(esVariable, constants.booleanValue(!isInverted))
MutableContextInfo.EMPTY.equal(esVariable, ESConstants.booleanValue(!isInverted))
override fun visitConstant(esConstant: ESConstant): MutableContextInfo = MutableContextInfo.EMPTY

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.contracts.model.visitors
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.contracts.model.*
import org.jetbrains.kotlin.contracts.model.structure.*
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
@@ -24,7 +25,7 @@ import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
* Reduces given list of effects by evaluating constant expressions,
* throwing away senseless checks and infeasible clauses, etc.
*/
class Reducer(private val constants: ESConstants) : ESExpressionVisitor<ESExpression?> {
class Reducer(private val builtIns: KotlinBuiltIns) : ESExpressionVisitor<ESExpression?> {
fun reduceEffects(schema: List<ESEffect>): List<ESEffect> =
schema.mapNotNull { reduceEffect(it) }
@@ -50,25 +51,28 @@ class Reducer(private val constants: ESConstants) : ESExpressionVisitor<ESExpres
override fun visitIs(isOperator: ESIs): ESExpression {
val reducedArg = isOperator.left.accept(this) as ESValue
val argType = reducedArg.type?.toKotlinType(builtIns)
val isType = isOperator.functor.type.toKotlinType(builtIns)
val result = when (reducedArg) {
is ESConstant -> reducedArg.type.isSubtypeOf(isOperator.functor.type)
is ESVariable -> if (reducedArg.type?.isSubtypeOf(isOperator.functor.type) == true) true else null
is ESConstant -> argType!!.isSubtypeOf(isType)
is ESVariable -> if (argType?.isSubtypeOf(isType) == true) true else null
else -> throw IllegalStateException("Unknown ESValue: $reducedArg")
}
// Result is unknown, do not evaluate
result ?: return ESIs(reducedArg, isOperator.functor)
return constants.booleanValue(result.xor(isOperator.functor.isNegated))
return ESConstants.booleanValue(result.xor(isOperator.functor.isNegated))
}
override fun visitEqual(equal: ESEqual): ESExpression {
val reducedLeft = equal.left.accept(this) as ESValue
val reducedRight = equal.right
if (reducedLeft is ESConstant) return constants.booleanValue((reducedLeft == reducedRight).xor(equal.functor.isNegated))
if (reducedLeft is ESConstant) return ESConstants.booleanValue((reducedLeft == reducedRight).xor(equal.functor.isNegated))
return ESEqual(constants, reducedLeft, reducedRight, equal.functor.isNegated)
return ESEqual(reducedLeft, reducedRight, equal.functor.isNegated)
}
override fun visitAnd(and: ESAnd): ESExpression? {
@@ -79,7 +83,7 @@ class Reducer(private val constants: ESConstants) : ESExpressionVisitor<ESExpres
reducedLeft.isFalse || reducedRight.isFalse -> reducedLeft
reducedLeft.isTrue -> reducedRight
reducedRight.isTrue -> reducedLeft
else -> ESAnd(constants, reducedLeft, reducedRight)
else -> ESAnd(reducedLeft, reducedRight)
}
}
@@ -91,7 +95,7 @@ class Reducer(private val constants: ESConstants) : ESExpressionVisitor<ESExpres
reducedLeft.isTrue || reducedRight.isTrue -> reducedLeft
reducedLeft.isFalse -> reducedRight
reducedRight.isFalse -> reducedLeft
else -> ESOr(constants, reducedLeft, reducedRight)
else -> ESOr(reducedLeft, reducedRight)
}
}
@@ -99,8 +103,8 @@ class Reducer(private val constants: ESConstants) : ESExpressionVisitor<ESExpres
val reducedArg = not.arg.accept(this) ?: return null
return when {
reducedArg.isTrue -> constants.falseValue
reducedArg.isFalse -> constants.trueValue
reducedArg.isTrue -> ESConstants.falseValue
reducedArg.isFalse -> ESConstants.trueValue
else -> reducedArg
}
}

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.contracts.model.visitors
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.contracts.model.Computation
import org.jetbrains.kotlin.contracts.model.ESExpression
import org.jetbrains.kotlin.contracts.model.ESExpressionVisitor
@@ -29,34 +28,34 @@ import org.jetbrains.kotlin.contracts.model.structure.*
*/
class Substitutor(
private val substitutions: Map<ESVariable, Computation>,
private val builtIns: KotlinBuiltIns
private val reducer: Reducer
) : ESExpressionVisitor<Computation?> {
override fun visitIs(isOperator: ESIs): Computation? {
val arg = isOperator.left.accept(this) ?: return null
return CallComputation(builtIns.booleanType, isOperator.functor.invokeWithArguments(arg))
return CallComputation(ESBooleanType, isOperator.functor.invokeWithArguments(arg))
}
override fun visitNot(not: ESNot): Computation? {
val arg = not.arg.accept(this) ?: return null
return CallComputation(builtIns.booleanType, not.functor.invokeWithArguments(arg))
return CallComputation(ESBooleanType, not.functor.invokeWithArguments(arg))
}
override fun visitEqual(equal: ESEqual): Computation? {
val left = equal.left.accept(this) ?: return null
val right = equal.right.accept(this) ?: return null
return CallComputation(builtIns.booleanType, equal.functor.invokeWithArguments(listOf(left, right)))
return CallComputation(ESBooleanType, equal.functor.invokeWithArguments(listOf(left, right), reducer))
}
override fun visitAnd(and: ESAnd): Computation? {
val left = and.left.accept(this) ?: return null
val right = and.right.accept(this) ?: return null
return CallComputation(builtIns.booleanType, and.functor.invokeWithArguments(left, right))
return CallComputation(ESBooleanType, and.functor.invokeWithArguments(left, right))
}
override fun visitOr(or: ESOr): Computation? {
val left = or.left.accept(this) ?: return null
val right = or.right.accept(this) ?: return null
return CallComputation(builtIns.booleanType, or.functor.invokeWithArguments(left, right))
return CallComputation(ESBooleanType, or.functor.invokeWithArguments(left, right))
}
override fun visitVariable(esVariable: ESVariable): Computation? = substitutions[esVariable] ?: esVariable

View File

@@ -212,7 +212,14 @@ object NewCommonSuperTypeCalculator {
if (thereIsStar || typeProjections.isEmpty()) {
createStarProjection(parameter)
} else {
calculateArgument(parameter, typeProjections, depth)
val argument = calculateArgument(parameter, typeProjections, depth)
val argumentType = argument.getType().asSimpleType()
val argumentConstructor = argumentType?.typeConstructor()
if (argument.getVariance() == TypeVariance.OUT && argumentConstructor == constructor && argumentType.asArgumentList()[index].isStarProjection()) {
createStarProjection(parameter)
} else {
argument
}
}
arguments.add(argument)

View File

@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
@@ -41,6 +42,7 @@ interface KotlinResolutionCallbacks {
receiverType: UnwrappedType?,
parameters: List<UnwrappedType>,
expectedReturnType: UnwrappedType?, // null means, that return type is not proper i.e. it depends on some type variables
annotations: Annotations,
stubsForPostponedVariables: Map<NewTypeVariable, StubType>
): Pair<List<KotlinCallArgument>, InferenceSession?>
@@ -53,6 +55,8 @@ interface KotlinResolutionCallbacks {
val inferenceSession: InferenceSession
fun getExpectedTypeFromAsExpressionAndRecordItInTrace(resolvedAtom: ResolvedCallAtom): UnwrappedType?
fun disableContractsIfNecessary(resolvedAtom: ResolvedCallAtom)
}
interface SamConversionTransformer {

View File

@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
import org.jetbrains.kotlin.types.model.isIntegerLiteralTypeConstructor
import org.jetbrains.kotlin.types.model.typeConstructor
import org.jetbrains.kotlin.types.typeUtil.contains
class KotlinCallCompleter(
private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
@@ -132,7 +133,10 @@ class KotlinCallCompleter(
val candidate = candidates.singleOrNull()
// this is needed at least for non-local return checker, because when we analyze lambda we should already bind descriptor for outer call
candidate?.resolvedCall?.let { resolutionCallbacks.bindStubResolvedCallForCandidate(it) }
candidate?.resolvedCall?.let {
resolutionCallbacks.bindStubResolvedCallForCandidate(it)
resolutionCallbacks.disableContractsIfNecessary(it)
}
return candidate ?: factory.createErrorCandidate().forceResolution()
}
@@ -140,7 +144,7 @@ class KotlinCallCompleter(
private fun KotlinResolutionCandidate.returnTypeWithSmartCastInfo(resolutionCallbacks: KotlinResolutionCallbacks): UnwrappedType? {
val returnType = resolvedCall.candidateDescriptor.returnType?.unwrap() ?: return null
val returnTypeWithSmartCastInfo = computeReturnTypeWithSmartCastInfo(returnType, resolutionCallbacks)
return resolvedCall.substitutor.substituteKeepAnnotations(returnTypeWithSmartCastInfo)
return resolvedCall.substitutor.safeSubstitute(returnTypeWithSmartCastInfo)
}
private fun KotlinResolutionCandidate.addExpectedTypeConstraint(
@@ -197,10 +201,27 @@ class KotlinCallCompleter(
else
ConstraintSystemCompletionMode.PARTIAL
// Return type has proper equal constraints => there is no need in the outer call
containsTypeVariablesWithProperEqualConstraints(currentReturnType) -> ConstraintSystemCompletionMode.FULL
else -> ConstraintSystemCompletionMode.PARTIAL
}
}
private fun KotlinResolutionCandidate.containsTypeVariablesWithProperEqualConstraints(type: UnwrappedType): Boolean {
for ((variableConstructor, variableWithConstraints) in csBuilder.currentStorage().notFixedTypeVariables) {
if (!type.contains { it.constructor == variableConstructor }) continue
val constraints = variableWithConstraints.constraints
val onlyProperEqualConstraints =
constraints.isNotEmpty() && constraints.all { it.kind.isEqual() && csBuilder.isProperType(it.type) }
if (!onlyProperEqualConstraints) return false
}
return true
}
private fun KotlinResolutionCandidate.hasProperNonTrivialLowerConstraints(typeVariable: UnwrappedType): Boolean {
assert(csBuilder.isTypeVariable(typeVariable)) { "$typeVariable is not a type variable" }
@@ -210,7 +231,8 @@ class KotlinCallCompleter(
val constraints = variableWithConstraints.constraints
return constraints.isNotEmpty() && constraints.all {
!it.type.typeConstructor(context).isIntegerLiteralTypeConstructor(context) &&
it.kind.isLower() && csBuilder.isProperType(it.type)
(it.kind.isLower() || it.kind.isEqual()) &&
csBuilder.isProperType(it.type)
}
}

View File

@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.addSubsystemFromArgument
import org.jetbrains.kotlin.resolve.calls.inference.model.*
@@ -105,6 +106,7 @@ class PostponedArgumentsAnalyzer(
receiver,
parameters,
expectedTypeForReturnArguments,
lambda.expectedType?.annotations ?: Annotations.EMPTY,
stubsForPostponedVariables.cast()
)

View File

@@ -5,9 +5,8 @@
package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
@@ -27,7 +26,6 @@ import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.checker.anySuperTypeConstructor
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -290,7 +288,7 @@ private fun KotlinResolutionCandidate.prepareExpectedType(
callComponents.languageVersionSettings
)
val resultType = knownTypeParametersResultingSubstitutor?.substitute(argumentType) ?: argumentType
return resolvedCall.substitutor.substituteKeepAnnotations(resultType)
return resolvedCall.substitutor.safeSubstitute(resultType)
}
private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
@@ -300,7 +298,7 @@ private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
if (!callComponents.samConversionTransformer.shouldRunSamConversionForFunction(resolvedCall.candidateDescriptor)) return null
val argumentIsFunctional = when (argument) {
is SimpleKotlinCallArgument -> argument.receiver.stableType.isSubtypeOfFunctionType()
is SimpleKotlinCallArgument -> argument.receiver.stableType.isFunctionType
is LambdaKotlinCallArgument, is CallableReferenceKotlinCallArgument -> true
else -> false
}
@@ -324,10 +322,6 @@ private fun KotlinResolutionCandidate.getExpectedTypeWithSAMConversion(
return convertedTypeByCandidate
}
private fun UnwrappedType.isSubtypeOfFunctionType() = anySuperTypeConstructor {
it.declarationDescriptor?.getFunctionalClassKind() == FunctionClassDescriptor.Kind.Function
}
internal object CheckReceivers : ResolutionPart() {
private fun KotlinResolutionCandidate.checkReceiver(
receiverArgument: SimpleKotlinCallArgument?,

View File

@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.checker.captureFromExpression
import org.jetbrains.kotlin.types.checker.hasSupertypeWithGivenTypeConstructor
import org.jetbrains.kotlin.types.lowerIfFlexible
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.supertypes
import org.jetbrains.kotlin.types.upperIfFlexible
@@ -66,6 +67,14 @@ private fun checkExpressionArgument(
return UnstableSmartCast(expressionArgument, unstableType)
}
}
if (argumentType.isMarkedNullable) {
if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, actualExpectedType, position)) return null
if (csBuilder.addSubtypeConstraintIfCompatible(argumentType.makeNotNullable(), actualExpectedType, position)) {
return ArgumentTypeMismatchDiagnostic(actualExpectedType, argumentType, expressionArgument)
}
}
csBuilder.addSubtypeConstraint(argumentType, actualExpectedType, position)
return null
}

View File

@@ -22,10 +22,8 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext
import org.jetbrains.kotlin.types.model.StubTypeMarker
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
import org.jetbrains.kotlin.types.model.*
import java.util.*
fun ConstraintStorage.buildCurrentSubstitutor(
context: TypeSystemInferenceExtensionContext,
@@ -84,4 +82,4 @@ fun CallableDescriptor.substituteAndApproximateCapturedTypes(substitutor: NewTyp
return substitute(TypeSubstitutor.create(wrappedSubstitution))
}
internal fun <E> MutableList<E>.trimToSize(newSize: Int) = subList(newSize, size).clear()
internal fun <E> MutableList<E>.trimToSize(newSize: Int) = subList(newSize, size).clear()

View File

@@ -29,6 +29,8 @@ class ConstraintIncorporator(
fun getConstraintsForVariable(typeVariable: TypeVariableMarker): Collection<Constraint>
fun addNewIncorporatedConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker)
fun addNewIncorporatedConstraint(typeVariable: TypeVariableMarker, type: KotlinTypeMarker, constraintContext: ConstraintContext)
}
// \alpha is typeVariable, \beta -- other type variable registered in ConstraintStorage
@@ -138,24 +140,49 @@ class ConstraintIncorporator(
if (baseConstraint.kind != ConstraintKind.UPPER) {
val generatedConstraintType = approximateCapturedTypes(typeForApproximation, toSuper = false)
if (!trivialConstraintTypeInferenceOracle.isGeneratedConstraintTrivial(
otherConstraint, generatedConstraintType, isSubtype = true
)
) {
addNewIncorporatedConstraint(generatedConstraintType, targetVariable.defaultType())
}
addNewConstraint(targetVariable, baseConstraint, otherVariable, otherConstraint, generatedConstraintType, isSubtype = true)
}
if (baseConstraint.kind != ConstraintKind.LOWER) {
val generatedConstraintType = approximateCapturedTypes(typeForApproximation, toSuper = true)
if (!trivialConstraintTypeInferenceOracle.isGeneratedConstraintTrivial(
otherConstraint, generatedConstraintType, isSubtype = false
)
) {
addNewIncorporatedConstraint(targetVariable.defaultType(), generatedConstraintType)
}
addNewConstraint(targetVariable, baseConstraint, otherVariable, otherConstraint, generatedConstraintType, isSubtype = false)
}
}
private fun Context.addNewConstraint(
targetVariable: TypeVariableMarker,
baseConstraint: Constraint,
otherVariable: TypeVariableMarker,
otherConstraint: Constraint,
newConstraint: KotlinTypeMarker,
isSubtype: Boolean
) {
if (targetVariable in getNestedTypeVariables(newConstraint)) return
if (!containsConstrainingTypeWithoutProjection(newConstraint, otherConstraint)) return
if (trivialConstraintTypeInferenceOracle.isGeneratedConstraintTrivial(otherConstraint, newConstraint, isSubtype)) return
val derivedFrom = (baseConstraint.derivedFrom + otherConstraint.derivedFrom).toMutableSet()
if (otherVariable in derivedFrom) return
derivedFrom.add(otherVariable)
val kind = if (isSubtype) ConstraintKind.LOWER else ConstraintKind.UPPER
addNewIncorporatedConstraint(targetVariable, newConstraint, ConstraintContext(kind, derivedFrom))
}
fun Context.containsConstrainingTypeWithoutProjection(
newConstraint: KotlinTypeMarker,
otherConstraint: Constraint
): Boolean {
return getNestedArguments(newConstraint).any {
it.getType().typeConstructor() == otherConstraint.type.typeConstructor() && it.getVariance() == TypeVariance.INV
}
}
fun Context.getNestedTypeVariables(type: KotlinTypeMarker): List<TypeVariableMarker> =
getNestedArguments(type).mapNotNull { getTypeVariable(it.getType().typeConstructor()) }
private fun KotlinTypeMarker.substitute(c: Context, typeVariable: TypeVariableMarker, value: KotlinTypeMarker): KotlinTypeMarker {
val substitutor = c.typeSubstitutorByTypeConstructor(mapOf(typeVariable.freshTypeConstructor(c) to value))
return substitutor.safeSubstitute(c, this)
@@ -166,3 +193,23 @@ class ConstraintIncorporator(
if (toSuper) typeApproximator.approximateToSuperType(type, TypeApproximatorConfiguration.IncorporationConfiguration) ?: type
else typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.IncorporationConfiguration) ?: type
}
private fun TypeSystemInferenceExtensionContext.getNestedArguments(type: KotlinTypeMarker): List<TypeArgumentMarker> {
val result = ArrayList<TypeArgumentMarker>()
val stack = ArrayDeque<TypeArgumentMarker>()
stack.push(createTypeArgument(type, TypeVariance.INV))
while (!stack.isEmpty()) {
val typeProjection = stack.pop()
if (typeProjection.isStarProjection()) continue
result.add(typeProjection)
val projectedType = typeProjection.getType()
for (argumentIndex in 0 until projectedType.argumentsCount()) {
stack.add(projectedType.getArgument(argumentIndex))
}
}
return result
}

View File

@@ -101,12 +101,10 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
return true // T <: T(?!)
}
if (constraintType.isSimpleType()) {
if (constraint.position.from is DeclaredUpperBoundConstraintPosition &&
constraint.kind == UPPER && constraintType.isNullableAny()
) {
return true // T <: Any?
}
if (constraint.position.from is DeclaredUpperBoundConstraintPosition &&
constraint.kind == UPPER && constraintType.isNullableAny()
) {
return true // T <: Any?
}
return false
@@ -163,7 +161,24 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
private fun addConstraint(typeVariableConstructor: TypeConstructorMarker, type: KotlinTypeMarker, kind: ConstraintKind) {
val typeVariable = c.allTypeVariables[typeVariableConstructor]
?: error("Should by type variableConstructor: $typeVariableConstructor. ${c.allTypeVariables.values}")
?: error("Should by type variableConstructor: $typeVariableConstructor. ${c.allTypeVariables.values}")
addNewIncorporatedConstraint(typeVariable, type, ConstraintContext(kind, emptySet()))
}
// from ConstraintIncorporator.Context
override fun addNewIncorporatedConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker) {
if (c.isAllowedType(lowerType) && c.isAllowedType(upperType)) {
runIsSubtypeOf(lowerType, upperType)
}
}
override fun addNewIncorporatedConstraint(
typeVariable: TypeVariableMarker,
type: KotlinTypeMarker,
constraintContext: ConstraintContext
) {
val (kind, derivedFrom) = constraintContext
var targetType = type
if (targetType.isUninferredParameter()) {
@@ -181,7 +196,7 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
if (kind == UPPER) {
val subType =
typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation)
if (subType != null && !subType.typeConstructor().isNothingConstructor()) {
if (subType != null) {
targetType = subType
}
}
@@ -189,7 +204,7 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
if (kind == LOWER) {
val superType =
typeApproximator.approximateToSuperType(type, TypeApproximatorConfiguration.SubtypeCapturedTypesApproximation)
if (superType != null && !superType.typeConstructor().isAnyConstructor()) { // todo rethink error reporting for Any cases
if (superType != null) { // todo rethink error reporting for Any cases
targetType = superType
}
}
@@ -200,14 +215,7 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
}
}
possibleNewConstraints.add(typeVariable to Constraint(kind, targetType, position))
}
// from ConstraintIncorporator.Context
override fun addNewIncorporatedConstraint(lowerType: KotlinTypeMarker, upperType: KotlinTypeMarker) {
if (c.isAllowedType(lowerType) && c.isAllowedType(upperType)) {
runIsSubtypeOf(lowerType, upperType)
}
possibleNewConstraints.add(typeVariable to Constraint(kind, targetType, position, derivedFrom = derivedFrom))
}
override val allTypeVariablesWithConstraints: Collection<VariableWithConstraints>
@@ -234,4 +242,6 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
private fun renderBaseConstraint() = "Base constraint: $baseLowerType <: $baseUpperType from position: $position"
}
}
}
data class ConstraintContext(val kind: ConstraintKind, val derivedFrom: Set<TypeVariableMarker>)

View File

@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.resolve.calls.inference.components
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
import org.jetbrains.kotlin.types.*
@@ -17,9 +18,7 @@ import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
interface NewTypeSubstitutor: TypeSubstitutorMarker {
fun substituteNotNullTypeWithConstructor(constructor: TypeConstructor): UnwrappedType?
fun safeSubstitute(type: UnwrappedType): UnwrappedType = substitute(type, runCapturedChecks = true, keepAnnotation = false) ?: type
fun substituteKeepAnnotations(type: UnwrappedType): UnwrappedType =
fun safeSubstitute(type: UnwrappedType): UnwrappedType =
substitute(type, runCapturedChecks = true, keepAnnotation = true) ?: type
private fun substitute(type: UnwrappedType, keepAnnotation: Boolean, runCapturedChecks: Boolean): UnwrappedType? =
@@ -114,7 +113,7 @@ interface NewTypeSubstitutor: TypeSubstitutorMarker {
// simple classifier type
var replacement = substituteNotNullTypeWithConstructor(typeConstructor) ?: return null
if (keepAnnotation) {
replacement = replacement.replaceAnnotations(type.annotations)
replacement = replacement.replaceAnnotations(CompositeAnnotations(replacement.annotations, type.annotations))
}
if (type.isMarkedNullable) {
replacement = replacement.makeNullableAsSpecified(true)

View File

@@ -67,7 +67,8 @@ class Constraint(
val kind: ConstraintKind,
val type: KotlinTypeMarker, // flexible types here is allowed
val position: IncorporationConstraintPosition,
val typeHashCode: Int = type.hashCode()
val typeHashCode: Int = type.hashCode(),
val derivedFrom: Set<TypeVariableMarker>
) {
override fun equals(other: Any?): Boolean {
if (this === other) return true

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