Compare commits

...

342 Commits

Author SHA1 Message Date
Simon Ogorodnik
a2bc2cc53c Minor: Fix dokka config
Revert "Fix documentation for stdlib"

This reverts commit e14de32939.
2017-03-20 19:54:12 +03:00
Simon Ogorodnik
2e7da8fcae Minor: Add Dokka format param to build-docs script
To have an ability to change it in TeamCity between custom builds
2017-03-15 19:44:48 +03:00
Simon Ogorodnik
e14de32939 Fix documentation for stdlib
Add forgotten files to file list used by
Dokka when generating documentation
2017-03-15 18:22:54 +03:00
Mikhael Bogdanov
40b00ee5b5 Test data fix 2017-03-14 09:38:31 +01:00
Mikhail Zarechenskiy
47369d1191 Add note about JS to the changelog 2017-03-13 21:06:19 +03:00
Mikhail Zarechenskiy
e85d6d9803 Remove KT-15200 from the changelog
It was postponed until 1.1.2
2017-03-13 20:42:33 +03:00
Mikhail Zarechenskiy
4d26204ef9 Update Changelog for version 1.1.1 2017-03-13 17:18:29 +03:00
Mikhael Bogdanov
e62255b517 Fix for KT-16801: Accessors of @PublishedApi property gets mangled
#KT-16801 Fixed

(cherry picked from commit ce3b455)
2017-03-13 11:12:08 +01:00
Yan Zhulanow
073c3bd7da Do not check if the star projection contains local types to avoid stack overflow.
Fixes EA-95181.
2017-03-13 02:14:41 +03:00
Denis Zharkov
87cc248fca Add diagnostic info to assertion on type argument consistency 2017-03-10 18:22:12 +03:00
Denis Zharkov
5110affb2c Revert "Make computation of arguments for raw types lazy"
This reverts commit 9cf54bf83f.
2017-03-10 15:57:44 +03:00
Stanislav Erokhin
7a8b85a916 Fix potential CCE -- use unwrappedType after instanceof check. 2017-03-10 15:15:07 +03:00
Mikhail Glukhikh
d363ae94d8 Do not run write actions from J2K #KT-16714 Fixed
Also #EA-97363 Fixed

(cherry picked from commit 5e8afd2)
2017-03-10 14:57:22 +03:00
Denis Zharkov
9cf54bf83f Make computation of arguments for raw types lazy
See how we translate raw types to Kotlin model:
RawType(A) = A<ErasedUpperBound(T1), ...>
ErasedUpperBound(T : G<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F

Stack overflow happens with the following classes:
class A<X extends B> // NB: raw type B in upper bound
class B<Y extends A> // NB: raw type A in upper bound

when calculating raw type for A, we start calculate ErasedUpperBound(Y),
thus starting calculating raw type for B => ErasedUpperBound(X) => RawType(A),
so we have SOE here.
The problem is that we calculating the arguments for these raw types eagerly,
while from the definition of ErasedUpperBound(Y) we only need a type constructor
of raw type B (and the number of parameters), we don't use its arguments.

The solution is to make arguments calculating for raw types lazy

 #KT-16528 Fixed
2017-03-10 13:33:50 +03:00
Ilya Gorbunov
63b6f90926 Add missing SinceKotlin to IntStream.toList.
(cherry picked from commit b83b534374)
2017-03-09 17:27:00 +03:00
Ilya Gorbunov
b8b9e43c05 Mark all api in kotlin.reflect.full package with SinceKotlin(1.1), since it actually appeared in that package only in 1.1. #KT-16557 Fixed.
It doesn't matter that some functions were since 1.0 in the old package.

(cherry picked from commit c038d3e9a3)
2017-03-09 17:27:00 +03:00
Ilya Gorbunov
98f0acdb8c Add samples for sequence building API.
(cherry picked from commit 61e8848aa2)
2017-03-09 17:27:00 +03:00
Ilya Gorbunov
ce1be19da6 Add groupingBy and eachCount sample.
(cherry picked from commit a04e6de047)
2017-03-09 17:27:00 +03:00
Ilya Gorbunov
6c1bb136ad Improve sample comments.
Improve sample for lastIndex property.

(cherry picked from commit 75ae42121b)
2017-03-09 17:27:00 +03:00
Sergey Igushkin
c6a33fb9cb Added gradle-plugins properties with fqnames
Added .property files to make the plugins available by fqnames in
order to publish them to Gradle Plugin Portal.

#KT-5756

(cherry picked from commit 991de64)

(cherry picked from commit 999ef51)
2017-03-09 14:16:45 +03:00
Mikhail Zarechenskiy
dc065cb362 Update Changelog: add link to the previous release 2017-03-09 12:07:10 +03:00
Mikhail Zarechenskiy
f3d769d8d5 Update Changelog for Kotlin 1.1.1-RC 2017-03-07 12:18:15 +03:00
Sergey Igushkin
2c235b0585 Enabled incremental compilation by default in Gradle plugin.
#KT-16546 Fixed

(cherry picked from commit 06715c5)
2017-03-07 11:38:04 +03:00
Dmitry Petrov
161c67c2ac Potential fix for KT-16673
See also:
http://stackoverflow.com/questions/42571812/unsupportedoperationexception-while-building-a-kotlin-project-in-idea

'original' for SamAdapterFunctionScope.MyFunctionDescriptor#doSubstitute should exactly match 'this.original',
so we can just provide it by default in SamAdapterFunctionScope.MyFunctionDescriptor#newCopyBuilder.
2017-03-06 22:02:15 +03:00
Mikhail Zarechenskiy
1bf290903a Disable InterfaceDefaultMethodCallChecker checker
This checker is disabled due to its incorrect behaviour and will
be available again in 1.1.2
2017-03-06 22:02:08 +03:00
Dmitry Jemerov
b7888138cf "Configure Kotlin plugin updates" shows 1.2 and doesn't show 1.0.x
(cherry picked from commit 268f7b7)
2017-03-06 19:53:45 +01:00
Ilya Chernikov
c25e26fd0d Implement verification workaround for annotation-like class InvalidScriptResolverAnnotation
fixes #KT-16621
2017-03-06 16:27:39 +01:00
Sergey Mashkov
ec6189a860 Revert "EA-88059 - assert: CompositeElement.addChild"
This reverts commit 6bcffb8289.
2017-03-06 18:06:07 +03:00
Sergey Mashkov
4c4c62e815 Revert "EA-86479 - ISE: PomFile.<init>"
This reverts commit da50776e80.
2017-03-06 18:06:01 +03:00
Sergey Mashkov
da50776e80 EA-86479 - ISE: PomFile.<init>
don't apply any inspections for inappropriate pom files
2017-03-06 17:35:50 +03:00
Sergey Mashkov
6bcffb8289 EA-88059 - assert: CompositeElement.addChild
ensure parent element for anchor elements so we never try to insert at wrong place
2017-03-06 17:35:50 +03:00
Alexander Udalov
072524946f Allow references to nested class constructors in objects in LV = 1.0
#KT-16598 Fixed

(cherry picked from commit 0111c4d581)
2017-03-06 14:20:21 +03:00
Mikhail Zarechenskiy
a02ffd6d2b Regenerate tests: add missing LightAnalysisCodegen test
This kind of tests presents in 1.1.1 but not in master
2017-03-06 14:00:30 +03:00
Anton Bannykh
20d92e161e JS: mute some tests with extension functions in external declarations
(cherry-picked 4c6b9b695c)
2017-03-03 21:55:03 +03:00
Anton Bannykh
94cbe71eff JS: prohibited extension function arguments in external functions; removed extension receiver in jQuery declarations.
(cherry-picked from fcffd190d0)
2017-03-03 20:44:26 +03:00
Sergey Igushkin
97420afb3d Fix for androidTest variants of Android Gradle build.
Added a workaround reflection call to TaskManager to create a
javac task since it is missing for androidTest variants with jack.
Added source configuration with the tested variant to make
the tested sources visible to the compiler.

#KT-16434 Fixed

(cherry picked from commit 84efd05)
2017-03-03 15:34:25 +03:00
Mikhael Bogdanov
8c2bcc6eaa Fix for KT-16581: VerifyError when calling default value parameter with jvm-target 1.8
#KT-16581 Fixed

(cherry picked from commit a03ed6f)
2017-03-03 12:00:49 +01:00
Ilya Chernikov
a4ea155d22 Do not pollute IDEA log with fake script dependencies 2017-03-03 10:54:20 +01:00
Mikhail Zarechenskiy
fe956668b3 Add test for class delegation with private constructor
#KT-16583 Obsolete
2017-03-02 18:43:06 +03:00
Mikhail Zarechenskiy
1e8e740816 Fix access to top-level declarations inside anonymous initializer
#KT-16583 Fixed
2017-03-02 18:38:42 +03:00
Denis Zharkov
f177af12d7 Fix substitutor for synthetic SAM adapters
When synthetic member comes not from the receiver type itself,
but from one of its supertypes it doesn't make sense to subsitute
the member with receiver type, we should obtain relevant supertype
and use it instead.

 #KT-16578 Fixed
2017-03-02 15:07:35 +03:00
Simon Ogorodnik
7a63d1af24 Revert "Fix Show implementation to show inheritance through type-aliases"
This reverts commit 7e59108cae.
2017-03-01 23:49:14 +03:00
Simon Ogorodnik
7e59108cae Fix Show implementation to show inheritance through type-aliases
Show implementation(Ctrl-Hover) now should show classes which inherit such class through type-alias
 #KT-15200 fixed

(cherry picked from commit 6dd75f6)
2017-03-01 23:14:20 +03:00
Simon Ogorodnik
b18f790d10 Fix of <ERROR CLASS>-es pointing to public TypeAliases
(cherry picked from commit 000da2f)
2017-03-01 16:19:28 +01:00
Dmitry Jemerov
b861a432c9 Don't generate documentation for option that doesn't work in Gradle
(cherry picked from commit 78b4cbd)
2017-03-01 16:19:28 +01:00
Alexey Andreev
951b1d527a JS: add some docs to declarations related to interop
(cherry picked from commit 0c0e0aa)
2017-03-01 16:19:28 +01:00
Dmitry Jemerov
8c3d13b31f Assorted stdlib KDocs
(cherry picked from commit 322379e)
2017-03-01 16:19:28 +01:00
Dmitry Jemerov
fc135efb21 Build multiplatform stdlib docs
(cherry picked from commit 1d86bd5)
2017-03-01 16:19:27 +01:00
Dmitry Jemerov
596adb9b1e Extract separate target for preprocessing JS stdlib sources
(cherry picked from commit adc937c)
2017-03-01 16:19:27 +01:00
Mikhail Glukhikh
c506871195 Change log: note about javaClass added
(cherry picked from commit 91cd590)

(cherry picked from commit 4c69c34)
2017-03-01 10:32:56 +03:00
Mikhail Glukhikh
15b99c3629 Change log 1.1: added link to 1.1-rc
(cherry picked from commit 4d76cc1)
2017-03-01 10:32:42 +03:00
Mikhail Glukhikh
4f859fd727 Change log for 1.1 (release)
(cherry picked from commit afd6e0d)
2017-03-01 10:32:33 +03:00
Alexey Sedunov
716d00338e Kotlin Facet: Do not concat "additional argument" string as configuration gets duplicated
KT-16548 Fixed

(cherry picked from commit 387c91f)
2017-02-28 16:29:38 +03:00
Alexey Sedunov
d2ab12bc97 Kotlin Facet: Import more configuration options from Maven
(cherry picked from commit dca696f)
2017-02-28 15:00:32 +03:00
Alexey Sedunov
cefa344a77 Kotlin Facet: Import Maven option specified in <jvmTarget> element
#KT-16329 In Progress

(cherry picked from commit 358a0ae)
2017-02-28 15:00:31 +03:00
Alexander Udalov
19814558f8 Update KotlinVersion.CURRENT to 1.1.1 2017-02-28 13:40:48 +03:00
Alexander Udalov
c8a00fc012 Specify language / API version in .idea/kotlinc.xml
(cherry picked from commit d124912c91)
2017-02-28 13:28:08 +03:00
Yan Zhulanow
9d942383f1 Force using the 'kotlin-stdlib-jre7' artifact when configuring Android modules with JDK >= 1.8 as Dex can't process our 'kotlin-stdlib-jre8' artifact.
This fixes KT-16530: Configure Kotlin in Project inserts dependency to kotlin-stdlib-jre8 in Android projects.
2017-02-27 20:21:14 +03:00
Nikolay Krasko
e81f19c30a Use doResume name for suspend lambdas context (KT-16481)
#KT-16481 Fixed

(cherry picked from commit f0be88f)
2017-02-27 15:28:09 +03:00
Nikolay Krasko
896be11aaa Count JVM class name for inlined function from base declaration
Drop code with naive removing all anonymous classes.
Breakpoints now works when inline call is in anonymous call.

(cherry picked from commit dffbe0f)
2017-02-27 15:28:02 +03:00
Nikolay Krasko
a9b5ddd7d2 Refactoring: use constants instead of string literals
(cherry picked from commit cd92e3f)
2017-02-27 15:27:55 +03:00
Mikhael Bogdanov
340036fbcb Test data fix 2017-02-27 11:05:28 +01:00
Mikhael Bogdanov
4d80738dd6 Fix for KT-16441: NoSuchFieldError: $$delegatedProperties when delegating through provideDelegate in companion object
#KT-16441 Fixed

(cherry picked from commit d24ebf7)
2017-02-27 11:02:37 +01:00
Yan Zhulanow
307a5001ac Remove kotlin-annotation-processing artifact from the serialized compiler options. It is unused in kapt3 (or if no annotation processor dependencies are provided) but is still imported into the IDEA module files. This leads to compilation error due to the plugin incompatibility.
Incompatibility reason: kotlin-annotation-processing has references to the shaded intellij-core, so, being provided to the unshaded kotlinc from the Kotlin plugin, it throws the AbstractMethodError.

This fixes #KT-16184.
2017-02-27 00:35:07 +03:00
Dmitry Jemerov
0cfaea28a1 Disable @PublishedApi quickfix
(cherry picked from commit 9356781)
2017-02-26 13:38:02 +01:00
Ilya Chernikov
6f651d7338 Use sessions with connection to eliminate asyn shutdown problems 2017-02-24 16:51:09 +01:00
Ilya Chernikov
9329eaa457 Make daemon connection more reliable by retrying on certain exceptions 2017-02-24 16:51:09 +01:00
Alexey Tsvetkov
50ffc8d0c5 Start daemon with explicit server ip address to prevent host name resolution
(cherry picked from commit 7b35ce0)
2017-02-24 16:51:09 +01:00
Ilya Chernikov
01a1aa9b62 Attempt to fix flaky parallel daemon test 2017-02-24 16:51:09 +01:00
Ilya Chernikov
4b2f4f0bc2 Fixes after review 2017-02-24 16:51:09 +01:00
Ilya Chernikov
6a449faf5d Adjust test after introducing shutdown delay 2017-02-24 16:51:09 +01:00
Ilya Chernikov
d0f7edab08 Implement more reliable daemon election, fixes KT-15562
also making shutdown more reliable
2017-02-24 16:51:09 +01:00
Ilya Chernikov
716956f917 Add test reproducing "Service is dying" problem (KT-15562) 2017-02-24 16:51:09 +01:00
Anton Bannykh
daf4711478 JS: changed BoxedChar visibility to internal
(cherry picked from commit 3eb5b3e08c)
2017-02-24 16:17:07 +03:00
Alexey Tsvetkov
30c2c2f17f Replace daemon's message after start with constant string
#KT-15783 fixed

When a daemon client cannot find an existing daemon, it starts a new one.
The client waits for a daemon to start and initialize.
Then the daemon is expected to signal that it is ready for compiling by printing message in stdout.
Before this change the message was the daemons' run path (a directory where all daemons store
their "flag" files).
However the path printed by the daemon was not matched by the path expected by the client somehow
on Windows for a user with a username containing non-English letters.
This commit replaces the message with the constant string.
2017-02-22 17:52:45 +03:00
Ilya Gorbunov
b9efc2e1ac Drop ERROR deprecations in JS library that were introduced in 1.1-rc
(cherry picked from commit 6e8f227121)
2017-02-22 17:30:51 +03:00
Ilya Gorbunov
9e0d31714c Drop ERROR deprecations from kotlin-reflect.
(cherry picked from commit b393c66426)
2017-02-22 17:30:50 +03:00
Ilya Gorbunov
1e8c4933f1 Drop HIDDEN deprecations from kotlin-stdlib.
(cherry picked from commit c0c01d6e49)
2017-02-22 17:30:48 +03:00
Ilya Gorbunov
6648a1f669 Drop remaining ERROR deprecations from kotlin-stdlib-js.
Leave only `native`, `parseInt`, `parseFloat` and `noImpl`.

(cherry picked from commit 8e951dee16)
2017-02-22 17:30:46 +03:00
Ilya Gorbunov
37f0bc1716 Do not refer to java packages in common completion tests
(cherry picked from commit eebb820060)
2017-02-22 17:30:44 +03:00
Ilya Gorbunov
8a0a9152da Drop entire java.util package from kotlin-stdlib-js
#KT-6561 Fixed

(cherry picked from commit 3cea5c4510)
2017-02-22 17:30:42 +03:00
Ilya Gorbunov
53c3e75740 [Standard Library] Take the javaClass deprecation back as its replacement is often inconvenient.
(cherry picked from commit 5867d27fb7)
2017-02-22 17:30:41 +03:00
Stanislav Erokhin
a9ef3845fd Fix type deserialization for suspend function types which was written by pre-release compiler.
Notes: if arity == 0, it means that type was `suspend () -> String` => arguments.size == 1, and it means that SuspendFunction0 has only one type argument and it is return type.

(cherry picked from commit 0a24bf1)
2017-02-21 18:07:20 +03:00
Alexander Udalov
17d05bb7fd Minor, improve error message
(cherry picked from commit 407815449a)
2017-02-21 14:04:59 +03:00
Mikhael Bogdanov
fbe67da5f1 Fix for KT-16411, KT-16412: Exception from compiler when try call SAM constructor where argument is callable reference to nested class inside object
#Fixed KT-16411
  #Fixed KT-16412

(cherry picked from commit a8625b6)
2017-02-21 11:42:04 +01:00
Denis Zharkov
02d8c193c8 Get rid of redundant not-null assertion for parameter
The problem was that in `Function<T>.apply(T)` T is now not-platform,
so when checking if not-null assertion is needed for parameter in SAM,
it's defined by the upper bounds of T that is a platform (Any..Any?),
and while it's definitely not marked as nullable it's still nullable
in a sense that it can contain null as a value.

So the solution is obvious

 #KT-16413 Fixed
2017-02-21 13:17:39 +03:00
Dmitry Jemerov
9240d7695c Don't overwrite explicitly specified language version in facet with version from dependencies; add tests for setting language version based on dependencies
(cherry picked from commit fc2b9f6)
2017-02-20 11:33:35 +01:00
Dmitry Jemerov
f16f97583f Don't replace explicitly configured project settings with autodetected ones 2017-02-17 14:04:57 +01:00
Dmitry Jemerov
50be60d71b Don't pass paths to non-existing metadata files from dependent modules
(cherry picked from commit 3225c93)
2017-02-16 19:17:10 +01:00
Mikhail Glukhikh
e30cd05bea Link fix 2017-02-16 20:40:40 +03:00
Mikhail Glukhikh
9c831cca8b Change log 1.1-RC: link to 1.1-Beta2 2017-02-16 20:40:08 +03:00
Mikhail Glukhikh
4467ac0b42 Change log update (final) for 1.1-RC
(cherry picked from commit 797813a)
2017-02-16 18:58:14 +03:00
Dmitry Jemerov
07a48b080b Disable facet detection; force detection of API/language level from dependencies on project opening 2017-02-16 15:14:53 +01:00
Dmitry Jemerov
09c6feddb6 Ask to update runtime library when increasing language version for module
(cherry picked from commit b0463fc)
2017-02-16 14:08:32 +01:00
Alexey Tsvetkov
9b44a7ea82 Minor: remove the word 'experimental' from Gradle IC description 2017-02-15 18:36:47 +03:00
Alexander Udalov
9013f50b28 Fix overload resolution ambiguity on *Array.clone() with runtime 1.0
#KT-16371 Fixed
2017-02-16 15:11:18 +03:00
Dmitry Jemerov
5614874bf7 Warn when running the compiler under Java 6 or 7
(cherry picked from commit 5537800)
2017-02-16 10:12:22 +01:00
Alexander Udalov
009f991ac3 Fix stub builder for builtins after cdeabf26b4
(cherry picked from commit 612481f0f4)
2017-02-16 10:43:53 +03:00
Alexander Udalov
9711854a2c Fix NPE from KotlinBuiltInDecompiler
This happened because of bae955aafd: similarly to the corresponding code in
the compiler, the IDE should also skip the metadata for kotlin.Cloneable when
decompiling built-ins because the deserializer is not going to resolve this
class from the metadata

(cherry picked from commit cdeabf26b4)
2017-02-16 01:36:51 +03:00
Dmitry Jemerov
ed98ff3dc0 Correctly locate build.gradle for modules created from source sets
(cherry picked from commit ecce92d)
2017-02-15 22:49:59 +01:00
Dmitry Jemerov
7e098e8827 Quickfixes to enable unsupported and experimental features handle API level correctly and support updating the runtime library
(cherry picked from commit 41c8168)
2017-02-15 22:49:48 +01:00
Vyacheslav Gerasimov
4b011767ef Fixed exception in getUastLocation of class annotation argument
#KT-16326 Fixed

(cherry picked from commit a2e429a)
2017-02-15 21:27:11 +03:00
Vyacheslav Gerasimov
324819d20b Fixed InvalidMirrorException in uast while getting annotation argument location
(cherry picked from commit 1452129)
2017-02-15 21:27:11 +03:00
Mikhail Glukhikh
4897af1ef9 Change log for 1.1-RC updated 2017-02-15 20:52:41 +03:00
Alexander Udalov
be0537f3f8 Suggest to provide explicit dependency on new kotlin-reflect
In case when there's kotlin-stdlib 1.1 and kotlin-reflect 1.0 in the classpath

(cherry picked from commit 8e407d548a)
2017-02-15 20:44:28 +03:00
Alexander Udalov
899ca8bc65 Infer API version from older runtime in compiler's classpath
For example, if you invoke kotlinc 1.1 with kotlin-stdlib 1.0 in the classpath,
we now infer -api-version 1.0 automatically

(cherry picked from commit 71fcb07fad)
2017-02-15 20:44:26 +03:00
Alexander Udalov
86ffd634ec Filter out files with the same paths in runtime version checker
To prevent listing them several times in the diagnostic message

(cherry picked from commit b56639a775)
2017-02-15 20:44:25 +03:00
Alexander Udalov
f30d0904fc Report warnings instead of errors in runtime version checker
(cherry picked from commit 8457ab7c58)
2017-02-15 20:44:23 +03:00
Alexander Udalov
d9b45f667d Support smart cast for nullability in LHS of class literal
#KT-16291 Fixed

(cherry picked from commit ba84338862)
2017-02-15 20:44:21 +03:00
Alexander Udalov
e159028c97 Serialize metadata for Cloneable and discard it during deserialization
#KT-16358 Fixed

(cherry picked from commit bae955aafd)
2017-02-15 20:44:19 +03:00
Alexander Udalov
11847c121a Rename FunctionImpl -> FunctionBase, restore abstract class FunctionImpl
This fixes the IncompatibleClassChangeError which happens when kotlin-reflect
1.0.x and kotlin-stdlib 1.1.x are in the classpath

 #KT-16358 In Progress

(cherry picked from commit 46bd64f59a)
2017-02-15 20:44:16 +03:00
Ilya Gorbunov
ba857a83ff Change log clarifications regarding stdlib 2017-02-15 18:15:02 +03:00
Dmitry Jemerov
7019dcf3b1 Fix Kotlin facet autodetection so that it actually works and stores the correct language/API level based on project dependencies
(cherry picked from commit 7704310)
2017-02-15 15:52:01 +01:00
Mikhail Glukhikh
46f7c37021 Change log for 1.1-RC updated
(cherry picked from commit 3bc322c)
2017-02-15 17:47:38 +03:00
Alexey Sedunov
70de1a7d2a Minor: Fix compilation 2017-02-15 16:42:10 +03:00
Yan Zhulanow
ec7b3c6240 Revert "Kapt3: Add generated source files to Java compile task after kapt execution. Filter only .java files."
This reverts commit 82c2ce3a33.
2017-02-15 16:26:17 +03:00
Yan Zhulanow
499b6c2b91 Kapt3: Fix annotation processor option passing 2017-02-15 16:26:16 +03:00
Alexey Sedunov
5d56da2567 Kotlin Facet: Facet migration workaround for the case pre-1.1-beta -> 1.1.rc+ (reset useProjectSettings to false for old configurations)
(cherry picked from commit 5d65e6b)
2017-02-15 14:42:42 +03:00
Alexey Sedunov
0e030241a6 Kotlin Facet: Detect language/API version by stdlib when "Use project settings" is enabled, but project-level language/api version is not specified explicitly
(cherry picked from commit 2e01f62)
2017-02-15 14:42:41 +03:00
Alexey Sedunov
1d3ff1d81a Kotlin Facet: Do not rewrite language/API version based on compiler arguments if they do not contain explicit language/API version
(cherry picked from commit 0d2122b)
2017-02-15 14:42:40 +03:00
Alexey Sedunov
358f572b1f Kotlin Facet: Synchronize version info on opening the configuration editor
(cherry picked from commit 2790fcf)
2017-02-15 14:42:39 +03:00
Anton Bannykh
5a14d97642 JS: concat vararg arguments using Kotlin.concat and Kotlin.concatPrimitive functions in order to be binary compatible with (Kotlin PrimitiveArray -> JS TypedArrays) mapping. 2017-02-15 14:32:12 +03:00
Dmitry Jemerov
d1f4c4c348 Use correct resolution facade for resolving cross-module links in KDoc comments
#KT-15647 Fixed

(cherry picked from commit 060a865)
2017-02-15 12:13:24 +01:00
Mikhail Glukhikh
44dd831e71 Change log for 1.1-RC added
(cherry picked from commit 4b7380b)
2017-02-15 12:50:28 +03:00
Alexey Sedunov
da5ddd76c8 Kotlin Facet: Fix detection of pre-1.1-beta JS-stdlib dependencies
(cherry picked from commit e1463f9)
2017-02-14 18:42:36 +03:00
Alexey Sedunov
fe62995274 Kotlin Facet: Reset all coroutine support flags before importing them frm Gradle
(cherry picked from commit 8c84717)
2017-02-14 17:26:20 +03:00
Stanislav Erokhin
f67f387daa Disable some features when LV=1.1 API=1.0.
Feature list:
 - bound callable references
 - local delegated properties
 - coroutines.

#KT-16017 Fixed

(cherry picked from commit b6fa10c)
2017-02-13 20:34:05 +03:00
Simon Ogorodnik
e9f33c4045 KT-16076 Completion inserts FQN kotlin.text.String
KT-14831 Don't add import statement and FQN on converting lambda to reference if typealias is used
KT-16088 Completion wrongly inserts FQN for `kotlin` package
 #KT-16076 fixed
 #KT-14831 fixed
 #KT-16088 fixed

(cherry picked from commit 2490318)
2017-02-13 16:53:43 +03:00
Ilya Gorbunov
5f24329dca Introduce 'takeUnless' function which is like 'takeIf' but with the predicate inverted.
#KT-7858

(cherry picked from commit fee676a281)
2017-02-13 16:11:21 +03:00
Ilya Gorbunov
c6e9e992a4 JS kotlin.dom: deprecate asElementList harder.
Minor: correct exception message.

(cherry picked from commit c6cb389591)
2017-02-13 16:10:27 +03:00
Ilya Gorbunov
c38180efa8 Make javaClass extension property inline to remove further references from Kotlin.
(cherry picked from commit 9a7405adc6)
2017-02-13 16:10:27 +03:00
Sergey Igushkin
683f61fdc2 Fixed Kotlin2Js output not being the output of the compileKotlin2Js tasks.
Therefore, fixed Kotlin2Js output not present in JAR.
Reworked the clean behavior in regard to compileKotlin2Js tasks.
Fixed duplicate source roots passed to the compiler.

Issues:
- #KT-15829 Fixed
- #KT-16267 Fixed
- #KT-15902 Fixed
2017-02-13 15:50:47 +03:00
Alexey Sedunov
8e5853e5c3 Kotlin Gradle Plugin: Extend implicit argument set
(cherry picked from commit 1452d7e)
2017-02-13 14:58:23 +03:00
Alexey Sedunov
4bbdeb00be Line Markers: Do not attempt to resolve suspend call candidates which are not call-like expressions
(cherry picked from commit 75c56d5)
2017-02-13 14:58:14 +03:00
Alexey Sedunov
45b060d0dd Kotlin Facet: Fix stdlib dependency detection
(cherry picked from commit 574a0e6)
2017-02-13 14:57:58 +03:00
Alexey Sedunov
5c065efa20 Kotlin Facet: Scan classpath backwards when looking for kotlin-gradle-plugin dependency
#KT-15899 Fixed

(cherry picked from commit 7fbca4e)
2017-02-13 14:57:47 +03:00
Alexey Sedunov
83ca7d9b64 Extract Function: Fix detection of suspend calls containing extracted parameters
#KT-16251 Fixed

(cherry picked from commit 3c6f329)
2017-02-13 14:56:54 +03:00
Alexey Sedunov
9166f5ba9d Kotlin Facet: Check contradictory values of "coroutine support" option
#KT-16109 Fixed

(cherry picked from commit ee120a6)
2017-02-13 14:56:53 +03:00
Stanislav Erokhin
7a65e59d39 Reserve yield if it isn't function call.
(cherry picked from commit 3efda0e)
2017-02-13 07:08:51 +03:00
Dmitry Jemerov
c91f6fabd1 Ugly deadlock workaround for KT-16149: members of DataBindingComponent are calculated via annotations search which causes resolve reentrering
(cherry picked from commit 1d225ebae30bc8de811344bac804f79d2279859f)
2017-02-11 08:53:21 +01:00
Stanislav Erokhin
49f1c95171 Change IS_PRE_RELEASE to false. 2017-02-10 20:31:33 +03:00
Ilya Gorbunov
d77f20dc63 Introduce ItemArrayLike interface and replace multiple asList adapters with the single one.
(cherry picked from commit ec01200997)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
f9fb6c6a34 Massive deprecations in kotlin.dom
(cherry picked from commit 41c980bcab)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
29eb286df4 Drop pre-1.0 deprecated dom helpers.
(cherry picked from commit 365f8d0256)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
becd00f33d Provide KDoc for js collection implementations.
(cherry picked from commit 287a513f23)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
9beabdeb34 Restrict visibility of AbstractMap.SimpleEntry in JS
(cherry picked from commit 2269b9839f)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
9c738177b8 KDoc for mutable abstract collections.
Document abstract overrides.

(cherry picked from commit fc7b1c8611)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
8f3cfb5b1b KDoc for read-only abstract collections
(cherry picked from commit ef5e53b37b)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
c2fd91da65 Add a note about generic parameter variance to Iterable, Collection, List, Set, Map and their mutable counterparts.
Minor: correct docs, code formatting.

(cherry picked from commit 7c54c48e00)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
a574943696 Deprecate javaClass with replacement this::class.java.
Suppress deprecation in diagnostics tests.

(cherry picked from commit b8de78dd43)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
69b302e4f6 Remove public synthetic annotation holder methods from public API dump.
(cherry picked from commit d4d647ab00)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
9eb3925048 Add deprecated parseInt overload without radix parameter to provide better replacement.
(cherry picked from commit 84f324e04f)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
ee977bc0a1 Add LowPriority annotation to deprecated functions to allow star-importing their replacements from kotlin.reflect.full.
(cherry picked from commit da81fb3)
2017-02-10 18:23:06 +03:00
Ilya Gorbunov
07629e8a48 Search java version in java.specification.version, prepare to that starting from java 9 it will contain only a single component.
(cherry picked from commit af443ac046)
2017-02-10 18:23:06 +03:00
Ilya Chernikov
8197240eec Make maven/aether dependencies optional in the script-util 2017-02-10 15:59:11 +01:00
Ilya Chernikov
175d74ce5f Get rid of daemon-client dependency on openapi, making others "provided" 2017-02-10 15:59:10 +01:00
Ilya Chernikov
c06592ed6c Move scripting options into separate panel 2017-02-10 14:41:31 +01:00
Alexey Sedunov
b34363317a Kotlin Facet: Do not show implicit compiler arguments in "Additional arguments" field
(cherry picked from commit ba73269)
2017-02-09 15:48:31 +03:00
Alexey Sedunov
2ab47b4d6b Kotlin Gradle Plugin: Expose default compiler arguments via compilation task API
(cherry picked from commit 52102d3)
2017-02-09 15:48:30 +03:00
Alexey Sedunov
aee36ac552 Kotlin Gradle Plugin: Postpone friend dependency collection until the actual compilation as it may cause an error during Gradle-IDEA project synchronization
#KT-16174 Fixed

(cherry picked from commit 615c316)
2017-02-09 15:48:29 +03:00
Alexey Sedunov
48c64e9b43 Kotlin Facet: Always parse argument string to proper compiler arguments bean
#KT-16137 Fixed
 #KT-16157 Fixed
 #KT-16206 Fixed

(cherry picked from commit 4325632)
2017-02-09 15:48:28 +03:00
Alexey Sedunov
d2284af69d Compiler Configuration: Minor UI improvements
(cherry picked from commit 396e9af)
2017-02-09 15:48:27 +03:00
Alexey Sedunov
f9e45a1cea Kotlin Facet: Support multiple configuration editor
#KT-15914 Fixed

(cherry picked from commit 0c331a3)
2017-02-09 15:48:26 +03:00
Alexey Sedunov
7710d4576d Kotlin Facet: Combine "General" and "Compiler" tabs
(cherry picked from commit 8849d0e)
2017-02-09 15:48:25 +03:00
Alexey Sedunov
733f1166af Rename/Find Usages: Disable text occurrence search for KtParameter
(cherry picked from commit 59fe744)
2017-02-09 15:48:24 +03:00
Alexey Sedunov
b98b2b6846 Kotlin Facet: Support multiple artifact Ids corresponding to target platform
(cherry picked from commit 79e67f4)
2017-02-09 15:48:24 +03:00
Anton Bannykh
f0fcb4c513 JS: companion object dispatch receiver translation fixed (KT-16160); imported function inlining fixed.
(cherry picked fom commit a74fffeac8)
2017-02-09 15:46:56 +03:00
Anton Bannykh
d265383968 JS: fixed inlining functions called through inheritor ("fake" override) from another module (#KT-16144)
(cherry picked from commit a2431f0d85)
2017-02-09 15:46:56 +03:00
Mikhael Bogdanov
103cd381f4 Fix for KT-16225: enumValues non-reified stub implementation references nonexistent method
#KT-16225 Fixed

(cherry picked from commit b1e2db2)
2017-02-09 10:59:54 +01:00
Dmitry Petrov
c8c8894f91 Fix https://ea.jetbrains.com/browser/ea_reports/1337846:
Properly handle AbbreviatedTypeBinding for error types.
Get rid of code duplication.
2017-02-09 12:39:02 +03:00
Denis Zharkov
8c829564f1 Initialize JvmBuiltins for module configuration used in test
This method is only used within tests, and they didn't fail
mostly by coincidence.

But because of more eager reading of
JvmBuiltIns.isAdditionalBuiltInsFeatureSupported (that checks if built-ins
have been initialized) these tests started failing

(cherry picked from commit f4690eb)
2017-02-09 09:59:23 +03:00
Denis Zharkov
9d1fec77b8 Simplify compatibility mode with ll=1.0 on JDK dependent built-ins
A lot of problem arise with current solution
(loading them with lowpriority annotation + additional call checkers):
- We errorneously treated ArrayList.stream as an existing method, while
  it's just a fake override from List
- The same problem arises when creating a class delegating to List.
  Also the latter case is failing with codegen internal error
  (see issue KT-16171)

The negative side of this solution is that instead of reporting meaningful
diagnostic, there will be UNRESOLVED_REFERENCE.
But it seems to be better than having strange problems like ones described above.

 #KT-16073 Fixed
 #KT-16171 Fixed

(cherry picked from commit 1bb40af)
2017-02-09 09:59:23 +03:00
Denis Zharkov
7000b3ef33 Prohibit unsupported suspend operators
contains/get/set operators don't work properly on both backends

Also add box test checking that 'compareTo' operator works just fine

 #KT-16219 Fixed

(cherry picked from commit 80638eb)
2017-02-09 09:59:23 +03:00
Denis Zharkov
8ab204819d Mark as UNSUPPORTED suspension points in default parameters
#KT-16124 Fixed
 #KT-16218 Open

(cherry picked from commit 4921bd8)
2017-02-09 09:59:23 +03:00
Denis Zharkov
6a31cd834a Add callee name to diagnostic about illegal suspension call
#KT-15938 Fixed

(cherry picked from commit 4ee818a)
2017-02-09 09:59:23 +03:00
Denis Zharkov
8ba9e0271f Refine cc7f0e2d83
getDispatchReceiver/getExtensionReceiver always return not-null value,
but in the absence of receiver this value is equal StackValue.none(), i.e.
has a size 1

The tests were passing because of the problems with the test framework:
4b9e20ab8c

(cherry picked from commit 81c3edf)
2017-02-09 09:59:23 +03:00
Denis Zharkov
9391ff4141 Fix codegen problem with safe-call on suspension point with two receivers
#KT-16145 Fixed

(cherry picked from commit cc7f0e2)
2017-02-09 09:59:23 +03:00
Denis Zharkov
d73d42cc23 Put startCoroutineUninterceptedOrReturn header to common stdlib
(cherry picked from commit 9697196)
2017-02-09 09:59:23 +03:00
Denis Zharkov
832e777b2a Introduce createCoroutineUnchecked intrinsic
Also use it for buildSequence implenentation

 #KT-16155 Fixed

(cherry picked from commit 4f6a77c)
2017-02-09 09:59:23 +03:00
Denis Zharkov
c1cd139396 Minor. Get rid of code duplications for resume call wrapping in stdlib
Use processBareContinuationResume instead

(cherry picked from commit 230564f)
2017-02-09 09:59:23 +03:00
Denis Zharkov
09a6e9c591 Optimize startCoroutine impls, move them to common stdlib
Do not wrap initial continuation for startCoroutine in SafeContinuation

This changes leaves only internal declarations and intrinsics as platform
dependent parts of the coroutine library, the rest parts (public API)
is implemented through them in common module

(cherry picked from commit 6dde567)
2017-02-09 09:59:23 +03:00
Denis Zharkov
4101206e12 Improve coroutines library layout
- Split CoroutinesLibrary into common and JVM parts
- Get rid of startCoroutine duplications
- Make suspendCoroutine implementation to be platform independent

(cherry picked from commit a65d862)
2017-02-09 09:59:23 +03:00
Denis Zharkov
fbe49d0cc9 Introduce startCoroutineUninterceptedOrReturn coroutine intrinsic
#KT-15716 Fixed

(cherry picked from commit 258ee0d)
2017-02-09 09:59:23 +03:00
Denis Zharkov
78e4295c2c Make createCoroutine return a safe continuation
#KT-15718 Fixed

(cherry picked from commit 29b0b30)
2017-02-09 09:59:23 +03:00
Denis Zharkov
426944744d Fix VerifyError in coroutines caused by null spilling
While within a method by the JVM spec null-value has a special
Nothing-like type, when we spill it for a coroutine, we must choose
some real type to CHECKCAST to after restoring the variable's value.

But the problem is that such a real type depends on usage of that null value,
and there may be more than one usage.

The solution is not to spill such variables into fields, but instead
init them with ACONST_NULL after each suspension point

 #KT-16122 Fixed

(cherry picked from commit cc28fec)
2017-02-09 09:59:23 +03:00
Denis Zharkov
52a310f202 Support parameter destructuring in suspend lambdas
#KT-16092 Fixed

(cherry picked from commit 529b526)
2017-02-09 09:59:23 +03:00
Ilya Chernikov
894ee4ce4f Convert line endings when creating ReplCodeLine, fixes KT-15861 2017-02-08 20:54:27 +01:00
Simon Ogorodnik
08915389e2 Fix for complete slowdown of DefaultImportProvider after introducing languageVersion for default imports
KT-16243 Very slow completion after variable of type `ArrayList`
 #KT-16243 fixed

(cherry picked from commit a9f2f5c)
2017-02-08 21:32:48 +03:00
Anton Bannykh
fc6465084b JPS review fixes: simplified the code and fixed a bug in JpsJsModuleUtils.getDependencyModulesAndSources 2017-02-08 21:22:37 +03:00
Anton Bannykh
beff463a92 JPS: fixed duplicate meta.js in case of multiple source roots in the same module.
(cherry picked from commit f0e3c87b84)
2017-02-08 21:22:37 +03:00
Anton Bannykh
b67e3f824c JS: fixed support for test source roots (KT-6627)
(cherry picked from commit 289a7a9cc3)
2017-02-08 21:22:37 +03:00
Yan Zhulanow
c578e8b8f1 Kapt3: Generate import statements in stubs 2017-02-08 19:29:31 +03:00
Yan Zhulanow
0395d90ef7 Kapt3: Serialize annotation processor options to base64 to support spaces in option values 2017-02-08 19:29:25 +03:00
Yan Zhulanow
dfb21a81a0 Kapt3: Invoke integration tests with the Kotlin runtime in the compile classpath (this fixes integration tests, nullability annotations from org.jetbrains were not found) 2017-02-08 19:29:18 +03:00
Yan Zhulanow
4c69df28b4 Kapt3: Allow users to disable error type correction (and now it's disabled by default) 2017-02-08 19:28:40 +03:00
Yan Zhulanow
da1dc9cfe7 Kapt3: Use the javac's finalCompiler log to determine if there were any annotation processing errors (KT-16176) 2017-02-08 19:28:29 +03:00
Yan Zhulanow
3413cb977c Minor: Update test data because of KT-15697 2017-02-08 19:28:20 +03:00
Yan Zhulanow
d9c54449a4 Minor: Remove obsolete JAVA_FILE_PARSING_ERROR constant, fix corresponding test 2017-02-08 19:28:13 +03:00
Yan Zhulanow
cc6127a343 Kapt3: Ignore declarations with illegal Java identifiers (KT-16153) 2017-02-08 19:28:05 +03:00
Yan Zhulanow
e44d0c4d5d Kapt3: Fix working in verbose mode (NPE in JavacFiler.java:597) (KT-16146) 2017-02-08 19:27:53 +03:00
Yan Zhulanow
e6c27e7f32 Kapt3: Write Intellij annotations (NotNull/Nullable) to stubs 2017-02-08 19:26:07 +03:00
Yan Zhulanow
82c2ce3a33 Kapt3: Add generated source files to Java compile task after kapt execution. Filter only .java files.
This is needed to generate Kotlin files using kapt.
2017-02-08 19:08:43 +03:00
Sergey Igushkin
679efb61ab Fixed Kotlin2JsCompile not picking dependencies from configurations other than compile.
Example:

	apply plugin: 'kotlin2js'

    dependencies {
    	...
    	testCompile "org.jetbrains.kotlin:kotlin-test-js:$kotlin_version"
    }

Here, the `:compileTestKotlin2Js` task did not pick the dependency and used the `compile` classpath.
This has been fixed.

Also, fixed `testCompileTestCouldAccessProduction` and added `testJsCustomSourceSet`.
2017-02-08 17:29:50 +03:00
Alexander Udalov
ab44f5cc0e Deprecate kotlin.reflect.findAnnotation with ERROR
(cherry picked from commit cfe159181d)
2017-02-08 13:08:12 +03:00
Alexander Udalov
277b1cbf1e Annotate findAnnotation and IllegalPropertyDelegateAccessException with SinceKotlin(1.1)
(cherry picked from commit 5987e8a47c)
2017-02-08 13:07:17 +03:00
Alexander Udalov
1ceb7f5656 Annotate new API in runtime.jvm with SinceKotlin(1.1)
(cherry picked from commit 845d6526b0)
2017-02-08 13:07:08 +03:00
Alexey Andreev
ccffa26add JS: don't treat library without JS metadata as error, report warning and continue instead. See KT-16158 2017-02-08 12:01:08 +03:00
Alexey Andreev
cfc08328e0 JS: escape quotes in some diagnostics with parametrized messages 2017-02-08 11:52:25 +03:00
Mikhael Bogdanov
f53c5ed30e Use appropriate ApiVersion if LanguageVersion is specified in test
(cherry picked from commit 37a94ea)
2017-02-08 09:11:52 +01:00
Mikhael Bogdanov
fe44159962 Revert 'Temporary disable new intrinsics usage in ieee754 arithmetic'
(cherry picked from commit 5095ef1)
2017-02-08 09:11:49 +01:00
Simon Ogorodnik
74e9a632a9 KT-16110 Missing suspend keyword completion inside generic arguments
#KT-16110 fixed

(cherry picked from commit be7158e)
2017-02-07 20:53:56 +03:00
Roman Elizarov
bb1354660d Fixed corotine context performance by using reference equality for contexts and keys
Added documentation explaining that keys are compared by reference
2017-02-07 19:38:34 +03:00
Nikolay Krasko
b95875536f Return old hack with returning null as file scope for standard scripts
(cherry picked from commit ef55bd1)
2017-02-07 15:14:49 +01:00
Ilya Chernikov
fb74040dde Fix version calculation code 2017-02-07 13:39:49 +01:00
Ilya Chernikov
4cf2bce003 Set jvmTarget property for repl compilation from sys prop or java version, fixes KT-16126 2017-02-07 13:39:49 +01:00
Mikhail Glukhikh
982e67276f Join declaration and assignment: extra descriptor check for assignment of the same property
(cherry picked from commit 81e083a)
2017-02-07 12:48:06 +03:00
Mikhail Glukhikh
9a255169ee Join declaration & assignment: do not suggest for non-first line of init / constructor #KT-15545 Fixed
(cherry picked from commit 153bc79)
2017-02-07 12:47:53 +03:00
Mikhail Glukhikh
cdeb2e80b5 Join declaration & assignment: treat assignment with this. correctly #KT-16000 Fixed
(cherry picked from commit ea6e3c8)
2017-02-07 12:47:40 +03:00
Mikhail Glukhikh
b2c7521277 Correct order added for 'suspend' modifier #KT-16104 Fixed
(cherry picked from commit 6db698f)
2017-02-07 12:47:00 +03:00
Alexander Udalov
b416769434 Update stdlib reference and binary compatibility test data
After 5cffb38
2017-02-07 10:20:34 +03:00
Alexander Udalov
ad5e3a52ff Do not import "kotlin.comparisons" by default for language version 1.0
#KT-16199 Fixed

(cherry picked from commit b780e6d374)
2017-02-07 10:19:12 +03:00
Alexander Udalov
0a54b6104a Update stdlib reference and binary compatibility test data
After 5cffb38
2017-02-06 19:46:42 +03:00
Alexander Udalov
f516b21e5b Rename DoubleColonLHS.Expression.isObject -> isObjectQualifier
(cherry picked from commit e58baa51ae)
2017-02-06 19:44:51 +03:00
Alexander Udalov
f64a25801f Fix callable reference to constructor of nested class in object
#KT-15951 Fixed

(cherry picked from commit 478352b7e7)
2017-02-06 19:44:47 +03:00
Alexander Udalov
77fc61ce73 Improve error on runtime of version different than API version
Include the actual runtime version in the error message

(cherry picked from commit ca1ed850b8)
2017-02-06 19:44:41 +03:00
Alexander Udalov
eaaf656ec9 Report different runtime versions earlier than incompatibility with API version
Previously if you had kotlin-reflect 1.0 and kotlin-runtime 1.1 in the
classpath, checkCompatibleWithApiVersion was invoked first, and an error was
reported that suggested to pass "-api-version" to the compiler. However, no
correct "-api-version" can be passed in this case, because
checkMatchingVersions would then report that the two libraries have different
versions anyway. So, now we first ensure that all libraries have the same
version, and only then do check if the version is correct

(cherry picked from commit 57f8ef372f)
2017-02-06 19:44:35 +03:00
Alexander Udalov
bb892a8510 Check API version instead of language in JVM runtime versions checker
It should be a valid case to invoke the 1.1 compiler with the 1.0 runtime in
the classpath and "-api-version 1.0". However, previously it was an error and
the message suggested to specify "-language-version 1.0". Language version 1.0
implies API version 1.0, so this effectively made the "-api-version" option
useless

(cherry picked from commit 3a7eec8635)
2017-02-06 19:44:31 +03:00
Alexander Udalov
936e787d58 Do not use LanguageVersionSettings.languageVersion directly
(cherry picked from commit 389ddf26b3)
2017-02-06 19:44:24 +03:00
Simon Ogorodnik
b82ad57472 KT-15744 Intention to import sleep wrongly suggests Thread.sleep
#KT-15744 fixed

(cherry picked from commit 98269c1)
2017-02-06 15:12:28 +03:00
Denis Zharkov
1c4ac5a74b Fix annotation deserialization on suspend functions
Use proper initial/frontend version of suspend descriptor
when writing METHOD_FOR_FUNCTION, because serializer uses this version

Also this commit contains adjustments of neighboring code to the describe
change

 #KT-16093 Fixed
2017-02-03 17:43:42 +03:00
Dmitry Jemerov
1a74058dc8 Find Usages checks that the signature of the method a property usage resolves to matches the signature of the method being searched
#KT-15291 Fixed

(cherry picked from commit 9594147)
2017-02-03 14:42:21 +01:00
Dmitry Jemerov
5ed5008db4 When calculating import candidates, skip redundant deduplication performed by PsiShortNamesCacheImpl
#KT-16071 Fixed

(cherry picked from commit faac1c3)
2017-02-03 14:42:21 +01:00
Dmitry Jemerov
34192a1785 Calculate autoimport candidates in daemon thread when import fix is created, not in EDT
(cherry picked from commit 1d37c8c)
2017-02-03 14:42:21 +01:00
Dmitry Jemerov
9ce396ad54 Look at parent project when checking whether the Kotlin Maven plugin is applied in a module
#KT-15954 Fixed

(cherry picked from commit f73d32a)
2017-02-03 14:42:21 +01:00
Mikhail Glukhikh
04364f4b3e Generate test support: error hints moved out of write action
(cherry picked from commit 4c2ae5e)
2017-02-03 14:38:12 +03:00
Mikhail Glukhikh
6028a4facc Let implement interface: create write action manually to avoid AWT events inside
(cherry picked from commit d8f0167)
2017-02-03 14:37:58 +03:00
Mikhail Glukhikh
1aba4fe4da Generate equals or hash code: do not run in write action to avoid AWT events inside
(cherry picked from commit b839e52)
2017-02-03 14:37:45 +03:00
Mikhail Glukhikh
54367bd8e8 Move file to package matching directory: run write action manually to avoid AWT events inside
(cherry picked from commit a204e57)
2017-02-03 14:37:31 +03:00
Mikhail Glukhikh
5c73c59b9e Create kotlin sub class: run write action manually to avoid AWT events inside
(cherry picked from commit 72b8b85)
2017-02-03 14:37:18 +03:00
Mikhail Glukhikh
a0c3187a93 Generate test support: ask everything before write action to avoid AWT events inside
(cherry picked from commit 9664a06)
2017-02-03 14:37:04 +03:00
Mikhail Glukhikh
9b118ff81d Create test intention: do not start in write action to avoid AWT events inside
(cherry picked from commit 70c5d8b)
2017-02-03 14:36:50 +03:00
Mikhail Glukhikh
483b59516c if-then --> safe access: run write action manually to avoid AWT events inside
(cherry picked from commit 07f0635)
2017-02-03 14:36:36 +03:00
Mikhail Glukhikh
607db11011 if-then --> elvis: run write action manually to avoid AWT events inside
(cherry picked from commit 834c3f5)
2017-02-03 14:36:21 +03:00
Mikhael Bogdanov
d04b7e9784 Temporary disable new intrinsics usage in ieee754 arithmetic
(cherry picked from commit aa3f64b)
2017-02-03 09:01:14 +01:00
Mikhael Bogdanov
0320fe8261 Use proper type for nullability check in 'calcTypeForIEEE754ArithmeticIfNeeded'
(cherry picked from commit 560226c)
2017-02-03 09:01:11 +01:00
Mikhael Bogdanov
cf99fc4908 Added intrinsics for nullable Double/Float equals check
(cherry picked from commit 5cffb38)
2017-02-03 09:01:05 +01:00
Mikhael Bogdanov
52c7bdf280 Update for "Fix for KT-15868: NPE when comparing nullable doubles"
(cherry picked from commit 87529f9)
2017-02-03 09:00:58 +01:00
Mikhael Bogdanov
7ab3afd00d Test data update 2017-02-02 09:37:05 +01:00
Mikhail Glukhikh
f49ef8e919 Stub creation from cls fixed for suspend function types 2017-02-02 00:47:05 +03:00
Mikhail Glukhikh
0e1b61b422 Change log: last-shot issues for 1.1-Beta2
(cherry picked from commit 5f6d65c)
2017-02-01 21:08:15 +03:00
Dmitry Jemerov
aaddfa8561 Advance binary stub version due to coroutine metadata format changes
(cherry picked from commit 66f7382)
2017-02-01 18:13:30 +01:00
Mikhael Bogdanov
05cfe4ca39 Fix for KT-15868: NPE when comparing nullable doubles
#KT-15868 Fixed

(cherry picked from commit a2c5c94)
2017-02-01 17:45:13 +01:00
Alexey Tsvetkov
65437a5c21 Increment data container cache version
Reason: coroutines metadata format has been changed (since 1.1-beta-1)
2017-02-01 18:51:11 +03:00
Alexey Tsvetkov
1026605627 Avoid checking incremental caches versions if corresponding property is set 2017-02-01 18:51:11 +03:00
Alexey Tsvetkov
a08bc11064 Refactoring: extract checking caches versions to function 2017-02-01 18:51:11 +03:00
Stanislav Erokhin
5c694bf95b Change IS_PRE_RELEASE to true 2017-02-01 18:27:42 +03:00
Stanislav Erokhin
44ea407de5 Advance JvmMetadataVersion to 1.1.5 after change serialization format for suspend function types. 2017-02-01 18:27:41 +03:00
Yan Zhulanow
a455b46073 Kapt: Fix error messages map name 2017-02-01 18:13:43 +03:00
Yan Zhulanow
3c22087a50 Kapt3: Allow annotations with Kotlin-only targets, such as PROPERTY (KT-15697) 2017-02-01 18:13:42 +03:00
Yan Zhulanow
52aead1143 Kapt: Fix javac error reporting in Kotlin daemon, also fix parsing error reporting (KT-15524) 2017-02-01 18:13:41 +03:00
Mikhail Glukhikh
7ee259de02 Change log: 1.1-RC --> 1.1-Beta2 2017-02-01 18:11:05 +03:00
Alexey Sedunov
1102517554 Kotlin Facet: Test longer afrifact name first when detecting module platform to prevent false positive on artifact name which is a prefix of another afrifact name
(cherry picked from commit 9adc183)
2017-02-01 16:57:10 +03:00
Stanislav Erokhin
3518cbeb12 Fix serialization for suspend function types.
Since now `suspend (Int) -> String` will be serialized as `(Int, Continuation<String>) -> Any?` + suspend flag.

Before this change such type serialized like this: Function2<Int, String> + suspend flag. And yes, type `Function2<Int, String>` isn't correct, because Function2 expect 3 type arguments.
We have special logic for this case and we deserialize such error-written types correctly.
2017-02-01 16:39:51 +03:00
Mikhail Glukhikh
ef519dc14f Minor change log fix 2017-02-01 14:39:50 +03:00
Alexey Sedunov
d6663a0c77 Kotlin Facet: Ignore invalid platform-specific compiler arguments
(cherry picked from commit 55e7391)
2017-02-01 12:41:11 +03:00
Mikhail Glukhikh
536181bf06 1.1-RC change log polishing
(cherry picked from commit dc57f97)
2017-01-31 19:13:30 +03:00
Alexey Tsvetkov
0e30e13dec Update ChangeLog.md 2017-01-31 19:10:06 +03:00
Alexey Tsvetkov
8a345be259 Fix kapt1 with stubs test to main internal references 2017-01-31 19:07:11 +03:00
Alexey Tsvetkov
1608fde341 Revert "Avoid having -d and -module set at the same time"
This reverts commit ac241e2676.
2017-01-31 19:07:11 +03:00
Ilya Gorbunov
f7d731d1b9 Edit 1.1-RC changelog regarding Standard Library and JS 2017-01-31 18:44:09 +03:00
Stanislav Erokhin
00018650f8 Use LanguageVersionSettings from project instead of LanguageVersionSettingsImpl.DEFAULT for sdk and library resolver.
General effect will be the following:
- all member scopes for libraries and JDK will be constructed with -language-version/-api-version specified in project settings
- for modules with another (not like in project settings) -api-version or -language-version we will have not correct member scope -- for example we will see typealiases from such libraries.

#KT-15979 Fixed
2017-01-31 18:13:32 +03:00
Mikhail Glukhikh
cc4ee6d888 1.1-RC: change log (final?) update
(cherry picked from commit 8d48452)
2017-01-31 17:31:41 +03:00
Alexey Tsvetkov
ac241e2676 Avoid having -d and -module set at the same time
#KT-14619 fixed
2017-01-31 16:52:32 +03:00
Alexey Tsvetkov
d59b9e7059 Fix annotation processors outputting to classes dir with kapt 3
#KT-15915 fixed

 Annotation processor can access a classes directory provided by AP environment.
Previously kapt 3 was using kotlin-classes directory as a a classes directory.
However compileKotlin task does not expect this.
Also having multiple tasks with the same output dir is a bad practise in Gradle.

This change introduces a separate directory for classes generated by kapt 3.
Its output is copied to a resulting classes dir (just as a kotlin-classes dir).
2017-01-31 16:52:27 +03:00
Alexey Tsvetkov
10079ceba3 Fix downgrading from 1.1 to 1.0.x in Gradle
If @Input property is added in new plugin version
and this property has a new type (a class/enum which is not presented in previous plugin)
then downgrading leads to an exception,
because Gradle tries to deserialize the property value from its caches,
but the type of value does not exist.

Workaround: add new String property.
2017-01-31 16:52:23 +03:00
Alexey Tsvetkov
4c3f221c38 Fix exception when Groovy lazy string (GString) is in freeCompilerArgs
#KT-15500 fixed

GString is an object that represents string literal like `"${project.name}"`
in Groovy. It is not an instance of string.
Groovy automatically converts GString to String when it is passed where String is expected.
However freeCompilerArgs is a List<String>, so type parameter info is lost at runtime.
When iterating freeCompilerArgs in Kotlin as a list of string, an exception
is thrown because GString cannot be casted to String (toString should be called instead).
2017-01-31 16:52:19 +03:00
Dmitry Jemerov
66db1449d1 Make sure that we don't have multiple coroutine status flags in the facet settings if one flag was set before parsing the command line options and another is specified through the command line options.
#KT-16075 Fixed

(cherry picked from commit 62e1d49)
2017-01-31 14:33:14 +01:00
Alexander Udalov
0bbb53a03d JS: rename "-library-files" argument to "-libraries" and change separator
Use the system separator (':' or ';') instead of commas

 #KT-16083 Fixed

(cherry picked from commit 464820458e)
2017-01-31 16:27:44 +03:00
Dmitry Jemerov
e069aad656 Don't show "Convert lambda to reference" for lambdas passed to suspend functions
#KT-16072 Fixed

(cherry picked from commit ffa3cf0)
2017-01-31 13:43:38 +01:00
Mikhail Glukhikh
5823d05d32 1.1.0: change log from previous releases changed to the reference link 2017-01-31 15:23:29 +03:00
Mikhail Glukhikh
a8c35f3cb7 Change log update for 1.1.0
(cherry picked from commit 7021b0b)
2017-01-31 15:22:08 +03:00
Simon Ogorodnik
3befac7138 KT-14252 Completion could suggest constructors available via typealiases
#KT-14252 fixed

(cherry picked from commit c2ba4e3)
2017-01-31 15:17:05 +03:00
Denis Zharkov
b4e2705a99 Prohibit inline lambda parameters of suspend function type
#KT-16068 Fixed
2017-01-31 14:57:56 +03:00
Stanislav Erokhin
b22044216a Do not show url for multi platform projects.
(cherry picked from commit 67835b6)
2017-01-31 13:12:27 +03:00
Mikhail Zarechenskiy
1531915c1b Introduce language feature for type inference on generics for callable references
#KT-16061 Fixed
2017-01-31 01:43:26 +03:00
Ilya Gorbunov
273ea38e01 Fix tests after introducing exlcusions to default imports of kotlin.js package.
(cherry picked from commit 38b79a5)
2017-01-31 00:12:35 +03:00
Ilya Gorbunov
0b5baabfb2 Do not use Math in common code.
(cherry picked from commit 33f3106)
2017-01-31 00:12:34 +03:00
Ilya Gorbunov
d4a82ffafe Add explicit imports of kotlin.js.* to stdlib where required.
(cherry picked from commit 66abea1)
2017-01-31 00:12:32 +03:00
Ilya Gorbunov
6d489f2d17 Add explicit imports of kotlin.js.* to generated files.
(cherry picked from commit 25c3064)
2017-01-31 00:12:30 +03:00
Ilya Gorbunov
4eca1585e7 Add exclusions to JS platform default imports
(cherry picked from commit cd5f68f)
2017-01-31 00:12:28 +03:00
Ilya Gorbunov
0ada85d692 Remove test for named native
(cherry picked from commit f4ef98c)
2017-01-31 00:12:27 +03:00
Ilya Gorbunov
7726e01bcc Change LoadBuiltinsTest testData, add runtime and import to box tests.
#KT-16030

(cherry picked from commit c4a0bb7)
2017-01-31 00:12:25 +03:00
Ilya Gorbunov
44867affbe Retract bitwise operators from builtins for Byte and Short and add them as extensions in kotlin.experimental package in stdlib.
#KT-16030

(cherry picked from commit 4ac7be9)
2017-01-31 00:12:23 +03:00
Dmitry Jemerov
42dd6453fe Minor fixes for stdlb kdoc
(cherry picked from commit 8968d56)
2017-01-31 00:12:22 +03:00
Nikolay Krasko
cf9af05420 Stop in the method with suitable name if no descriptor found
Absence of descriptor is possible when sources are outdated or absent.
Early stop is better than iterating in step into till the program end.

(cherry picked from commit 563196a)
2017-01-30 21:47:56 +03:00
Nikolay Krasko
db77866cb7 Fix smart step into functions call with suspend lambdas (KT-14700)
#KT-14700 Fixed

(cherry picked from commit 4a4a825)
2017-01-30 21:47:47 +03:00
Nikolay Krasko
3e40bc15b3 Exclude errors descriptors from the set of conflicting declarations
Resolve hanging in evaluate expression

(cherry picked from commit 2add36e)
2017-01-30 21:47:24 +03:00
Alexander Udalov
1bf7e9cbad Increase SOURCE_STUB_VERSION
Because of a974ed1 and b9f9894

(cherry picked from commit ad0178ee64)
2017-01-30 20:33:21 +03:00
Alexander Udalov
f516a08415 Report error on callable reference or class literal with "-no-stdlib"
Also workaround the NoSuchElementException that was happening because error
type never has any type arguments

 #KT-14547 Fixed

(cherry picked from commit 8811165de8)
2017-01-30 20:33:21 +03:00
Alexander Udalov
c6ad7ffeca Minor, fix typo in assertion message
(cherry picked from commit 7371dc9b54)
2017-01-30 20:33:21 +03:00
Alexander Udalov
2fe8f449b3 Add hint to use "-language-version", when applicable, in JVM runtime checker
(cherry picked from commit 424afba246)
2017-01-30 20:33:21 +03:00
Alexander Udalov
d5f692c206 Refactor JvmRuntimeVersionsConsistencyChecker for readability
(cherry picked from commit 7167139c2e)
2017-01-30 20:33:21 +03:00
Alexander Udalov
24c0e4fea8 Do not report error on libraries that bundle Kotlin runtime in classpath
Instead, report a strong warning, suggesting to remove such libraries from the
classpath

 #KT-15995 Fixed

(cherry picked from commit 9e877b4a9e)
2017-01-30 20:33:21 +03:00
Alexander Udalov
9b75934b47 Slightly refactor inline functions at serializationUtils.kt
Extract large bodies to separate functions, use KType.classifier instead of
KClass.createType

(cherry picked from commit 2d975d74cb)
2017-01-30 20:33:21 +03:00
Alexander Udalov
70703c6184 Fix JvmBuildMetaInfoTest.testSerialization
Do not check against hard-coded values of parameters, because they might be
changed a lot in the future

(cherry picked from commit f6c3aa0807)
2017-01-30 20:33:21 +03:00
Mikhail Glukhikh
d0cb701907 Change log update for 1.1.0
(cherry picked from commit 8bf233e)
2017-01-30 20:22:33 +03:00
Yan Zhulanow
4b41ccdb72 Generate enum values with bodies properly (KT-15803) 2017-01-30 20:14:56 +03:00
Yan Zhulanow
d7640a7047 Kapt: Allow empty .kt files list in kapt in order to support kapt with Java-only source files. (KT-15675) 2017-01-30 20:14:50 +03:00
Alexey Andreev
5adc19e4da JS: don't fail when generating signature for function which refers to undefined type
(cherry picked from commit d0b7dc8)
2017-01-30 19:57:05 +03:00
Alexey Sedunov
9f9287368c Spring Support: Consider declaration open if it's supplemented with a preconfigured annotation in corresponding compiler plugin
#KT-15444 Fixed
2017-01-30 17:46:11 +03:00
Alexey Andreev
f1970ac7c8 JS: don't report error when FAKE function overrides external function with optional parameters. Report only when it overrides at least two such functions. See KT-15961
(cherry picked from commit 06e8f7b328)
2017-01-30 17:28:48 +03:00
Anton Bannykh
141803b156 JS: char boxing
(cherry picked from commit 77aa685496)
2017-01-30 17:03:44 +03:00
Denis Zharkov
fbca946420 Exclude coroutine inrinsics and internal packages
#KT-16018
2017-01-30 16:49:14 +03:00
Denis Zharkov
a7054bce15 Fix coroutine-related VerifyError
The problem was that we spilled the `origin` variable (see test) as Object, because
we determined the type of merge(null, String) incorrectly.

 #KT-15973 Fixed
2017-01-30 16:49:14 +03:00
Dmitry Petrov
0d8a4b61a6 Fix testData in smart completion test
(abbreviation is preserved for 'arrayListOf').
2017-01-30 16:49:14 +03:00
Simon Ogorodnik
fd349ae104 Revert "KT-14252 Completion could suggest constructors available via typealiases"
Reverted due problems with test
This reverts commit 0ad979823e.
2017-01-30 16:47:38 +03:00
Simon Ogorodnik
0ad979823e KT-14252 Completion could suggest constructors available via typealiases
#KT-14252 fixed

(cherry picked from commit 55eeb74)
2017-01-30 16:25:42 +03:00
Dmitry Jemerov
fcb2e5ed19 Register ControlFlowFactory in KotlinCoreProjectEnvironment
#KT-16047 Fixed

(cherry picked from commit 3a3cf04)
2017-01-30 14:14:17 +01:00
Alexander Udalov
57a9ec8b29 Rename JsBinaryVersion -> JsMetadataVersion
For consistency with JvmMetadataVersion

(cherry picked from commit 167155388d)
2017-01-30 16:13:21 +03:00
Alexander Udalov
3373e49fd0 Promote severity of configuration warnings to STRONG_WARNING
The reason is that these configuration problems may be the reason of
compilation errors, but they were hidden from the output because warnings are
not reported when there's at least one error

(cherry picked from commit e9a737b85a)
2017-01-30 16:13:18 +03:00
Alexander Udalov
a008a4e8c3 Introduce CompilerMessageSeverity.STRONG_WARNING
This is a severity for mandatory warnings, i.e. those which should be reported
in any case, even if there are compilation errors

(cherry picked from commit 7ac96163ac)
2017-01-30 16:13:15 +03:00
Alexander Udalov
17d0daff86 Advance JvmMetadataVersion to 1.1.4, change IS_PRE_RELEASE to false
Kotlin 1.1 is no longer considered a pre-release

(cherry picked from commit 268d10d3f0)
2017-01-30 16:13:12 +03:00
Alexander Udalov
2be9922b71 Minor, remove unnecessary logging for valid erroneous case
It seems that it's normal for VirtualFile in this place to be invalid in this
way

(cherry picked from commit 1025fe9307)
2017-01-30 16:13:08 +03:00
Alexander Udalov
e25ce9548e JS: do not require "id" in the File protobuf message
(cherry picked from commit 933bcb3511)
2017-01-30 16:13:05 +03:00
Zalim Bashorov
45a7fa9f08 KJS: mark as inline only some functions form js stdlib
(cherry picked from commit 0dd3f11)
2017-01-30 15:44:27 +03:00
Zalim Bashorov
b1bf048295 KJS: change visibility of subSequence helper function to internal to avoid to use it directly from kotlin
(cherry picked from commit a49ad3c)
2017-01-30 15:44:18 +03:00
Zalim Bashorov
4f906ac65f KJS: rename baseClass field in metadata to interfaces since we plan to store there only implemented interfaces (see KT-15037)
(cherry picked from commit d5dca38)
2017-01-30 15:44:10 +03:00
Zalim Bashorov
eb03c50ca8 KJS: turn Json class into external interface
#KT-12712 Fixed

(cherry picked from commit 1b8b6be)
2017-01-30 15:43:52 +03:00
Dmitry Jemerov
44b156e1a7 Disable "Create type alias from usage" fix when language level doesn't support type aliases
#KT-16036 Fixed

(cherry picked from commit f0e8907)
2017-01-30 12:40:30 +01:00
Dmitry Jemerov
b3754e7194 Disable "Introduce type alias" refactoring when type aliases aren't supported by the current language level
(cherry picked from commit 17c73ce)
2017-01-30 12:40:21 +01:00
Dmitry Jemerov
fde2b7607d Exclude keywords from completion if the corresponding feature is unsupported by the language level selected for the module
(cherry picked from commit 720da17)
2017-01-30 12:36:27 +01:00
Alexander Udalov
51c510fb0c Make KTypeProjection's constructor public
To make it easier to create a KTypeProjection instance given a KVariance
instance (otherwise you currently need to do a "when" on it). Also it's exposed
via automatically generated "copy" anyway
2017-01-30 11:37:38 +03:00
Alexander Udalov
770cbad36f JS: drop "-kjsm" flag, merge logic with "-meta-info"
#KT-16049 Fixed
2017-01-30 11:37:37 +03:00
Alexander Udalov
350b89e14e JS: minor, drop obsolete VFS_PROTOCOL 2017-01-30 11:37:36 +03:00
Alexander Udalov
5002f7159a JS: write full version (major.minor.patch) to .meta.js 2017-01-30 11:37:35 +03:00
Alexander Udalov
34ca29cee7 Do not crash JS decompiler on non-existing .jar entries
See the comment for clarification
2017-01-30 11:37:34 +03:00
Alexander Udalov
2db2c449f5 Update tests on decompiled text for JS
Because .kjsm files now contain all declarations from the package (contrary to
the JVM decompiler which produces one file for one class/package facade), some
common decompiled text tests started to behave differently on JVM and JS.
Update two of them (Modifiers, ClassWithClassObject) to make results the same,
copy another (TypeAliases) to JVM-/JS-specific tests with different outputs
2017-01-30 11:37:33 +03:00
Alexander Udalov
1fe5fbff5b Drop tests on JS decompiled text / stub consistency
They're no longer needed because the logic of the decompiler / stub builder is
now trivial (see KotlinJavaScriptDeserializerForDecompiler,
KotlinJavaScriptStubBuilder) and after it's merged to the decompiler for
built-ins, it's going to be tested anyway with BuiltInDecompilerConsistencyTest
2017-01-30 11:37:32 +03:00
Alexander Udalov
3ede93d496 JS: simplify KotlinJavascriptSerializationUtil
Inline recently introduced SerializerCallbacks
2017-01-30 11:37:32 +03:00
Alexander Udalov
00ffa08659 JS: serialize .kjsm package-wise, adapt decompiler & stub builder
Instead of multiple .kjsm files for different classes and .kotlin_string_table,
.kotlin_file_table, .kotlin_classes files for each package, serialize the
contents of each package to a single foo/bar/baz/baz.kjsm file. The short name
of the file is the last segment in the FQ name of the package, or
"root-package" if the package is root.

There are two main reasons for this change:
1) Such structure takes less space, is more IO-friendly and will not cause
   multiple exceptions as the old one, where we sometimes tried to read
   non-existing files
2) This is exactly the same format that is used to serialize built-in
   declarations (.kotlin_builtins) at the moment, which will allow us to reuse
   some code

Also write a separate Header protobuf message to the beginning of the .kjsm
file. This will be used as arguments of the kotlin.Metadata annotation are used
in the JVM-specific parts of the compiler: to be able to provide some general
information about the binary file without parsing the whole protobuf data.

This commit breaks decompiled text & stub builder consistency tests. This is OK
because they're removed in a future commit.

Fixes EA-79605, EA-81947, EA-84277 and maybe EA-86787

 #KT-10894 Fixed
 #KT-14124 Fixed
 #KT-15755 Fixed
2017-01-30 11:37:31 +03:00
Alexander Udalov
4cc3212c9a JS: do not generate .meta.js and .kjsm for built-ins 2017-01-30 11:37:30 +03:00
Alexander Udalov
b1b0770a86 JS: improve binary representation format of metadata in .meta.js
Instead of writing many different files and serializing this "virtual file
system" to a byte array in a protobuf message, just write the needed stuff
directly, as fields in the Library message. Make it consist of many Part
messages, where the Part message is equivalent to the BuiltIns message in
builtins.proto. The next step would be to combine Library.Part and BuiltIns,
which will allow us to simplify some serialization-related code soon.

In this commit, no changes happened to the .kjsm format. But since the code
that serialized the abovementioned files was shared, a temporary abstraction
over two serialization formats was made, see SerializerCallbacks.

This commit temporarily breaks .kjsm decompiler and stub builder
2017-01-30 11:37:29 +03:00
1061 changed files with 19625 additions and 8196 deletions

View File

@@ -25,6 +25,7 @@
<element id="module-output" name="js.parser" />
<element id="module-output" name="cli-common" />
<element id="module-output" name="idea-jps-common" />
<element id="module-output" name="build-common" />
<element id="module-output" name="preloader" />
<element id="module-output" name="deserialization" />
<element id="module-output" name="backend-common" />

4
.idea/kotlinc.xml generated
View File

@@ -1,5 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinCommonCompilerArguments">
<option name="languageVersion" value="1.1" />
<option name="apiVersion" value="1.1" />
</component>
<component name="KotlinCompilerSettings">
<option name="additionalArguments" value="-version -Xallow-kotlin-package -Xskip-metadata-version-check" />
</component>

File diff suppressed because it is too large Load Diff

View File

@@ -22,7 +22,7 @@ import java.io.File
class Kotlin2JsTask : KotlinCompilerBaseTask() {
override val compilerFqName = "org.jetbrains.kotlin.cli.js.K2JSCompiler"
var library: Path? = null
var libraries: Path? = null
var outputPrefix: File? = null
var outputPostfix: File? = null
var sourceMap: Boolean = false
@@ -35,15 +35,9 @@ class Kotlin2JsTask : KotlinCompilerBaseTask() {
*/
var main: String? = null
fun createLibrary(): Path {
val libraryPath = library
if (libraryPath == null) {
val t = Path(getProject())
library = t
return t
}
return libraryPath.createPath()
fun createLibraries(): Path {
val libraryPaths = libraries ?: return Path(getProject()).also { libraries = it }
return libraryPaths.createPath()
}
override fun fillSpecificArguments() {
@@ -51,9 +45,9 @@ class Kotlin2JsTask : KotlinCompilerBaseTask() {
args.add(output!!.canonicalPath)
// TODO: write test
library?.let {
args.add("-library-files")
args.add(it.list().joinToString(separator = ",") { File(it).canonicalPath })
libraries?.let {
args.add("-libraries")
args.add(it.list().joinToString(File.pathSeparator) { File(it).canonicalPath })
}
outputPrefix?.let {

View File

@@ -17,14 +17,14 @@
package org.jetbrains.kotlin.build
import kotlin.reflect.KClass
import kotlin.reflect.KParameter
import kotlin.reflect.full.createType
import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.primaryConstructor
inline fun <reified T : Any> serializeToPlainText(instance: T): String {
inline fun <reified T : Any> serializeToPlainText(instance: T): String = serializeToPlainText(instance, T::class)
fun <T : Any> serializeToPlainText(instance: T, klass: KClass<T>): String {
val lines = ArrayList<String>()
for (property in T::class.memberProperties) {
for (property in klass.memberProperties) {
val value = property.get(instance)
if (value != null) {
lines.add("${property.name}=$value")
@@ -33,18 +33,18 @@ inline fun <reified T : Any> serializeToPlainText(instance: T): String {
return lines.joinToString("\n")
}
inline fun <reified T : Any> deserializeFromPlainText(str: String): T? {
inline fun <reified T : Any> deserializeFromPlainText(str: String): T? = deserializeFromPlainText(str, T::class)
fun <T : Any> deserializeFromPlainText(str: String, klass: KClass<T>): T? {
val args = ArrayList<Any?>()
val properties = str
.split("\n")
.filter(String::isNotBlank)
.associate { it.substringBefore("=") to it.substringAfter("=") }
val primaryConstructor = T::class.primaryConstructor
?: throw IllegalStateException("Class ${T::class.java} does not have primary constructor")
val params = primaryConstructor.parameters
val sortedBy = params.sortedBy { it.index }
for (param in sortedBy) {
val primaryConstructor = klass.primaryConstructor
?: throw IllegalStateException("${klass.java} does not have primary constructor")
for (param in primaryConstructor.parameters.sortedBy { it.index }) {
val argumentString = properties[param.name]
if (argumentString == null) {
@@ -57,10 +57,10 @@ inline fun <reified T : Any> deserializeFromPlainText(str: String): T? {
}
}
val argument: Any? = when {
param.isTypeOrNullableType(Int::class) -> argumentString.toInt()
param.isTypeOrNullableType(Boolean::class) -> argumentString.toBoolean()
param.isTypeOrNullableType(String::class) -> argumentString
val argument: Any? = when (param.type.classifier) {
Int::class -> argumentString.toInt()
Boolean::class -> argumentString.toBoolean()
String::class -> argumentString
else -> throw IllegalStateException("Unexpected property type: ${param.type}")
}
@@ -69,9 +69,3 @@ inline fun <reified T : Any> deserializeFromPlainText(str: String): T? {
return primaryConstructor.call(*args.toTypedArray())
}
@PublishedApi
internal fun <T : Any> KParameter.isTypeOrNullableType(klass: KClass<T>): Boolean =
this.type == klass.createType(nullable = true) || this.type == klass.createType(nullable = false)

View File

@@ -24,7 +24,7 @@ import java.io.File
private val NORMAL_VERSION = 8
private val EXPERIMENTAL_VERSION = 4
private val DATA_CONTAINER_VERSION = 1
private val DATA_CONTAINER_VERSION = 2
private val NORMAL_VERSION_FILE_NAME = "format-version.txt"
private val EXPERIMENTAL_VERSION_FILE_NAME = "experimental-format-version.txt"

View File

@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.build
import junit.framework.TestCase
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import org.junit.Assert.assertNotEquals
import org.junit.Test
@@ -28,27 +30,26 @@ class JvmBuildMetaInfoTest : TestCase() {
val args = K2JVMCompilerArguments()
val info = JvmBuildMetaInfo(args)
val actual = JvmBuildMetaInfo.serializeToString(info)
val expectedTempalte =
"""apiVersionString=1.1
bytecodeVersionMajor=1
bytecodeVersionMinor=0
bytecodeVersionPatch=1
compilerBuildVersion=@snapshot@
coroutinesEnable=false
coroutinesError=false
coroutinesVersion=0
coroutinesWarn=false
isEAP=@isEAP@
languageVersionString=1.1
metadataVersionMajor=1
metadataVersionMinor=1
metadataVersionPatch=3
multiplatformEnable=false
multiplatformVersion=0
ownVersion=0"""
val expected = expectedTempalte.replace("@snapshot@", KotlinCompilerVersion.VERSION)
.replace("@isEAP@", KotlinCompilerVersion.IS_PRE_RELEASE.toString())
assertEquals(expected, actual)
val expectedKeys = listOf(
"apiVersionString",
"bytecodeVersionMajor",
"bytecodeVersionMinor",
"bytecodeVersionPatch",
"compilerBuildVersion",
"coroutinesEnable",
"coroutinesError",
"coroutinesVersion",
"coroutinesWarn",
"isEAP",
"languageVersionString",
"metadataVersionMajor",
"metadataVersionMinor",
"metadataVersionPatch",
"multiplatformEnable",
"multiplatformVersion",
"ownVersion"
)
assertEquals(expectedKeys, actual.split("\r\n", "\n").map { line -> line.split("=").first() })
}
@Test

View File

@@ -314,6 +314,7 @@
<macrodef name="new-kotlin2js">
<attribute name="output"/>
<attribute name="additionalOptions" default=""/>
<element name="src"/>
<sequential>
@@ -341,8 +342,7 @@
<arg value="@{output}"/>
<arg value="-no-stdlib"/>
<arg value="-version"/>
<arg value="-meta-info"/>
<arg value="-kjsm"/>
<arg line="@{additionalOptions}"/>
<arg line="-main noCall"/>
<arg line="-module-kind commonjs"/>
<arg value="-Xallow-kotlin-package"/>
@@ -406,9 +406,13 @@
byline="true" encoding="UTF-8" />
</target>
<target name="js-stdlib">
<property environment="env"/>
<target name="js-stdlib-preprocess">
<kotlin-pp src="libraries/stdlib/src" output="${intermediate-sources}/stdlib/js" profile="JS" />
</target>
<target name="js-stdlib" depends="js-stdlib-preprocess">
<property environment="env"/>
<cleandir dir="${js.stdlib.output.dir}"/>
<!-- We don't want descriptors for built-ins to be serialized, so we compile these files separately. -->
<new-kotlin2js output="${js.stdlib.output.dir}/tmp-builtins/kotlin.js">
@@ -419,7 +423,7 @@
</src>
</new-kotlin2js>
<new-kotlin2js output="${js.stdlib.output.dir}/tmp/kotlin.js">
<new-kotlin2js output="${js.stdlib.output.dir}/tmp/kotlin.js" additionalOptions="-meta-info">
<src>
<union>
<fileset refid="kotlin.builtin.files"/>
@@ -473,7 +477,7 @@
<copy file="${kotlin-home}/lib/kotlin-stdlib-js.jar" tofile="${kotlin-home}/lib/kotlin-jslib.jar" />
</target>
<target name="pack-js-stdlib-sources">
<target name="pack-js-stdlib-sources" depends="js-stdlib-preprocess">
<jar destfile="${kotlin-home}/lib/kotlin-stdlib-js-sources.jar" duplicate="fail">
<resources refid="js.lib.files" />
<fileset refid="kotlin.builtin.files" />
@@ -1023,13 +1027,13 @@
<sequential>
<java classname="org.jetbrains.kotlin.preloading.Preloader" failonerror="true" fork="true" maxmemory="${max.heap.size.for.forked.jvm}">
<classpath>
<pathelement location="${kotlin-home}/lib/kotlin-preloader.jar"/>
<pathelement location="${bootstrap.compiler.home}/lib/kotlin-preloader.jar"/>
</classpath>
<assertions>
<enable/>
</assertions>
<arg value="-cp"/>
<arg value="${kotlin-home}/lib/kotlin-compiler.jar"/>
<arg value="${bootstrap.compiler.home}/lib/kotlin-compiler.jar"/>
<arg value="org.jetbrains.kotlin.preprocessor.PreprocessorCLI"/>
<arg value="@{src}"/>
<arg value="@{output}"/>
@@ -1118,7 +1122,6 @@
<arg value="${output}/classes/kotlin-test-js/kotlin-test.js"/>
<arg value="-version"/>
<arg value="-meta-info"/>
<arg value="-kjsm"/>
<arg line="-main noCall"/>
<arg line="-module-kind umd"/>
<arg value="-Xmulti-platform"/>

View File

@@ -168,6 +168,11 @@ public class AsmUtil {
return Type.getType(internalName.substring(1));
}
@NotNull
public static Type getArrayType(@NotNull Type componentType) {
return Type.getType("[" + componentType.getDescriptor());
}
@Nullable
public static PrimitiveType asmPrimitiveTypeToLangPrimitiveType(Type type) {
JvmPrimitiveType jvmPrimitiveType = primitiveTypeByAsmSort.get(type.getSort());
@@ -587,6 +592,10 @@ public class AsmUtil {
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(Ljava/lang/Object;Ljava/lang/Object;)Z", false);
}
public static void genIEEE754EqualForNullableTypesCall(InstructionAdapter v, Type left, Type right) {
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "areEqual", "(" + left.getDescriptor() + right.getDescriptor() + ")Z", false);
}
public static void numConst(int value, Type type, InstructionAdapter v) {
if (type == Type.FLOAT_TYPE) {
v.fconst(value);

View File

@@ -232,9 +232,10 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
@Override
protected void generateKotlinMetadataAnnotation() {
FunctionDescriptor freeLambdaDescriptor = createFreeLambdaDescriptor(funDescriptor);
Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, funDescriptor);
assert method != null : "No method for " + funDescriptor;
FunctionDescriptor frontendFunDescriptor = CodegenUtilKt.unwrapFrontendVersion(funDescriptor);
FunctionDescriptor freeLambdaDescriptor = createFreeLambdaDescriptor(frontendFunDescriptor);
Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, frontendFunDescriptor);
assert method != null : "No method for " + frontendFunDescriptor;
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, freeLambdaDescriptor, method);
final DescriptorSerializer serializer =

View File

@@ -17,12 +17,8 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
class ClosureGenerationStrategy(
state: GenerationState,
@@ -30,35 +26,8 @@ class ClosureGenerationStrategy(
) : FunctionGenerationStrategy.FunctionDefault(state, declaration) {
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
processDestructuringInLambdaParameters(codegen)
initializeVariablesForDestructuredLambdaParameters(codegen, codegen.context.functionDescriptor.valueParameters)
super.doGenerateBody(codegen, signature)
}
private fun processDestructuringInLambdaParameters(codegen: ExpressionCodegen) {
val savedIsShouldMarkLineNumbers = codegen.isShouldMarkLineNumbers
// Do not write line numbers until destructuring happens
// (otherwise destructuring variables will be uninitialized in the beginning of lambda)
codegen.isShouldMarkLineNumbers = false
for (parameterDescriptor in codegen.context.functionDescriptor.valueParameters) {
if (parameterDescriptor !is ValueParameterDescriptorImpl.WithDestructuringDeclaration) continue
for (entry in parameterDescriptor.destructuringVariables.filterOutDescriptorsWithSpecialNames()) {
codegen.myFrameMap.enter(entry, codegen.typeMapper.mapType(entry.type))
}
val destructuringDeclaration =
(DescriptorToSourceUtils.descriptorToDeclaration(parameterDescriptor) as? KtParameter)?.destructuringDeclaration
?: error("Destructuring declaration for descriptor $parameterDescriptor not found")
codegen.initializeDestructuringDeclarationVariables(
destructuringDeclaration,
TransientReceiver(parameterDescriptor.type),
codegen.findLocalOrCapturedValue(parameterDescriptor) ?: error("Local var not found for parameter $parameterDescriptor")
)
}
codegen.isShouldMarkLineNumbers = savedIsShouldMarkLineNumbers
}
}

View File

@@ -50,6 +50,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.codegen.when.SwitchCodegen;
import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
import org.jetbrains.kotlin.config.ApiVersion;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
@@ -2942,13 +2943,35 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
// The solution is to spill stack just after receiver is loaded (after IFNULL) in case of safe call.
// But the problem is that we should leave the receiver itself on the stack, so we store it in a temporary variable.
if (isSuspensionPoint && isSafeCallOrOnStack) {
int tmpVar = myFrameMap.enterTemp(receiver.type);
boolean bothReceivers =
receiver instanceof StackValue.CallReceiver
&& ((StackValue.CallReceiver) receiver).getDispatchReceiver().type.getSort() != Type.VOID
&& ((StackValue.CallReceiver) receiver).getExtensionReceiver().type.getSort() != Type.VOID;
Type firstReceiverType =
bothReceivers
? ((StackValue.CallReceiver) receiver).getDispatchReceiver().type
: receiver.type;
Type secondReceiverType = bothReceivers ? receiver.type : null;
int tmpVarForFirstReceiver = myFrameMap.enterTemp(firstReceiverType);
int tmpVarForSecondReceiver = -1;
if (secondReceiverType != null) {
tmpVarForSecondReceiver = myFrameMap.enterTemp(secondReceiverType);
v.store(tmpVarForSecondReceiver, secondReceiverType);
}
v.store(tmpVarForFirstReceiver, firstReceiverType);
v.store(tmpVar, receiver.type);
addInlineMarker(v, true);
v.load(tmpVar, receiver.type);
myFrameMap.leaveTemp(receiver.type);
v.load(tmpVarForFirstReceiver, firstReceiverType);
if (secondReceiverType != null) {
v.load(tmpVarForSecondReceiver, secondReceiverType);
myFrameMap.leaveTemp(secondReceiverType);
}
myFrameMap.leaveTemp(firstReceiverType);
}
callableMethod.afterReceiverGeneration(v);
@@ -3362,7 +3385,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@Override
public Unit invoke(InstructionAdapter v) {
KotlinType type = lhs.getType();
if (lhs instanceof DoubleColonLHS.Expression && !((DoubleColonLHS.Expression) lhs).isObject()) {
if (lhs instanceof DoubleColonLHS.Expression && !((DoubleColonLHS.Expression) lhs).isObjectQualifier()) {
JavaClassProperty.INSTANCE.generateImpl(v, gen(receiverExpression));
}
else {
@@ -3604,18 +3627,43 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
/*tries to use IEEE 754 arithmetic*/
private StackValue genEqualsForExpressionsPreferIEEE754Arithmetic(
@Nullable KtExpression left,
@Nullable KtExpression right,
@NotNull IElementType opToken,
@Nullable final KtExpression left,
@Nullable final KtExpression right,
@NotNull final IElementType opToken,
@NotNull Type leftType,
@NotNull Type rightType,
@Nullable StackValue pregeneratedLeft
@Nullable final StackValue pregeneratedLeft
) {
Type left754Type = calcTypeForIEEE754ArithmeticIfNeeded(left);
Type right754Type = calcTypeForIEEE754ArithmeticIfNeeded(right);
if (left754Type != null && right754Type != null && left754Type.equals(right754Type)) {
leftType = left754Type;
rightType = right754Type;
assert (opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) : "Optoken should be '==' or '!=', but: " + opToken;
final TypeAndNullability left754Type = calcTypeForIEEE754ArithmeticIfNeeded(left);
final TypeAndNullability right754Type = calcTypeForIEEE754ArithmeticIfNeeded(right);
if (left754Type != null && right754Type != null && left754Type.type.equals(right754Type.type)) {
//check nullability cause there is some optimizations in codegen for non-nullable case
if (left754Type.isNullable || right754Type.isNullable) {
if (state.getLanguageVersionSettings().getApiVersion().compareTo(ApiVersion.KOTLIN_1_1) >= 0) {
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
generate754EqualsForNullableTypesViaIntrinsic(v, opToken, pregeneratedLeft, left, left754Type, right, right754Type);
return Unit.INSTANCE;
}
});
}
else {
return StackValue.operation(Type.BOOLEAN_TYPE, new Function1<InstructionAdapter, Unit>() {
@Override
public Unit invoke(InstructionAdapter v) {
generate754EqualsForNullableTypes(v, opToken, pregeneratedLeft, left, left754Type, right, right754Type);
return Unit.INSTANCE;
}
});
}
}
else {
leftType = left754Type.type;
rightType = right754Type.type;
}
}
return genEqualsForExpressionsOnStack(
@@ -3625,6 +3673,126 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
);
}
private void generate754EqualsForNullableTypesViaIntrinsic(
@NotNull InstructionAdapter v,
@NotNull IElementType opToken,
@Nullable StackValue pregeneratedLeft,
@Nullable KtExpression left,
@NotNull TypeAndNullability left754Type,
@Nullable KtExpression right,
@NotNull TypeAndNullability right754Type
) {
Type leftType = left754Type.isNullable ? AsmUtil.boxType(left754Type.type) : left754Type.type;
if (pregeneratedLeft != null) {
StackValue.coercion(pregeneratedLeft, leftType).put(leftType, v);
}
else {
gen(left, leftType);
}
Type rightType = right754Type.isNullable ? AsmUtil.boxType(right754Type.type) : right754Type.type;
gen(right, rightType);
AsmUtil.genIEEE754EqualForNullableTypesCall(v, leftType, rightType);
if (opToken == KtTokens.EXCLEQ) {
genInvertBoolean(v);
}
}
private void generate754EqualsForNullableTypes(
@NotNull InstructionAdapter v,
@NotNull IElementType opToken,
@Nullable StackValue pregeneratedLeft,
@Nullable KtExpression left,
@NotNull TypeAndNullability left754Type,
@Nullable KtExpression right,
@NotNull TypeAndNullability right754Type
) {
int equals = opToken == KtTokens.EQEQ ? 1 : 0;
int notEquals = opToken != KtTokens.EQEQ ? 1 : 0;
Label end = new Label();
StackValue leftValue = pregeneratedLeft != null ? pregeneratedLeft : gen(left);
leftValue.put(leftValue.type, v);
leftValue = StackValue.onStack(leftValue.type);
Type leftType = left754Type.type;
Type rightType = right754Type.type;
if (left754Type.isNullable) {
leftValue.dup(v, false);
Label leftIsNull = new Label();
v.ifnull(leftIsNull);
StackValue.coercion(leftValue, leftType).put(leftType, v);
StackValue nonNullLeftValue = StackValue.onStack(leftType);
StackValue rightValue = gen(right);
rightValue.put(rightValue.type, v);
rightValue = StackValue.onStack(rightValue.type);
if (right754Type.isNullable) {
rightValue.dup(v, false);
Label rightIsNotNull = new Label();
v.ifnonnull(rightIsNotNull);
AsmUtil.pop(v, rightValue.type);
AsmUtil.pop(v, nonNullLeftValue.type);
v.iconst(notEquals);
v.goTo(end);
v.mark(rightIsNotNull);
}
StackValue.coercion(rightValue, rightType).put(rightType, v);
StackValue nonNullRightValue = StackValue.onStack(rightType);
StackValue.cmp(opToken, leftType, nonNullLeftValue, nonNullRightValue).put(Type.BOOLEAN_TYPE, v);
v.goTo(end);
//left is null case
v.mark(leftIsNull);
AsmUtil.pop(v, leftValue.type);//pop null left
rightValue = gen(right);
rightValue.put(rightValue.type, v);
rightValue = StackValue.onStack(rightValue.type);
if (right754Type.isNullable) {
Label rightIsNotNull = new Label();
v.ifnonnull(rightIsNotNull);
v.iconst(equals);
v.goTo(end);
v.mark(rightIsNotNull);
v.iconst(notEquals);
//v.goTo(end);
}
else {
AsmUtil.pop(v, rightValue.type);
v.iconst(notEquals);
//v.goTo(end);
}
v.mark(end);
return;
}
else {
StackValue.coercion(leftValue, leftType).put(leftType, v);
leftValue = StackValue.onStack(leftType);
}
//right is nullable cause left is not
StackValue rightValue = gen(right);
rightValue.put(rightValue.type, v);
rightValue = StackValue.onStack(rightValue.type);
rightValue.dup(v, false);
Label rightIsNotNull = new Label();
v.ifnonnull(rightIsNotNull);
AsmUtil.pop(v, rightValue.type);
AsmUtil.pop(v, leftValue.type);
v.iconst(notEquals);
v.goTo(end);
v.mark(rightIsNotNull);
StackValue.coercion(rightValue, rightType).put(rightType, v);
StackValue nonNullRightValue = StackValue.onStack(rightType);
StackValue.cmp(opToken, leftType, leftValue, nonNullRightValue).put(Type.BOOLEAN_TYPE, v);
v.mark(end);
}
private boolean isIntZero(KtExpression expr, Type exprType) {
ConstantValue<?> exprValue = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext, state.getShouldInlineConstVals());
return isIntPrimitive(exprType) && exprValue != null && Integer.valueOf(0).equals(exprValue.getValue());
@@ -3686,12 +3854,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
StackValue rightValue;
Type leftType = expressionType(left);
Type rightType = expressionType(right);
Type left754Type = calcTypeForIEEE754ArithmeticIfNeeded(left);
Type right754Type = calcTypeForIEEE754ArithmeticIfNeeded(right);
TypeAndNullability left754Type = calcTypeForIEEE754ArithmeticIfNeeded(left);
TypeAndNullability right754Type = calcTypeForIEEE754ArithmeticIfNeeded(right);
Callable callable = resolveToCallable((FunctionDescriptor) resolvedCall.getResultingDescriptor(), false, resolvedCall);
boolean is754Arithmetic = left754Type != null && right754Type != null && left754Type.equals(right754Type);
boolean is754Arithmetic = left754Type != null && right754Type != null && left754Type.type.equals(right754Type.type);
if (callable instanceof IntrinsicCallable && ((isPrimitive(leftType) && isPrimitive(rightType)) || is754Arithmetic)) {
type = is754Arithmetic ? left754Type : comparisonOperandType(leftType, rightType);
type = is754Arithmetic ? left754Type.type : comparisonOperandType(leftType, rightType);
leftValue = gen(left);
rightValue = gen(right);
}
@@ -3703,7 +3871,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return StackValue.cmp(expression.getOperationToken(), type, leftValue, rightValue);
}
private Type calcTypeForIEEE754ArithmeticIfNeeded(@Nullable KtExpression expression) {
private TypeAndNullability calcTypeForIEEE754ArithmeticIfNeeded(@Nullable KtExpression expression) {
return CodegenUtilKt.calcTypeForIEEE754ArithmeticIfNeeded(expression, bindingContext, context.getFunctionDescriptor());
}
@@ -4705,7 +4873,8 @@ The "returned" value of try expression with no finally is either the last expres
public NameGenerator getInlineNameGenerator() {
NameGenerator nameGenerator = getParentCodegen().getInlineNameGenerator();
Name name = context.getContextDescriptor().getName();
return nameGenerator.subGenerator((name.isSpecial() ? "$special" : name.asString()) + "$$inlined" );
String inlinedName = name.isSpecial() ? InlineCodegenUtil.SPECIAL_TRANSFORMATION_NAME : name.asString();
return nameGenerator.subGenerator(inlinedName + InlineCodegenUtil.INLINE_CALL_TRANSFORMATION_SUFFIX);
}
public Type getReturnType() {

View File

@@ -209,7 +209,11 @@ public class FunctionCodegen {
getThrownExceptions(functionDescriptor, typeMapper));
if (CodegenContextUtil.isImplClassOwner(owner)) {
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, functionDescriptor, asmMethod);
v.getSerializationBindings().put(
METHOD_FOR_FUNCTION,
CodegenUtilKt.<FunctionDescriptor>unwrapFrontendVersion(functionDescriptor),
asmMethod
);
}
generateMethodAnnotations(functionDescriptor, asmMethod, mv);

View File

@@ -37,6 +37,8 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isObject;
public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrategy.CodegenBased {
private final ResolvedCall<?> resolvedCall;
private final FunctionDescriptor referencedFunction;
@@ -146,6 +148,12 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
(referencedFunction.getExtensionReceiverParameter() != null ? 1 : 0) -
(receiverType != null ? 1 : 0);
if (receivers < 0 && referencedFunction instanceof ConstructorDescriptor && isObject(referencedFunction.getContainingDeclaration().getContainingDeclaration())) {
//reference to object nested class
//TODO: seems problem should be fixed on frontend side (note that object instance are captured by generated class)
receivers = 0;
}
List<ValueParameterDescriptor> parameters = CollectionsKt.drop(functionDescriptor.getValueParameters(), receivers);
for (int i = 0; i < parameters.size(); i++) {
ValueParameterDescriptor parameter = parameters.get(i);

View File

@@ -492,10 +492,11 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
int indexOfDelegatedProperty = PropertyCodegen.indexOfDelegatedProperty(property);
StackValue delegateValue = PropertyCodegen.invokeDelegatedPropertyConventionMethodWithReceiver(
codegen, typeMapper, provideDelegateResolvedCall, indexOfDelegatedProperty, 1, provideDelegateReceiver);
codegen, typeMapper, provideDelegateResolvedCall, indexOfDelegatedProperty, 1,
provideDelegateReceiver, propertyDescriptor
);
propValue.store(delegateValue, codegen.v);
}
protected boolean shouldInitializeProperty(@NotNull KtProperty property) {
@@ -583,7 +584,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
}
if (delegatedProperties.isEmpty()) return;
v.newField(NO_ORIGIN, ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME,
v.newField(NO_ORIGIN, ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME,
"[" + K_PROPERTY_TYPE, null, null);
if (!state.getClassBuilderMode().generateBodies) return;

View File

@@ -58,6 +58,9 @@ import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.getDeprecatedAccessFlag;
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField;
import static org.jetbrains.kotlin.codegen.AsmUtil.isPropertyWithBackingFieldCopyInOuterClass;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
@@ -540,7 +543,7 @@ public class PropertyCodegen {
StackValue.Property receiver = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
return invokeDelegatedPropertyConventionMethodWithReceiver(
codegen, typeMapper, resolvedCall, indexInPropertyMetadataArray, propertyMetadataArgumentIndex,
receiver
receiver, propertyDescriptor
);
}
@@ -550,9 +553,12 @@ public class PropertyCodegen {
@NotNull ResolvedCall<FunctionDescriptor> resolvedCall,
final int indexInPropertyMetadataArray,
int propertyMetadataArgumentIndex,
@Nullable StackValue receiver
@Nullable StackValue receiver,
@NotNull PropertyDescriptor propertyDescriptor
) {
final Type owner = getDelegatedPropertyMetadataOwner(codegen, typeMapper);
final Type owner = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor) ?
codegen.getState().getTypeMapper().mapOwner(propertyDescriptor) :
getDelegatedPropertyMetadataOwner(codegen, typeMapper);
codegen.tempVariables.put(
resolvedCall.getCall().getValueArguments().get(propertyMetadataArgumentIndex).asElement(),

View File

@@ -281,33 +281,24 @@ public abstract class StackValue {
}
private static void box(Type type, Type toType, InstructionAdapter v) {
if (type == Type.BYTE_TYPE || toType.getInternalName().equals(NULLABLE_BYTE_TYPE_NAME) && type == Type.INT_TYPE) {
v.cast(type, Type.BYTE_TYPE);
v.invokestatic(NULLABLE_BYTE_TYPE_NAME, "valueOf", "(B)L" + NULLABLE_BYTE_TYPE_NAME + ";", false);
}
else if (type == Type.SHORT_TYPE || toType.getInternalName().equals(NULLABLE_SHORT_TYPE_NAME) && type == Type.INT_TYPE) {
v.cast(type, Type.SHORT_TYPE);
v.invokestatic(NULLABLE_SHORT_TYPE_NAME, "valueOf", "(S)L" + NULLABLE_SHORT_TYPE_NAME + ";", false);
}
else if (type == Type.LONG_TYPE || toType.getInternalName().equals(NULLABLE_LONG_TYPE_NAME) && type == Type.INT_TYPE) {
v.cast(type, Type.LONG_TYPE);
v.invokestatic(NULLABLE_LONG_TYPE_NAME, "valueOf", "(J)L" + NULLABLE_LONG_TYPE_NAME + ";", false);
}
else if (type == Type.INT_TYPE) {
v.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
}
else if (type == Type.BOOLEAN_TYPE) {
v.invokestatic("java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
}
else if (type == Type.CHAR_TYPE) {
v.invokestatic("java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
}
else if (type == Type.FLOAT_TYPE) {
v.invokestatic("java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
}
else if (type == Type.DOUBLE_TYPE) {
v.invokestatic("java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
if (type == Type.INT_TYPE) {
if (toType.getInternalName().equals(NULLABLE_BYTE_TYPE_NAME)) {
type = Type.BYTE_TYPE;
}
else if (toType.getInternalName().equals(NULLABLE_SHORT_TYPE_NAME)) {
type = Type.SHORT_TYPE;
}
else if (toType.getInternalName().equals(NULLABLE_LONG_TYPE_NAME)) {
type = Type.LONG_TYPE;
}
v.cast(Type.INT_TYPE, type);
}
Type boxedType = AsmUtil.boxType(type);
if (boxedType == type) return;
v.invokestatic(boxedType.getInternalName(), "valueOf", Type.getMethodDescriptor(boxedType, type), false);
coerce(boxedType, toType, v);
}
private static void unbox(Type type, InstructionAdapter v) {
@@ -1596,6 +1587,16 @@ public abstract class StackValue {
public void dup(@NotNull InstructionAdapter v, boolean withReceiver) {
AsmUtil.dup(v, extensionReceiver.type, dispatchReceiver.type);
}
@NotNull
public StackValue getDispatchReceiver() {
return dispatchReceiver;
}
@NotNull
public StackValue getExtensionReceiver() {
return extensionReceiver;
}
}
public abstract static class StackValueWithSimpleReceiver extends StackValue {

View File

@@ -21,11 +21,13 @@ import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
import org.jetbrains.kotlin.codegen.context.PackageContext
import org.jetbrains.kotlin.codegen.coroutines.unwrapInitialDescriptorForSuspendFunction
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
import org.jetbrains.kotlin.diagnostics.rendering.RenderingContext
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature.SpecialSignatureInfo
@@ -33,12 +35,10 @@ import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtObjectDeclaration
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.isSubclass
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
import org.jetbrains.kotlin.serialization.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
@@ -270,25 +271,27 @@ private fun CallableDescriptor.isJvmStaticIn(predicate: (DeclarationDescriptor)
fun Collection<VariableDescriptor>.filterOutDescriptorsWithSpecialNames() = filterNot { it.name.isSpecial }
fun calcTypeForIEEE754ArithmeticIfNeeded(expression: KtExpression?, bindingContext: BindingContext, descriptor: DeclarationDescriptor): Type? {
class TypeAndNullability(@JvmField val type: Type, @JvmField val isNullable: Boolean)
fun calcTypeForIEEE754ArithmeticIfNeeded(expression: KtExpression?, bindingContext: BindingContext, descriptor: DeclarationDescriptor): TypeAndNullability? {
val ktType = expression.kotlinType(bindingContext) ?: return null
if (KotlinBuiltIns.isDoubleOrNullableDouble(ktType)) {
return Type.DOUBLE_TYPE
return TypeAndNullability(Type.DOUBLE_TYPE, TypeUtils.isNullableType(ktType))
}
if (KotlinBuiltIns.isFloatOrNullableFloat(ktType)) {
return Type.FLOAT_TYPE
return TypeAndNullability(Type.FLOAT_TYPE, TypeUtils.isNullableType(ktType))
}
val dataFlow = DataFlowValueFactory.createDataFlowValue(expression!!, ktType, bindingContext, descriptor)
val stableTypes = bindingContext.getDataFlowInfoBefore(expression).getStableTypes(dataFlow)
return stableTypes.firstNotNullResult {
if (KotlinBuiltIns.isDoubleOrNullableDouble(it)) {
Type.DOUBLE_TYPE
TypeAndNullability(Type.DOUBLE_TYPE, TypeUtils.isNullableType(it))
}
else if (KotlinBuiltIns.isFloatOrNullableFloat(it)) {
Type.FLOAT_TYPE
TypeAndNullability(Type.FLOAT_TYPE, TypeUtils.isNullableType(it))
}
else {
null
@@ -345,3 +348,32 @@ fun MemberDescriptor.isToArrayFromCollection(): Boolean {
fun FqName.topLevelClassInternalName() = JvmClassName.byClassId(ClassId(parent(), shortName())).internalName
fun FqName.topLevelClassAsmType(): Type = Type.getObjectType(topLevelClassInternalName())
fun initializeVariablesForDestructuredLambdaParameters(codegen: ExpressionCodegen, valueParameters: List<ValueParameterDescriptor>) {
val savedIsShouldMarkLineNumbers = codegen.isShouldMarkLineNumbers
// Do not write line numbers until destructuring happens
// (otherwise destructuring variables will be uninitialized in the beginning of lambda)
codegen.isShouldMarkLineNumbers = false
for (parameterDescriptor in valueParameters) {
if (parameterDescriptor !is ValueParameterDescriptorImpl.WithDestructuringDeclaration) continue
for (entry in parameterDescriptor.destructuringVariables.filterOutDescriptorsWithSpecialNames()) {
codegen.myFrameMap.enter(entry, codegen.typeMapper.mapType(entry.type))
}
val destructuringDeclaration =
(DescriptorToSourceUtils.descriptorToDeclaration(parameterDescriptor) as? KtParameter)?.destructuringDeclaration
?: error("Destructuring declaration for descriptor $parameterDescriptor not found")
codegen.initializeDestructuringDeclarationVariables(
destructuringDeclaration,
TransientReceiver(parameterDescriptor.type),
codegen.findLocalOrCapturedValue(parameterDescriptor) ?: error("Local var not found for parameter $parameterDescriptor")
)
}
codegen.isShouldMarkLineNumbers = savedIsShouldMarkLineNumbers
}
fun <D : CallableDescriptor> D.unwrapFrontendVersion() = unwrapInitialDescriptorForSuspendFunction()

View File

@@ -110,6 +110,8 @@ class CoroutineCodegen private constructor(
setReturnType(
funDescriptor.module.getContinuationOfTypeOrAny(builtIns.unitType)
)
// 'create' method should not inherit initial descriptor for suspend function from original descriptor
putUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION, null)
setVisibility(Visibilities.PUBLIC)
}
@@ -268,6 +270,9 @@ class CoroutineCodegen private constructor(
generateLoadField(parameter.getFieldInfoForCoroutineLambdaParameter())
v.store(newIndex, mappedType)
}
if (isSuspendLambda) {
initializeVariablesForDestructuredLambdaParameters(this, originalSuspendFunctionDescriptor.valueParameters)
}
}
private fun allLambdaParameters() =
@@ -316,6 +321,11 @@ class CoroutineCodegen private constructor(
}
companion object {
fun shouldCreateByLambda(
originalSuspendLambdaDescriptor: CallableDescriptor,
declaration: KtElement): Boolean {
return (declaration is KtFunctionLiteral && originalSuspendLambdaDescriptor.isSuspendLambda)
}
@JvmStatic
fun createByLambda(
@@ -324,8 +334,7 @@ class CoroutineCodegen private constructor(
declaration: KtElement,
classBuilder: ClassBuilder
): ClosureCodegen? {
if (declaration !is KtFunctionLiteral) return null
if (!originalSuspendLambdaDescriptor.isSuspendLambda) return null
if (!shouldCreateByLambda(originalSuspendLambdaDescriptor, declaration)) return null
return CoroutineCodegen(
expressionCodegen,

View File

@@ -229,6 +229,18 @@ class CoroutineTransformerMethodVisitor(
}
for ((index, basicValue) in variablesToSpill) {
if (basicValue === StrictBasicValue.NULL_VALUE) {
postponedActions.add {
with(instructions) {
insert(suspension.tryCatchBlockEndLabelAfterSuspensionCall, withInstructionAdapter {
aconst(null)
store(index, AsmTypes.OBJECT_TYPE)
})
}
}
continue
}
val type = basicValue.type
val normalizedType = type.normalize()

View File

@@ -239,12 +239,12 @@ public class InlineCodegen extends CallGenerator {
assert resolvedCall != null : "Resolved call for " + functionDescriptor + " should be not null";
Map<TypeParameterDescriptor, KotlinType> arguments = resolvedCall.getTypeArguments();
assert arguments.size() == 1 : "Resolved call for " + functionDescriptor + " should have 1 type argument";
KotlinType type = arguments.values().iterator().next();
MethodNode node =
InlineCodegenUtil.createSpecialEnumMethodBody(
codegen,
functionDescriptor.getName().asString(),
type,
arguments.keySet().iterator().next().getDefaultType(),
codegen.getState().getTypeMapper()
);
return new SMAPAndMethodNode(node, SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1));

View File

@@ -23,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.codegen.AsmUtil;
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.codegen.MemberCodegen;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
@@ -60,6 +61,9 @@ import java.io.StringWriter;
import java.util.List;
import java.util.ListIterator;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.ENUM_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_CLASS_TYPE;
public class InlineCodegenUtil {
public static final boolean GENERATE_SMAP = true;
public static final int API = Opcodes.ASM5;
@@ -77,7 +81,9 @@ public class InlineCodegenUtil {
private static final String INLINE_MARKER_AFTER_METHOD_NAME = "afterInlineCall";
private static final String INLINE_MARKER_FINALLY_START = "finallyStart";
private static final String INLINE_MARKER_FINALLY_END = "finallyEnd";
public static final String SPECIAL_TRANSFORMATION_NAME = "$special";
public static final String INLINE_TRANSFORMATION_SUFFIX = "$inlined";
public static final String INLINE_CALL_TRANSFORMATION_SUFFIX = "$" + INLINE_TRANSFORMATION_SUFFIX;
public static final String INLINE_FUN_THIS_0_SUFFIX = "$inline_fun";
public static final String INLINE_FUN_VAR_SUFFIX = "$iv";
@@ -530,7 +536,7 @@ public class InlineCodegenUtil {
if (!(containingDeclaration instanceof PackageFragmentDescriptor)) {
return false;
}
if (!containingDeclaration.getName().equals(KotlinBuiltIns.BUILT_INS_PACKAGE_NAME)) {
if (!((PackageFragmentDescriptor) containingDeclaration).getFqName().equals(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME)) {
return false;
}
if (functionDescriptor.getTypeParameters().size() != 1) {
@@ -548,23 +554,30 @@ public class InlineCodegenUtil {
@NotNull KotlinType type,
@NotNull KotlinTypeMapper typeMapper
) {
boolean isEnumValues = "enumValues".equals(name);
boolean isValueOf = "enumValueOf".equals(name);
Type invokeType = typeMapper.mapType(type);
String desc = getSpecialEnumFunDescriptor(invokeType, isEnumValues);
String desc = getSpecialEnumFunDescriptor(invokeType, isValueOf);
MethodNode node = new MethodNode(API, Opcodes.ACC_STATIC, "fake", desc, null, null);
if (!isEnumValues) {
node.visitVarInsn(Opcodes.ALOAD, 0);
}
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, new InstructionAdapter(node));
node.visitMethodInsn(Opcodes.INVOKESTATIC, invokeType.getInternalName(), isEnumValues ? "values" : "valueOf", desc, false);
if (isValueOf) {
node.visitInsn(Opcodes.ACONST_NULL);
node.visitVarInsn(Opcodes.ALOAD, 0);
node.visitMethodInsn(Opcodes.INVOKESTATIC, ENUM_TYPE.getInternalName(), "valueOf",
Type.getMethodDescriptor(ENUM_TYPE, JAVA_CLASS_TYPE, AsmTypes.JAVA_STRING_TYPE), false);
}
else {
node.visitInsn(Opcodes.ICONST_0);
node.visitTypeInsn(Opcodes.ANEWARRAY, ENUM_TYPE.getInternalName());
}
node.visitInsn(Opcodes.ARETURN);
node.visitMaxs(isEnumValues ? 2 : 3, isEnumValues ? 0 : 1);
node.visitMaxs(isValueOf ? 3 : 2, isValueOf ? 1 : 0);
return node;
}
public static String getSpecialEnumFunDescriptor(@NotNull Type type, boolean isEnumValues) {
return (isEnumValues ? "()[" : "(Ljava/lang/String;)") + "L" + type.getInternalName() + ";";
@NotNull
public static String getSpecialEnumFunDescriptor(@NotNull Type type, boolean isValueOf) {
return isValueOf ? Type.getMethodDescriptor(type, AsmTypes.JAVA_STRING_TYPE) : Type.getMethodDescriptor(AsmUtil.getArrayType(type));
}
}

View File

@@ -16,11 +16,13 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.context.MethodContext
import org.jetbrains.kotlin.codegen.generateAsCast
import org.jetbrains.kotlin.codegen.generateIsCheck
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
import org.jetbrains.kotlin.codegen.optimization.removeNodeGetNext
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.Variance
@@ -139,7 +141,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
OperationKind.SAFE_AS -> processAs(insn, instructions, kotlinType, asmType, safe = true)
OperationKind.IS -> processIs(insn, instructions, kotlinType, asmType)
OperationKind.JAVA_CLASS -> processJavaClass(insn, asmType)
OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, asmType)
OperationKind.ENUM_REIFIED -> processSpecialEnumFunction(insn, instructions, asmType)
}) {
instructions.remove(insn.previous.previous!!) // PUSH operation ID
instructions.remove(insn.previous!!) // PUSH type parameter
@@ -221,12 +223,27 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
return true
}
private fun processSpecialEnumFunction(insn: MethodInsnNode, parameter: Type): Boolean {
val next = insn.next
if (next !is MethodInsnNode) return false
next.owner = parameter.internalName
next.desc = InlineCodegenUtil.getSpecialEnumFunDescriptor(parameter, "values" == next.name)
return true
private fun processSpecialEnumFunction(insn: MethodInsnNode, instructions: InsnList, parameter: Type): Boolean {
val next1 = insn.next ?: return false
val next2 = next1.next ?: return false
if (next1.opcode == Opcodes.ACONST_NULL && next2.opcode == Opcodes.ALOAD) {
val next3 = next2.next ?: return false
if (next3 is MethodInsnNode && next3.name == "valueOf") {
instructions.remove(next1)
next3.owner = parameter.internalName
next3.desc = InlineCodegenUtil.getSpecialEnumFunDescriptor(parameter, true)
return true
}
}
else if (next1.opcode == Opcodes.ICONST_0 && next2.opcode == Opcodes.ANEWARRAY) {
instructions.remove(next1)
instructions.remove(next2)
val desc = InlineCodegenUtil.getSpecialEnumFunDescriptor(parameter, false)
instructions.insert(insn, MethodInsnNode(Opcodes.INVOKESTATIC, parameter.internalName, "values", desc, false))
return true
}
return false
}
}

View File

@@ -72,13 +72,9 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
@Override
public BasicValue newOperation(@NotNull AbstractInsnNode insn) throws AnalyzerException {
if (insn.getOpcode() == Opcodes.ACONST_NULL) {
return newValue(Type.getObjectType("java/lang/Object"));
}
switch (insn.getOpcode()) {
case ACONST_NULL:
return newValue(Type.getObjectType("null"));
return NULL_VALUE;
case ICONST_M1:
case ICONST_0:
case ICONST_1:
@@ -362,6 +358,9 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
// if merge of two references then `lub` is java/lang/Object
// arrays also are BasicValues with reference type's
if (isReference(v) && isReference(w)) {
if (v == NULL_VALUE) return newValue(w.getType());
if (w == NULL_VALUE) return newValue(v.getType());
return StrictBasicValue.REFERENCE_VALUE;
}

View File

@@ -45,6 +45,9 @@ open class StrictBasicValue(type: Type?) : BasicValue(type) {
val SHORT_VALUE = StrictBasicValue(Type.SHORT_TYPE)
@JvmField
val REFERENCE_VALUE = StrictBasicValue(Type.getObjectType("java/lang/Object"))
@JvmField
val NULL_VALUE = StrictBasicValue(Type.getObjectType("java/lang/Object"))
}
override fun equals(other: Any?): Boolean {
@@ -60,4 +63,9 @@ open class StrictBasicValue(type: Type?) : BasicValue(type) {
}
override fun hashCode() = (type?.hashCode() ?: 0)
override fun toString(): String {
if (this === UNINITIALIZED_VALUE) return "."
return super.toString()
}
}

View File

@@ -958,7 +958,7 @@ public class KotlinTypeMapper {
if (!(descriptor instanceof ConstructorDescriptor) &&
descriptor.getVisibility() == Visibilities.INTERNAL &&
!descriptor.getAnnotations().hasAnnotation(KotlinBuiltIns.FQ_NAMES.publishedApi)) {
!DescriptorUtilsKt.isPublishedApi(descriptor)) {
return name + "$" + NameUtils.sanitizeAsJavaIdentifier(moduleName);
}

View File

@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.serialization.builtins
import com.intellij.openapi.util.Disposer
import org.jetbrains.kotlin.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.builtins.JvmBuiltInClassDescriptorFactory
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.messages.*
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
@@ -26,12 +28,16 @@ import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.addKotlinSourceRoots
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.serialization.MetadataSerializer
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import java.io.File
class BuiltInsSerializer(dependOnOldBuiltIns: Boolean) : MetadataSerializer(dependOnOldBuiltIns) {
@@ -88,11 +94,21 @@ class BuiltInsSerializer(dependOnOldBuiltIns: Boolean) : MetadataSerializer(depe
fqName ->
val packageView = module.getPackage(fqName)
PackageSerializer(
packageView.memberScope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS),
packageView.memberScope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) + createCloneable(module),
packageView.fragments.flatMap { fragment -> DescriptorUtils.getAllDescriptors(fragment.getMemberScope()) },
packageView.fqName,
File(destDir, BuiltInSerializerProtocol.getBuiltInsFilePath(packageView.fqName))
).run()
}
}
// Serialize metadata for kotlin.Cloneable manually for compatibility with kotlin-reflect 1.0 which expects this metadata to be there.
// Since Kotlin 1.1, we always discard this class during deserialization (see ClassDeserializer.kt).
private fun createCloneable(module: ModuleDescriptor): ClassDescriptor {
val factory = JvmBuiltInClassDescriptorFactory(LockBasedStorageManager.NO_LOCKS, module) {
EmptyPackageFragmentDescriptor(module, KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME)
}
return factory.createClass(ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.cloneable.toSafe()))
?: error("Could not create kotlin.Cloneable in $module")
}
}

View File

@@ -76,6 +76,9 @@ public abstract class CommonCompilerArguments implements Serializable {
@Argument(value = "Xno-check-impl", description = "Do not check presence of 'impl' modifier in multi-platform projects")
public boolean noCheckImpl;
@Argument(value = "Xskip-java-check", description = "Do not warn when running the compiler under Java 6 or 7")
public boolean noJavaVersionWarning;
@Argument(value = "Xcoroutines=warn")
public boolean coroutinesWarn;

View File

@@ -35,22 +35,18 @@ public class K2JSCompilerArguments extends CommonCompilerArguments {
@Argument(value = "no-stdlib", description = "Don't use bundled Kotlin stdlib")
public boolean noStdlib;
@Argument(value = "library-files", description = "Path to zipped library sources or kotlin files separated by commas")
@ValueDescription("<path[,]>")
public String[] libraryFiles;
@Argument(value = "libraries", description = "Paths to Kotlin libraries with .meta.js and .kjsm files, separated by system file separator")
@ValueDescription("<path>")
public String libraries;
@GradleOption(DefaultValues.BooleanFalseDefault.class)
@Argument(value = "source-map", description = "Generate source map")
public boolean sourceMap;
@GradleOption(DefaultValues.BooleanTrueDefault.class)
@Argument(value = "meta-info", description = "Generate metadata")
@Argument(value = "meta-info", description = "Generate .meta.js and .kjsm files with metadata. Use to create a library")
public boolean metaInfo;
@GradleOption(DefaultValues.BooleanTrueDefault.class)
@Argument(value = "kjsm", description = "Generate kjsm-files (for creating libraries)")
public boolean kjsm;
@GradleOption(DefaultValues.JsEcmaVersions.class)
@Argument(value = "target", description = "Generate JS files for specific ECMA version")
@ValueDescription("{ v5 }")

View File

@@ -37,16 +37,22 @@ import java.util.*
}
}
fun <T : Any> copyBean(bean: T) = copyFields(bean, bean.javaClass.newInstance(), true)
fun <T : Any> copyBean(bean: T) = copyFields(bean, bean.javaClass.newInstance(), true, collectFieldsToCopy(bean.javaClass, false))
fun <From : Any, To : From> mergeBeans(from: From, to: To): To {
// TODO: rewrite when updated version of com.intellij.util.xmlb is available on TeamCity
return copyFields(from, XmlSerializerUtil.createCopy(to), false)
return copyFields(from, XmlSerializerUtil.createCopy(to), false, collectFieldsToCopy(from.javaClass, false))
}
private fun <From : Any, To : From> copyFields(from: From, to: To, deepCopyWhenNeeded: Boolean = false): To {
val fromFields = collectFieldsToCopy(from.javaClass)
for (fromField in fromFields) {
fun <From : Any, To : Any> copyInheritedFields(from: From, to: To) = copyFields(from, to, true, collectFieldsToCopy(from.javaClass, true))
fun <From : Any, To : Any> copyFieldsSatisfying(from: From, to: To, predicate: (Field) -> Boolean) =
copyFields(from, to, true, collectFieldsToCopy(from.javaClass, false).filter(predicate))
private fun <From : Any, To : Any> copyFields(from: From, to: To, deepCopyWhenNeeded: Boolean, fieldsToCopy: List<Field>): To {
if (from == to) return to
for (fromField in fieldsToCopy) {
val toField = to.javaClass.getField(fromField.name)
val fromValue = fromField.get(from)
toField.set(to, if (deepCopyWhenNeeded) fromValue?.copyValueIfNeeded() else fromValue)
@@ -83,10 +89,10 @@ private fun Any.copyValueIfNeeded(): Any {
}
}
private fun collectFieldsToCopy(clazz: Class<*>): List<Field> {
private fun collectFieldsToCopy(clazz: Class<*>, inheritedOnly: Boolean): List<Field> {
val fromFields = ArrayList<Field>()
var currentClass: Class<*>? = clazz
var currentClass: Class<*>? = if (inheritedOnly) clazz.superclass else clazz
while (currentClass != null) {
for (field in currentClass.declaredFields) {
val modifiers = field.modifiers

View File

@@ -16,13 +16,16 @@
package org.jetbrains.kotlin.cli.common.messages;
import org.jetbrains.annotations.NotNull;
import java.util.EnumSet;
public enum CompilerMessageSeverity {
INFO,
ERROR,
WARNING,
EXCEPTION,
ERROR,
STRONG_WARNING,
WARNING,
INFO,
LOGGING,
OUTPUT;
@@ -32,4 +35,25 @@ public enum CompilerMessageSeverity {
public boolean isError() {
return ERRORS.contains(this);
}
@NotNull
public String getPresentableName() {
switch (this) {
case EXCEPTION:
return "exception";
case ERROR:
return "error";
case STRONG_WARNING:
case WARNING:
return "warning";
case INFO:
return "info";
case LOGGING:
return "logging";
case OUTPUT:
return "output";
default:
throw new UnsupportedOperationException("Unknown severity: " + this);
}
}
}

View File

@@ -68,7 +68,7 @@ public class GroupingMessageCollector implements MessageCollector {
for (String path : sortedKeys()) {
for (Message message : groupedMessages.get(path)) {
if (!hasErrors || message.severity.isError()) {
if (!hasErrors || message.severity.isError() || message.severity == CompilerMessageSeverity.STRONG_WARNING) {
delegate.report(message.severity, message.message, message.location);
}
}

View File

@@ -22,10 +22,7 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.concurrency.AppExecutorUtil;
import com.intellij.util.concurrency.AppScheduledExecutorService;
import com.sampullara.cli.Args;
import kotlin.Pair;
import kotlin.collections.ArraysKt;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.fusesource.jansi.AnsiConsole;
import org.jetbrains.annotations.NotNull;
@@ -44,6 +41,7 @@ import org.jetbrains.kotlin.utils.StringsKt;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
@@ -158,6 +156,7 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
}
reportUnknownExtraFlags(messageCollector, arguments);
reportUnsupportedJavaVersion(messageCollector, arguments);
GroupingMessageCollector groupingCollector = new GroupingMessageCollector(messageCollector);
@@ -278,7 +277,12 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
configuration.put(
CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS,
new LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion), extraLanguageFeatures)
new LanguageVersionSettingsImpl(
languageVersion,
ApiVersion.createByLanguageVersion(apiVersion),
extraLanguageFeatures,
arguments.apiVersion != null
)
);
}
@@ -339,13 +343,23 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
private void reportUnknownExtraFlags(@NotNull MessageCollector collector, @NotNull A arguments) {
for (String flag : arguments.unknownExtraFlags) {
collector.report(
CompilerMessageSeverity.WARNING,
CompilerMessageSeverity.STRONG_WARNING,
"Flag is not supported by this version of the compiler: " + flag,
CompilerMessageLocation.NO_LOCATION
);
}
}
private void reportUnsupportedJavaVersion(MessageCollector collector, A arguments) {
if (!SystemInfo.isJavaVersionAtLeast("1.8") && !arguments.noJavaVersionWarning) {
collector.report(
CompilerMessageSeverity.STRONG_WARNING,
"Running the Kotlin compiler under Java 6 or 7 is unsupported and will no longer be possible in a future update.",
CompilerMessageLocation.NO_LOCATION
);
}
}
@NotNull
protected abstract ExitCode doExecute(
@NotNull A arguments,

View File

@@ -206,7 +206,7 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
fun reportBytecodeVersionErrors(bindingContext: BindingContext, messageCollector: MessageCollector) {
val severity = if (System.getProperty("kotlin.jvm.disable.bytecode.version.error") == "true")
CompilerMessageSeverity.WARNING
CompilerMessageSeverity.STRONG_WARNING
else
CompilerMessageSeverity.ERROR

View File

@@ -49,7 +49,7 @@ public abstract class PlainTextMessageRenderer implements MessageRenderer {
private static final String LINE_SEPARATOR = LineSeparator.getSystemLineSeparator().getSeparatorString();
private static final Set<CompilerMessageSeverity> IMPORTANT_MESSAGE_SEVERITIES = EnumSet.of(EXCEPTION, ERROR, WARNING);
private static final Set<CompilerMessageSeverity> IMPORTANT_MESSAGE_SEVERITIES = EnumSet.of(EXCEPTION, ERROR, STRONG_WARNING, WARNING);
@Override
public String renderPreamble() {
@@ -83,7 +83,7 @@ public abstract class PlainTextMessageRenderer implements MessageRenderer {
Ansi ansi = Ansi.ansi()
.bold()
.fg(severityColor(severity))
.a(severity.name().toLowerCase())
.a(severity.getPresentableName())
.a(": ")
.reset();
@@ -102,7 +102,7 @@ public abstract class PlainTextMessageRenderer implements MessageRenderer {
}
}
else {
result.append(severity.name().toLowerCase());
result.append(severity.getPresentableName());
result.append(": ");
result.append(decapitalizeIfNeeded(message));
}
@@ -141,6 +141,8 @@ public abstract class PlainTextMessageRenderer implements MessageRenderer {
return Ansi.Color.RED;
case ERROR:
return Ansi.Color.RED;
case STRONG_WARNING:
return Ansi.Color.YELLOW;
case WARNING:
return Ansi.Color.YELLOW;
case INFO:

View File

@@ -28,7 +28,8 @@ public class XmlMessageRenderer implements MessageRenderer {
@Override
public String render(@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location) {
StringBuilder out = new StringBuilder();
out.append("<").append(severity.toString());
String tagName = severity.getPresentableName();
out.append("<").append(tagName);
if (location.getPath() != null) {
out.append(" path=\"").append(e(location.getPath())).append("\"");
out.append(" line=\"").append(location.getLine()).append("\"");
@@ -38,11 +39,11 @@ public class XmlMessageRenderer implements MessageRenderer {
out.append(e(message));
out.append("</").append(severity.toString()).append(">\n");
out.append("</").append(tagName).append(">\n");
return out.toString();
}
private String e(String str) {
private static String e(String str) {
return StringUtil.escapeXml(str);
}

View File

@@ -25,8 +25,6 @@ import com.intellij.util.Function;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.analyzer.AnalysisResult;
@@ -58,8 +56,8 @@ import org.jetbrains.kotlin.js.facade.MainCallParameters;
import org.jetbrains.kotlin.js.facade.TranslationResult;
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
import org.jetbrains.kotlin.serialization.js.ModuleKind;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
import org.jetbrains.kotlin.utils.PathUtil;
import java.io.File;
@@ -140,11 +138,15 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
configuration.put(CommonConfigurationKeys.MODULE_NAME, FileUtil.getNameWithoutExtension(outputFile));
JsConfig config = new LibrarySourcesConfig(project, configuration);
if (config.checkLibFilesAndReportErrors(new Function1<String, Unit>() {
if (config.checkLibFilesAndReportErrors(new JsConfig.Reporter() {
@Override
public Unit invoke(String message) {
public void error(@NotNull String message) {
messageCollector.report(CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION);
return Unit.INSTANCE;
}
@Override
public void warning(@NotNull String message) {
messageCollector.report(CompilerMessageSeverity.STRONG_WARNING, message, CompilerMessageLocation.NO_LOCATION);
}
})) {
return COMPILATION_ERROR;
@@ -275,20 +277,17 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
if (arguments.metaInfo) {
configuration.put(JSConfigurationKeys.META_INFO, true);
}
if (arguments.kjsm) {
configuration.put(JSConfigurationKeys.KJSM, true);
}
List<String> libraryFiles = new SmartList<String>();
List<String> libraries = new SmartList<String>();
if (!arguments.noStdlib) {
libraryFiles.add(0, PathUtil.getKotlinPathsForCompiler().getJsStdLibJarPath().getAbsolutePath());
libraries.add(0, PathUtil.getKotlinPathsForCompiler().getJsStdLibJarPath().getAbsolutePath());
}
if (arguments.libraryFiles != null) {
ContainerUtil.addAllNotNull(libraryFiles, arguments.libraryFiles);
if (arguments.libraries != null) {
ContainerUtil.addAllNotNull(libraries, arguments.libraries.split(File.pathSeparator));
}
configuration.put(JSConfigurationKeys.LIBRARY_FILES, libraryFiles);
configuration.put(JSConfigurationKeys.LIBRARIES, libraries);
String moduleKindName = arguments.moduleKind;
ModuleKind moduleKind = moduleKindName != null ? moduleKindMap.get(moduleKindName) : ModuleKind.PLAIN;

View File

@@ -16,22 +16,19 @@
package org.jetbrains.kotlin.cli.jvm
import com.intellij.ide.highlighter.JavaClassFileType
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.MavenComparableVersion
import org.jetbrains.kotlin.config.*
import java.io.IOException
import java.util.*
import java.util.jar.Attributes
import java.util.jar.Manifest
internal inline fun Properties.getString(propertyName: String, otherwise: () -> String): String =
getProperty(propertyName) ?: otherwise()
object JvmRuntimeVersionsConsistencyChecker {
private val LOG = Logger.getInstance(JvmRuntimeVersionsConsistencyChecker::class.java)
@@ -43,8 +40,6 @@ object JvmRuntimeVersionsConsistencyChecker {
private fun <T> T?.assertNotNull(message: () -> String): T =
if (this == null) fatal(message()) else this
private val VERSION_ISSUE_SEVERITY = CompilerMessageSeverity.ERROR
private const val META_INF = "META-INF"
private const val MANIFEST_MF = "$META_INF/MANIFEST.MF"
@@ -56,7 +51,10 @@ object JvmRuntimeVersionsConsistencyChecker {
private const val KOTLIN_STDLIB_MODULE = "$META_INF/kotlin-stdlib.kotlin_module"
private const val KOTLIN_REFLECT_MODULE = "$META_INF/kotlin-reflection.kotlin_module"
private const val KOTLIN_COMPILER_MODULE = "$META_INF/kotlin-compiler.kotlin_module"
private val RUNTIME_IMPLEMENTATION_TITLES = setOf(
"kotlin-runtime", "kotlin-stdlib", "kotlin-reflect", "Kotlin Runtime", "Kotlin Standard Library", "Kotlin Reflect"
)
private val KOTLIN_VERSION_ATTRIBUTE: String
private val CURRENT_COMPILER_VERSION: MavenComparableVersion
@@ -86,8 +84,8 @@ object JvmRuntimeVersionsConsistencyChecker {
MavenComparableVersion(kotlinVersionString)
}
if (CURRENT_COMPILER_VERSION != MavenComparableVersion(LanguageVersion.LATEST)) {
fatal("Kotlin compiler version $CURRENT_COMPILER_VERSION in kotlinManifest.properties doesn't match ${LanguageVersion.LATEST}")
if (CURRENT_COMPILER_VERSION != ApiVersion.LATEST.version) {
fatal("Kotlin compiler version $CURRENT_COMPILER_VERSION in kotlinManifest.properties doesn't match ${ApiVersion.LATEST}")
}
KOTLIN_RUNTIME_COMPONENT_ATTRIBUTE = manifestProperties.getProperty(MANIFEST_KOTLIN_RUNTIME_COMPONENT)
@@ -98,141 +96,278 @@ object JvmRuntimeVersionsConsistencyChecker {
.assertNotNull { "$MANIFEST_KOTLIN_RUNTIME_COMPONENT_MAIN not found in kotlinManifest.properties" }
}
private class KotlinLibraryFile(val component: String, val file: VirtualFile, val version: MavenComparableVersion) {
private class KotlinLibraryFile(val file: VirtualFile, val version: MavenComparableVersion) {
override fun toString(): String =
"${file.name}:$version ($component)"
"${file.name}:$version"
}
private class RuntimeJarsInfo(
// Runtime jars with components "Main" and "Core"
val jars: List<KotlinLibraryFile>,
// Runtime jars with components "Core" only (a subset of [jars])
val coreJars: List<KotlinLibraryFile>
val coreJars: List<KotlinLibraryFile>,
// Library jars which have some Kotlin Runtime library bundled into them
val otherLibrariesWithBundledRuntime: List<VirtualFile>
)
fun checkCompilerClasspathConsistency(
messageCollector: MessageCollector,
languageVersionSettings: LanguageVersionSettings?,
configuration: CompilerConfiguration,
classpathJarRoots: List<VirtualFile>
) {
val runtimeJarsInfo = collectRuntimeJarsInfo(classpathJarRoots)
if (runtimeJarsInfo.jars.isEmpty()) return
val languageVersion = languageVersionSettings?.let { MavenComparableVersion(it.languageVersion) } ?: CURRENT_COMPILER_VERSION
val languageVersionSettings = configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS)
val apiVersion = languageVersionSettings?.apiVersion?.version ?: CURRENT_COMPILER_VERSION
if (checkCompilerClasspathConsistency(messageCollector, languageVersion, runtimeJarsInfo)) {
messageCollector.issue(null, "Some runtime JAR files in the classpath have an incompatible version. " +
"Remove them from the classpath or use '-Xskip-runtime-version-check' to suppress errors")
val consistency = checkCompilerClasspathConsistency(messageCollector, apiVersion, runtimeJarsInfo)
if (consistency is ClasspathConsistency.InconsistentWithApiVersion) {
val actualRuntimeVersion = consistency.actualRuntimeVersion
messageCollector.issue(
null,
"Runtime JAR files in the classpath have the version $actualRuntimeVersion, " +
"which is older than the API version $apiVersion. " +
"Consider using the runtime of version $apiVersion, or pass '-api-version $actualRuntimeVersion' explicitly to " +
"restrict the available APIs to the runtime of version $actualRuntimeVersion. " +
"You can also pass '-language-version $actualRuntimeVersion' instead, which will restrict " +
"not only the APIs to the specified version, but also the language features. " +
"Alternatively, you can use '-Xskip-runtime-version-check' to suppress this warning"
)
val actualApi = ApiVersion.parse(actualRuntimeVersion.toString())
if (actualApi != null) {
val newSettings = if (languageVersionSettings == null) {
LanguageVersionSettingsImpl(
LanguageVersionSettingsImpl.DEFAULT.languageVersion,
actualApi,
listOf(LanguageFeature.WarnOnCoroutines)
)
}
else {
val inferredApiVersion =
if (@Suppress("DEPRECATION") languageVersionSettings.isApiVersionExplicit)
languageVersionSettings.apiVersion
else
minOf(languageVersionSettings.apiVersion, actualApi)
// "minOf" is needed in case when API version was inferred from language version and it's older than actualApi.
// For example, in "kotlinc-1.2 -language-version 1.0 -cp kotlin-runtime-1.1.jar" we should still infer API = 1.0
LanguageVersionSettingsImpl(
languageVersionSettings.languageVersion,
inferredApiVersion,
languageVersionSettings.additionalFeatures,
isApiVersionExplicit = false
)
}
messageCollector.issue(null, "Old runtime has been found in the classpath. " +
"Initial language version settings: $languageVersionSettings. " +
"Updated language version settings: $newSettings", CompilerMessageSeverity.LOGGING)
configuration.put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS, newSettings)
}
else {
messageCollector.issue(null, "Could not parse runtime JAR version: $actualRuntimeVersion")
}
}
else if (consistency != ClasspathConsistency.Consistent) {
messageCollector.issue(
null,
"Some runtime JAR files in the classpath have an incompatible version. " +
"Consider removing them from the classpath or use '-Xskip-runtime-version-check' to suppress this warning"
)
}
val librariesWithBundled = runtimeJarsInfo.otherLibrariesWithBundledRuntime
if (librariesWithBundled.isNotEmpty()) {
messageCollector.issue(
null,
"Some JAR files in the classpath have the Kotlin Runtime library bundled into them. " +
"This may cause difficult to debug problems if there's a different version of the Kotlin Runtime library in the classpath. " +
"Consider removing these libraries from the classpath or use '-Xskip-runtime-version-check' to suppress this warning"
)
for (library in librariesWithBundled) {
messageCollector.issue(library, "Library has Kotlin runtime bundled into it")
}
}
}
private sealed class ClasspathConsistency {
object Consistent : ClasspathConsistency()
class InconsistentWithApiVersion(val actualRuntimeVersion: MavenComparableVersion) : ClasspathConsistency()
object InconsistentWithCompilerVersion : ClasspathConsistency()
object InconsistentBecauseOfRuntimesWithDifferentVersions : ClasspathConsistency()
}
private fun checkCompilerClasspathConsistency(
messageCollector: MessageCollector,
languageVersion: MavenComparableVersion,
apiVersion: MavenComparableVersion,
runtimeJarsInfo: RuntimeJarsInfo
): Boolean {
): ClasspathConsistency {
// The "Core" jar files should not be newer than the compiler. This behavior is reserved for the future if we realise that we're
// going to break language/library compatibility in such a way that it's easier to make the old compiler just report an error
// in the case the new runtime library is specified in the classpath, rather than employing any other compatibility breakage tools
// we have at our disposal (Deprecated, SinceKotlin, SinceKotlinInfo in metadata, etc.)
if (runtimeJarsInfo.coreJars.map {
checkNotNewerThanCompiler(messageCollector, it)
}.any { it }) return true
}.any { it }) return ClasspathConsistency.InconsistentWithCompilerVersion
if (runtimeJarsInfo.jars.map {
checkCompatibleWithLanguageVersion(messageCollector, it, languageVersion)
}.any { it }) return true
val jars = runtimeJarsInfo.jars
if (jars.isEmpty()) return ClasspathConsistency.Consistent
return checkMatchingVersions(messageCollector, runtimeJarsInfo)
val runtimeVersion = checkMatchingVersionsAndGetRuntimeVersion(messageCollector, jars)
?: return ClasspathConsistency.InconsistentBecauseOfRuntimesWithDifferentVersions
if (jars.map {
checkCompatibleWithApiVersion(messageCollector, it, apiVersion)
}.any { it }) return ClasspathConsistency.InconsistentWithApiVersion(runtimeVersion)
return ClasspathConsistency.Consistent
}
private fun checkNotNewerThanCompiler(messageCollector: MessageCollector, jar: KotlinLibraryFile): Boolean {
if (jar.version > CURRENT_COMPILER_VERSION) {
messageCollector.issue(jar.file, "Runtime JAR file has version ${jar.version} which is newer than compiler version $CURRENT_COMPILER_VERSION")
messageCollector.issue(
jar.file,
"Runtime JAR file has version ${jar.version} which is newer than compiler version $CURRENT_COMPILER_VERSION",
CompilerMessageSeverity.ERROR
)
return true
}
return false
}
private fun checkCompatibleWithLanguageVersion(
messageCollector: MessageCollector, jar: KotlinLibraryFile, languageVersion: MavenComparableVersion
private fun checkCompatibleWithApiVersion(
messageCollector: MessageCollector, jar: KotlinLibraryFile, apiVersion: MavenComparableVersion
): Boolean {
if (jar.version < languageVersion) {
messageCollector.issue(jar.file, "Runtime JAR file has version ${jar.version} which is older than required for language version $languageVersion")
if (jar.version < apiVersion) {
messageCollector.issue(
jar.file,
"Runtime JAR file has version ${jar.version} which is older than required for API version $apiVersion"
)
return true
}
return false
}
private fun checkMatchingVersions(messageCollector: MessageCollector, runtimeJarsInfo: RuntimeJarsInfo): Boolean {
val oldestJar = runtimeJarsInfo.jars.minBy { it.version } ?: return false
val newestJar = runtimeJarsInfo.jars.maxBy { it.version } ?: return false
// Returns the version if it's the same across all jars, or null if versions of some jars differ.
private fun checkMatchingVersionsAndGetRuntimeVersion(
messageCollector: MessageCollector,
jars: List<KotlinLibraryFile>
): MavenComparableVersion? {
assert(jars.isNotEmpty()) { "'jars' must not be empty" }
val oldestVersion = jars.minBy { it.version }!!.version
val newestVersion = jars.maxBy { it.version }!!.version
if (oldestJar.version != newestJar.version) {
messageCollector.issue(null, buildString {
appendln("Runtime JAR files in the classpath must have the same version. These files were found in the classpath:")
for (jar in runtimeJarsInfo.jars) {
appendln(" ${jar.file.path} (version ${jar.version})")
}
}.trimEnd())
return true
// If the oldest version is the same as the newest version, then all jars have the same version
if (oldestVersion == newestVersion) return oldestVersion
messageCollector.issue(null, buildString {
appendln("Runtime JAR files in the classpath should have the same version. These files were found in the classpath:")
for (jar in jars) {
appendln(" ${jar.file.path} (version ${jar.version})")
}
}.trimEnd())
// If there's kotlin-stdlib of version X in the classpath and kotlin-reflect of version Y < X,
// we suggest to provide an explicit dependency on version X.
// TODO: report this depending on the content of the jars instead
val minReflectJar =
jars.filter { it.file.name.startsWith("kotlin-reflect") }.minBy { it.version }
val maxStdlibJar =
jars.filter { it.file.name.startsWith("kotlin-runtime") || it.file.name.startsWith("kotlin-stdlib") }.maxBy { it.version }
if (minReflectJar != null && maxStdlibJar != null && minReflectJar.version < maxStdlibJar.version) {
messageCollector.issue(
null,
"Consider providing an explicit dependency on kotlin-reflect ${maxStdlibJar.version} to prevent strange errors"
)
}
return false
return null
}
private fun MessageCollector.issue(file: VirtualFile?, message: String) {
report(VERSION_ISSUE_SEVERITY, message, CompilerMessageLocation.create(file?.let(VfsUtilCore::virtualToIoFile)?.path))
private fun MessageCollector.issue(
file: VirtualFile?,
message: String,
severity: CompilerMessageSeverity = CompilerMessageSeverity.STRONG_WARNING
) {
report(severity, message, CompilerMessageLocation.create(file?.let(VfsUtilCore::virtualToIoFile)?.path))
}
private fun collectRuntimeJarsInfo(classpathJarRoots: List<VirtualFile>): RuntimeJarsInfo {
val jars = ArrayList<KotlinLibraryFile>(2)
val coreJars = ArrayList<KotlinLibraryFile>(2)
val otherLibrariesWithBundledRuntime = ArrayList<VirtualFile>(0)
val visitedPaths = hashSetOf<String>()
for (jarRoot in classpathJarRoots) {
val manifest = try {
val manifestFile = jarRoot.findFileByRelativePath(MANIFEST_MF) ?: continue
Manifest(manifestFile.inputStream)
}
catch (e: Exception) {
continue
}
val runtimeComponent = getKotlinRuntimeComponent(jarRoot, manifest) ?: continue
val version = manifest.getKotlinLanguageVersion()
val fileKind = determineFileKind(jarRoot)
if (fileKind is FileKind.Irrelevant) continue
val jarFile = VfsUtilCore.getVirtualFileForJar(jarRoot) ?: continue
val file = KotlinLibraryFile(runtimeComponent, jarFile, version)
if (!visitedPaths.add(jarFile.path)) continue
if (runtimeComponent == KOTLIN_RUNTIME_COMPONENT_CORE) {
jars.add(file)
coreJars.add(file)
}
else if (runtimeComponent == KOTLIN_RUNTIME_COMPONENT_MAIN) {
jars.add(file)
when (fileKind) {
is FileKind.Runtime -> {
val file = KotlinLibraryFile(jarFile, fileKind.version)
jars.add(file)
if (fileKind.isCoreComponent) {
coreJars.add(file)
}
}
FileKind.OldRuntime -> jars.add(KotlinLibraryFile(jarFile, ApiVersion.KOTLIN_1_0.version))
FileKind.LibraryWithBundledRuntime -> otherLibrariesWithBundledRuntime.add(jarFile)
}
}
return RuntimeJarsInfo(jars, coreJars)
return RuntimeJarsInfo(jars, coreJars, otherLibrariesWithBundledRuntime)
}
private fun getKotlinRuntimeComponent(jar: VirtualFile, manifest: Manifest): String? {
manifest.mainAttributes.getValue(KOTLIN_RUNTIME_COMPONENT_ATTRIBUTE)?.let { return it }
private sealed class FileKind {
class Runtime(val version: MavenComparableVersion, val isCoreComponent: Boolean) : FileKind()
// Do not treat kotlin-compiler and kotlin-compiler-embeddable as Kotlin runtime libraries.
// The second condition is needed because when the compiler is built with "compiler-quick", there's no kotlin-compiler.kotlin_module
if (jar.findFileByRelativePath(KOTLIN_COMPILER_MODULE) != null ||
jar.findFileByRelativePath(this::class.java.name.replace('.', '/') + "." + JavaClassFileType.INSTANCE.defaultExtension) != null) return null
// Runtime library of Kotlin 1.0
object OldRuntime : FileKind()
if (jar.findFileByRelativePath(KOTLIN_STDLIB_MODULE) != null) return KOTLIN_RUNTIME_COMPONENT_MAIN
if (jar.findFileByRelativePath(KOTLIN_REFLECT_MODULE) != null) return KOTLIN_RUNTIME_COMPONENT_MAIN
object LibraryWithBundledRuntime : FileKind()
return null
object Irrelevant : FileKind()
}
private fun determineFileKind(jarRoot: VirtualFile): FileKind {
val manifestFile = jarRoot.findFileByRelativePath(MANIFEST_MF)
val manifest = try {
manifestFile?.let { Manifest(it.inputStream) }
}
catch (e: IOException) {
return FileKind.Irrelevant
}
val runtimeComponent = manifest?.mainAttributes?.getValue(KOTLIN_RUNTIME_COMPONENT_ATTRIBUTE)
return when (runtimeComponent) {
KOTLIN_RUNTIME_COMPONENT_MAIN ->
FileKind.Runtime(manifest.getKotlinLanguageVersion(), isCoreComponent = false)
KOTLIN_RUNTIME_COMPONENT_CORE ->
FileKind.Runtime(manifest.getKotlinLanguageVersion(), isCoreComponent = true)
null -> when {
jarRoot.findFileByRelativePath(KOTLIN_STDLIB_MODULE) == null &&
jarRoot.findFileByRelativePath(KOTLIN_REFLECT_MODULE) == null -> FileKind.Irrelevant
isGenuineKotlinRuntime(manifest) -> FileKind.OldRuntime
else -> FileKind.LibraryWithBundledRuntime
}
else -> FileKind.Irrelevant
}
}
// Returns true if the manifest is from the original Kotlin Runtime jar, false if it's from a library with a bundled runtime
private fun isGenuineKotlinRuntime(manifest: Manifest?): Boolean {
return manifest != null &&
manifest.mainAttributes.getValue(Attributes.Name.IMPLEMENTATION_TITLE) in RUNTIME_IMPLEMENTATION_TITLES
}
private fun Manifest.getKotlinLanguageVersion(): MavenComparableVersion =
MavenComparableVersion(mainAttributes.getValue(KOTLIN_VERSION_ATTRIBUTE) ?: LanguageVersion.KOTLIN_1_0.versionString)
private fun MavenComparableVersion(languageVersion: LanguageVersion): MavenComparableVersion =
MavenComparableVersion(languageVersion.versionString)
(mainAttributes.getValue(KOTLIN_VERSION_ATTRIBUTE)?.let((ApiVersion)::parse) ?: ApiVersion.KOTLIN_1_0).version
}

View File

@@ -152,7 +152,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
if (destination != null) {
messageCollector.report(
CompilerMessageSeverity.WARNING,
CompilerMessageSeverity.STRONG_WARNING,
"The '-d' option with a directory destination is ignored because '-module' is specified",
CompilerMessageLocation.NO_LOCATION
)
@@ -365,7 +365,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
}
else {
if (arguments.jdkHome != null) {
messageCollector.report(CompilerMessageSeverity.WARNING,
messageCollector.report(CompilerMessageSeverity.STRONG_WARNING,
"The '-jdk-home' option is ignored because '-no-jdk' is specified",
CompilerMessageLocation.NO_LOCATION)
}

View File

@@ -67,8 +67,7 @@ import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
import org.jetbrains.kotlin.cli.common.toBooleanLenient
import org.jetbrains.kotlin.cli.jvm.JvmRuntimeVersionsConsistencyChecker
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
@@ -160,7 +159,7 @@ class KotlinCoreEnvironment private constructor(
if (messageCollector != null) {
JvmRuntimeVersionsConsistencyChecker.checkCompilerClasspathConsistency(
messageCollector,
configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS),
configuration,
initialRoots.mapNotNull { (file, type) -> if (type == JavaRoot.RootType.BINARY) file else null }
)
}
@@ -217,7 +216,7 @@ class KotlinCoreEnvironment private constructor(
FqName(it)
}
else {
report(WARNING, "Invalid package prefix name is ignored: $it")
report(STRONG_WARNING, "Invalid package prefix name is ignored: $it")
null
}
}
@@ -273,7 +272,7 @@ class KotlinCoreEnvironment private constructor(
val path = root.file
val localFile = findLocalDirectory(path.absolutePath)
if (localFile == null) {
report(WARNING, "Classpath entry points to a non-existent location: $path")
report(STRONG_WARNING, "Classpath entry points to a non-existent location: $path")
return null
}
return localFile
@@ -286,7 +285,7 @@ class KotlinCoreEnvironment private constructor(
val path = root.file
val jarFile = applicationEnvironment.jarFileSystem.findFileByPath("$path${URLUtil.JAR_SEPARATOR}")
if (jarFile == null) {
report(WARNING, "Classpath entry points to a file that is not a JAR archive: $path")
report(STRONG_WARNING, "Classpath entry points to a file that is not a JAR archive: $path")
return null
}
return jarFile
@@ -297,7 +296,7 @@ class KotlinCoreEnvironment private constructor(
configuration.kotlinSourceRoots.forEach { path ->
if (!uniqueSourceRoots.add(path)) {
report(WARNING, "Duplicate source root: $path")
report(STRONG_WARNING, "Duplicate source root: $path")
}
}

View File

@@ -20,10 +20,17 @@ import com.intellij.core.JavaCoreApplicationEnvironment
import com.intellij.core.JavaCoreProjectEnvironment
import com.intellij.openapi.Disposable
import com.intellij.psi.PsiManager
import com.intellij.psi.controlFlow.ControlFlowFactory
open class KotlinCoreProjectEnvironment(
disposable: Disposable,
applicationEnvironment: JavaCoreApplicationEnvironment
) : JavaCoreProjectEnvironment(disposable, applicationEnvironment) {
init {
myProject.registerService<ControlFlowFactory>(ControlFlowFactory::class.java,
ControlFlowFactory(myPsiManager))
}
override fun createCoreFileManager() = KotlinCliJavaFileManagerImpl(PsiManager.getInstance(project))
}

View File

@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.cli.jvm.repl
import com.intellij.openapi.Disposable
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.CharsetToolkit
import com.intellij.psi.PsiFileFactory
import com.intellij.psi.impl.PsiFileFactoryImpl
@@ -34,6 +35,7 @@ import org.jetbrains.kotlin.cli.jvm.repl.messages.DiagnosticMessageHolder
import org.jetbrains.kotlin.cli.jvm.repl.messages.ReplTerminalDiagnosticMessageHolder
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtFile
@@ -42,6 +44,8 @@ import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.read
import kotlin.concurrent.write
const val KOTLIN_REPL_JVM_TARGET_PROPERTY = "kotlin.repl.jvm.target"
open class GenericReplChecker(
disposable: Disposable,
val scriptDefinition: KotlinScriptDefinition,
@@ -54,6 +58,12 @@ open class GenericReplChecker(
add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, scriptDefinition)
put<MessageCollector>(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
put(JVMConfigurationKeys.RETAIN_OUTPUT_IN_MEMORY, true)
if (get(JVMConfigurationKeys.JVM_TARGET) == null) {
put(JVMConfigurationKeys.JVM_TARGET,
System.getProperty(KOTLIN_REPL_JVM_TARGET_PROPERTY)?.let { JvmTarget.fromString(it) }
?: if (getJavaVersion() >= 0x10008) JvmTarget.JVM_1_8 else JvmTarget.JVM_1_6)
}
}
KotlinCoreEnvironment.createForProduction(disposable, compilerConfiguration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
}
@@ -76,7 +86,7 @@ open class GenericReplChecker(
stateLock.write {
val scriptFileName = makeScriptBaseName(codeLine, generation)
val virtualFile =
LightVirtualFile("$scriptFileName${KotlinParserDefinition.STD_SCRIPT_EXT}", KotlinLanguage.INSTANCE, codeLine.code).apply {
LightVirtualFile("$scriptFileName${KotlinParserDefinition.STD_SCRIPT_EXT}", KotlinLanguage.INSTANCE, StringUtil.convertLineSeparators(codeLine.code)).apply {
charset = CharsetToolkit.UTF8_CHARSET
}
val psiFile: KtFile = psiFileFactory.trySetupPsiForFile(virtualFile, KotlinLanguage.INSTANCE, true, false) as KtFile?
@@ -98,3 +108,21 @@ open class GenericReplChecker(
}
}
}
// initially taken from libraries/stdlib/src/kotlin/internal/PlatformImplementations.kt
// fixed according to JEP 223 - http://openjdk.java.net/jeps/223
// TODO: consider to place it to some common place
private fun getJavaVersion(): Int {
val default = 0x10006
val version = System.getProperty("java.specification.version") ?: return default
val components = version.split('.')
return try {
when (components.size) {
0 -> default
1 -> components[0].toInt() * 0x10000
else -> components[0].toInt() * 0x10000 + components[1].toInt()
}
} catch (e: NumberFormatException) {
default
}
}

View File

@@ -65,7 +65,7 @@ class K2MetadataCompiler : CLICompiler<K2MetadataCompilerArguments>() {
if (destination.endsWith(".jar")) {
// TODO: support .jar destination
collector.report(
CompilerMessageSeverity.WARNING,
CompilerMessageSeverity.STRONG_WARNING,
".jar destination is not yet supported, results will be written to the directory with the given name",
CompilerMessageLocation.NO_LOCATION
)

View File

@@ -7,11 +7,10 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="daemon-common" />
<orderEntry type="module" module-name="util" />
<orderEntry type="library" name="native-platform-uberjar" level="project" />
<orderEntry type="module" module-name="cli-common" />
<orderEntry type="module" module-name="descriptors" />
<orderEntry type="library" name="intellij-core" level="project" />
<orderEntry type="module" module-name="daemon-common" scope="PROVIDED" />
<orderEntry type="module" module-name="util" scope="PROVIDED" />
<orderEntry type="library" scope="PROVIDED" name="native-platform-uberjar" level="project" />
<orderEntry type="module" module-name="cli-common" scope="PROVIDED" />
<orderEntry type="module" module-name="descriptors" scope="PROVIDED" />
</component>
</module>

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.daemon.client
import com.intellij.openapi.progress.ProcessCanceledException
import org.jetbrains.kotlin.daemon.common.CompilerCallbackServicesFacade
import org.jetbrains.kotlin.daemon.common.LoopbackNetworkInterface
import org.jetbrains.kotlin.daemon.common.RmiFriendlyCompilationCanceledException
@@ -27,7 +26,9 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompil
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.utils.rethrow
import java.rmi.server.UnicastRemoteObject
import kotlin.reflect.full.allSuperclasses
open class CompilerCallbackServicesFacadeServer(
@@ -83,10 +84,12 @@ open class CompilerCallbackServicesFacadeServer(
try {
compilationCanceledStatus!!.checkCanceled()
}
catch (e: ProcessCanceledException) {
catch (e: Exception) {
// avoid passing exceptions that may have different serialVersionUID on across rmi border
// TODO: doublecheck whether we need to distinguish different cancellation exceptions
throw RmiFriendlyCompilationCanceledException()
// removing dependency from openapi (this is obsolete part anyway, and will be removed soon)
if ((e::class.allSuperclasses + e::class).any { it.qualifiedName == "com.intellij.openapi.progress.ProcessCanceledException" })
throw RmiFriendlyCompilationCanceledException()
else throw e
}
}
}

View File

@@ -28,6 +28,10 @@ import org.jetbrains.kotlin.utils.addToStdlib.check
import java.io.File
import java.io.OutputStream
import java.io.PrintStream
import java.net.SocketException
import java.rmi.ConnectException
import java.rmi.ConnectIOException
import java.rmi.UnmarshalException
import java.rmi.server.UnicastRemoteObject
import java.util.concurrent.Semaphore
import java.util.concurrent.TimeUnit
@@ -70,32 +74,49 @@ object KotlinCompilerClient {
daemonOptions: DaemonOptions,
reportingTargets: DaemonReportingTargets,
autostart: Boolean = true
): CompileService? {
): CompileService? =
connectAndLease(compilerId,
clientAliveFlagFile,
daemonJVMOptions,
daemonOptions,
reportingTargets,
autostart,
leaseSession = false,
sessionAliveFlagFile = null)?.first
var attempts = 0
try {
while (attempts++ < DAEMON_CONNECT_CYCLE_ATTEMPTS) {
val (service, newJVMOptions) = tryFindSuitableDaemonOrNewOpts(File(daemonOptions.runFilesPath), compilerId, daemonJVMOptions, { cat, msg -> reportingTargets.report(cat, msg) })
if (service != null) {
// the newJVMOptions could be checked here for additional parameters, if needed
service.registerClient(clientAliveFlagFile.absolutePath)
reportingTargets.report(DaemonReportCategory.DEBUG, "connected to the daemon")
return service
}
reportingTargets.report(DaemonReportCategory.DEBUG, "no suitable daemon found")
if (autostart) {
startDaemon(compilerId, newJVMOptions, daemonOptions, reportingTargets)
reportingTargets.report(DaemonReportCategory.DEBUG, "new daemon started, trying to find it")
}
fun connectAndLease(compilerId: CompilerId,
clientAliveFlagFile: File,
daemonJVMOptions: DaemonJVMOptions,
daemonOptions: DaemonOptions,
reportingTargets: DaemonReportingTargets,
autostart: Boolean,
leaseSession: Boolean,
sessionAliveFlagFile: File? = null
): Pair<CompileService, Int>? = connectLoop(reportingTargets) {
val (service, newJVMOptions) = tryFindSuitableDaemonOrNewOpts(File(daemonOptions.runFilesPath), compilerId, daemonJVMOptions, { cat, msg -> reportingTargets.report(cat, msg) })
if (service != null) {
// the newJVMOptions could be checked here for additional parameters, if needed
service.registerClient(clientAliveFlagFile.absolutePath)
reportingTargets.report(DaemonReportCategory.DEBUG, "connected to the daemon")
if (!leaseSession) service to CompileService.NO_SESSION
else {
val sessionId = service.leaseCompileSession(sessionAliveFlagFile?.absolutePath)
if (sessionId is CompileService.CallResult.Dying)
null
else
service to sessionId.get()
}
} else {
reportingTargets.report(DaemonReportCategory.DEBUG, "no suitable daemon found")
if (autostart) {
startDaemon(compilerId, newJVMOptions, daemonOptions, reportingTargets)
reportingTargets.report(DaemonReportCategory.DEBUG, "new daemon started, trying to find it")
}
null
}
catch (e: Throwable) {
reportingTargets.report(DaemonReportCategory.EXCEPTION, e.toString())
}
return null
}
fun shutdownCompileService(compilerId: CompilerId, daemonOptions: DaemonOptions): Unit {
connectToCompileService(compilerId, DaemonJVMOptions(), daemonOptions, DaemonReportingTargets(out = System.out), autostart = false, checkId = false)
?.shutdown()
@@ -107,6 +128,13 @@ object KotlinCompilerClient {
}
fun leaseCompileSession(compilerService: CompileService, aliveFlagPath: String?): Int =
compilerService.leaseCompileSession(aliveFlagPath).get()
fun releaseCompileSession(compilerService: CompileService, sessionId: Int): Unit {
compilerService.releaseCompileSession(sessionId)
}
fun compile(compilerService: CompileService,
sessionId: Int,
targetPlatform: CompileService.TargetPlatform,
@@ -270,6 +298,33 @@ object KotlinCompilerClient {
// --- Implementation ---------------------------------------
private inline fun <R> connectLoop(reportingTargets: DaemonReportingTargets, body: () -> R?): R? {
try {
var attempts = 0
while (attempts < DAEMON_CONNECT_CYCLE_ATTEMPTS) {
attempts += 1
val (res, err) = try {
body() to null
}
catch (e: SocketException) { null to e }
catch (e: ConnectException) { null to e }
catch (e: ConnectIOException) { null to e }
catch (e: UnmarshalException) { null to e }
when {
res != null -> return res
err != null && attempts >= DAEMON_CONNECT_CYCLE_ATTEMPTS -> throw err
err != null ->
reportingTargets.report(DaemonReportCategory.INFO, "retrying($attempts) on: " + err.toString())
}
}
}
catch (e: Throwable) {
reportingTargets.report(DaemonReportCategory.EXCEPTION, e.toString())
}
return null
}
private fun DaemonReportingTargets.report(category: DaemonReportCategory, message: String, source: String = "daemon client") {
if (category == DaemonReportCategory.DEBUG && !verboseReporting) return
out?.println("[$source] ${category.name}: $message")
@@ -291,23 +346,33 @@ object KotlinCompilerClient {
}
private fun tryFindSuitableDaemonOrNewOpts(registryDir: File, compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, report: (DaemonReportCategory, String) -> Unit): Pair<CompileService?, DaemonJVMOptions> {
val aliveWithOpts = walkDaemons(registryDir, compilerId, report = report)
.map { Pair(it, it.getDaemonJVMOptions()) }
.filter { it.second.isGood }
.sortedWith(compareByDescending(DaemonJVMOptionsMemoryComparator(), { it.second.get() }))
registryDir.mkdirs()
val timestampMarker = createTempFile("kotlin-daemon-client-tsmarker", directory = registryDir)
val aliveWithMetadata = try {
walkDaemons(registryDir, compilerId, timestampMarker, report = report).toList()
}
finally {
timestampMarker.delete()
}
val comparator = compareByDescending<DaemonWithMetadata, DaemonJVMOptions>(DaemonJVMOptionsMemoryComparator(), { it.jvmOptions })
.thenBy(FileAgeComparator()) { it.runFile }
val optsCopy = daemonJVMOptions.copy()
// if required options fit into fattest running daemon - return the daemon and required options with memory params set to actual ones in the daemon
return aliveWithOpts.firstOrNull()?.check { daemonJVMOptions memorywiseFitsInto it.second.get() }?.let {
Pair(it.first, optsCopy.updateMemoryUpperBounds(it.second.get()))
return aliveWithMetadata.maxWith(comparator)?.takeIf { daemonJVMOptions memorywiseFitsInto it.jvmOptions }?.let {
Pair(it.daemon, optsCopy.updateMemoryUpperBounds(it.jvmOptions))
}
// else combine all options from running daemon to get fattest option for a new daemon to run
?: Pair(null, aliveWithOpts.fold(optsCopy, { opts, d -> opts.updateMemoryUpperBounds(d.second.get()) }))
?: Pair(null, aliveWithMetadata.fold(optsCopy, { opts, d -> opts.updateMemoryUpperBounds(d.jvmOptions) }))
}
private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, reportingTargets: DaemonReportingTargets) {
val javaExecutable = File(File(System.getProperty("java.home"), "bin"), "java")
val platformSpecificOptions = listOf("-Djava.awt.headless=true") // hide daemon window
val platformSpecificOptions = listOf(
// hide daemon window
"-Djava.awt.headless=true",
// prevent host name resolution
"-Djava.rmi.server.hostname=${LoopbackNetworkInterface.loopbackInetAddressName}")
val args = listOf(
javaExecutable.absolutePath, "-cp", compilerId.compilerClasspath.joinToString(File.pathSeparator)) +
platformSpecificOptions +
@@ -331,7 +396,7 @@ object KotlinCompilerClient {
daemon.inputStream
.reader()
.forEachLine {
if (daemonOptions.runFilesPath.isNotEmpty() && it.contains(daemonOptions.runFilesPath)) {
if (it == COMPILE_DAEMON_IS_READY_MESSAGE) {
isEchoRead.release()
return@forEachLine
}

View File

@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.daemon.client
import com.intellij.openapi.Disposable
import com.intellij.openapi.util.Disposer
import org.jetbrains.kotlin.cli.common.repl.*
import org.jetbrains.kotlin.daemon.common.CompileService
import org.jetbrains.kotlin.daemon.common.RemoteOperationsTracer
@@ -29,7 +27,6 @@ import java.io.OutputStream
// TODO: reduce number of ports used then SOCKET_ANY_FREE_PORT is passed (same problem with other calls)
open class KotlinRemoteReplClientBase(
disposable: Disposable,
protected val compileService: CompileService,
clientAliveFlagFile: File?,
targetPlatform: CompileService.TargetPlatform,
@@ -60,20 +57,18 @@ open class KotlinRemoteReplClientBase(
operationsTracer
).get()
init {
Disposer.register(disposable, Disposable {
try {
compileService.releaseReplSession(sessionId)
}
catch (ex: java.rmi.RemoteException) {
// assuming that communication failed and daemon most likely is already down
}
})
// dispose should be called at the end of the repl lifetime to free daemon repl session and appropriate resources
open fun dispose() {
try {
compileService.releaseReplSession(sessionId)
}
catch (ex: java.rmi.RemoteException) {
// assuming that communication failed and daemon most likely is already down
}
}
}
class KotlinRemoteReplCompiler(
disposable: Disposable,
compileService: CompileService,
clientAliveFlagFile: File?,
targetPlatform: CompileService.TargetPlatform,
@@ -83,7 +78,6 @@ class KotlinRemoteReplCompiler(
port: Int = SOCKET_ANY_FREE_PORT,
operationsTracer: RemoteOperationsTracer? = null
) : KotlinRemoteReplClientBase(
disposable = disposable,
compileService = compileService,
clientAliveFlagFile = clientAliveFlagFile,
targetPlatform = targetPlatform,
@@ -114,7 +108,6 @@ class KotlinRemoteReplCompiler(
// TODO: consider removing daemon eval completely - it is not required now and has questionable security. This will simplify daemon interface as well
class KotlinRemoteReplEvaluator(
disposable: Disposable,
compileService: CompileService,
clientAliveFlagFile: File?,
targetPlatform: CompileService.TargetPlatform,
@@ -129,7 +122,6 @@ class KotlinRemoteReplEvaluator(
port: Int = SOCKET_ANY_FREE_PORT,
operationsTracer: RemoteOperationsTracer? = null
) : KotlinRemoteReplClientBase(
disposable = disposable,
compileService = compileService,
clientAliveFlagFile = clientAliveFlagFile,
targetPlatform = targetPlatform,

View File

@@ -40,30 +40,48 @@ fun makePortFromRunFilenameExtractor(digest: String): (String) -> Int? {
}
}
private const val ORPHANED_RUN_FILE_AGE_THRESHOLD_MS = 1000000L
data class DaemonWithMetadata(val daemon: CompileService, val runFile: File, val jvmOptions: DaemonJVMOptions)
fun walkDaemons(registryDir: File,
compilerId: CompilerId,
filter: (File, Int) -> Boolean = { f, p -> true },
report: (DaemonReportCategory, String) -> Unit = { cat, msg -> }
): Sequence<CompileService> {
fileToCompareTimestamp: File,
filter: (File, Int) -> Boolean = { _, _ -> true },
report: (DaemonReportCategory, String) -> Unit = { _, _ -> }
): Sequence<DaemonWithMetadata> {
val classPathDigest = compilerId.compilerClasspath.map { File(it).absolutePath }.distinctStringsDigest().toHexString()
val portExtractor = makePortFromRunFilenameExtractor(classPathDigest)
return registryDir.walk()
.map { Pair(it, portExtractor(it.name)) }
.filter { it.second != null && filter(it.first, it.second!!) }
.mapNotNull {
assert(it.second!! > 0 && it.second!! < MAX_PORT_NUMBER)
report(DaemonReportCategory.DEBUG, "found daemon on port ${it.second}, trying to connect")
val daemon = tryConnectToDaemon(it.second!!, report)
.filter { (file, port) -> port != null && filter(file, port) }
.mapNotNull { (file, port) ->
assert(port!! in 1..(MAX_PORT_NUMBER - 1))
val relativeAge = fileToCompareTimestamp.lastModified() - file.lastModified()
report(DaemonReportCategory.DEBUG, "found daemon on port $port ($relativeAge ms old), trying to connect")
val daemon = tryConnectToDaemon(port, report)
// cleaning orphaned file; note: daemon should shut itself down if it detects that the run file is deleted
if (daemon == null && !it.first.delete()) {
report(DaemonReportCategory.INFO, "WARNING: unable to delete seemingly orphaned file '${it.first.absolutePath}', cleanup recommended")
if (daemon == null) {
if (relativeAge - ORPHANED_RUN_FILE_AGE_THRESHOLD_MS <= 0) {
report(DaemonReportCategory.DEBUG, "found fresh run file '${file.absolutePath}' ($relativeAge ms old), but no daemon, ignoring it")
}
else {
report(DaemonReportCategory.DEBUG, "found seemingly orphaned run file '${file.absolutePath}' ($relativeAge ms old), deleting it")
if (!file.delete()) {
report(DaemonReportCategory.INFO, "WARNING: unable to delete seemingly orphaned file '${file.absolutePath}', cleanup recommended")
}
}
}
try {
daemon?.let { DaemonWithMetadata(it, file, it.getDaemonJVMOptions().get()) }
}
catch (e: Exception) {
report(DaemonReportCategory.INFO, "ERROR: unable to retrieve daemon JVM options, assuming daemon is dead: ${e.message}")
null
}
daemon
}
}
private inline fun tryConnectToDaemon(port: Int, report: (DaemonReportCategory, String) -> Unit): CompileService? {
try {
@@ -88,3 +106,19 @@ fun makeAutodeletingFlagFile(keyword: String = "compiler-client", baseDir: File?
flagFile.deleteOnExit()
return flagFile
}
// Comparator for reliable choice between daemons
class FileAgeComparator : Comparator<File> {
override fun compare(left: File, right: File): Int {
val leftTS = left.lastModified()
val rightTS = right.lastModified()
return when {
leftTS == 0L || rightTS == 0L -> 0 // cannot read any file timestamp, => undecidable
leftTS > rightTS -> -1
leftTS < rightTS -> 1
else -> compareValues(left.canonicalPath, right.canonicalPath)
}
}
}
const val LOG_PREFIX_ASSUMING_OTHER_DAEMONS_HAVE = "Assuming other daemons have"

View File

@@ -48,6 +48,7 @@ val COMPILE_DAEMON_DEFAULT_SHUTDOWN_DELAY_MS: Long = 1000L // 1 sec
val COMPILE_DAEMON_MEMORY_THRESHOLD_INFINITE: Long = 0L
val COMPILE_DAEMON_FORCE_SHUTDOWN_DEFAULT_TIMEOUT_MS: Long = 10000L // 10 secs
val COMPILE_DAEMON_TIMEOUT_INFINITE_MS: Long = 0L
val COMPILE_DAEMON_IS_READY_MESSAGE = "Kotlin compile daemon is ready"
val COMPILE_DAEMON_DEFAULT_RUN_DIR_PATH: String get() =
FileSystem.getRuntimeStateFilesPath("kotlin", "daemon")

View File

@@ -272,22 +272,30 @@ class CompileServiceImpl(
}
override fun scheduleShutdown(graceful: Boolean): CompileService.CallResult<Boolean> = ifAlive(minAliveness = Aliveness.Alive) {
CompileService.CallResult.Good(
if (!graceful || state.alive.compareAndSet(Aliveness.Alive.ordinal, Aliveness.LastSession.ordinal)) {
timer.schedule(0) {
ifAliveExclusive(minAliveness = Aliveness.LastSession, ignoreCompilerChanged = true) {
if (!graceful || state.sessions.isEmpty()) {
shutdownImpl()
}
else {
when {
!graceful -> {
shutdownWithDelay()
CompileService.CallResult.Good(true)
}
state.alive.compareAndSet(Aliveness.Alive.ordinal, Aliveness.LastSession.ordinal) -> {
timer.schedule(1) {
ifAliveExclusive(minAliveness = Aliveness.LastSession, ignoreCompilerChanged = true) {
when {
state.sessions.isEmpty() -> shutdownWithDelay()
else -> {
daemonOptions.autoshutdownIdleSeconds = TimeUnit.MILLISECONDS.toSeconds(daemonOptions.forceShutdownTimeoutMilliseconds).toInt()
daemonOptions.autoshutdownUnusedSeconds = daemonOptions.autoshutdownIdleSeconds
log.info("Graceful shutdown signalled; unused/idle timeouts are set to ${daemonOptions.autoshutdownUnusedSeconds}/${daemonOptions.autoshutdownIdleSeconds}s")
log.info("Some sessions are active, waiting for them to finish")
}
CompileService.CallResult.Ok()
}
CompileService.CallResult.Ok()
}
true
}
else false)
CompileService.CallResult.Good(true)
}
else -> CompileService.CallResult.Good(false)
}
}
override fun remoteCompile(sessionId: Int,
@@ -529,7 +537,7 @@ class CompileServiceImpl(
val stub = UnicastRemoteObject.exportObject(this, port, LoopbackNetworkInterface.clientLoopbackSocketFactory, LoopbackNetworkInterface.serverLoopbackSocketFactory) as CompileService
registry.rebind (COMPILER_SERVICE_RMI_NAME, stub)
timer.schedule(0) {
timer.schedule(10) {
initiateElections()
}
timer.schedule(delay = DAEMON_PERIODIC_CHECK_INTERVAL_MS, period = DAEMON_PERIODIC_CHECK_INTERVAL_MS) {
@@ -552,7 +560,7 @@ class CompileServiceImpl(
// 1. check if unused for a timeout - shutdown
if (shutdownCondition({ daemonOptions.autoshutdownUnusedSeconds != COMPILE_DAEMON_TIMEOUT_INFINITE_S && compilationsCounter.get() == 0 && nowSeconds() - lastUsedSeconds > daemonOptions.autoshutdownUnusedSeconds },
"Unused timeout exceeded ${daemonOptions.autoshutdownUnusedSeconds}s, shutting down")) {
shutdown()
scheduleShutdown(true)
}
else {
var anyDead = state.sessions.cleanDead()
@@ -600,39 +608,61 @@ class CompileServiceImpl(
}
// TODO: handover should include mechanism for client to switch to a new daemon then previous "handed over responsibilities" and shot down
private fun initiateElections() {
ifAlive {
val aliveWithOpts = walkDaemons(File(daemonOptions.runFilesPathOrDefault), compilerId, filter = { f, p -> p != port }, report = { lvl, msg -> log.info(msg) })
.map { Pair(it, it.getDaemonJVMOptions()) }
.filter { it.second.isGood }
.sortedWith(compareByDescending(DaemonJVMOptionsMemoryComparator(), { it.second.get() }))
if (aliveWithOpts.any()) {
val fattestOpts = aliveWithOpts.first().second.get()
// second part of the condition means that we prefer other daemon if is "equal" to the current one
if (fattestOpts memorywiseFitsInto daemonJVMOptions && !(daemonJVMOptions memorywiseFitsInto fattestOpts)) {
val aliveWithOpts = walkDaemons(File(daemonOptions.runFilesPathOrDefault), compilerId, runFile, filter = { f, p -> p != port }, report = { _, msg -> log.info(msg) }).toList()
val comparator = compareByDescending<DaemonWithMetadata, DaemonJVMOptions>(DaemonJVMOptionsMemoryComparator(), { it.jvmOptions })
.thenBy(FileAgeComparator()) { it.runFile }
aliveWithOpts.maxWith(comparator)?.let { bestDaemonWithMetadata ->
val fattestOpts = bestDaemonWithMetadata.jvmOptions
if (fattestOpts memorywiseFitsInto daemonJVMOptions && FileAgeComparator().compare(bestDaemonWithMetadata.runFile, runFile) < 0 ) {
// all others are smaller that me, take overs' clients and shut them down
aliveWithOpts.forEach {
it.first.getClients().check { it.isGood }?.let {
it.get().forEach { registerClient(it) }
log.info("$LOG_PREFIX_ASSUMING_OTHER_DAEMONS_HAVE lower prio, taking clients from them and schedule them to shutdown: my runfile: ${runFile.name} (${runFile.lastModified()}) vs best other runfile: ${bestDaemonWithMetadata.runFile.name} (${bestDaemonWithMetadata.runFile.lastModified()})")
aliveWithOpts.forEach { (daemon, runFile, _) ->
try {
daemon.getClients().takeIf { it.isGood }?.let {
it.get().forEach { clientAliveFile -> registerClient(clientAliveFile) }
}
daemon.scheduleShutdown(true)
}
catch (e: Exception) {
log.info("Cannot connect to a daemon, assuming dying ('${runFile.canonicalPath}'): ${e.message}")
}
it.first.scheduleShutdown(true)
}
}
else if (daemonJVMOptions memorywiseFitsInto fattestOpts) {
// TODO: seems that the second part of condition is incorrect, reconsider:
// the comment by @tsvtkv from review:
// Algorithm in plain english:
// (1) If the best daemon fits into me and the best daemon is younger than me, then I take over all other daemons clients.
// (2) If I fit into the best daemon and the best daemon is older than me, then I give my clients to that daemon.
//
// For example:
//
// daemon A starts with params: maxMem=100, codeCache=50
// daemon B starts with params: maxMem=200, codeCache=50
// daemon C starts with params: maxMem=150, codeCache=100
// A performs election: (1) is false because neither B nor C does not fit into A, (2) is false because both B and C are younger than A.
// B performs election: (1) is false because neither A nor C does not fit into B, (2) is false because B does not fit into neither A nor C.
// C performs election: (1) is false because B is better than A and B does not fit into C, (2) is false C does not fit into neither A nor B.
// Result: all daemons are alive and well.
else if (daemonJVMOptions memorywiseFitsInto fattestOpts && FileAgeComparator().compare(bestDaemonWithMetadata.runFile, runFile) > 0) {
// there is at least one bigger, handover my clients to it and shutdown
scheduleShutdown(true)
aliveWithOpts.first().first.let { fattest ->
getClients().check { it.isGood }?.let {
it.get().forEach { fattest.registerClient(it) }
}
log.info("$LOG_PREFIX_ASSUMING_OTHER_DAEMONS_HAVE higher prio, handover clients to it and schedule shutdown: my runfile: ${runFile.name} (${runFile.lastModified()}) vs best other runfile: ${bestDaemonWithMetadata.runFile.name} (${bestDaemonWithMetadata.runFile.lastModified()})")
getClients().takeIf { it.isGood }?.let {
it.get().forEach { bestDaemonWithMetadata.daemon.registerClient(it) }
}
scheduleShutdown(true)
}
else {
// undecided, do nothing
log.info("$LOG_PREFIX_ASSUMING_OTHER_DAEMONS_HAVE equal prio, continue: ${runFile.name} (${runFile.lastModified()}) vs best other runfile: ${bestDaemonWithMetadata.runFile.name} (${bestDaemonWithMetadata.runFile.lastModified()})")
// TODO: implement some behaviour here, e.g.:
// - shutdown/takeover smaller daemon
// - run (or better persuade client to run) a bigger daemon (in fact may be even simple shutdown will do, because of client's daemon choosing logic)
}
// else - do nothing, all daemons are staying
// TODO: implement some behaviour here, e.g.:
// - shutdown/takeover smaller daemon
// - run (or better persuade client to run) a bigger daemon (in fact may be even simple shutdown will do, because of client's daemon choosing logic)
}
CompileService.CallResult.Ok()
}
@@ -653,8 +683,11 @@ class CompileServiceImpl(
timer.schedule(daemonOptions.shutdownDelayMilliseconds) {
state.delayedShutdownQueued.set(false)
if (currentCompilationsCount == compilationsCounter.get()) {
log.fine("Execute delayed shutdown")
shutdown()
ifAliveExclusive(minAliveness = Aliveness.LastSession, ignoreCompilerChanged = true) {
log.fine("Execute delayed shutdown")
shutdownImpl()
CompileService.CallResult.Ok()
}
}
else {
log.info("Cancel delayed shutdown due to new client")
@@ -801,7 +834,7 @@ class CompileServiceImpl(
state.alive.get() < minAliveness.ordinal -> CompileService.CallResult.Dying()
!ignoreCompilerChanged && classpathWatcher.isChanged -> {
log.info("Compiler changed, scheduling shutdown")
timer.schedule(0) { shutdown() }
shutdownWithDelay()
CompileService.CallResult.Dying()
}
else -> {

View File

@@ -30,9 +30,7 @@ import java.net.URLClassLoader
import java.text.SimpleDateFormat
import java.util.*
import java.util.jar.Manifest
import java.util.logging.Level
import java.util.logging.LogManager
import java.util.logging.Logger
import java.util.logging.*
import kotlin.concurrent.schedule
val DAEMON_PERIODIC_CHECK_INTERVAL_MS = 1000L
@@ -55,7 +53,6 @@ class LogStream(name: String) : OutputStream() {
}
}
object KotlinCompileDaemon {
init {
@@ -71,7 +68,7 @@ object KotlinCompileDaemon {
"java.util.logging.FileHandler.count = ${if (fileIsGiven) 1 else 3}\n" +
"java.util.logging.FileHandler.append = $fileIsGiven\n" +
"java.util.logging.FileHandler.pattern = ${if (fileIsGiven) logPath else (logPath + File.separator + "${COMPILE_DAEMON_DEFAULT_FILES_PREFIX}.$logTime.%u%g.log")}\n" +
"java.util.logging.SimpleFormatter.format = %1\$tF %1\$tT.%1\$tL [%3\$s] %4\$s: %5\$s\\n\n"
"java.util.logging.SimpleFormatter.format = %1\$tF %1\$tT.%1\$tL [%3\$s] %4\$s: %5\$s%n\n"
LogManager.getLogManager().readConfiguration(cfg.byteInputStream())
}
@@ -96,6 +93,7 @@ object KotlinCompileDaemon {
log.info("Kotlin compiler daemon version " + (loadVersionFromResource() ?: "<unknown>"))
log.info("daemon JVM args: " + ManagementFactory.getRuntimeMXBean().inputArguments.joinToString(" "))
log.info("daemon args: " + args.joinToString(" "))
log.info("daemon process name: " + ManagementFactory.getRuntimeMXBean().name)
val compilerId = CompilerId()
val daemonOptions = DaemonOptions()
@@ -156,8 +154,10 @@ object KotlinCompileDaemon {
}
})
if (daemonOptions.runFilesPath.isNotEmpty())
println(daemonOptions.runFilesPath)
println(COMPILE_DAEMON_IS_READY_MESSAGE)
log.info("daemon is listening on port: $port")
log.info("daemon is listening on port: $port")
// this supposed to stop redirected streams reader(s) on the client side and prevent some situations with hanging threads, but doesn't work reliably
// TODO: implement more reliable scheme

View File

@@ -46,7 +46,7 @@ internal class CompileServicesFacadeMessageCollector(
else -> {
val reportSeverity = when (severity) {
CompilerMessageSeverity.ERROR -> ReportSeverity.ERROR
CompilerMessageSeverity.WARNING -> ReportSeverity.WARNING
CompilerMessageSeverity.WARNING, CompilerMessageSeverity.STRONG_WARNING -> ReportSeverity.WARNING
CompilerMessageSeverity.INFO -> ReportSeverity.INFO
else -> ReportSeverity.DEBUG
}
@@ -57,7 +57,7 @@ internal class CompileServicesFacadeMessageCollector(
}
}
hasErrors = hasErrors || severity == CompilerMessageSeverity.ERROR || severity == CompilerMessageSeverity.EXCEPTION
hasErrors = hasErrors || severity.isError
}
override fun hasErrors(): Boolean = hasErrors

View File

@@ -17,9 +17,7 @@
package org.jetbrains.kotlin.fileClasses;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
public final class OldPackageFacadeClassUtils {
private static final String PACKAGE_CLASS_NAME_SUFFIX = "Package";
@@ -41,14 +39,4 @@ public final class OldPackageFacadeClassUtils {
private static String capitalizeNonEmptyString(@NotNull String s) {
return Character.isUpperCase(s.charAt(0)) ? s : Character.toUpperCase(s.charAt(0)) + s.substring(1);
}
@NotNull
public static FqName getPackageClassFqName(@NotNull FqName packageFQN) {
return packageFQN.child(Name.identifier(getPackageClassName(packageFQN)));
}
@NotNull
public static ClassId getPackageClassId(@NotNull FqName packageFQN) {
return new ClassId(packageFQN, Name.identifier(getPackageClassName(packageFQN)));
}
}

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.load.java.sam;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
@@ -25,18 +24,18 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension;
import org.jetbrains.kotlin.load.java.descriptors.*;
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.JavaResolverUtils;
import org.jetbrains.kotlin.resolve.source.PsiSourceElement;
import org.jetbrains.kotlin.types.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.jetbrains.kotlin.types.Variance.IN_VARIANCE;
@@ -134,6 +133,10 @@ public class SingleAbstractMethodUtils {
return null;
}
if (DescriptorUtilsKt.getFqNameSafe(klass).asString().equals("android.databinding.DataBindingComponent")) {
return null;
}
List<CallableMemberDescriptor> abstractMembers = getAbstractMembers(klass.getDefaultType());
if (abstractMembers.size() == 1) {
CallableMemberDescriptor member = abstractMembers.get(0);

View File

@@ -29,6 +29,7 @@ public class AsmTypes {
public static final Type JAVA_STRING_TYPE = getType(String.class);
public static final Type JAVA_THROWABLE_TYPE = getType(Throwable.class);
public static final Type JAVA_CLASS_TYPE = getType(Class.class);
public static final Type ENUM_TYPE = getType(Enum.class);
public static final Type UNIT_TYPE = Type.getObjectType("kotlin/Unit");

View File

@@ -99,7 +99,7 @@ object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
targetEnvironment,
LookupTracker.DO_NOTHING,
packagePartProvider,
languageSettingsProvider.getLanguageVersionSettings(moduleInfo),
languageSettingsProvider.getLanguageVersionSettings(moduleInfo, project),
useBuiltInsProvider = false, // TODO: load built-ins from module dependencies in IDE
useLazyResolve = true,
compilerConfiguration = compilerConfiguration

View File

@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.resolve.jvm
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.Modality
@@ -29,7 +29,8 @@ import org.jetbrains.kotlin.serialization.deserialization.PLATFORM_DEPENDENT_ANN
object JvmDelegationFilter : DelegationFilter {
override fun filter(interfaceMember: CallableMemberDescriptor, languageVersionSettings: LanguageVersionSettings): Boolean {
if (languageVersionSettings.languageVersion == LanguageVersion.KOTLIN_1_0) return true
if (!languageVersionSettings.supportsFeature(LanguageFeature.NoDelegationToJavaDefaultInterfaceMembers)) return true
//We always have only one implementation otherwise it's an error in kotlin and java
val realMember = DescriptorUtils.unwrapFakeOverride(interfaceMember)
return !isJavaDefaultMethod(realMember) && !isBuiltInMemberMappedToJavaDefault(realMember)

View File

@@ -24,6 +24,7 @@ import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.builtins.JvmBuiltInsPackageFragmentProvider
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.JVMConfigurationKeys
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
@@ -56,7 +57,6 @@ import org.jetbrains.kotlin.platform.JvmBuiltIns
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.LazyTopDownAnalyzer
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
import org.jetbrains.kotlin.resolve.TopDownAnalysisMode
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
@@ -253,6 +253,7 @@ object TopDownAnalyzerFacadeForJVM {
fun createContextWithSealedModule(project: Project, configuration: CompilerConfiguration): MutableModuleContext =
createModuleContext(project, configuration, false).apply {
setDependencies(module, module.builtIns.builtInsModule)
(module.builtIns as JvmBuiltIns).initialize(module, configuration.get(LANGUAGE_VERSION_SETTINGS, LanguageVersionSettingsImpl.DEFAULT))
}
private fun createModuleContext(

View File

@@ -1,67 +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.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
object AdditionalBuiltInsMembersCallChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
if (context.languageVersionSettings.supportsFeature(LanguageFeature.AdditionalBuiltInsMembers)) return
val resultingDescriptor = resolvedCall.resultingDescriptor as? CallableMemberDescriptor ?: return
if (resultingDescriptor.isAdditionalBuiltInMember()) {
context.trace.report(Errors.UNSUPPORTED_FEATURE.on(reportOn, LanguageFeature.AdditionalBuiltInsMembers))
}
}
}
object AdditionalBuiltInsMemberOverrideDeclarationChecker : DeclarationChecker {
override fun check(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext,
languageVersionSettings: LanguageVersionSettings
) {
if (languageVersionSettings.supportsFeature(LanguageFeature.AdditionalBuiltInsMembers)) return
val resultingDescriptor = descriptor as? CallableMemberDescriptor ?: return
val overrideKeyword = declaration.modifierList?.getModifier(KtTokens.OVERRIDE_KEYWORD) ?: return
val overriddenDescriptors = resultingDescriptor.original.overriddenDescriptors
if (overriddenDescriptors.isNotEmpty() && overriddenDescriptors.all { it.isAdditionalBuiltInMember() }) {
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(overrideKeyword, LanguageFeature.AdditionalBuiltInsMembers))
}
}
}
private fun CallableMemberDescriptor.isAdditionalBuiltInMember() =
KotlinBuiltIns.isBuiltIn(this) && this is JavaCallableMemberDescriptor

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.resolve.jvm.platform
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.platform.JvmBuiltIns
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -24,8 +25,8 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager
import java.util.*
object JvmPlatform : TargetPlatform("JVM") {
override val defaultImports: List<ImportPath> = ArrayList<ImportPath>().apply {
addAll(Default.defaultImports)
override fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath> = ArrayList<ImportPath>().apply {
addAll(Default.getDefaultImports(languageVersionSettings))
add(ImportPath("java.lang.*"))
add(ImportPath("kotlin.jvm.*"))

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* 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.
@@ -44,21 +44,18 @@ object JvmPlatformConfigurator : PlatformConfigurator(
TypeParameterBoundIsNotArrayChecker(),
JvmSyntheticApplicabilityChecker(),
StrictfpApplicabilityChecker(),
AdditionalBuiltInsMemberOverrideDeclarationChecker,
HeaderImplDeclarationChecker()
),
additionalCallCheckers = listOf(
JavaAnnotationCallChecker(),
InterfaceDefaultMethodCallChecker(),
JavaClassOnCompanionChecker(),
ProtectedInSuperClassCompanionCallChecker(),
UnsupportedSyntheticCallableReferenceChecker(),
SuperCallWithDefaultArgumentsChecker(),
MissingDependencyClassChecker,
ProtectedSyntheticExtensionCallChecker,
ReifiedTypeParameterSubstitutionChecker(),
AdditionalBuiltInsMembersCallChecker
ReifiedTypeParameterSubstitutionChecker()
),
additionalTypeCheckers = listOf(

View File

@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.SyntheticScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.findCorrespondingSupertype
import java.util.*
import kotlin.properties.Delegates
@@ -58,10 +59,8 @@ class SamAdapterFunctionsScope(
override fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
var result: SmartList<FunctionDescriptor>? = null
for (type in receiverTypes) {
val substitutorForType by lazy { buildMemberScopeSubstitutorForType(type) }
for (function in type.memberScope.getContributedFunctions(name, location)) {
val extension = extensionForFunction(function.original)?.substitute(substitutorForType)
val extension = extensionForFunction(function.original)?.substituteForReceiverType(type)
if (extension != null) {
if (result == null) {
result = SmartList()
@@ -77,15 +76,24 @@ class SamAdapterFunctionsScope(
}
}
private fun buildMemberScopeSubstitutorForType(type: KotlinType) =
TypeConstructorSubstitution.create(type).wrapWithCapturingSubstitution(needApproximation = true).buildSubstitutor()
private fun FunctionDescriptor.substituteForReceiverType(receiverType: KotlinType): FunctionDescriptor? {
val containingClass = containingDeclaration as? ClassDescriptor ?: return null
val correspondingSupertype = findCorrespondingSupertype(receiverType, containingClass.defaultType) ?: return null
return substitute(
TypeConstructorSubstitution
.create(correspondingSupertype)
.wrapWithCapturingSubstitution(needApproximation = true)
.buildSubstitutor()
)
}
override fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> {
return receiverTypes.flatMapTo(LinkedHashSet<FunctionDescriptor>()) { type ->
type.memberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
.filterIsInstance<FunctionDescriptor>()
.mapNotNull {
extensionForFunction(it.original)?.substitute(buildMemberScopeSubstitutorForType(type))
extensionForFunction(it.original)?.substituteForReceiverType(type)
}
}
}
@@ -159,10 +167,13 @@ class SamAdapterFunctionsScope(
}
}
override fun newCopyBuilder(substitutor: TypeSubstitutor): CopyConfiguration =
super.newCopyBuilder(substitutor).setOriginal(this.original)
override fun doSubstitute(configuration: CopyConfiguration): FunctionDescriptor? {
val descriptor = super.doSubstitute(configuration) as MyFunctionDescriptor? ?: return null
val original = configuration.original
?: throw UnsupportedOperationException("doSubstitute with no original should not be called for synthetic extension")
?: throw UnsupportedOperationException("doSubstitute with no original should not be called for synthetic extension $this")
original as MyFunctionDescriptor
assert(original.original == original) { "original in doSubstitute should have no other original" }

View File

@@ -259,12 +259,12 @@ private class DelegatingPackageFragmentProvider(
}
interface LanguageSettingsProvider {
fun getLanguageVersionSettings(moduleInfo: ModuleInfo): LanguageVersionSettings
fun getLanguageVersionSettings(moduleInfo: ModuleInfo, project: Project): LanguageVersionSettings
fun getTargetPlatform(moduleInfo: ModuleInfo): DescriptionAware
object Default : LanguageSettingsProvider {
override fun getLanguageVersionSettings(moduleInfo: ModuleInfo) = LanguageVersionSettingsImpl.DEFAULT
override fun getLanguageVersionSettings(moduleInfo: ModuleInfo, project: Project) = LanguageVersionSettingsImpl.DEFAULT
override fun getTargetPlatform(moduleInfo: ModuleInfo): DescriptionAware = DescriptionAware.NoVersion
}

View File

@@ -25,6 +25,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.cfg.WhenMissingCase;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.config.LanguageVersion;
import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.lexer.KtKeywordToken;
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
@@ -63,11 +64,11 @@ public interface Errors {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
DiagnosticFactory1<PsiElement, String> UNSUPPORTED = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, LanguageFeature> UNSUPPORTED_FEATURE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, Pair<LanguageFeature, LanguageVersionSettings>> UNSUPPORTED_FEATURE = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, Throwable> EXCEPTION_FROM_ANALYZER = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, LanguageFeature> EXPERIMENTAL_FEATURE_WARNING = DiagnosticFactory1.create(WARNING);
DiagnosticFactory1<PsiElement, LanguageFeature> EXPERIMENTAL_FEATURE_ERROR = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, Pair<LanguageFeature, LanguageVersionSettings>> EXPERIMENTAL_FEATURE_WARNING = DiagnosticFactory1.create(WARNING);
DiagnosticFactory1<PsiElement, Pair<LanguageFeature, LanguageVersionSettings>> EXPERIMENTAL_FEATURE_ERROR = DiagnosticFactory1.create(ERROR);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -193,6 +194,7 @@ public interface Errors {
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> WRONG_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(ERROR);
DiagnosticFactory2<PsiElement, KtModifierKeywordToken, String> DEPRECATED_MODIFIER_CONTAINING_DECLARATION = DiagnosticFactory2.create(WARNING);
DiagnosticFactory1<PsiElement, KtModifierKeywordToken> ILLEGAL_INLINE_PARAMETER_MODIFIER = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<KtParameter> INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<KtAnnotationEntry, String> WRONG_ANNOTATION_TARGET = DiagnosticFactory1.create(ERROR);
DiagnosticFactory2<KtAnnotationEntry, String, String> WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET = DiagnosticFactory2.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> REPEATED_ANNOTATION = DiagnosticFactory0.create(ERROR);
@@ -452,7 +454,6 @@ public interface Errors {
DiagnosticFactory0<KtPropertyDelegate> ABSTRACT_DELEGATED_PROPERTY = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtPropertyAccessor> ACCESSOR_FOR_DELEGATED_PROPERTY = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtPropertyDelegate> DELEGATED_PROPERTY_IN_INTERFACE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtPropertyDelegate> LOCAL_VARIABLE_WITH_DELEGATE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtProperty> PROPERTY_WITH_NO_TYPE_NO_INITIALIZER = DiagnosticFactory0.create(ERROR, DECLARATION_SIGNATURE);
@@ -701,7 +702,7 @@ public interface Errors {
DiagnosticFactory2<KtExpression, String, Collection<? extends ResolvedCall<?>>> DELEGATE_PD_METHOD_NONE_APPLICABLE = DiagnosticFactory2.create(WARNING);
DiagnosticFactory1<KtSimpleNameExpression, KotlinType> COMPARE_TO_TYPE_MISMATCH = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, String> YIELD_IS_RESERVED = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> UNDERSCORE_IS_RESERVED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, String> INVALID_CHARACTERS = DiagnosticFactory1.create(ERROR);
@@ -910,7 +911,7 @@ public interface Errors {
DiagnosticFactory0<PsiElement> NON_LOCAL_SUSPENSION_POINT = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> ILLEGAL_SUSPEND_FUNCTION_CALL = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, CallableDescriptor> ILLEGAL_SUSPEND_FUNCTION_CALL = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL = DiagnosticFactory0.create(ERROR);

View File

@@ -159,6 +159,7 @@ public class DefaultErrorMessages {
MAP.put(WRONG_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is not applicable inside ''{1}''", TO_STRING, TO_STRING);
MAP.put(DEPRECATED_MODIFIER_CONTAINING_DECLARATION, "Modifier ''{0}'' is deprecated inside ''{1}''", TO_STRING, TO_STRING);
MAP.put(ILLEGAL_INLINE_PARAMETER_MODIFIER, "Modifier ''{0}'' is allowed only for function parameters of an inline function", TO_STRING);
MAP.put(INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED, "Inline lambda parameters of suspend function type are not fully supported. Add 'noinline' modifier.");
MAP.put(WRONG_ANNOTATION_TARGET, "This annotation is not applicable to target ''{0}''", TO_STRING);
MAP.put(WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET, "This annotation is not applicable to target ''{0}'' and use site target ''@{1}''", TO_STRING, TO_STRING);
MAP.put(REPEATED_ANNOTATION, "This annotation is not repeatable");
@@ -236,7 +237,6 @@ public class DefaultErrorMessages {
MAP.put(ABSTRACT_DELEGATED_PROPERTY, "Delegated property cannot be abstract");
MAP.put(ACCESSOR_FOR_DELEGATED_PROPERTY, "Delegated property cannot have accessors with non-default implementations");
MAP.put(DELEGATED_PROPERTY_IN_INTERFACE, "Delegated properties are not allowed in interfaces");
MAP.put(LOCAL_VARIABLE_WITH_DELEGATE, "Local variables are not allowed to have delegates");
MAP.put(INAPPLICABLE_LATEINIT_MODIFIER, "''lateinit'' modifier {0}", STRING);
@@ -462,6 +462,7 @@ public class DefaultErrorMessages {
MAP.put(COMPARE_TO_TYPE_MISMATCH, "''compareTo()'' must return Int, but returns {0}", RENDER_TYPE);
MAP.put(UNDERSCORE_IS_RESERVED, "Names _, __, ___, ..., are reserved in Kotlin");
MAP.put(YIELD_IS_RESERVED, "{0}", STRING);
MAP.put(INVALID_CHARACTERS, "Name {0}", STRING);
MAP.put(INAPPLICABLE_OPERATOR_MODIFIER, "''operator'' modifier is inapplicable on this function: {0}", STRING);
@@ -596,30 +597,11 @@ public class DefaultErrorMessages {
MAP.put(UNSAFE_IMPLICIT_INVOKE_CALL, "Reference has a nullable type ''{0}'', use explicit ''?.invoke()'' to make a function-like call instead", RENDER_TYPE);
MAP.put(AMBIGUOUS_LABEL, "Ambiguous label");
MAP.put(UNSUPPORTED, "Unsupported [{0}]", STRING);
MAP.put(UNSUPPORTED_FEATURE, "The feature is {0}", new DiagnosticParameterRenderer<LanguageFeature>() {
@NotNull
@Override
public String render(LanguageFeature feature, @NotNull RenderingContext renderingContext) {
LanguageVersion version = feature.getSinceVersion();
return version != null
? "only available since Kotlin " + version.getVersionString() + ": " + feature.getPresentableText()
: "experimental and should be turned on explicitly via a command line option or in IDE settings: " + feature.getPresentableText();
}
});
MAP.put(EXPERIMENTAL_FEATURE_WARNING, "The feature is experimental: {0}", new DiagnosticParameterRenderer<LanguageFeature>() {
@NotNull
@Override
public String render(LanguageFeature feature, @NotNull RenderingContext renderingContext) {
return feature.getPresentableText();
}
});
MAP.put(EXPERIMENTAL_FEATURE_ERROR, "The experimental feature is disabled: {0}", new DiagnosticParameterRenderer<LanguageFeature>() {
@NotNull
@Override
public String render(LanguageFeature feature, @NotNull RenderingContext renderingContext) {
return feature.getPresentableText();
}
});
MAP.put(UNSUPPORTED_FEATURE, "{0}", new LanguageFeatureMessageRenderer(LanguageFeatureMessageRenderer.Type.UNSUPPORTED));
MAP.put(EXPERIMENTAL_FEATURE_WARNING, "{0}", new LanguageFeatureMessageRenderer(LanguageFeatureMessageRenderer.Type.WARNING));
MAP.put(EXPERIMENTAL_FEATURE_ERROR, "{0}", new LanguageFeatureMessageRenderer(LanguageFeatureMessageRenderer.Type.ERROR));
MAP.put(EXCEPTION_FROM_ANALYZER, "Internal Error occurred while analyzing this expression:\n{0}", THROWABLE);
MAP.put(UNNECESSARY_SAFE_CALL, "Unnecessary safe call on a non-null receiver of type {0}", RENDER_TYPE);
MAP.put(UNEXPECTED_SAFE_CALL, "Safe-call is not allowed here");
@@ -904,7 +886,7 @@ public class DefaultErrorMessages {
MAP.put(INLINE_CALL_CYCLE, "The ''{0}'' invocation is a part of inline cycle", NAME);
MAP.put(NON_LOCAL_RETURN_IN_DISABLED_INLINE, "Non-local returns are not allowed with inlining disabled");
MAP.put(NON_LOCAL_SUSPENSION_POINT, "Suspension functions can be called only within coroutine body");
MAP.put(ILLEGAL_SUSPEND_FUNCTION_CALL, "Suspend functions are only allowed to be called from a coroutine or another suspend function");
MAP.put(ILLEGAL_SUSPEND_FUNCTION_CALL, "Suspend function ''{0}'' should be called only from a coroutine or another suspend function", NAME);
MAP.put(ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL, "Restricted suspending functions can only invoke member or extension suspending functions on their restricted coroutine scope");
MAP.setImmutable();

View File

@@ -0,0 +1,69 @@
/*
* 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.diagnostics.rendering
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
class LanguageFeatureMessageRenderer @JvmOverloads constructor(
private val type: Type,
private val useHtml: Boolean = false
): DiagnosticParameterRenderer<Pair<LanguageFeature, LanguageVersionSettings>> {
enum class Type {
UNSUPPORTED,
WARNING,
ERROR
}
override fun render(obj: Pair<LanguageFeature, LanguageVersionSettings>, renderingContext: RenderingContext): String {
val (feature, settings) = obj
val since = feature.sinceVersion
val sb = StringBuilder()
sb.append("The feature \"").append(feature.presentableName).append("\" is ")
when (type) {
Type.UNSUPPORTED ->
when {
since == null ->
sb.append("experimental and should be enabled explicitly")
since > settings.languageVersion ->
sb.append("only available since language version ").append(since.versionString)
feature.sinceApiVersion > settings.apiVersion ->
sb.append("only available since API version ").append(feature.sinceApiVersion.versionString)
else ->
sb.append("disabled")
}
Type.WARNING -> sb.append("experimental")
Type.ERROR -> sb.append("experimental and disabled")
}
val hintUrl = feature.hintUrl
if (hintUrl != null) {
if (useHtml) {
sb.append(" (").append("see more <a href=\"").append(hintUrl).append("\">here</a>)")
}
else {
sb.append(" (see: ").append(hintUrl).append(")")
}
}
return sb.toString()
}
}

View File

@@ -123,5 +123,6 @@ private val MODIFIERS_TO_REPLACE = mapOf(
private val MODIFIERS_ORDER = listOf(PUBLIC_KEYWORD, PROTECTED_KEYWORD, PRIVATE_KEYWORD, INTERNAL_KEYWORD,
FINAL_KEYWORD, OPEN_KEYWORD, ABSTRACT_KEYWORD,
OVERRIDE_KEYWORD,
SUSPEND_KEYWORD,
INNER_KEYWORD,
ENUM_KEYWORD, COMPANION_KEYWORD, INFIX_KEYWORD, OPERATOR_KEYWORD, DATA_KEYWORD)

View File

@@ -461,6 +461,25 @@ fun checkReservedPrefixWord(sink: DiagnosticSink, element: PsiElement, word: Str
}
}
fun checkReservedYield(expression: KtSimpleNameExpression?, sink: DiagnosticSink) {
// do not force identifier calculation for elements from stubs.
if (expression?.getReferencedName() != "yield") return
val identifier = expression.getIdentifier() ?: return
if (identifier.node.elementType == KtTokens.IDENTIFIER && "yield" == identifier.text) {
sink.report(Errors.YIELD_IS_RESERVED.on(identifier, "Identifier 'yield' is reserved. Use backticks to call it: `yield`"))
}
}
val MESSAGE_FOR_YIELD_BEFORE_LAMBDA = "Reserved yield block/lambda. Use 'yield() { ... }' or 'yield(fun...)'"
fun checkReservedYieldBeforeLambda(element: PsiElement, sink: DiagnosticSink) {
KtPsiUtil.getPreviousWord(element, "yield")?.let {
sink.report(Errors.YIELD_IS_RESERVED.on(it, MESSAGE_FOR_YIELD_BEFORE_LAMBDA))
}
}
fun KtElement.nonStaticOuterClasses(): Sequence<KtClass> {
return generateSequence(containingClass()) { if (it.isInner()) it.containingClass() else null }
}

View File

@@ -23,12 +23,12 @@ object KotlinStubVersions {
// Though only kotlin declarations (no code in the bodies) are stubbed, please do increase this version
// if you are not 100% sure it can be avoided.
// Increasing this version will lead to reindexing of all kotlin source files on the first IDE startup with the new version.
const val SOURCE_STUB_VERSION = 120
const val SOURCE_STUB_VERSION = 121
// Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed
// or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder).
// Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files).
private const val BINARY_STUB_VERSION = 57
private const val BINARY_STUB_VERSION = 58
// Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile)
// Increasing this version will lead to reindexing of all classfiles.
@@ -40,5 +40,5 @@ object KotlinStubVersions {
// JS stub version should be increased if changes are made to js stub building subsystem (org.jetbrains.kotlin.idea.decompiler.js)
// Increasing this version will lead to reindexing of js binary files (see KotlinJavaScriptMetaFileType).
const val JS_STUB_VERSION = BINARY_STUB_VERSION + 0
const val JS_STUB_VERSION = BINARY_STUB_VERSION + 1
}

View File

@@ -711,7 +711,7 @@ class DeclarationsChecker(
}
}
else if (property.typeReference == null && !languageVersionSettings.supportsFeature(LanguageFeature.ShortSyntaxForPropertyGetters)) {
trace.report(Errors.UNSUPPORTED_FEATURE.on(property, LanguageFeature.ShortSyntaxForPropertyGetters))
trace.report(Errors.UNSUPPORTED_FEATURE.on(property, LanguageFeature.ShortSyntaxForPropertyGetters to languageVersionSettings))
}
else if (noExplicitTypeOrGetterType(property)) {
trace.report(PROPERTY_WITH_NO_TYPE_NO_INITIALIZER.on(property))

View File

@@ -22,6 +22,7 @@ import com.google.common.collect.Sets;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import kotlin.Pair;
import kotlin.TuplesKt;
import kotlin.collections.CollectionsKt;
import kotlin.collections.SetsKt;
import kotlin.jvm.functions.Function0;
@@ -324,7 +325,8 @@ public class DescriptorResolver {
Function0<List<VariableDescriptor>> destructuringVariables;
if (destructuringDeclaration != null) {
if (!languageVersionSettings.supportsFeature(LanguageFeature.DestructuringLambdaParameters)) {
trace.report(Errors.UNSUPPORTED_FEATURE.on(valueParameter, LanguageFeature.DestructuringLambdaParameters));
trace.report(Errors.UNSUPPORTED_FEATURE.on(valueParameter,
TuplesKt.to(LanguageFeature.DestructuringLambdaParameters, languageVersionSettings)));
}
destructuringVariables = new Function0<List<VariableDescriptor>>() {
@@ -742,7 +744,8 @@ public class DescriptorResolver {
else if (!languageVersionSettings.supportsFeature(LanguageFeature.TypeAliases)) {
typeResolver.resolveAbbreviatedType(scopeWithTypeParameters, typeReference, trace);
PsiElement typeAliasKeyword = typeAlias.getTypeAliasKeyword();
trace.report(UNSUPPORTED_FEATURE.on(typeAliasKeyword != null ? typeAliasKeyword : typeAlias, LanguageFeature.TypeAliases));
trace.report(UNSUPPORTED_FEATURE.on(typeAliasKeyword != null ? typeAliasKeyword : typeAlias,
TuplesKt.to(LanguageFeature.TypeAliases, languageVersionSettings)));
typeAliasDescriptor.initialize(
typeParameterDescriptors,
ErrorUtils.createErrorType(name.asString()),

View File

@@ -77,7 +77,7 @@ class LocalVariableResolver(
val delegateExpression = property.delegateExpression
if (delegateExpression != null) {
if (!languageVersionSettings.supportsFeature(LanguageFeature.LocalDelegatedProperties)) {
context.trace.report(LOCAL_VARIABLE_WITH_DELEGATE.on(property.delegate!!))
context.trace.report(UNSUPPORTED_FEATURE.on(property.delegate!!, LanguageFeature.LocalDelegatedProperties to languageVersionSettings))
}
if (propertyDescriptor is VariableDescriptorWithAccessors) {

View File

@@ -277,6 +277,7 @@ object ModifierCheckerCore {
val errorOnDependencyFeature = errorOnFeature[dependency]?.let { languageVersionSettings.supportsFeature(it) } ?: false
val supportsFeature = languageVersionSettings.supportsFeature(dependency)
val diagnosticData = dependency to languageVersionSettings
if (!supportsFeature || errorOnDependencyFeature) {
val restrictedTargets = featureDependenciesTargets[dependency]
if (restrictedTargets != null && actualTargets.intersect(restrictedTargets).isEmpty()) {
@@ -284,17 +285,17 @@ object ModifierCheckerCore {
}
if (!supportsFeature) {
trace.report(Errors.UNSUPPORTED_FEATURE.on(node.psi, dependency))
trace.report(Errors.UNSUPPORTED_FEATURE.on(node.psi, diagnosticData))
}
else if (errorOnDependencyFeature) {
trace.report(Errors.EXPERIMENTAL_FEATURE_ERROR.on(node.psi, dependency))
trace.report(Errors.EXPERIMENTAL_FEATURE_ERROR.on(node.psi, diagnosticData))
}
return false
}
val pairedWarningFeature = warningOnFeature[dependency]
if (pairedWarningFeature != null && languageVersionSettings.supportsFeature(pairedWarningFeature)) {
trace.report(Errors.EXPERIMENTAL_FEATURE_WARNING.on(node.psi, dependency))
trace.report(Errors.EXPERIMENTAL_FEATURE_WARNING.on(node.psi, diagnosticData))
}
return true

View File

@@ -66,7 +66,7 @@ object OperatorModifierChecker {
private fun checkSupportsFeature(feature: LanguageFeature, languageVersionSettings: LanguageVersionSettings, diagnosticHolder: DiagnosticSink, modifier: PsiElement) {
if (!languageVersionSettings.supportsFeature(feature)) {
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(modifier, feature))
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(modifier, feature to languageVersionSettings))
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* 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.
@@ -16,9 +16,12 @@
package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.composeContainer
import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap
import org.jetbrains.kotlin.resolve.calls.checkers.*
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
@@ -33,20 +36,24 @@ abstract class TargetPlatform(val platformName: String) {
override fun toString() = platformName
abstract val platformConfigurator: PlatformConfigurator
abstract val defaultImports: List<ImportPath>
abstract fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath>
open val excludedImports: List<FqName> get() = emptyList()
abstract val multiTargetPlatform: MultiTargetPlatform
object Default : TargetPlatform("Default") {
override val defaultImports: List<ImportPath> = ArrayList<ImportPath>().apply {
override fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath> = ArrayList<ImportPath>().apply {
add(ImportPath("kotlin.*"))
add(ImportPath("kotlin.annotation.*"))
add(ImportPath("kotlin.collections.*"))
add(ImportPath("kotlin.ranges.*"))
add(ImportPath("kotlin.sequences.*"))
add(ImportPath("kotlin.text.*"))
add(ImportPath("kotlin.comparisons.*"))
add(ImportPath("kotlin.io.*"))
if (languageVersionSettings.supportsFeature(LanguageFeature.DefaultImportOfPackageKotlinComparisons)) {
add(ImportPath("kotlin.comparisons.*"))
}
}
override val platformConfigurator =
@@ -77,14 +84,16 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
ReifiedTypeParameterAnnotationChecker(),
DynamicReceiverChecker,
DelegationChecker(),
KClassWithIncorrectTypeArgumentChecker
KClassWithIncorrectTypeArgumentChecker,
SuspendOperatorsCheckers
)
private val DEFAULT_CALL_CHECKERS = listOf(
CapturingInClosureChecker(), InlineCheckerWrapper(), SafeCallChecker(),
DeprecatedCallChecker, CallReturnsArrayOfNothingChecker(), InfixCallChecker(), OperatorCallChecker(),
ConstructorHeaderCallChecker, ProtectedConstructorCallChecker, ApiVersionCallChecker,
CoroutineSuspendCallChecker, BuilderFunctionsCallChecker, DslScopeViolationCallChecker
CoroutineSuspendCallChecker, BuilderFunctionsCallChecker, DslScopeViolationCallChecker,
CallableReferenceCompatibilityChecker()
)
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(DeprecatedClassifierUsageChecker(), ApiVersionClassifierUsageChecker)

View File

@@ -116,12 +116,9 @@ private class AbbreviatedTypeBinding(
override val isInAbbreviation: Boolean get() = true
override val arguments: List<TypeArgumentBinding<KtTypeElement>?>
get() = type.arguments.mapIndexed { index, argument ->
TypeArgumentBindingImpl(
argument,
type.constructor.parameters[index],
AbbreviatedTypeBinding(argument.type, psiElement)
)
get() = createTypeArgumentBindingsWithSinglePsiElement(type) {
argumentType ->
AbbreviatedTypeBinding(argumentType, psiElement)
}
}
@@ -133,16 +130,22 @@ private class NoTypeElementBinding<out P : PsiElement>(
override val isInAbbreviation: Boolean get() = false
override val arguments: List<TypeArgumentBinding<P>?>
get() {
val isErrorBinding = type.isError || type.constructor.parameters.size != type.arguments.size
return type.arguments.indices.map {
val typeProjection = type.arguments[it]
TypeArgumentBindingImpl(
typeProjection,
if (isErrorBinding) null else type.constructor.parameters[it],
NoTypeElementBinding(trace, psiElement, typeProjection.type)
)
}
get() = createTypeArgumentBindingsWithSinglePsiElement(type) {
argumentType ->
NoTypeElementBinding(trace, psiElement, argumentType)
}
}
internal fun <P : PsiElement> createTypeArgumentBindingsWithSinglePsiElement(
type: KotlinType,
createBinding: (KotlinType) -> TypeBinding<P>
) : List<TypeArgumentBinding<P>> {
val isErrorBinding = type.isError || type.constructor.parameters.size != type.arguments.size
return type.arguments.mapIndexed { index, typeProjection ->
TypeArgumentBindingImpl(
typeProjection,
if (isErrorBinding) null else type.constructor.parameters[index],
createBinding(typeProjection.type)
)
}
}

View File

@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.codeFragmentUtil.debugTypeInfo
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
import org.jetbrains.kotlin.psi.debugText.getDebugText
import org.jetbrains.kotlin.psi.psiUtil.checkReservedYield
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.resolve.PossiblyBareType.bare
import org.jetbrains.kotlin.resolve.PossiblyBareType.type
@@ -227,6 +228,8 @@ class TypeResolver(
}
val referenceExpression = type.referenceExpression ?: return
checkReservedYield(referenceExpression, c.trace)
c.trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, classifier)
result = resolveTypeForClassifier(c, classifier, qualifierResolutionResult, type, annotations)
@@ -509,7 +512,7 @@ class TypeResolver(
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor)
}
if (!languageVersionSettings.supportsFeature(LanguageFeature.TypeAliases)) {
c.trace.report(UNSUPPORTED_FEATURE.on(type, LanguageFeature.TypeAliases))
c.trace.report(UNSUPPORTED_FEATURE.on(type, LanguageFeature.TypeAliases to languageVersionSettings))
return createErrorTypeForTypeConstructor(c, projectionFromAllQualifierParts, typeConstructor)
}

View File

@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
import org.jetbrains.kotlin.resolve.OverrideResolver;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.*;
@@ -185,7 +186,9 @@ public class ValueArgumentsToParametersMapper {
ValueArgumentName argumentName = argument.getArgumentName();
assert argumentName != null;
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(argumentName.getAsName());
KtReferenceExpression nameReference = argumentName.getReferenceExpression();
KtSimpleNameExpression nameReference = argumentName.getReferenceExpression();
KtPsiUtilKt.checkReservedYield(nameReference, candidateCall.getTrace());
if (!candidate.hasStableParameterNames() && nameReference != null) {
report(NAMED_ARGUMENTS_NOT_ALLOWED.on(
nameReference,

View File

@@ -0,0 +1,44 @@
/*
* 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.resolve.calls.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.callUtil.isCallableReference
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
class CallableReferenceCompatibilityChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
val typeInferenceForCallableReferencesFeature = LanguageFeature.TypeInferenceOnGenericsForCallableReferences
if (context.languageVersionSettings.supportsFeature(typeInferenceForCallableReferencesFeature)) return
for ((_, resolvedArgument) in resolvedCall.valueArguments) {
inner@ for (argument in resolvedArgument.arguments) {
val argumentExpression = argument.getArgumentExpression() as? KtCallableReferenceExpression ?: continue@inner
val callableReferenceResolvedCall = argumentExpression.callableReference.getResolvedCall(context.trace.bindingContext) ?: continue@inner
if (callableReferenceResolvedCall.call.isCallableReference() &&
callableReferenceResolvedCall.candidateDescriptor.typeParameters.isNotEmpty()) {
context.trace.report(Errors.UNSUPPORTED_FEATURE.on(argumentExpression,
typeInferenceForCallableReferencesFeature to context.languageVersionSettings))
}
}
}
}
}

View File

@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.hasRestrictsSuspensionAnnotation
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
@@ -59,18 +60,24 @@ object CoroutineSuspendCallChecker : CallChecker {
if (!InlineUtil.checkNonLocalReturnUsage(enclosingSuspendFunction, callElement, context.resolutionContext)) {
context.trace.report(Errors.NON_LOCAL_SUSPENSION_POINT.on(reportOn))
}
else if (context.scope.parentsWithSelf.any { it.isScopeForDefaultParameterValuesOf(enclosingSuspendFunction) }) {
context.trace.report(Errors.UNSUPPORTED.on(reportOn, "suspend function calls in a context of default parameter value"))
}
context.trace.record(BindingContext.ENCLOSING_SUSPEND_FUNCTION_FOR_SUSPEND_FUNCTION_CALL, resolvedCall.call, enclosingSuspendFunction)
checkRestrictsSuspension(enclosingSuspendFunction, resolvedCall, reportOn, context)
}
else -> {
context.trace.report(Errors.ILLEGAL_SUSPEND_FUNCTION_CALL.on(reportOn))
context.trace.report(Errors.ILLEGAL_SUSPEND_FUNCTION_CALL.on(reportOn, resolvedCall.candidateDescriptor))
}
}
}
}
private fun HierarchicalScope.isScopeForDefaultParameterValuesOf(enclosingSuspendFunction: FunctionDescriptor) =
this is LexicalScope && this.kind == LexicalScopeKind.DEFAULT_VALUE && this.ownerDescriptor == enclosingSuspendFunction
object BuilderFunctionsCallChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
val descriptor = resolvedCall.candidateDescriptor as? FunctionDescriptor ?: return
@@ -81,14 +88,15 @@ object BuilderFunctionsCallChecker : CallChecker {
}
fun checkCoroutinesFeature(languageVersionSettings: LanguageVersionSettings, diagnosticHolder: DiagnosticSink, reportOn: PsiElement) {
val diagnosticData = LanguageFeature.Coroutines to languageVersionSettings
if (!languageVersionSettings.supportsFeature(LanguageFeature.Coroutines)) {
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(reportOn, LanguageFeature.Coroutines))
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(reportOn, diagnosticData))
}
else if (languageVersionSettings.supportsFeature(LanguageFeature.ErrorOnCoroutines)) {
diagnosticHolder.report(Errors.EXPERIMENTAL_FEATURE_ERROR.on(reportOn, LanguageFeature.Coroutines))
diagnosticHolder.report(Errors.EXPERIMENTAL_FEATURE_ERROR.on(reportOn, diagnosticData))
}
else if (languageVersionSettings.supportsFeature(LanguageFeature.WarnOnCoroutines)) {
diagnosticHolder.report(Errors.EXPERIMENTAL_FEATURE_WARNING.on(reportOn, LanguageFeature.Coroutines))
diagnosticHolder.report(Errors.EXPERIMENTAL_FEATURE_WARNING.on(reportOn, diagnosticData))
}
}

View File

@@ -16,7 +16,9 @@
package org.jetbrains.kotlin.resolve.checkers
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
@@ -35,10 +37,15 @@ object InlineParameterChecker : SimpleDeclarationChecker {
val inline = declaration.hasModifier(KtTokens.INLINE_KEYWORD)
for (parameter in declaration.valueParameters) {
val parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, parameter)
if (!inline || (parameterDescriptor != null && !parameterDescriptor.type.isFunctionType)) {
if (!inline || (parameterDescriptor != null && !parameterDescriptor.type.isBuiltinFunctionalType)) {
parameter.reportIncorrectInline(KtTokens.NOINLINE_KEYWORD, diagnosticHolder)
parameter.reportIncorrectInline(KtTokens.CROSSINLINE_KEYWORD, diagnosticHolder)
}
if (inline && !parameter.hasModifier(KtTokens.NOINLINE_KEYWORD) &&
parameterDescriptor?.type?.isSuspendFunctionType == true) {
diagnosticHolder.report(Errors.INLINE_SUSPEND_FUNCTION_TYPE_UNSUPPORTED.on(parameter))
}
}
}
}

View File

@@ -0,0 +1,47 @@
/*
* 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.resolve.checkers
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.util.OperatorNameConventions
object SuspendOperatorsCheckers : SimpleDeclarationChecker {
private val UNSUPPORTED_OPERATOR_NAMES = setOf(
OperatorNameConventions.CONTAINS,
OperatorNameConventions.GET, OperatorNameConventions.SET
)
override fun check(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
diagnosticHolder: DiagnosticSink,
bindingContext: BindingContext
) {
if (descriptor is FunctionDescriptor && descriptor.isSuspend && descriptor.isOperator &&
descriptor.name in UNSUPPORTED_OPERATOR_NAMES) {
declaration.modifierList?.getModifier(KtTokens.OPERATOR_KEYWORD)?.let {
diagnosticHolder.report(Errors.UNSUPPORTED.on(it, "suspend operator \"${descriptor.name}\""))
}
}
}
}

View File

@@ -42,7 +42,7 @@ object UnderscoreChecker : DeclarationChecker {
diagnosticHolder.report(Errors.UNDERSCORE_IS_RESERVED.on(identifier))
}
else if (isValidSingleUnderscore && !languageVersionSettings.supportsFeature(LanguageFeature.SingleUnderscoreForParameterName)) {
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(identifier, LanguageFeature.SingleUnderscoreForParameterName))
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(identifier, LanguageFeature.SingleUnderscoreForParameterName to languageVersionSettings))
}
}

View File

@@ -140,7 +140,7 @@ class ConstantExpressionEvaluator(
val lhsExpression = argumentExpression.receiverExpression
if (lhsExpression != null) {
val doubleColonLhs = trace.bindingContext.get(BindingContext.DOUBLE_COLON_LHS, lhsExpression)
if (doubleColonLhs is DoubleColonLHS.Expression && !doubleColonLhs.isObject) {
if (doubleColonLhs is DoubleColonLHS.Expression && !doubleColonLhs.isObjectQualifier) {
trace.report(Errors.ANNOTATION_PARAMETER_MUST_BE_KCLASS_LITERAL.on(argumentExpression))
}
}

View File

@@ -28,7 +28,6 @@ internal val unaryOperations: HashMap<UnaryOperationKey<*>, Pair<Function1<Any?,
= hashMapOf<UnaryOperationKey<*>, Pair<Function1<Any?, Any>, Function1<Long, Long>>>(
unaryOperation(BOOLEAN, "not", { a -> a.not() }, emptyUnaryFun),
unaryOperation(BOOLEAN, "toString", { a -> a.toString() }, emptyUnaryFun),
unaryOperation(BYTE, "inv", { a -> a.inv() }, emptyUnaryFun),
unaryOperation(BYTE, "toByte", { a -> a.toByte() }, emptyUnaryFun),
unaryOperation(BYTE, "toChar", { a -> a.toChar() }, emptyUnaryFun),
unaryOperation(BYTE, "toDouble", { a -> a.toDouble() }, emptyUnaryFun),
@@ -89,7 +88,6 @@ internal val unaryOperations: HashMap<UnaryOperationKey<*>, Pair<Function1<Any?,
unaryOperation(LONG, "toString", { a -> a.toString() }, emptyUnaryFun),
unaryOperation(LONG, "unaryMinus", { a -> a.unaryMinus() }, { a -> a.unaryMinus() }),
unaryOperation(LONG, "unaryPlus", { a -> a.unaryPlus() }, emptyUnaryFun),
unaryOperation(SHORT, "inv", { a -> a.inv() }, emptyUnaryFun),
unaryOperation(SHORT, "toByte", { a -> a.toByte() }, emptyUnaryFun),
unaryOperation(SHORT, "toChar", { a -> a.toChar() }, emptyUnaryFun),
unaryOperation(SHORT, "toDouble", { a -> a.toDouble() }, emptyUnaryFun),
@@ -111,7 +109,6 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(BOOLEAN, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(BOOLEAN, BOOLEAN, "or", { a, b -> a.or(b) }, emptyBinaryFun),
binaryOperation(BOOLEAN, BOOLEAN, "xor", { a, b -> a.xor(b) }, emptyBinaryFun),
binaryOperation(BYTE, BYTE, "and", { a, b -> a.and(b) }, { a, b -> a.and(b) }),
binaryOperation(BYTE, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(BYTE, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(BYTE, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
@@ -137,7 +134,6 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(BYTE, INT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, LONG, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, SHORT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(BYTE, BYTE, "or", { a, b -> a.or(b) }, { a, b -> a.or(b) }),
binaryOperation(BYTE, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(BYTE, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(BYTE, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
@@ -156,7 +152,6 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(BYTE, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(BYTE, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(BYTE, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(BYTE, BYTE, "xor", { a, b -> a.xor(b) }, { a, b -> a.xor(b) }),
binaryOperation(CHAR, CHAR, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(CHAR, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(CHAR, CHAR, "minus", { a, b -> a.minus(b) }, emptyBinaryFun),
@@ -346,7 +341,6 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(LONG, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(LONG, INT, "ushr", { a, b -> a.ushr(b) }, emptyBinaryFun),
binaryOperation(LONG, LONG, "xor", { a, b -> a.xor(b) }, { a, b -> a.xor(b) }),
binaryOperation(SHORT, SHORT, "and", { a, b -> a.and(b) }, { a, b -> a.and(b) }),
binaryOperation(SHORT, BYTE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(SHORT, DOUBLE, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(SHORT, FLOAT, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
@@ -372,7 +366,6 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(SHORT, INT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, LONG, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, SHORT, "mod", { a, b -> a.mod(b) }, { a, b -> a.mod(b) }),
binaryOperation(SHORT, SHORT, "or", { a, b -> a.or(b) }, { a, b -> a.or(b) }),
binaryOperation(SHORT, BYTE, "plus", { a, b -> a.plus(b) }, { a, b -> a.add(b) }),
binaryOperation(SHORT, DOUBLE, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
binaryOperation(SHORT, FLOAT, "plus", { a, b -> a.plus(b) }, emptyBinaryFun),
@@ -391,7 +384,6 @@ internal val binaryOperations: HashMap<BinaryOperationKey<*, *>, Pair<Function2<
binaryOperation(SHORT, INT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(SHORT, LONG, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(SHORT, SHORT, "times", { a, b -> a.times(b) }, { a, b -> a.multiply(b) }),
binaryOperation(SHORT, SHORT, "xor", { a, b -> a.xor(b) }, { a, b -> a.xor(b) }),
binaryOperation(STRING, STRING, "compareTo", { a, b -> a.compareTo(b) }, emptyBinaryFun),
binaryOperation(STRING, ANY, "equals", { a, b -> a.equals(b) }, emptyBinaryFun),
binaryOperation(STRING, INT, "get", { a, b -> a.get(b) }, emptyBinaryFun),

View File

@@ -39,7 +39,7 @@ class DefaultImportProvider(
private val languageVersionSettings: LanguageVersionSettings
) {
val defaultImports: List<ImportPath>
get() = targetPlatform.defaultImports
by storageManager.createLazyValue { targetPlatform.getDefaultImports(languageVersionSettings) }
val excludedImports: List<FqName> by storageManager.createLazyValue {
val packagesWithAliases = listOf(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME, KotlinBuiltIns.TEXT_PACKAGE_FQ_NAME)
@@ -63,6 +63,6 @@ class DefaultImportProvider(
.mapNotNull { it.expandedType.constructor.declarationDescriptor?.fqNameSafe }
.filter { nonKotlinDefaultImportedPackages.any(it::isChildOf) }
nonKotlinAliasedTypeFqNames
nonKotlinAliasedTypeFqNames + targetPlatform.excludedImports
}
}

View File

@@ -43,7 +43,9 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri
?: if (cacheOfNulls.contains(path)) null
else scriptDefinitionProvider.findScriptDefinition(file)?.getDependenciesFor(file, project, null)
.apply {
log.info("[kts] new cached deps for $path: ${this?.classpath?.joinToString(File.pathSeparator)}")
if (this != null) {
log.info("[kts] new cached deps for $path: ${this.classpath.joinToString(File.pathSeparator)}")
}
cacheLock.write {
if (this == null) {
cacheOfNulls.add(path)

View File

@@ -55,4 +55,10 @@ internal fun constructAnnotation(psi: KtAnnotationEntry, targetClass: KClass<out
}
}
class InvalidScriptResolverAnnotation(val name: String, val annParams: List<Pair<String?, Any?>>?, val error: Exception? = null) : Annotation
// NOTE: this class is used for error reporting. But in order to pass plugin verification, it should derive directly from java's Annotation
// and implement annotationType method (see #KT-16621 for details).
// TODO: instead of the workaround described above, consider using a sum-type for returning errors from constructAnnotation
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
class InvalidScriptResolverAnnotation(val name: String, val annParams: List<Pair<String?, Any?>>?, val error: Exception? = null) : Annotation, java.lang.annotation.Annotation {
override fun annotationType(): Class<out Annotation> = InvalidScriptResolverAnnotation::class.java
}

View File

@@ -89,11 +89,11 @@ public class CommonSupertypes {
for (KotlinType type : types) {
UnwrappedType unwrappedType = type.unwrap();
if (unwrappedType instanceof FlexibleType) {
if (DynamicTypesKt.isDynamic(type)) {
return type;
if (DynamicTypesKt.isDynamic(unwrappedType)) {
return unwrappedType;
}
hasFlexible = true;
FlexibleType flexibleType = (FlexibleType) type;
FlexibleType flexibleType = (FlexibleType) unwrappedType;
upper.add(flexibleType.getUpperBound());
lower.add(flexibleType.getLowerBound());
}

View File

@@ -22,6 +22,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.util.PsiTreeUtil;
import kotlin.TuplesKt;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
@@ -37,6 +38,7 @@ import org.jetbrains.kotlin.lexer.KtKeywordToken;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
@@ -162,6 +164,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
@Override
public KotlinTypeInfo visitSimpleNameExpression(@NotNull KtSimpleNameExpression expression, ExpressionTypingContext context) {
KtPsiUtilKt.checkReservedYield(expression, context.trace);
// TODO : other members
// TODO : type substitutions???
CallExpressionResolver callExpressionResolver = components.callExpressionResolver;
@@ -235,7 +239,8 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
if (!text.contains("_")) return;
if (!components.languageVersionSettings.supportsFeature(LanguageFeature.UnderscoresInNumericLiterals)) {
context.trace.report(Errors.UNSUPPORTED_FEATURE.on(expression, LanguageFeature.UnderscoresInNumericLiterals));
context.trace.report(Errors.UNSUPPORTED_FEATURE.on(expression,
TuplesKt.to(LanguageFeature.UnderscoresInNumericLiterals, components.languageVersionSettings)));
return;
}
@@ -942,6 +947,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
boolean isStatement
) {
KtSimpleNameExpression labelExpression = expression.getTargetLabel();
KtPsiUtilKt.checkReservedYield(labelExpression, context.trace);
if (labelExpression != null) {
PsiElement labelIdentifier = labelExpression.getIdentifier();
UnderscoreChecker.INSTANCE.checkIdentifier(labelIdentifier, context.trace, components.languageVersionSettings);

View File

@@ -29,15 +29,18 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
import org.jetbrains.kotlin.psi.psiUtil.checkReservedYield
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElementSelector
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.calls.CallResolver
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.ResolveArgumentsMode
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.context.*
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResultsUtil
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.calls.util.CallMaker
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
import org.jetbrains.kotlin.resolve.calls.util.createValueParametersForInvokeInFunctionType
@@ -52,14 +55,25 @@ import org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE
import org.jetbrains.kotlin.types.expressions.typeInfoFactory.createTypeInfo
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.lang.UnsupportedOperationException
import java.util.*
import javax.inject.Inject
sealed class DoubleColonLHS(val type: KotlinType) {
class Expression(typeInfo: KotlinTypeInfo, val isObject: Boolean) : DoubleColonLHS(typeInfo.type!!) {
/**
* [isObjectQualifier] is true iff the LHS of a callable reference is a qualified expression which references a named object.
* Note that such LHS can be treated both as a type and as an expression, so special handling may be required.
*
* For example, if `Obj` is an object:
*
* Obj::class // object qualifier
* test.Obj::class // object qualifier
* (Obj)::class // not an object qualifier (can only be treated as an expression, not as a type)
* { Obj }()::class // not an object qualifier
*/
class Expression(typeInfo: KotlinTypeInfo, val isObjectQualifier: Boolean) : DoubleColonLHS(typeInfo.type!!) {
val dataFlowInfo: DataFlowInfo = typeInfo.dataFlowInfo
}
@@ -94,12 +108,20 @@ class DoubleColonExpressionResolver(
}
else {
val result = resolveDoubleColonLHS(expression, c)
val type = result?.type
if (type != null && !type.isError) {
checkClassLiteral(c, expression, result)
val variance = if (result is DoubleColonLHS.Expression && !result.isObject) Variance.OUT_VARIANCE else Variance.INVARIANT
val kClassType = reflectionTypes.getKClassType(Annotations.EMPTY, type, variance)
if (result != null && !result.type.isError) {
val inherentType = result.type
val dataFlowInfo = (result as? DoubleColonLHS.Expression)?.dataFlowInfo ?: c.dataFlowInfo
val dataFlowValue = DataFlowValueFactory.createDataFlowValue(expression.receiverExpression!!, inherentType, c)
val type =
if (!dataFlowInfo.getStableNullability(dataFlowValue).canBeNull()) inherentType.makeNotNullable()
else inherentType
checkClassLiteral(c, expression, type, result)
val variance =
if (result is DoubleColonLHS.Expression && !result.isObjectQualifier) Variance.OUT_VARIANCE else Variance.INVARIANT
val kClassType = reflectionTypes.getKClassType(Annotations.EMPTY, type, variance)
if (kClassType.isError) {
c.trace.report(MISSING_DEPENDENCY_CLASS.on(expression.receiverExpression!!, KotlinBuiltIns.FQ_NAMES.kClass.toSafe()))
}
return dataFlowAnalyzer.checkType(createTypeInfo(kClassType, dataFlowInfo), expression, c)
}
}
@@ -107,11 +129,14 @@ class DoubleColonExpressionResolver(
return createTypeInfo(ErrorUtils.createErrorType("Unresolved class"), c)
}
private fun checkClassLiteral(c: ExpressionTypingContext, expression: KtClassLiteralExpression, result: DoubleColonLHS) {
val type = result.type
private fun checkClassLiteral(
c: ExpressionTypingContext,
expression: KtClassLiteralExpression,
type: KotlinType,
result: DoubleColonLHS
) {
if (result is DoubleColonLHS.Expression) {
if (!result.isObject) {
if (!result.isObjectQualifier) {
if (!type.isSubtypeOf(type.builtIns.anyType)) {
c.trace.report(EXPRESSION_OF_NULLABLE_TYPE_IN_CLASS_LITERAL_LHS.on(expression.receiverExpression!!, type))
}
@@ -181,7 +206,7 @@ class DoubleColonExpressionResolver(
private fun reportUnsupportedIfNeeded(expression: KtDoubleColonExpression, c: ExpressionTypingContext) {
if (!languageVersionSettings.supportsFeature(LanguageFeature.BoundCallableReferences)) {
c.trace.report(UNSUPPORTED_FEATURE.on(expression.receiverExpression!!, LanguageFeature.BoundCallableReferences))
c.trace.report(UNSUPPORTED_FEATURE.on(expression.receiverExpression!!, LanguageFeature.BoundCallableReferences to languageVersionSettings))
}
}
@@ -312,7 +337,7 @@ class DoubleColonExpressionResolver(
val lhs = resultForExpr.lhs
// If expression result is an object, we remember this and skip it here, because there are valid situations where
// another type (representing another classifier) should win
if (lhs != null && !lhs.isObject) {
if (lhs != null && !lhs.isObjectQualifier) {
return resultForExpr.commit()
}
}
@@ -400,7 +425,7 @@ class DoubleColonExpressionResolver(
if (classDescriptor.companionObjectDescriptor != null) return null
if (DescriptorUtils.isObject(classDescriptor)) {
return DoubleColonLHS.Expression(typeInfo, isObject = true)
return DoubleColonLHS.Expression(typeInfo, isObjectQualifier = true)
}
}
@@ -408,7 +433,7 @@ class DoubleColonExpressionResolver(
if (expression.canBeConsideredProperType() && resultingDescriptor !is VariableDescriptor) return null
}
return DoubleColonLHS.Expression(typeInfo, isObject = false)
return DoubleColonLHS.Expression(typeInfo, isObjectQualifier = false)
}
private fun resolveTypeOnLHS(
@@ -509,6 +534,9 @@ class DoubleColonExpressionResolver(
checkReferenceIsToAllowedMember(descriptor, context.trace, expression)
val type = createKCallableTypeForReference(descriptor, lhs, reflectionTypes, context.scope.ownerDescriptor) ?: return null
if (type.isError) {
context.trace.report(MISSING_DEPENDENCY_CLASS.on(expression, KotlinBuiltIns.FQ_NAMES.kCallable.toSafe()))
}
when (descriptor) {
is FunctionDescriptor -> bindFunctionReference(expression, type, context)
@@ -551,10 +579,13 @@ class DoubleColonExpressionResolver(
/* isCoroutine = */ false
)
val parameterTypes = if (type.isError) emptyList() else type.arguments.dropLast(1)
val returnType = if (type.isError) null else type.arguments.last().type
functionDescriptor.initialize(
null, null, emptyList(),
createValueParametersForInvokeInFunctionType(functionDescriptor, type.arguments.dropLast(1)),
type.arguments.last().type,
createValueParametersForInvokeInFunctionType(functionDescriptor, parameterTypes),
returnType,
Modality.FINAL,
Visibilities.PUBLIC
)
@@ -580,27 +611,30 @@ class DoubleColonExpressionResolver(
if (expression.isEmptyLHS) null
else resolveDoubleColonLHS(expression, context)
if (lhsResult is DoubleColonLHS.Expression) {
reportUnsupportedIfNeeded(expression, context)
}
val resolutionResults = resolveCallableReferenceRHS(expression, lhsResult, context, resolveArgumentsMode)
val resolutionResults =
resolveCallableReferenceRHS(expression, lhsResult, context, resolveArgumentsMode)
reportUnsupportedReferenceToSuspendFunction(resolutionResults, expression, context)
reportUnsupportedCallableReferenceIfNeeded(expression, context, lhsResult, resolutionResults)
return lhsResult to resolutionResults
}
private fun reportUnsupportedReferenceToSuspendFunction(
resolutionResults: OverloadResolutionResults<CallableDescriptor>?,
private fun reportUnsupportedCallableReferenceIfNeeded(
expression: KtCallableReferenceExpression,
context: ExpressionTypingContext
context: ExpressionTypingContext,
lhsResult: DoubleColonLHS?,
resolutionResults: OverloadResolutionResults<CallableDescriptor>?
) {
if (resolutionResults?.isSingleResult == true &&
resolutionResults.resultingDescriptor.safeAs<FunctionDescriptor>()?.isSuspend == true) {
val descriptor =
if (resolutionResults?.isSingleResult == true) resolutionResults.resultingDescriptor as? FunctionDescriptor else null
if (descriptor?.isSuspend == true) {
context.trace.report(UNSUPPORTED.on(expression.callableReference, "Callable references to suspend functions"))
}
val expressionResult = lhsResult as? DoubleColonLHS.Expression ?: return
// "<expr>::foo" was not supported without bound callable references, except the case of a nested class constructor in an object
if (!expressionResult.isObjectQualifier || descriptor !is ConstructorDescriptor) {
reportUnsupportedIfNeeded(expression, context)
}
}
private fun tryResolveRHSWithReceiver(
@@ -610,6 +644,8 @@ class DoubleColonExpressionResolver(
outerContext: ResolutionContext<*>,
resolutionMode: ResolveArgumentsMode
): OverloadResolutionResults<CallableDescriptor>? {
checkReservedYield(reference, outerContext.trace)
// we should preserve information about `call` because callable references are analyzed two times,
// otherwise there will be not completed calls in trace
val call = outerContext.trace[BindingContext.CALL, reference] ?: CallMaker.makeCall(reference, receiver, null, reference, emptyList())
@@ -673,6 +709,18 @@ class DoubleColonExpressionResolver(
"resolve bound callable reference", expressionReceiver, reference, c, mode
)
if (result != null) return result
if (lhs.isObjectQualifier) {
val classifier = lhsType.constructor.declarationDescriptor
val calleeExpression = expression.receiverExpression?.getCalleeExpressionIfAny()
if (calleeExpression is KtSimpleNameExpression && classifier is ClassDescriptor) {
val qualifier = ClassQualifier(calleeExpression, classifier)
val possibleStatic = tryResolveRHSWithReceiver(
"resolve object callable reference in static scope", qualifier, reference, c, mode
)
if (possibleStatic != null) return possibleStatic
}
}
}
}

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.types.expressions
import com.google.common.collect.Lists
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
@@ -27,6 +28,8 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.diagnostics.Errors.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.checkReservedPrefixWord
import org.jetbrains.kotlin.psi.psiUtil.checkReservedYieldBeforeLambda
import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.EXPECTED_RETURN_TYPE
@@ -137,6 +140,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
}
override fun visitLambdaExpression(expression: KtLambdaExpression, context: ExpressionTypingContext): KotlinTypeInfo? {
checkReservedYieldBeforeLambda(expression, context.trace)
if (!expression.functionLiteral.hasBody()) return null
val expectedType = context.expectedType
@@ -160,6 +164,10 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
return components.dataFlowAnalyzer.createCheckedTypeInfo(resultType, context, expression)
}
private fun checkReservedYield(context: ExpressionTypingContext, expression: PsiElement) {
checkReservedPrefixWord(context.trace, expression, "yield", "yield block/lambda. Use 'yield() { ... }' or 'yield(fun...)'")
}
private fun createFunctionLiteralDescriptor(
expression: KtLambdaExpression,
context: ExpressionTypingContext

View File

@@ -23,6 +23,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
@@ -138,6 +139,8 @@ public class LabelResolver {
@NotNull ResolutionContext context
) {
KtSimpleNameExpression labelElement = expression.getTargetLabel();
KtPsiUtilKt.checkReservedYield(labelElement, context.trace);
Name labelName = expression.getLabelNameAsName();
if (labelElement == null || labelName == null) return null;

View File

@@ -839,7 +839,7 @@ class ExpressionCodegen(
wrapIntoKClass: Boolean,
data: BlockInfo
) {
if (receiverExpression !is IrClassReference /* && DescriptorUtils.isObject(receiverExpression.descriptor)*/) {
if (receiverExpression !is IrClassReference /* && DescriptorUtils.isObjectQualifier(receiverExpression.descriptor)*/) {
JavaClassProperty.generateImpl(mv, gen(receiverExpression, data))
}
else {

View File

@@ -35,9 +35,9 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
val lhs = getOrFail(BindingContext.DOUBLE_COLON_LHS, ktArgument)
val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral)
return if (lhs is DoubleColonLHS.Expression && !lhs.isObject) {
return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) {
IrGetClassImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
statementGenerator.generateExpression(ktArgument))
statementGenerator.generateExpression(ktArgument))
}
else {
val typeConstructorDeclaration = lhs.type.constructor.declarationDescriptor

View File

@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.builtins.getFunctionalClassKind
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionType
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotated
@@ -451,6 +452,12 @@ class DescriptorSerializer private constructor(
return lowerBound
}
if (type.isSuspendFunctionType) {
val functionType = type(transformSuspendFunctionToRuntimeFunctionType(type))
functionType.flags = Flags.getTypeFlags(true)
return functionType
}
val descriptor = type.constructor.declarationDescriptor
when (descriptor) {
is ClassDescriptor, is TypeAliasDescriptor -> {
@@ -489,25 +496,12 @@ class DescriptorSerializer private constructor(
}
private fun fillFromPossiblyInnerType(builder: ProtoBuf.Type.Builder, type: PossiblyInnerType) {
val classifierDescriptor: ClassifierDescriptorWithTypeParameters
val isSuspendType: Boolean
val originalClassifierDescriptor = type.classifierDescriptor
if (originalClassifierDescriptor.getFunctionalClassKind() == FunctionClassDescriptor.Kind.SuspendFunction) {
classifierDescriptor = originalClassifierDescriptor.builtIns.getFunction(originalClassifierDescriptor.declaredTypeParameters.size)
isSuspendType = true
}
else {
classifierDescriptor = originalClassifierDescriptor
isSuspendType = false
}
val classifierDescriptor = type.classifierDescriptor
val classifierId = getClassifierId(classifierDescriptor)
when (classifierDescriptor) {
is ClassDescriptor -> builder.className = classifierId
is TypeAliasDescriptor -> builder.typeAliasName = classifierId
}
builder.flags = Flags.getTypeFlags(isSuspendType)
for (projection in type.arguments) {
builder.addArgument(typeArgument(projection))

View File

@@ -53,7 +53,6 @@ public final class BooleanArray {
public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte> {
/*primary*/ private constructor Byte()
@kotlin.SinceKotlin(version = "1.1") public final infix fun and(/*0*/ other: kotlin.Byte): kotlin.Byte
public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int
@@ -68,7 +67,6 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte> {
public final operator fun div(/*0*/ other: kotlin.Long): kotlin.Long
public final operator fun div(/*0*/ other: kotlin.Short): kotlin.Int
public final operator fun inc(): kotlin.Byte
@kotlin.SinceKotlin(version = "1.1") public final fun inv(): kotlin.Byte
public final operator fun minus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun minus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun minus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -81,7 +79,6 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte> {
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Int): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Long): kotlin.Long
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Short): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun or(/*0*/ other: kotlin.Byte): kotlin.Byte
public final operator fun plus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun plus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun plus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -113,7 +110,6 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte> {
public open override /*1*/ fun toShort(): kotlin.Short
public final operator fun unaryMinus(): kotlin.Int
public final operator fun unaryPlus(): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun xor(/*0*/ other: kotlin.Byte): kotlin.Byte
public companion object Companion {
/*primary*/ private constructor Companion()
@@ -613,7 +609,6 @@ public abstract class Number {
public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short> {
/*primary*/ private constructor Short()
@kotlin.SinceKotlin(version = "1.1") public final infix fun and(/*0*/ other: kotlin.Short): kotlin.Short
public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int
@@ -628,7 +623,6 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short> {
public final operator fun div(/*0*/ other: kotlin.Long): kotlin.Long
public final operator fun div(/*0*/ other: kotlin.Short): kotlin.Int
public final operator fun inc(): kotlin.Short
@kotlin.SinceKotlin(version = "1.1") public final fun inv(): kotlin.Short
public final operator fun minus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun minus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun minus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -641,7 +635,6 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short> {
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Int): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Long): kotlin.Long
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Short): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun or(/*0*/ other: kotlin.Short): kotlin.Short
public final operator fun plus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun plus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun plus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -673,7 +666,6 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short> {
public open override /*1*/ fun toShort(): kotlin.Short
public final operator fun unaryMinus(): kotlin.Int
public final operator fun unaryPlus(): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun xor(/*0*/ other: kotlin.Short): kotlin.Short
public companion object Companion {
/*primary*/ private constructor Companion()

View File

@@ -55,7 +55,6 @@ public final class BooleanArray : kotlin.Any, kotlin.Cloneable, java.io.Serializ
public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io.Serializable {
/*primary*/ private constructor Byte()
@kotlin.SinceKotlin(version = "1.1") public final infix fun and(/*0*/ other: kotlin.Byte): kotlin.Byte
public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int
@@ -70,7 +69,6 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io
public final operator fun div(/*0*/ other: kotlin.Long): kotlin.Long
public final operator fun div(/*0*/ other: kotlin.Short): kotlin.Int
public final operator fun inc(): kotlin.Byte
@kotlin.SinceKotlin(version = "1.1") public final fun inv(): kotlin.Byte
public final operator fun minus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun minus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun minus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -83,7 +81,6 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Int): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Long): kotlin.Long
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Short): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun or(/*0*/ other: kotlin.Byte): kotlin.Byte
public final operator fun plus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun plus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun plus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -115,7 +112,6 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io
public open override /*1*/ fun toShort(): kotlin.Short
public final operator fun unaryMinus(): kotlin.Int
public final operator fun unaryPlus(): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun xor(/*0*/ other: kotlin.Byte): kotlin.Byte
public companion object Companion {
/*primary*/ private constructor Companion()
@@ -629,7 +625,6 @@ public abstract class Number : kotlin.Any, java.io.Serializable {
public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.io.Serializable {
/*primary*/ private constructor Short()
@kotlin.SinceKotlin(version = "1.1") public final infix fun and(/*0*/ other: kotlin.Short): kotlin.Short
public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int
@@ -644,7 +639,6 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.
public final operator fun div(/*0*/ other: kotlin.Long): kotlin.Long
public final operator fun div(/*0*/ other: kotlin.Short): kotlin.Int
public final operator fun inc(): kotlin.Short
@kotlin.SinceKotlin(version = "1.1") public final fun inv(): kotlin.Short
public final operator fun minus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun minus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun minus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -657,7 +651,6 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Int): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Long): kotlin.Long
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Short): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun or(/*0*/ other: kotlin.Short): kotlin.Short
public final operator fun plus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun plus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun plus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -689,7 +682,6 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.
public open override /*1*/ fun toShort(): kotlin.Short
public final operator fun unaryMinus(): kotlin.Int
public final operator fun unaryPlus(): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun xor(/*0*/ other: kotlin.Short): kotlin.Short
public companion object Companion {
/*primary*/ private constructor Companion()

View File

@@ -55,7 +55,6 @@ public final class BooleanArray : kotlin.Any, kotlin.Cloneable, java.io.Serializ
public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io.Serializable {
/*primary*/ private constructor Byte()
@kotlin.SinceKotlin(version = "1.1") public final infix fun and(/*0*/ other: kotlin.Byte): kotlin.Byte
public open override /*1*/ fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int
@@ -70,7 +69,6 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io
public final operator fun div(/*0*/ other: kotlin.Long): kotlin.Long
public final operator fun div(/*0*/ other: kotlin.Short): kotlin.Int
public final operator fun inc(): kotlin.Byte
@kotlin.SinceKotlin(version = "1.1") public final fun inv(): kotlin.Byte
public final operator fun minus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun minus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun minus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -83,7 +81,6 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Int): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Long): kotlin.Long
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Short): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun or(/*0*/ other: kotlin.Byte): kotlin.Byte
public final operator fun plus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun plus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun plus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -115,7 +112,6 @@ public final class Byte : kotlin.Number, kotlin.Comparable<kotlin.Byte>, java.io
public open override /*1*/ fun toShort(): kotlin.Short
public final operator fun unaryMinus(): kotlin.Int
public final operator fun unaryPlus(): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun xor(/*0*/ other: kotlin.Byte): kotlin.Byte
public companion object Companion {
/*primary*/ private constructor Companion()
@@ -631,7 +627,6 @@ public abstract class Number : kotlin.Any, java.io.Serializable {
public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.io.Serializable {
/*primary*/ private constructor Short()
@kotlin.SinceKotlin(version = "1.1") public final infix fun and(/*0*/ other: kotlin.Short): kotlin.Short
public final operator fun compareTo(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Double): kotlin.Int
public final operator fun compareTo(/*0*/ other: kotlin.Float): kotlin.Int
@@ -646,7 +641,6 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.
public final operator fun div(/*0*/ other: kotlin.Long): kotlin.Long
public final operator fun div(/*0*/ other: kotlin.Short): kotlin.Int
public final operator fun inc(): kotlin.Short
@kotlin.SinceKotlin(version = "1.1") public final fun inv(): kotlin.Short
public final operator fun minus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun minus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun minus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -659,7 +653,6 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Int): kotlin.Int
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Long): kotlin.Long
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use rem(other) instead", replaceWith = kotlin.ReplaceWith(expression = "rem(other)", imports = {})) public final operator fun mod(/*0*/ other: kotlin.Short): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun or(/*0*/ other: kotlin.Short): kotlin.Short
public final operator fun plus(/*0*/ other: kotlin.Byte): kotlin.Int
public final operator fun plus(/*0*/ other: kotlin.Double): kotlin.Double
public final operator fun plus(/*0*/ other: kotlin.Float): kotlin.Float
@@ -691,7 +684,6 @@ public final class Short : kotlin.Number, kotlin.Comparable<kotlin.Short>, java.
public open override /*1*/ fun toShort(): kotlin.Short
public final operator fun unaryMinus(): kotlin.Int
public final operator fun unaryPlus(): kotlin.Int
@kotlin.SinceKotlin(version = "1.1") public final infix fun xor(/*0*/ other: kotlin.Short): kotlin.Short
public companion object Companion {
/*primary*/ private constructor Companion()

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