Compare commits

...

265 Commits

Author SHA1 Message Date
Nicolay Mitropolsky
d3f5293647 182: IDEA sdk set to 182.3458.5
(cherry picked from commit 80f022c3d5)
2018-07-02 14:41:01 +03:00
Vyacheslav Gerasimov
bf5b1f871c Allow plugin installation on Android Studio 3.2 Beta 2 2018-06-29 22:12:42 +03:00
Vyacheslav Gerasimov
a41469484d Allow plugin installation on Android Studio 3.2 Beta 1 2018-06-26 17:40:15 +03:00
Yan Zhulanow
b2836fa195 Allow installing plugin only on compatible Android Studio 3.2 versions 2018-06-25 20:44:47 +03:00
Raluca Sauciuc
13823a5299 Android Extensions: make synthetic import resolution more resilient
In commit ec0abb0 (Fix EA-79206: Process only valid layout.xml...) we
started to drop layouts with invalid PsiFiles during resolution of
(synthetic) package fragments.

In Android Studio we run into invalid files quite often, and it seems
to be caused by a race with some invokeLater'ed code from android-ndk;
this has the side effect of now showing all the corresponding symbols
as unresolved, and the imports themselves are suggested for removal.

As a temporary fix I propose we try again to get a valid PsiFile.

Bug: https://issuetracker.google.com/78547457
(cherry picked from commit 3e8789225bd653caaedeca7f761a6442d48214b0)
2018-06-25 20:43:25 +03:00
Raluca Sauciuc
c5a030000b Recognize Instant Apps plugin
Tested with sample project and Studio 3.2 Canary 18:
https://github.com/googlesamples/android-instant-apps/tree/master/hello-kotlin

(cherry picked from commit 528d66d5840cc8f584270c516e85da1a632df8b8)
2018-06-25 20:43:24 +03:00
Yan Zhulanow
c9767532b5 Kapt: Fix 'kapt.use.worker.api' option (#KT-24919) 2018-06-25 20:43:19 +03:00
Alexey Tsvetkov
9b85b1b173 Fix inter-project IC for android->non-android dependency
#KT-24832 fixed
2018-06-25 19:36:18 +03:00
Alexey Tsvetkov
30c16a654e Avoid iterating jar inputs in inspectClassesForKotlinIC task
Jar's inputs can contain zipTrees in case of fat jars,
which can cause slow build
(Gradle unpacks them into temporary dir; that can be slow)

    #KT-24956 fixed
2018-06-25 19:34:56 +03:00
Alexey Tsvetkov
4ce9b7f797 Don't create build directory for task in getter
Since the property is public, it can be invoked from outside,
possibly trough other properties.
This can lead to unwanted side effects: we can create taskBuildDirectory,
because some other task reads the property in parallel with 'clean' task
in current project.
That's exactly what happened when we referenced the property from
'GradleCompilerRunner#buildModulesInfo'.

    #KT-24938 fixed
2018-06-25 19:33:20 +03:00
Sergey Igushkin
f92bc49977 Fix Android ap option providers as Kapt task nested inputs
1) Exclude the providers arguments from the kapt inputs, as the values
may contain absolute paths, may be output properties etc. The providers
should correctly annotate their inputs.

2) Fix the options passed to kapt as 'value=option' (leading to all the
options collapse into one with the null key), use 'key=option' instead
to make Kapt pass them as '-Aoption'.

Issue #KT-23866 Fixed
Issue #KT-25027 Fixed
2018-06-25 14:54:07 +03:00
Alexander Udalov
933afcfa34 Update bootstrap to 1.2.51-eap-115 2018-06-25 12:58:35 +02:00
Alexey Tsvetkov
da1da0e52d Filter out non-existent java source roots in kapt tasks
#KT-24716 fixed
2018-06-22 19:25:17 +03:00
Ilya Gorbunov
8cf3871750 Remove state from parts of multifile classes
Split COROUTINE_SUSPENDED marker to expect and actual because Kotlin/JS backend
expects it to be property without getter.

#KT-24986 Fixed

(cherry picked from commit 6d027bbbfc)
2018-06-22 11:45:13 +03:00
Alexander Udalov
9838ed8e14 Fix MalformedParameterizedTypeException on classes from kotlin-reflect
This allows GraalVM's `native-image` to work correctly on
kotlin-reflect.jar. The size of the artifact has increased only by 66
bytes

 #KT-23962 Fixed

(cherry picked from commit 8749bd901b)
2018-06-21 14:31:13 +02:00
Alexander Udalov
decbe7dcb0 Revert "Map Kotlin TYPE target to Java TYPE_USE in bytecode"
This reverts commit a026c59aa6.

 #KT-23857 Open
 #KT-24952 Fixed
2018-06-21 14:30:30 +02:00
Alexander Udalov
a3eb82380d Fix serialization of type parameters inner generic class
The call to `createTopLevel` instead of `create` (which creates
serializers for outer classes properly, with correct type parameter
contexts) caused MetadataSerializer to write type parameter metadata
incorrectly.  For example, in the following case:

    class A<E> {
        inner class B<T, E> { ... }
    }

A's type parameter E would get id 0, and B's type parameters T and E
would get ids 0 and 1. This is a problem because ids are supposed to be
unique for each class including its outer classes, and deserializer,
decompiler and stub builder rely on this assumption.

JVM metadata is unaffected because `create` is called correctly there,
see MemberCodegen#generateKotlinClassMetadataAnnotation

 #KT-24944 Fixed
2018-06-21 14:29:25 +02:00
Vyacheslav Gerasimov
adabcc5c02 as31: Set until-build to 173.* instead of last AS 3.1 version (173.4301.25)
Was 173.4301.25 because of early builds of AS 3.2 which were 173 based
2018-06-20 19:05:09 +03:00
Ilya Chernikov
b86dec0511 Add test with other annotation, tests fix of #KT-24926 2018-06-20 12:01:27 +02:00
Rodrigo B. de Oliveira
738f2202ac Only collect annotations with a name starting with KotlinScript 2018-06-20 12:00:34 +02:00
Alexey Tsvetkov
fd07c698f1 Minor: reword progress message
#KT-24936 fixed
2018-06-19 22:42:43 +03:00
Natalia Selezneva
ae4c547547 Use field access instead of setter in clone method of KtCodeFragment
Fix EA-120381

(cherry picked from commit 077554c438)
2018-06-19 10:50:51 +03:00
Ilya Chernikov
691737dbf0 Add missing plugin to the gradle publishing config 2018-06-13 19:15:27 +02:00
Ilya Chernikov
363dbba402 Update changelog 2018-06-13 17:19:13 +02:00
Vyacheslav Gerasimov
78aed39efc 182: Fix toNullability clash in j2k
(cherry picked from commit 7fb2452)
2018-06-09 17:36:16 +03:00
Vyacheslav Gerasimov
d7fadb2661 182: Suppress compiler proguard warnings from intellij-core dependencies 2018-06-08 21:42:38 +03:00
Vyacheslav Gerasimov
fcb03eda67 182: Set since build to 182.3040 2018-06-08 21:42:38 +03:00
Yan Zhulanow
fd0e2abbef 182: Fix compatibility with the Android plugin from AS 3.1
(cherry picked from commit 0592121)
2018-06-08 21:42:38 +03:00
Vyacheslav Gerasimov
927ebe0de8 182: Switch 182 to SNAPSHOT builds (until next EAP)
Android plugin 3.1 is merged to IJ 182, we need to provide compatible plugin
2018-06-08 21:42:38 +03:00
Alexey Sedunov
647bb5f232 Configuration: Update settings.gradle without loading its PSI
Otherwise dumb-mode problems may happen in latest builds of 182

 #KT-24667 Fixed
2018-06-08 19:36:17 +03:00
Ilya Chernikov
811a6d044e Add missing tests dependencies on the renewed kotlin-scripting-idea plugin 2018-06-08 14:53:07 +02:00
Ilya Chernikov
18a5c4c6b1 Clean scripting plugin options and classpath on importing from gradle
should prevent problems that may appear if JPS will try to load
gradle scripting subplugin
2018-06-08 14:53:07 +02:00
Mikhail Glukhikh
90a6c3c5d4 Switch off "sealed sub-class to object inspection" by default
Provoked by KT-24816
2018-06-08 14:47:28 +03:00
Mikhael Bogdanov
ba57ae0337 Generate synthetic method for @JvmDefault properties in DefaultImpls
(cherry picked from commit a0060dd)
2018-06-08 11:32:09 +02:00
Ivan Gavrilovic
f32e13ee4b Revert access modifier change in android history 2018-06-07 19:11:26 +03:00
Ivan Gavrilovic
65a1ab606c Return an error when build history for dir does not exist 2018-06-07 19:11:26 +03:00
Ivan Gavrilovic
101e2f6d6a Support fetching build history files from directories for Android
Android Gradle plugin will start publishing clases in directories.
This commit adds support to find build history files when changed
files come from directories. It is similar to existing implementation
for jars i.e. it looks for .kotlin_module file under META-INF.

Test: ModulesApiHistoryAndroidTest
2018-06-07 19:11:26 +03:00
Natalia Selezneva
0b1c3f3a68 Fix AE in scratch for long lines
^KT-24638 Fixed
2018-06-07 10:44:10 +03:00
Ilya Chernikov
08c02acf62 Update bootstrap to 1.2.50-eap-85 2018-06-06 23:14:26 +02:00
Stanislav Erokhin
3c5a2fc90a Regenerate tests after reverts 2018-06-06 19:00:42 +03:00
Stanislav Erokhin
cf835ce375 Revert "KT-12330 Improve bytecode for data class equals/hashCode methods"
This reverts commit 0a11385006.
2018-06-06 19:00:41 +03:00
Stanislav Erokhin
4ff404c342 Revert "Fix NPE in data class 'equals' codegen"
This reverts commit 30b9caeae6.
2018-06-06 19:00:41 +03:00
Stanislav Erokhin
8df104c8ff Revert "Fix data class equals codegen for type parameters with interface bounds"
This reverts commit fd5d2275ce.
2018-06-06 19:00:41 +03:00
Alexey Sedunov
697bee6e5b Misc: Eliminate instances of IdeModifiableModelsProviderImpl or dispose them after use
(cherry picked from commit 8198599)
2018-06-06 17:50:08 +03:00
Ilya Gorbunov
2fd5a1a25b Restore default parameter values in JS collection constructors
Even if they now have overloads that will be selected when these parameters are omitted.
This is to preserve compatibility with the libraries compiled against the older library.

#KT-24782 Fixed
2018-06-06 15:24:33 +03:00
Ilya Gorbunov
cfb00723be Temporarily restore removed internal and experimental classes to overcome KT-24755 2018-06-06 15:22:06 +03:00
Mikhail Glukhikh
19e779c5cd If to when: do not add label to outer loop if not necessary
So #KT-24767 Fixed

(cherry picked from commit 24008cd)
2018-06-06 13:28:58 +03:00
Ilya Chernikov
349bfbcaad Set bootstrap to 1.2.50-eap-62 2018-06-05 17:39:47 +02:00
Dmitry Savvinov
849dd09fb9 Hack enabling of SAM conversion for Kotlin functions in IDE 2018-06-05 17:24:44 +03:00
Dmitry Savvinov
1aec99536b Support -Xprogressive in platform analysis 2018-06-05 14:53:31 +03:00
Natalia Selezneva
7795ac1839 Replace SLRUMap with ConcurrentHashMap
^KT-24645 Fixed

(cherry picked from commit ccacf1b)
2018-06-05 12:30:11 +03:00
Pavel V. Talanov
8a8d2587dd Mpp: fix production internals not visible from tests in platform modules
Caused by change in mpp resolve
Happened in platform modules that have expectedBy dependencies
2018-06-04 14:37:33 +02:00
Pavel V. Talanov
965937b8a4 Minor: better name for generated test 2018-06-04 14:37:31 +02:00
Stanislav Erokhin
7608fd71d5 [NI] Prototype for SAM-conversion.
Supported:
- conversion in resolution parts. Also sam-with-receiver is supported automatically
- separate flag for kotlin function with java SAM as parameters

TODO:
- fix overload conflict error when function type is the same byte origin types is ordered
- consider case when parameter type is T, T <:> Runnable
- support vararg of Runnable

[NI] Turn off synthetic scope with SAM adapter functions if NI enabled

(cherry picked from commit 8f0b073c08)
2018-06-04 15:11:37 +03:00
Stanislav Erokhin
045dfc021e Minor. Extract preparation for expected type to separate function
(cherry picked from commit 4b8e95c)
2018-06-04 15:09:03 +03:00
Stanislav Erokhin
fb0574d2ff Minor. Use getExpectedType as util function for parameter type calculation
For almost all cases this change do nothing, because if parameter isn't
vararg, then both methods (FlatSignature.argumentValueType &
getExpectedType) return same value. Moreover if it is vararg parameter
and spread operator is not used, then results will be the same.
We can observe difference only when spread operator used
and when we compare two candidates corresponding parameters
for both spread arguments should be vararg parameters.
I.e. old way compares: Int vs String
new way compares: Array<out Int> vs Array<out String>.

(cherry picked from commit 232d069)
2018-06-04 15:08:24 +03:00
Nikolay Krasko
96db6abfc5 Protect access to SLRUCache for scripts with a lock 2018-06-04 12:24:49 +03:00
Alexey Sedunov
cb9fb6a641 Configuration: Add non-release repository to main Gradle buildfile
#KT-24725 Fixed

(cherry picked from commit 48b55ed)
2018-06-04 02:50:43 +03:00
Alexey Sedunov
a0e7649167 Configuration: Enable dumb-mode alternative resolve when updating settings.gradle
#KT-24667 Fixed

(cherry picked from commit b826e85)
2018-06-04 02:50:27 +03:00
Ilya Chernikov
67331ab3a8 Fix native-platform repo after it was suddenly moved in the gradle repo 2018-06-01 18:18:15 +02:00
Mikhael Bogdanov
6e69b19df9 Update @JvmDefault documentation
(cherry picked from commit 4383335)
2018-06-01 14:24:46 +02:00
Roman Artemev
f23a96a82a Fix visibility of @JsName-annotated symbols in stdlib-js
(cherry picked from commit 9d2092e)
2018-05-31 20:04:51 +03:00
Ilya Chernikov
6935b7578b Update changelog for the second public EAP 2018-05-31 10:04:35 +02:00
Ilya Chernikov
c5b9f83ac3 Revert "Android Extensions: Allow to access library project resources in Gradle setup (#KT-22430)"
This commit seems causes #KT-24681
2018-05-30 14:06:00 +02:00
Alexey Sedunov
66612379c8 Configuration: Restore dependency on gradle plugin in buildscript block
#KT-24671 Fixed

(cherry picked from commit 6f8e25e)
2018-05-29 18:11:05 +03:00
Mikhael Bogdanov
81d965add2 Support properties in compatibility mode
(cherry picked from commit ad717d5)
2018-05-29 15:13:04 +02:00
Mikhael Bogdanov
6215258ad7 Don't copy descriptor for delegation generation
Actually source element for DEFAULT_IMPL_DELEGATION_TO_SUPERINTERFACE_DEFAULT_IMPL
  was always null cause descriptor was copies with new kind=DECLARATION.
  That causes element recalculation in DiagnosticFactory:
  element = data.classOrigin.element
  So DEFAULT_IMPL_DELEGATION_TO_SUPERINTERFACE_DEFAULT_IMPL is added to EXTERNAL_SOURCES_KINDS

(cherry picked from commit 0498c3b)
2018-05-29 15:12:52 +02:00
Mikhael Bogdanov
a0e3060157 Minor. Fix test data
(cherry picked from commit 689a492)
2018-05-29 12:56:54 +02:00
Mikhael Bogdanov
71d089f280 Rollback 'Don't copy interface member on DefaultImpl delegation generation, keep kind'
(cherry picked from commit 23a713d)
2018-05-29 12:56:54 +02:00
Mikhael Bogdanov
13d747f46f Update option message 2018-05-29 12:51:38 +02:00
Mikhael Bogdanov
24b79b498d Minor. Fix test data
(cherry picked from commit cc2e351)
2018-05-29 10:35:36 +02:00
Mikhael Bogdanov
0333a6063f Rename 'jvm-default-mode' to 'jvm-default'. Add description
(cherry picked from commit bd4253c)
2018-05-29 10:35:25 +02:00
Mikhael Bogdanov
6672b38370 Don't generate compatibility suffix twice for properties
(cherry picked from commit 020573e)
2018-05-29 10:34:05 +02:00
Mikhael Bogdanov
02f857bd77 Support property accessor in compatibility mode
(cherry picked from commit 60f2dbe)
2018-05-29 10:34:00 +02:00
Mikhael Bogdanov
23032e4f9f Add missed import 2018-05-29 08:54:21 +02:00
Mikhael Bogdanov
a70fa6871a Minor. Remove hack
(cherry picked from commit 1d6665d)
2018-05-28 22:23:03 +02:00
Mikhael Bogdanov
5ed5de727e Pass accessorKind into AccessorForCallableDescriptor
(cherry picked from commit b7bad2b)
2018-05-28 22:22:58 +02:00
Mikhael Bogdanov
56a4feff48 Convert AccessorForPropertyDescriptor to Kotlin
(cherry picked from commit 7a649e0)
2018-05-28 22:22:52 +02:00
Mikhael Bogdanov
d50ea1196d Rename AccessorForPropertyDescriptor.java to AccessorForPropertyDescriptor.kt
(cherry picked from commit 6d321e7)
2018-05-28 22:22:47 +02:00
Mikhael Bogdanov
a558358982 Minor. Code clean
(cherry picked from commit df13d33)
2018-05-28 22:22:41 +02:00
Mikhael Bogdanov
a7ff35c03e Convert AccessorForCallableDescriptor to Kotlin
(cherry picked from commit 15cbb68)
2018-05-28 22:22:36 +02:00
Mikhael Bogdanov
6b63fb7f1f Convert AccessorForFunctionDescriptor to Kotlin
(cherry picked from commit 2fa521b)
2018-05-28 22:22:30 +02:00
Mikhael Bogdanov
688377f5c4 Rename AccessorForFunctionDescriptor.java -> AccessorForFunctionDescriptor.kt
(cherry picked from commit 25af7c1)
2018-05-28 22:22:24 +02:00
Mikhael Bogdanov
d6e506d50e Rename FieldAccessorKind to AccessorKind
(cherry picked from commit 8f19dea)
2018-05-28 22:22:17 +02:00
Mikhael Bogdanov
b2f055f52f Minor. Code clean
(cherry picked from commit ad57ca7)
2018-05-28 22:22:10 +02:00
Mikhael Bogdanov
275a5bb2d9 Support compatibility mode for @JvmDefault
(cherry picked from commit 340920f)
2018-05-28 22:22:04 +02:00
Mikhael Bogdanov
74009c311c Don't copy interface member on DefaultImpl delegation generation, keep kind
Old logic is redundant and obsolete

(cherry picked from commit 9b718e8)
2018-05-28 22:21:54 +02:00
Mikhael Bogdanov
e83d4dcefc Skip annotation classes in $DefaultImpls method delegation logic
Annotation could be safely skipped (as already interfaces) cause
  compiler generates delegation to DefaultImpls only for classes

(cherry picked from commit 4421b41)
2018-05-28 22:21:44 +02:00
Mikhael Bogdanov
4235a77f74 Switch enableJvmDefault to jvmDefaultMode
(cherry picked from commit 065780d)
2018-05-28 22:21:27 +02:00
Ilya Chernikov
cda370366a Fix/workaround lazy lcript definition test and related scenarios 2018-05-28 22:07:37 +02:00
Ilya Chernikov
89495e2730 Fixes after review 2018-05-28 22:07:37 +02:00
Ilya Chernikov
d90fbc55d2 Fix custom script codegen test: add missing classpath entries 2018-05-28 22:07:37 +02:00
Ilya Chernikov
c71ea33b0e Avoid using reflected types in the scripting API
since it causes numerous classloading issues. Using the wrapping types
and reload them in the proper context when needed.
Note: this version supports only classes, but the wrapping type could
be extended to support other types in the future.
+ numerous fixes related to proper loading and handling of the templates.
2018-05-28 22:07:37 +02:00
Ilya Chernikov
24387fcccb Fix scripting plugin commandline processing 2018-05-28 22:07:37 +02:00
Ilya Chernikov
bf493b9a7f Add lazy discovery test 2018-05-28 22:07:37 +02:00
Ilya Chernikov
67b2f27dfe Move scripting codegen code from tests-common to compiler tests
getting rid of dependencies on scripting in the tests-common
2018-05-28 22:07:37 +02:00
Yan Zhulanow
fcc0425648 Remove unneeded empty build.gradle.kts.182 in buildSrc, fix 182 bunch 2018-05-28 21:34:38 +03:00
Pavel V. Talanov
e226f1bdcf IdeaModuleInfos: cache Module.findImplementedModules
Calling ModuleSourceInfo.expectedBy can be quite costly otherwise
    because creating IdeModifiableModuleProvider is not cheap
2018-05-28 20:10:46 +02:00
Pavel V. Talanov
cd2aff258b Cache result of collectModulesFromIdeaModel
Cache base module infos from idea model until next root modification
Calculate platform specific module infos (see PlatformModuleInfo)
    on demand based on cached module infos from idea model

 #KT-24144 Fixed
2018-05-28 20:10:44 +02:00
Pavel V. Talanov
7ee91a90fb Minor: split getModuleInfo into separate files 2018-05-28 20:10:42 +02:00
Alexey Sedunov
11e046eca1 Misc: Do not set icon via GUI Designer
Since Designer references icon by filename it fails
due to recent update in IDEA icon files

 #KT-24580 Fixed

(cherry picked from commit 4053278)
2018-05-28 20:18:02 +03:00
Yan Zhulanow
2d541de5b0 Pill: Import Kotlin facets 2018-05-28 19:11:15 +03:00
Yan Zhulanow
e24df1b8b7 Pill: Fetch kotlin compilation arguments 2018-05-28 19:11:13 +03:00
Yan Zhulanow
b5c8da9867 Pill: Fix launching debuggable Android Studio on 'as' bunches 2018-05-28 19:11:12 +03:00
Yan Zhulanow
7dc10f316e Pill: Import all defined source sets, not only "src" and "test" 2018-05-28 19:11:11 +03:00
Yan Zhulanow
7fd0dd327b Pill: Attach gradle-api dependency 2018-05-28 19:11:10 +03:00
Yan Zhulanow
5fbeddbd5a Pill: Import common modules as libraries 2018-05-28 19:11:09 +03:00
Yan Zhulanow
b916af81ef Pill: Download Android jars only if pill.android.tests option is set 2018-05-28 19:11:07 +03:00
Yan Zhulanow
85ed9eebd1 Pill: Exclude 'build' dirs from excluded projects 2018-05-28 19:11:06 +03:00
Yan Zhulanow
0fddc25cd9 Pill: Introduce pill{} extension to set extended Pill configuration
Also introduce the flavor concept which allows to specify what part of Kotlin project should be imported.
2018-05-28 19:11:05 +03:00
Yan Zhulanow
771aa0e9e4 PrePush: Add a pre-push warning before committing to locked branches 2018-05-28 18:58:36 +03:00
Alexander Udalov
31ddcabcee Fix multiple issues when expanding argfiles
- treat a contiguous whitespace sequence as a single argument separator,
  not as several empty-string arguments separated by whitespaces
- fix infinite loop when reading unfinished quoted argument
- do not attempt to perform escape if the backslash is the last
  character in the file
2018-05-28 18:15:29 +03:00
Alexander Udalov
1f4635ab08 Support -Xargfile in all scenarios; refactor & prettify code
Perform command line argument preprocessing in the beginning of
parseCommandLineArguments, so that argfiles are expanded in all
scenarios, not just when the compiler is invoked via
K2{JVM,JS}Compiler.exec
2018-05-28 18:15:29 +03:00
Dmitry Savvinov
97ea12e8d4 Support argfiles in kotlin compiler
Using '-Xargfile=path/to/argfile' will substitute
that argument with the content of argfile.

See KT-24472
2018-05-28 18:15:29 +03:00
Dmitry Savvinov
e6323afc27 Move importsDumper to compiler plugin 2018-05-28 18:15:28 +03:00
Dmitry Savvinov
e1b15b668d Fix tests for imports dumper
Remove local absolute paths from testdata, introduce new testrunner to
support relativization of imports dump.
2018-05-28 18:15:28 +03:00
Dmitry Savvinov
feab7f2e70 Introduce -Xoutput-imports mode of JVM compiler
In this mode, instead of analyzing files and generating bytecode for
them, compiler just saves imports of each file in JSON map of form

'<path to file> -> [<import1>, <import2>, ...]'

It is needed for some external tools, notably for Google3 toolchain.
2018-05-28 18:15:28 +03:00
Dmitry Savvinov
399337653d Introduce LanguageFeature.Kind
Mainly, Kind affects 'forcesPreReleaseBinaries' and
'enabledInProgressiveMode' flags, and allows to cover common
combinations of those flags.
2018-05-28 18:15:28 +03:00
Dmitry Savvinov
2e8c9d44e3 Add support of internal arguments for language feature settings
Arguments are passed in form '-XXLanguage:+LanguageFeatureName' for enabling
LanguageFeature.LanguageFeatureName, and '-XXLanguage:-LanguageFeatureName'
for disabling.

Note that they do override other settings, including 'language-version'
or extra ('-X') args.
2018-05-28 18:15:28 +03:00
Dmitry Savvinov
6635d0a93f Minor: reformat CommonToolArguments 2018-05-28 18:15:28 +03:00
Dmitry Savvinov
5fefb86f5a Minor: reformat parseCommandLineArguments, apply intentions 2018-05-28 18:15:28 +03:00
Dmitry Savvinov
65344fc057 Minor: reformat CommonCompilerArguments 2018-05-28 18:15:28 +03:00
Dmitry Savvinov
011e186c66 Introduce -Xprogressive 2018-05-28 18:15:28 +03:00
Anton Bannykh
5806de9886 JS: more default arguments fixes (KT-24413, KT-21968 fixed)
MPP-related:
* inherited from interfaces
* inherited body from interface
* default arguments in an interface, implemented by a class delegate
* super call of a method with default argument

Also:
* inheritance from an interface and another interface descendant (KT-21968)
* inheritance through an intermediate interface

(cherry picked from commit 03e46ce0ca)
2018-05-28 16:26:12 +03:00
Yan Zhulanow
03421c5953 Do not retain proxy-based components for compiler plugin settings in project model (#KT-24444) 2018-05-28 06:06:30 +03:00
Yan Zhulanow
0d84d1014d Kapt: Fix Gradle input/output verification 2018-05-28 06:06:30 +03:00
Yan Zhulanow
e9629023e3 Fix a number of potential exceptions in debugger (EA-119717) 2018-05-28 06:06:30 +03:00
Yan Zhulanow
1d98e527db Handle AbsentInformationException correctly (EA-119717) 2018-05-28 06:06:30 +03:00
Yan Zhulanow
c502488a18 Print source file location/contents if possible (EA-120038) 2018-05-28 06:06:30 +03:00
Yan Zhulanow
43e6283139 Fix NPE in DelegateSourcePosition (EA-120042) 2018-05-28 06:06:30 +03:00
Yan Zhulanow
46ff33268e Add missing read action in debugger (EA-120163) 2018-05-28 06:06:29 +03:00
Yan Zhulanow
aeda20993f Support types without backing ClassLoader in 'safeArgumentTypes()' (EA-120387) 2018-05-28 06:06:29 +03:00
Yan Zhulanow
9bb72961ac Kapt: Allow running kapt using Workers API in Gradle 2018-05-28 06:06:29 +03:00
Yan Zhulanow
694c8fa21e Kapt: Extract annotation processing running logic from the compiler plugin 2018-05-28 06:06:29 +03:00
Yan Zhulanow
b46f69e022 Kapt: Leave getBasePath() in ProGuard-ed kotlinc 2018-05-28 06:06:29 +03:00
Yan Zhulanow
58d499397f Kapt: Fix compatibility with Java 9
1. Move option set up to one place, before using any of Java context components;
2. Set Javac file manager options (new to Java 9)
2018-05-28 06:06:29 +03:00
Yan Zhulanow
e0d5714ba1 Kapt: Do now show a warning for APs from 'annotationProcessor' configuration also declared in 'kapt' configuration (#KT-23898) 2018-05-28 06:06:29 +03:00
Yan Zhulanow
0aeebcfbf2 MPP: Fix implemented modules importing in Android projects (#KT-23697) 2018-05-28 06:06:29 +03:00
Yan Zhulanow
9d91d8c634 Android Extensions: Allow to disable specific features of Android Extensions (#KT-23244) 2018-05-28 06:06:28 +03:00
Yan Zhulanow
a6d7b80dba Android Extensions: Allow to access library project resources in Gradle setup (#KT-22430) 2018-05-28 06:06:28 +03:00
Neonailol
b7c0805300 KT-23356 Cross-platform function to convert CharArray slice to String
Signed-off-by: Valeriy Zhirnov <neonailol@gmail.com>
(cherry picked from commit ede2e227c2)
2018-05-27 16:03:07 +03:00
Ilya Gorbunov
43b7433c39 Docs: clarify default element value of CharArray and BooleanArray
(cherry picked from commit 3245148206)
2018-05-27 16:02:56 +03:00
Ilya Gorbunov
1374918760 Array.copyOf docs: do not use 'primitive default' term, rewrite description
#KT-22298

(cherry picked from commit 418db53ba4)
2018-05-27 16:02:54 +03:00
Valeriy Zhirnov
d9720495ca KT-22298 Improve docs for Array.copyOf(newSize: Int)
Signed-off-by: Valeriy Zhirnov <neonailol@gmail.com>
(cherry picked from commit 9239de9a02)
2018-05-27 16:02:53 +03:00
Roman Artemev
b82efb0a03 [JS BE] Fix delegation of suspend method member (KT-23094) 2018-05-27 00:06:04 +03:00
Max Medvedev
713c271723 Extract function: make name editor focused
#KT-22333 Fixed

(cherry picked from commit 16ebcc6)
2018-05-26 00:18:25 +03:00
Alexey Sedunov
b53f230f41 Create Class from Usage: Filter out usages in super type entry list
#KT-22918 Fixed

(cherry picked from commit 610cc38)
2018-05-26 00:18:07 +03:00
Alexey Sedunov
86f673362a Quick Fixes: Fix adding parameter to Java constructor 2018-05-26 00:15:28 +03:00
Alexey Sedunov
3d0db05173 Change Signature: Use target declaration as a context for types
#KT-22387 Fixed

(cherry picked from commit 6e25db9)
2018-05-26 00:05:22 +03:00
Alexey Sedunov
723664bc92 Configuration: Drop Java -> Kotlin/JS configurator
#KT-24504 Fixed

(cherry picked from commit 6a21991)
2018-05-25 23:54:47 +03:00
Alexey Sedunov
76ecba56f6 Configuration: Support TeamCity repository for dev-versions
(cherry picked from commit 6fd060b)
2018-05-25 23:47:35 +03:00
Alexey Sedunov
6a026f6ce2 Configuration: Add 'mavenCentral() to generated script 'repositories' block
#KT-24586 Fixed

(cherry picked from commit c64f93b)
2018-05-25 23:46:28 +03:00
Alexander Udalov
a996bcf90e Temporarily remove OptionalExpectation and tests
Because of a problem described in KT-24617

 #KT-18882 Open
2018-05-25 15:27:00 +02:00
Alexander Udalov
280cb9d0d7 Check function name in isGenericToArray/isNonGenericToArray
#KT-24427 Fixed

(cherry picked from commit 9c5256434c)
2018-05-25 14:55:59 +02:00
Ilya Gorbunov
27d1c1e05e Advance bootstrap
Need to use -XXLanguage feature switch
2018-05-25 12:22:13 +02:00
Alexey Sedunov
8cca489c12 Configuration: Use 'plugins' block in generated/modified Gradle scripts
Follow-up for 172/173/AS3.1/AS3.2 bunches

(cherry picked from commit 44e7070)
2018-05-24 17:33:58 +03:00
Alexey Sedunov
2266861ef4 Misc: KtParsingTestCase fixes for 172/173/AS3.1 bunches
(cherry picked from commit efc369d)
2018-05-24 17:33:58 +03:00
Alexey Sedunov
b4a710a6a1 Configuration: Use 'plugins' block in generated/modified Gradle scripts
#KT-20665 Fixed

(cherry picked from commit 1650e69)
2018-05-24 17:33:57 +03:00
Alexey Sedunov
5b7940163d Misc: Migrate to IDEA 181.3
(cherry picked from commit 909ff3a)
2018-05-24 17:33:57 +03:00
Alexey Sedunov
7b55f57ef2 Configuration: Setup project settings even if library is not detected
#KT-22305 Fixed

(cherry picked from commit 1fb1431)
2018-05-24 17:33:57 +03:00
Alexey Sedunov
72f55d908c Configuration: Detect platform of libraries added via maven artifact ids
#KT-20511 Fixed

(cherry picked from commit eb14625)
2018-05-24 17:33:57 +03:00
Alexey Sedunov
349a187782 Configuration: Unify presentable names of Kotlin configurators
#KT-23658 Fixed

(cherry picked from commit 06f9be1)
2018-05-24 17:33:56 +03:00
Alexey Sedunov
5989671057 Misc: Follow-up fixes for 172/182 bunches
(cherry picked from commit 4a98f1d)
2018-05-24 17:33:56 +03:00
Mikhail Glukhikh
31eaf45f2a Provide language version settings correctly for platform modules
So #KT-24546 Fixed

(cherry picked from commit f8f3b1c)
2018-05-24 17:23:08 +03:00
Mikhail Glukhikh
b3cef661af Convert async {}.await() to withContext(DefaultDispatcher) {}
This fixes incorrect transformation related to KT-24235

(cherry picked from commit fbb0a3e)
2018-05-24 17:22:52 +03:00
Mikhail Glukhikh
ac340107f5 Additional tests for KT-21131
(cherry picked from commit 4ed4754)
2018-05-24 17:22:37 +03:00
Mikhail Glukhikh
77df1ef527 Code inliner: keep main property if it can have side effects
So #KT-24165 Fixed

(cherry picked from commit f3c2dd0)
2018-05-24 17:22:22 +03:00
Mikhail Glukhikh
533de6d0e9 Code inliner: move lambda outside parentheses always when possible
So #KT-24215 Fixed

(cherry picked from commit 93a510c)
2018-05-24 17:22:07 +03:00
Mikhail Glukhikh
7a88566979 Reformat & cleanup: CodeInliner
(cherry picked from commit bb8c349)
2018-05-24 17:21:53 +03:00
Mikhail Glukhikh
09af555698 Fix importing scope order in ReplaceWithAnnotationAnalyzer
So #KT-22615 Fixed

(cherry picked from commit 2d7e274)
2018-05-24 17:21:36 +03:00
Mikhail Glukhikh
d7aa7b5b65 Reformat: ReplaceWithAnnotationAnalyzer
(cherry picked from commit 394a547)
2018-05-24 17:20:57 +03:00
Mikhail Glukhikh
ce8de4c1b1 Reformat: CodeToInline
(cherry picked from commit 75724c0)
2018-05-24 17:20:39 +03:00
Natalia Selezneva
f59885510c Minor: add test that output at scratch line with spaces at the beginning is aligned properly
(cherry picked from commit 98fe8ea)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
b89cac274a Scratch: take into account only lines with expressions calculating inlay insert offset
(cherry picked from commit db63877)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
db0b4b29fa Run scratch if there are some compilation error during make
(cherry picked from commit aa7c13e)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
8062966b74 Substring long scratch output with new lines
(cherry picked from commit 5a7b58c)

^KT-24016 Fixed
2018-05-24 17:16:21 +03:00
Natalia Selezneva
533bd7c9bb Provide line info for scratch output in scratch toolwindow
(cherry picked from commit 94bb19c)

^KT-24016
2018-05-24 17:16:21 +03:00
Natalia Selezneva
b2234b1a53 Scratch tests: add check for toolwindow output
(cherry picked from commit a505a94)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
85541aa9fc Scratch: fix duplicating of errors in scratch output toolwindow
(cherry picked from commit bce0a77)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
80ea6dce99 Scratch: test alignment of inlays
(cherry picked from commit e3b6fad)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
175f1b5b8d Minor: rename file and rearrange classes
(cherry picked from commit 5da0252)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
afba9c2e75 Introduce ToolWindowScratchOutputHandler
(cherry picked from commit 420da0d)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
d4d0fc1a36 Refactoring: move ScratchToolWindowFactory to scratch.output package
(cherry picked from commit aa1e604)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
47ffa04f61 Refactoring: move ScratchFileRenderer to separate file
(cherry picked from commit 614fa9d)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
708e89c83e Minor: replace assert with user-friendly error
(cherry picked from commit afa6110)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
b43641a5aa Setting for auto-reloading script dependencies isn't loaded from xml on project reopening
(cherry picked from commit 75ad784)
2018-05-24 17:16:21 +03:00
Natalia Selezneva
f976383758 Minor: fixes after review
(cherry picked from commit 54f9359)
2018-05-24 17:16:21 +03:00
Ilmir Usmanov
8095c7cdda Minor: Add KotlinTypeMapper constructor overload 2018-05-24 15:44:06 +03:00
Alexander Udalov
a026c59aa6 Map Kotlin TYPE target to Java TYPE_USE in bytecode
And TYPE_PARAMETER -> TYPE_PARAMETER similarly

 #KT-23857 Fixed

(cherry picked from commit d122406dca)
2018-05-24 14:42:56 +02:00
Natalia Selezneva
f66f1e70d6 Refactoring: do not store scriptModuleInfo inside ScriptDependenciesInfo
Cache for ScriptDependenciesInfo.ForFile is dropped because there is a cache for ScriptModuleInfo, so the facade for dependencies shouldn't be created too often
Cache for ScriptDependenciesInfo.ForProject is stored in a field

(cherry picked from commit 30c62bc)
2018-05-24 15:12:05 +03:00
Natalia Selezneva
2078103269 Do not store external dependencies in ScriptModuleInfo
There is a cache from ScriptModuleInfo to ScriptDependenciesInfo.
In case when only script dependencies are changed we won't recreate the facade for them and will obtain external dependencies for ScriptModuleInfo stored in ScriptDependenciesInfo. So we cannot store external dependencies inside ScriptModuleInfo. The same problem is with relatedModuleSourceInfo.

(cherry picked from commit 2b322ec)
2018-05-24 15:11:42 +03:00
Natalia Selezneva
23a49b8dec Scripts: fix NPE during script dependencies update
(cherry picked from commit ab743ef)

^KT-24527 Fixed
2018-05-24 15:11:23 +03:00
Natalia Selezneva
4ed8cd69ee Optimize ScriptDependenciesUpdater to find scriptDefinition only for files with KotlinFileType
(cherry picked from commit f0a7642)
2018-05-24 15:10:58 +03:00
Natalia Selezneva
3cf7a9d4e4 Scripts: remove loaders when any result was received
(cherry picked from commit bb04998)

^KT-24470 Fixed
2018-05-24 15:10:42 +03:00
Sergey Rostov
02738ddc04 jps: support dev kit module types (and all other ModuleBasedBuildTargetType). fix brunch 172
(cherry picked from commit 098e51d)
2018-05-24 15:05:17 +03:00
Alexander Udalov
c7dea060f9 Introduce OptionalExpectation for annotations missing on some platforms
This commits adds a new annotation OptionalExpectation to the standard
library, which is experimental. To enable its usage, either pass
'-Xuse-experimental=kotlin.ExperimentalMultiplatform' as a compiler
argument, or '-Xuse-experimental=kotlin.Experimental' and also annotate
each usage with `@UseExperimental(ExperimentalMultiplatform::class)`

 #KT-18882 Fixed

(cherry picked from commit bf3419c3bd)
2018-05-24 13:31:11 +02:00
Sergey Rostov
03b9a18328 jps: support dev kit module types (and all other ModuleBasedBuildTargetType)
#KT-24500 fixed

(cherry picked from commit ec5110e)
2018-05-24 11:30:11 +03:00
Sergey Igushkin
8f77eeed3c (minor) Fix testApplyWithFeaturePlugin
(cherry picked from commit 721d9df)
2018-05-23 18:49:22 +03:00
Sergey Igushkin
051e32058c Add AP option providers of Android Gradle plugin as @Nested to Kapt
Also remove these option providers from the javac task compiler argument
providers so as to avoid output intersections of javac vs kapt.

The options generated by the providers are added to the Kapt subplugin
options as well in order to be passed to Kapt. Since these options
are a list, not a map, pass them without name (Kapt should decode them
into plain arguments). Remove the '-A' prefix as it is there for
command line annotation processor options, but we don't need it, it
is added by Kapt internally.

Issue #KT-23964 Fixed
Issue #KT-24420 Fixed

(cherry picked from commit 5719058)
2018-05-23 18:48:58 +03:00
Mikhael Bogdanov
f794c7bf3a Generate @JvmDefault for property accessors in LIGHT_CLASS MODE
(cherry picked from commit f826a25)
2018-05-23 13:56:40 +02:00
Mikhail Glukhikh
a0b38ab6b8 Result unused: a few enhancements for PSI checks
Related to KT-15063, KT-24433

(cherry picked from commit c95ed9f)
2018-05-22 17:18:29 +03:00
Mikhail Glukhikh
17bbc693b5 Extend "async result unused" to "Deferred result unused" #KT-15063 Fixed
(cherry picked from commit b8375d4)
2018-05-22 17:18:13 +03:00
Mikhail Glukhikh
792339bf6a Introduce inspection "async result unused" #KT-24433 Fixed
(cherry picked from commit ffcfa51)
2018-05-22 17:17:45 +03:00
Nicolay Mitropolsky
a241400d42 182: IDEA-SDK fixed to 182.2371.4
(cherry picked from commit eeab271)
2018-05-22 16:24:56 +03:00
Nicolay Mitropolsky
161926d967 182: gson set to 2.8.4
(cherry picked from commit 29ef865)
2018-05-22 16:24:19 +03:00
Alexander Udalov
fd5d2275ce Fix data class equals codegen for type parameters with interface bounds
#KT-24474 Fixed

(cherry picked from commit e7f6ac1e50)
2018-05-22 13:46:02 +02:00
Alexey Tsvetkov
831c1fc66c Improve JPS progress messages
#KT-9218 fixed
2018-05-19 20:05:58 +03:00
Alexey Tsvetkov
1a9b6cbd64 Fix NPE during lookup map GC
The cause of the issue is unknown, I was not able to reproduce it as
well

    #KT-24337 fixed
2018-05-19 20:05:53 +03:00
Alexey Tsvetkov
27c3396d19 Turn off inter-project IC when unknown task writes to java output dir 2018-05-17 22:23:36 +03:00
Alexey Tsvetkov
2ae054e79a Rebuild when dependency was built non-incrementally 2018-05-17 22:23:31 +03:00
Alexey Tsvetkov
9ec26b7f57 Implement module detection for Gradle IC with Android
#KT-22431 fixed
2018-05-17 22:23:26 +03:00
Alexey Tsvetkov
dc29e95c50 Track changes for jar files for non-Android Gradle projects 2018-05-17 22:23:21 +03:00
Alexey Tsvetkov
6203b03905 Track inter-project IC changes for Java 2018-05-17 22:23:17 +03:00
Alexey Tsvetkov
a2ff59a1d8 Remove global artifact history cache in Gradle
Each Kotlin task now writes build history to separate file.
A map of output directories to history files is used to get changes for
modified files.

    #KT-22623 fixed
2018-05-17 22:23:12 +03:00
Nikolay Krasko
e9f0a1f602 Don't show type hierarchy for elements without name 2018-05-17 13:48:04 +03:00
Nikolay Krasko
f19ac848e4 Don't build light classes for local classes with parse errors (KT-24323, EA-107235)
Also use checks for building light classes in `getLightClassDataHolder`.
2018-05-17 13:48:02 +03:00
Nikolay Krasko
2924c7fead Use comment directive for not generated case to be valid Java file 2018-05-17 13:48:01 +03:00
Nikolay Krasko
764c8308e5 Fight with valid absent, corrupted and missing files in archives (EA-119686)
Inspired by ClassFileViewProvider.
2018-05-17 13:47:59 +03:00
Nikolay Krasko
9cea01a2ef Use separate dirs in pill for running IDE to avoid test misbehaviour 2018-05-17 13:47:58 +03:00
Mikhail Glukhikh
83b44aebe5 Reformat: replace with operator assignment
(cherry picked from commit bec1ae3)
2018-05-17 12:49:34 +03:00
Mon_chi
217253aaee Fix hint text for replace with operator assignment #KT-23559 Fixed
(cherry picked from commit c49eaf2)
2018-05-17 12:49:18 +03:00
Mikhail Glukhikh
f5a805fa4c Convert KFunction to Function in type mismatch fixes #KT-16770 Fixed
(cherry picked from commit 8c3e787)
2018-05-17 12:49:00 +03:00
Mikhail Glukhikh
fa911f61a4 Create kotlin file: create abstract class if its name contains Abstract
So #KT-21844 Fixed

(cherry picked from commit 25609f1)
2018-05-17 12:48:40 +03:00
Mikhail Glukhikh
fc692cda6a Reformat: NewKotlinFileAction
(cherry picked from commit 1f8e24f)
2018-05-17 12:48:17 +03:00
Ilya Gorbunov
7ad0b90227 Fix incorrect @returns tag usage and improve padStart/End docs
#KT-24371 Fixed

(cherry picked from commit e7b445e4b5)
2018-05-17 05:30:56 +03:00
Ilya Chernikov
9e335d0f50 Revert "Debugging plugins uploading"
This reverts commit eae4153
2018-05-16 17:58:05 +02:00
Ilya Chernikov
eae4153373 Debugging plugins uploading 2018-05-16 16:58:26 +02:00
Ilya Chernikov
57d192d87b Update plugin-repository-rest-client repo url 2018-05-16 16:37:33 +02:00
Ilya Chernikov
e3e8b549fb Update plugin-repository-rest-client version 2018-05-16 16:20:25 +02:00
Ilya Chernikov
bda0f0db70 Fix the invalid code after "Fix order of jars" commit 2018-05-16 07:22:32 +02:00
Ilya Chernikov
57c7c7c92c Enumerate roots for script definitions only if project is initialized
fixes #KT-23805
2018-05-15 18:40:16 +02:00
Ilya Chernikov
4ac17ab81d Fix order of jars for the scripting plugin:
if gradle project is being built with JPS, the gradle scripting plugin
is passed in the plugin classpath. Since it is rebased on the embeddable
compiler, it hides expected plugin registrar signature, which leads to
the AbstractMethodError on attempt to load the plugin. Putting incoming
classpath at the end of the resulting one fixes the issue.
Fixes #KT-24448
2018-05-15 18:39:07 +02:00
Ilya Chernikov
99ba778e62 Prepare initial changelog for 1.2.50 2018-05-14 21:29:37 +02:00
Ilya Chernikov
bcfad29ae9 Add changelog from 1.2.40 - 1.2.41 2018-05-14 21:04:22 +02:00
Vyacheslav Gerasimov
8a6bedf5f0 Revert "Build: Copy uast to idea plugin as separate artifacts"
This reverts commit e6f6451
2018-05-14 20:41:54 +03:00
Vyacheslav Gerasimov
488a0c3adb Revert "Build: Exclude uast and lint artifacts from CIDR plugin"
This reverts commit da9175f
2018-05-14 20:40:23 +03:00
Vyacheslav Gerasimov
eb091c32d0 Revert "Move uast service registration to jvm.xml"
This reverts commit ec1a9d9
2018-05-14 20:40:15 +03:00
Vyacheslav Gerasimov
424df2432a Revert "Build: Extract android ide modules from kotlin-plugin.jar to standalone jars"
This reverts commit 838f1f9
2018-05-14 20:39:26 +03:00
Vyacheslav Gerasimov
dff1da823c Revert "Build: Fix zipCidrPlugin destination file name, missed zip extension"
This reverts commit 8773e2d
2018-05-14 20:39:14 +03:00
Vyacheslav Gerasimov
e72449229c Revert "Build: Extract j2k to standalone jar"
This reverts commit 42cfacd
2018-05-14 20:39:01 +03:00
Vyacheslav Gerasimov
e0fb7059e4 Revert "Build: Exclude kapt from CIDR plugin artifact"
This reverts commit 282f2a4
2018-05-14 20:38:49 +03:00
Vyacheslav Gerasimov
7f0007e93a Revert "Build: Exclude j2k from CIDR plugin artifact"
This reverts commit 80f5a1d
2018-05-14 20:38:29 +03:00
Vyacheslav Gerasimov
eefe268730 Revert "Build: Extract jvm ide module from kotlin-plugin.jar to standalone jar"
This reverts commit 4d4ff63
2018-05-14 20:38:17 +03:00
Vyacheslav Gerasimov
709948168d Revert "Build: Extract jps-common ide module from kotlin-plugin.jar to standalone jar"
This reverts commit f2b323f
2018-05-14 20:38:09 +03:00
Vyacheslav Gerasimov
4e3af8434e Revert "Build: Exclude standalone kotlin compiler and jps from CIDR artifact"
This reverts commit f666db7
2018-05-14 20:38:00 +03:00
Vyacheslav Gerasimov
753f53ddab Revert "Build: Extract maven ide module from kotlin-plugin.jar to standalone jar"
This reverts commit 3d7f2f6
2018-05-14 20:37:52 +03:00
Vyacheslav Gerasimov
e9db300e6b Revert "Build: Exclude maven from CIDR plugin artifact"
This reverts commit 06aaa99
2018-05-14 20:37:43 +03:00
Yan Zhulanow
3c9071ae84 Revert "Debugger: Fix breakpoints and stepping for inline-only function lambda arguments (#KT-23064)" 2018-05-14 18:31:11 +03:00
Ilya Gorbunov
4d77b34712 KT-24353 Include kotlin-test-junit5 into coreLibraries, use JDK_18 to build and test it
(cherry picked from commit 864f0fe)
2018-05-14 17:41:21 +03:00
evgzakharov
abea42c42b KT-24353 change junit5 version to minimal possible (5.2.0 -> 5.0.0)
However use the latest version of junit engine for running tests.

(cherry picked from commit 6342796)
2018-05-14 17:41:04 +03:00
evgzakharov
b5a9844359 KT-24353 add support for junit 5 in kotlin.test
(cherry picked from commit 84ee97c)
2018-05-14 17:40:48 +03:00
Simon Ogorodnik
ca736b50e9 KT-24146: Fix inserts imports automatically
Even if "add unambiguous imports on the fly" is off

 #KT-24146 fixed

(cherry picked from commit 6967028)
2018-05-14 17:33:19 +03:00
Denis Zharkov
fb9b9909be Support androidx under-migration-like nullability annotations
They are hardcoded to avoid having dependency from android.jar on
our annotations' jar with UnderMigration.

Even while it could be a compile-only dependency we need to make sure
that annotated types are read properly without RecentlyNonNull/RecentlyNullable
in the classpath

 #KT-24278 Fixed
2018-05-14 17:31:17 +03:00
Denis Zharkov
2d1b0b3008 Minor. Reformat signature enhancement parts 2018-05-14 17:31:05 +03:00
Natalia Selezneva
1df8d2a9f3 Scratch: report errors at the correct line
^KT-24364 Fixed

(cherry picked from commit 4ee41d5)
2018-05-14 15:59:18 +03:00
Natalia Selezneva
0b6e27d1af Trim last newline in scratch output with REPL
^KT-24362 Fixed

(cherry picked from commit 6427c79)
2018-05-14 15:58:58 +03:00
Natalia Selezneva
d5764f0fb6 Check for dumb mode before compiling scratch file
^KT-23560

(cherry picked from commit 02fa8b5)
2018-05-14 15:58:40 +03:00
Natalia Selezneva
e83a4ae72b Log exceptions thrown during Run Scratch Action
(cherry picked from commit 57b2400)
2018-05-14 15:58:03 +03:00
Natalia Selezneva
21d51548db Minor: reformat
(cherry picked from commit 5148a51)
2018-05-14 15:57:44 +03:00
Nicolay Mitropolsky
ecf84523c1 182: compilation fix due to quickFixActionMarkers made nullble
(cherry picked from commit 31b21a7)
2018-05-14 15:53:11 +03:00
Ilya Chernikov
747580d87c Implement lazy script definition and light discovery in cli plugin, ...
update appropriate parts of the scripting infrastructure
2018-05-14 11:16:39 +02:00
Natalia Selezneva
544f900268 Fix tests: attach script reports in cli
(cherry picked from commit 1e92dbf)
2018-05-14 09:23:48 +03:00
Ilya Chernikov
1a94884fa9 Fix build in 182 branch 2018-05-13 11:11:19 +02:00
Ilya Chernikov
1aebe45dd8 Fix lz4 dependency...
after snappy was replaced by lz4 in the platform (see the previous commit
with related test for the more info)
2018-05-12 19:05:08 +02:00
Alexey Tsvetkov
6cea85642c Add test for missing lz4 dependency
Adds Gradle test for the exception:
`java.lang.ClassNotFoundException: net.jpountz.lz4.LZ4Factory`

The exception breaks IC in Gradle. Gradle compiles non-incrementally as
a fallback strategy, so the build succeeds, but IC is not working.

IC uses persistent hash tables from Intellij as caches.
These tables's buffers are compressed when full.
Previously snappy was used for compression, but 181 platform switched to
LZ4, which was cut out by proguard.

The problem could only be reproduced with Gradle,
since in JPS plugin all caches are managed by JPS process,
which contains the necessary library.

To reproduce the compiler needs to be processed by proguard
(which always happens on TeamCity).
Many classes are needed to trigger the compression.
2018-05-12 19:04:46 +02:00
871 changed files with 17768 additions and 5153 deletions

32
.idea/misc.xml generated
View File

@@ -44,6 +44,38 @@
</list>
</option>
</component>
<component name="NullableNotNullManager">
<option name="myNullables">
<value>
<list size="9">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="9">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="javax.validation.constraints.NotNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
</list>
</value>
</option>
</component>
<component name="ProjectResources">
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
</component>

View File

@@ -1,5 +1,486 @@
# CHANGELOG
## 1.2.50
### Compiler
- [`KT-23360`](https://youtrack.jetbrains.com/issue/KT-23360) Do not serialize annotations with retention SOURCE to metadata
- [`KT-24278`](https://youtrack.jetbrains.com/issue/KT-24278) Hard-code to kotlin compiler annotation for android library migration
- [`KT-24472`](https://youtrack.jetbrains.com/issue/KT-24472) Support argfiles in kotlinc with -Xargfile
- [`KT-24593`](https://youtrack.jetbrains.com/issue/KT-24593) Support -XXLanguage:{+|-}LanguageFeature compiler arguments to enable/disable specific features
- [`KT-24637`](https://youtrack.jetbrains.com/issue/KT-24637) Introduce "progressive" mode of compiler
#### Backend. JS
- [`KT-23094`](https://youtrack.jetbrains.com/issue/KT-23094) JS compiler: Delegation fails to pass the continuation parameter to child suspend function
- [`KT-23582`](https://youtrack.jetbrains.com/issue/KT-23582) JS: Fails to inline, produces bad code
- [`KT-24335`](https://youtrack.jetbrains.com/issue/KT-24335) JS: Invalid implement of external interface
#### Backend. JVM
- [`KT-12330`](https://youtrack.jetbrains.com/issue/KT-12330) Slightly improve generated bytecode for data class equals/hashCode methods
- [`KT-18576`](https://youtrack.jetbrains.com/issue/KT-18576) Debugger fails to show decomposed suspend lambda parameters
- [`KT-22063`](https://youtrack.jetbrains.com/issue/KT-22063) Add intrinsics for javaObjectType and javaPrimitiveType
- [`KT-23402`](https://youtrack.jetbrains.com/issue/KT-23402) Internal error: Couldn't inline method call because the compiler couldn't obtain compiled body for inline function with reified type parameter
- [`KT-23704`](https://youtrack.jetbrains.com/issue/KT-23704) Unstable `checkExpressionValueIsNotNull()` generation in bytecode
- [`KT-23707`](https://youtrack.jetbrains.com/issue/KT-23707) Unstable bridge generation order
- [`KT-23857`](https://youtrack.jetbrains.com/issue/KT-23857) Annotation with target TYPE is not applicable to TYPE_USE in Java sources
- [`KT-23910`](https://youtrack.jetbrains.com/issue/KT-23910) @JvmOverloads doesn't work with default arguments in common code
- [`KT-24427`](https://youtrack.jetbrains.com/issue/KT-24427) Protected function having toArray-like signature from collection becomes public in bytecode
- [`KT-24661`](https://youtrack.jetbrains.com/issue/KT-24661) Support binary compatibility mode for @JvmDefault
#### Frontend
- [`KT-21129`](https://youtrack.jetbrains.com/issue/KT-21129) Unused parameter in property setter is not reported
- [`KT-21157`](https://youtrack.jetbrains.com/issue/KT-21157) Kotlin script: engine can take forever to eval certain code after several times
- [`KT-22740`](https://youtrack.jetbrains.com/issue/KT-22740) REPL slows down during extensions compiling
- [`KT-23124`](https://youtrack.jetbrains.com/issue/KT-23124) Kotlin multiplatform project causes IntelliJ build errors
- [`KT-23209`](https://youtrack.jetbrains.com/issue/KT-23209) Compiler throwing frontend exception
- [`KT-23589`](https://youtrack.jetbrains.com/issue/KT-23589) Report a warning on local annotation classes
- [`KT-23760`](https://youtrack.jetbrains.com/issue/KT-23760) Unable to implement common interface with fun member function with typealiased parameter
### Android
- [`KT-23244`](https://youtrack.jetbrains.com/issue/KT-23244) Option to Disable View Binding generation in Kotlin Android Extensions Plugin
### IDE
- [`KT-8407`](https://youtrack.jetbrains.com/issue/KT-8407) TestNG: running tests from context creates new run configuration every time
- [`KT-9218`](https://youtrack.jetbrains.com/issue/KT-9218) Searching for compilable files takes too long
- [`KT-15019`](https://youtrack.jetbrains.com/issue/KT-15019) Editor: `args` reference in .kts file is red
- [`KT-18769`](https://youtrack.jetbrains.com/issue/KT-18769) Expand Selection on opening curly brace should select the entire block right away
- [`KT-19055`](https://youtrack.jetbrains.com/issue/KT-19055) Idea hangs on copy-paste big Kotlin files
- [`KT-20605`](https://youtrack.jetbrains.com/issue/KT-20605) Unresolved reference on instance from common module function
- [`KT-20824`](https://youtrack.jetbrains.com/issue/KT-20824) Type mismatch for common function taking a non-mapped Kotlin's expected class from stdlib-common, with actual typealias on JVM
- [`KT-20897`](https://youtrack.jetbrains.com/issue/KT-20897) Can't navigate to declaration after PsiInvalidElementAccessException exception
- [`KT-22527`](https://youtrack.jetbrains.com/issue/KT-22527) Kotlin UAST does not evaluate values inside delegation expressions
- [`KT-22868`](https://youtrack.jetbrains.com/issue/KT-22868) Implementing an `expected class` declaration using `actual typealias` produces "good code that is red"
- [`KT-22922`](https://youtrack.jetbrains.com/issue/KT-22922) Override Members should add experimental annotation when required
- [`KT-23384`](https://youtrack.jetbrains.com/issue/KT-23384) Hotspot in org.jetbrains.kotlin.idea.caches.resolve.IDELightClassGenerationSupport.getKotlinInternalClasses(FqName, GlobalSearchScope) IDELightClassGenerationSupport.kt ?
- [`KT-23408`](https://youtrack.jetbrains.com/issue/KT-23408) Don't render @NonNull and @Nullable annotations in parameter info for Java methods
- [`KT-23557`](https://youtrack.jetbrains.com/issue/KT-23557) Expression Bodies should have implicit `return` in Uast
- [`KT-23745`](https://youtrack.jetbrains.com/issue/KT-23745) Unable to implement common interface
- [`KT-23746`](https://youtrack.jetbrains.com/issue/KT-23746) Logger$EmptyThrowable "[kts] cannot find a valid script definition annotation on the class class ScriptTemplateWithArgs" with LivePlugin enabled
- [`KT-23975`](https://youtrack.jetbrains.com/issue/KT-23975) Move Kotlin internal actions under Idea Internal actions menu
- [`KT-24268`](https://youtrack.jetbrains.com/issue/KT-24268) Other main menu item
- [`KT-24438`](https://youtrack.jetbrains.com/issue/KT-24438) ISE “The provided plugin org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar is not compatible with this version of compiler” after rebuilding simple Gradle-based project via JPS.
#### IDE. Configuration
- [`KT-10935`](https://youtrack.jetbrains.com/issue/KT-10935) Add menu entry to create new kotlin .kts scripts
- [`KT-20511`](https://youtrack.jetbrains.com/issue/KT-20511) Library added from maven (using IDEA UI) is not detected as Kotlin/JS library (since type="repository")
- [`KT-20665`](https://youtrack.jetbrains.com/issue/KT-20665) Kotlin Gradle script created by New Project/Module wizard fails with Gradle 4.1+
- [`KT-21844`](https://youtrack.jetbrains.com/issue/KT-21844) Create Kotlin class dialog: make class abstract automatically
- [`KT-22305`](https://youtrack.jetbrains.com/issue/KT-22305) Language and API versions of Kotlin compiler are “Latest” by default in some ways of creating new project
- [`KT-23261`](https://youtrack.jetbrains.com/issue/KT-23261) New MPP design: please show popup with error message if module name is not set
- [`KT-23638`](https://youtrack.jetbrains.com/issue/KT-23638) Kotlin plugin breaks project opening for PhpStorm/WebStorm
- [`KT-23658`](https://youtrack.jetbrains.com/issue/KT-23658) Unclear options “Gradle” and “Gradle (Javascript)” on configuring Kotlin in Gradle- and Maven-based projects
- [`KT-23845`](https://youtrack.jetbrains.com/issue/KT-23845) IntelliJ Maven Plugin does not pass javaParameters option to Kotlin facet
- [`KT-23980`](https://youtrack.jetbrains.com/issue/KT-23980) Move "Update Channel" from "Configure Kotlin Plugin Updates" to settings
- [`KT-24504`](https://youtrack.jetbrains.com/issue/KT-24504) Existent JPS-based Kotlin/JS module is converted to new format, while New Project wizard and facet manipulations still create old format
#### IDE. Debugger
- [`KT-23886`](https://youtrack.jetbrains.com/issue/KT-23886) Both java and kotlin breakpoints in kotlin files
- [`KT-24136`](https://youtrack.jetbrains.com/issue/KT-24136) Debugger: update drop-down menu for the line with lambdas
#### IDE. Editing
- [`KT-2582`](https://youtrack.jetbrains.com/issue/KT-2582) When user inputs triple quote, add matching triple quote automatically
- [`KT-5206`](https://youtrack.jetbrains.com/issue/KT-5206) Long lists of arguments are not foldable
- [`KT-23457`](https://youtrack.jetbrains.com/issue/KT-23457) Auto-import and Import quick fix do not suggest classes from common module [Common test can't find class with word `Abstract` in name.]
- [`KT-23235`](https://youtrack.jetbrains.com/issue/KT-23235) Super slow editing with auto imports enabled
#### IDE. Gradle
- [`KT-23234`](https://youtrack.jetbrains.com/issue/KT-23234) Test names for tests containing inner classes are sporadically reported to teamcity runs.
- [`KT-23383`](https://youtrack.jetbrains.com/issue/KT-23383) Optional plugin dependency for kotlin gradle plugin 'java' subsystem dependent features
- [`KT-22588`](https://youtrack.jetbrains.com/issue/KT-22588) Resolver for 'project source roots and libraries for platform JVM' does not know how to resolve on Gradle Kotlin DSL project without Java and Kotlin
- [`KT-23616`](https://youtrack.jetbrains.com/issue/KT-23616) Synchronize script dependencies not at Gradle Sync
- [`KT-24444`](https://youtrack.jetbrains.com/issue/KT-24444) Do not store proxy objects from Gradle importer in the project model
- [`KT-24586`](https://youtrack.jetbrains.com/issue/KT-24586) MVNFE “Cannot resolve external dependency org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.41 because no repositories are defined.” on creating Gradle project with Kotlin only (probably due to lack of repositories block)
- [`KT-24671`](https://youtrack.jetbrains.com/issue/KT-24671) dependencies missed in buildscript block after creating new Gradle-based project in 173 IDEA
#### IDE. Inspections and Intentions
##### New Features
- [`KT-7822`](https://youtrack.jetbrains.com/issue/KT-7822) Convert foreach to for loop should place caret on the variable declaration
- [`KT-9943`](https://youtrack.jetbrains.com/issue/KT-9943) Quick fix/Intention to indent a raw string
- [`KT-15063`](https://youtrack.jetbrains.com/issue/KT-15063) Inspection for coroutine: unused Deferred result
- [`KT-16085`](https://youtrack.jetbrains.com/issue/KT-16085) Inspection "main should return Unit"
- [`KT-20305`](https://youtrack.jetbrains.com/issue/KT-20305) Inspection: Refactor sealed sub-class to object
- [`KT-21413`](https://youtrack.jetbrains.com/issue/KT-21413) Missing inspection: parentheses can be deleted when the only constructor parameter is a function not existing
- [`KT-23137`](https://youtrack.jetbrains.com/issue/KT-23137) Intention for converting to block comment and vise versa
- [`KT-23266`](https://youtrack.jetbrains.com/issue/KT-23266) Add intention(s) to put arguments / parameters on one line
- [`KT-23419`](https://youtrack.jetbrains.com/issue/KT-23419) Intention to replace vararg with array and vice versa
- [`KT-23617`](https://youtrack.jetbrains.com/issue/KT-23617) Add inspection: redundant internal in local anonymous object / class
- [`KT-23775`](https://youtrack.jetbrains.com/issue/KT-23775) IntelliJ plugin: improve "accessor call that can be replaced with property"
- [`KT-24235`](https://youtrack.jetbrains.com/issue/KT-24235) Inspection to replace async.await with withContext
- [`KT-24263`](https://youtrack.jetbrains.com/issue/KT-24263) Add `Make variable immutable` quickfix for const
- [`KT-24433`](https://youtrack.jetbrains.com/issue/KT-24433) Inspection for coroutines: unused async result
##### Performance Improvements
- [`KT-23566`](https://youtrack.jetbrains.com/issue/KT-23566) "Can be private" works on ResolutionResultsCache.kt (from Kotlin project) enormously slow
##### Fixes
- [`KT-6364`](https://youtrack.jetbrains.com/issue/KT-6364) Incorrect quick-fixes are suggested for nullable extension function call
- [`KT-11156`](https://youtrack.jetbrains.com/issue/KT-11156) Incorrect highlighting for nested class in "Redundant SAM-constructor" inspection
- [`KT-11427`](https://youtrack.jetbrains.com/issue/KT-11427) "Replace if with when" does not take break / continue into account
- [`KT-11740`](https://youtrack.jetbrains.com/issue/KT-11740) Invert if condition intention should not remove line breaks
- [`KT-12042`](https://youtrack.jetbrains.com/issue/KT-12042) "Merge with next when" is not applicable when the statements delimited by semicolon or comment
- [`KT-12168`](https://youtrack.jetbrains.com/issue/KT-12168) "Remove explicit type specification" intention produce incompilable code in case of function type
- [`KT-14391`](https://youtrack.jetbrains.com/issue/KT-14391) RemoveUnnecessaryParenthesesIntention lost comment on closing parenthesis
- [`KT-14556`](https://youtrack.jetbrains.com/issue/KT-14556) Quickfix to suggest use of spread operator does not work with mapOf
- [`KT-15195`](https://youtrack.jetbrains.com/issue/KT-15195) Redundant parentheses shouldn't be reported if lambda is not on the same line
- [`KT-16770`](https://youtrack.jetbrains.com/issue/KT-16770) Change type of function quickfix does not propose most idiomatic solutions
- [`KT-19629`](https://youtrack.jetbrains.com/issue/KT-19629) "Convert to primary constructor" quick fix should not move `init{...}` section down
- [`KT-20123`](https://youtrack.jetbrains.com/issue/KT-20123) Kotlin Gradle script: “Refactoring cannot be performed. Cannot modify build.gradle.kts” for some refactorings and intentions
- [`KT-20332`](https://youtrack.jetbrains.com/issue/KT-20332) Unused property declaration suppression by annotation doesn't work if annotation is targeted to getter
- [`KT-21878`](https://youtrack.jetbrains.com/issue/KT-21878) "arrayOf() call can be replaced by array litteral [...]" quick fix inserts extra parentheses
- [`KT-22092`](https://youtrack.jetbrains.com/issue/KT-22092) Intention "Specify return type explicitly": Propose types from overriden declarations
- [`KT-22615`](https://youtrack.jetbrains.com/issue/KT-22615) "Replace with" intention does not work for equal names
- [`KT-22632`](https://youtrack.jetbrains.com/issue/KT-22632) Gutter icon "go to actual declaration" is absent for enum values on actual side
- [`KT-22741`](https://youtrack.jetbrains.com/issue/KT-22741) Wrong suggestion for `Replace 'if' expression with elvis expression`
- [`KT-22831`](https://youtrack.jetbrains.com/issue/KT-22831) Inspection for converting to elvis operator does not work for local vars
- [`KT-22860`](https://youtrack.jetbrains.com/issue/KT-22860) "Add annotation target" quick fix does not take into account existent annotations in Java source
- [`KT-22918`](https://youtrack.jetbrains.com/issue/KT-22918) Create interface quickfix is missing 'current class' container
- [`KT-23133`](https://youtrack.jetbrains.com/issue/KT-23133) "Remove redundant calls of the conversion method" wrongly shown for Boolan to Int conversion
- [`KT-23167`](https://youtrack.jetbrains.com/issue/KT-23167) Report "use expression body" also on left brace
- [`KT-23194`](https://youtrack.jetbrains.com/issue/KT-23194) Inspection "map.put() should be converted to assignment" leads to red code in case of labled return
- [`KT-23303`](https://youtrack.jetbrains.com/issue/KT-23303) "Might be const" inspection does not check explicit type specification
- [`KT-23320`](https://youtrack.jetbrains.com/issue/KT-23320) Quick fix to add constructor invocation doesn't work for sealed classes
- [`KT-23321`](https://youtrack.jetbrains.com/issue/KT-23321) Intention to move type to separate file shouldn't be available for sealed classes
- [`KT-23346`](https://youtrack.jetbrains.com/issue/KT-23346) Lift Assignment quick fix incorrectly processes block assignments
- [`KT-23377`](https://youtrack.jetbrains.com/issue/KT-23377) Simplify boolean expression produces incorrect results when mixing nullable and non-nullable variables
- [`KT-23465`](https://youtrack.jetbrains.com/issue/KT-23465) False positive `suspicious callable reference` on lambda invoke with parameters
- [`KT-23511`](https://youtrack.jetbrains.com/issue/KT-23511) "Remove parameter" quick fix makes generic function call incompilable when type could be inferred from removed parameter only
- [`KT-23513`](https://youtrack.jetbrains.com/issue/KT-23513) "Remove parameter" quick fix makes caret jump to the top of the editor
- [`KT-23559`](https://youtrack.jetbrains.com/issue/KT-23559) Wrong hint text for "assignment can be replaced with operator assignment"
- [`KT-23608`](https://youtrack.jetbrains.com/issue/KT-23608) AE “Failed to create expression from text” after applying quick fix “Convert too long character literal to string”
- [`KT-23620`](https://youtrack.jetbrains.com/issue/KT-23620) False positive `Redundant Companion reference` on calling object from companion
- [`KT-23634`](https://youtrack.jetbrains.com/issue/KT-23634) 'Add use-site target' intention drops annotation arguments
- [`KT-23753`](https://youtrack.jetbrains.com/issue/KT-23753) "Remove variable" quick fix should not remove comment
- [`KT-23756`](https://youtrack.jetbrains.com/issue/KT-23756) Bogus "Might be const" warning in object expression
- [`KT-23778`](https://youtrack.jetbrains.com/issue/KT-23778) "Convert function to property" intention shows broken warning
- [`KT-23796`](https://youtrack.jetbrains.com/issue/KT-23796) "Create extension function/property" quick fix suggests one for nullable type while creates for not-null
- [`KT-23801`](https://youtrack.jetbrains.com/issue/KT-23801) "Convert to constructor" (IntelliJ) quick fix uses wrong use-site target for annotating properties
- [`KT-23977`](https://youtrack.jetbrains.com/issue/KT-23977) wrong hint Unit redundant
- [`KT-24066`](https://youtrack.jetbrains.com/issue/KT-24066) 'Remove redundant Unit' false positive when Unit is returned as Any
- [`KT-24165`](https://youtrack.jetbrains.com/issue/KT-24165) @Deprecated ReplaceWith Constant gets replaced with nothing
- [`KT-24207`](https://youtrack.jetbrains.com/issue/KT-24207) Add parameter intent/red bulb should use auto casted type.
- [`KT-24215`](https://youtrack.jetbrains.com/issue/KT-24215) ReplaceWith produces broken code for lambda following default parameter
#### IDE. Multiplatform
- [`KT-20406`](https://youtrack.jetbrains.com/issue/KT-20406) Overload resolution ambiguity in IDE on expect class / actual typealias from kotlin-stdlib-common / kotlin-stdlib
- [`KT-24316`](https://youtrack.jetbrains.com/issue/KT-24316) Missing dependencies in Kotlin MPP when using gradle composite builds
#### IDE. Navigation
- [`KT-7622`](https://youtrack.jetbrains.com/issue/KT-7622) Searching usages of a field/constructor parameter in a private class seems to scan through the whole project
- [`KT-23182`](https://youtrack.jetbrains.com/issue/KT-23182) Find Usages checks whether there are unused variables in functions which contain search result candidates
- [`KT-23223`](https://youtrack.jetbrains.com/issue/KT-23223) Navigate to actual declaration from actual usage
#### IDE. Refactorings
- [`KT-12078`](https://youtrack.jetbrains.com/issue/KT-12078) Introduce Variable adds explicit type when invoked on anonymous object
- [`KT-15517`](https://youtrack.jetbrains.com/issue/KT-15517) Change signature refactoring shows confusing warning dialog
- [`KT-22387`](https://youtrack.jetbrains.com/issue/KT-22387) Change signature reports "Type cannot be resolved" for class from different package
- [`KT-22669`](https://youtrack.jetbrains.com/issue/KT-22669) Refactor / Copy Kotlin source to plain text causes CCE: "PsiPlainTextFileImpl cannot be cast to KtFile" at CopyKotlinDeclarationsHandler$doCopy$2$1$1.invoke()
- [`KT-22888`](https://youtrack.jetbrains.com/issue/KT-22888) Rename completion cuts off all characters except letters from existent name
- [`KT-23298`](https://youtrack.jetbrains.com/issue/KT-23298) AE: "2 declarations in null..." on rename of a field to `object` or `class`
- [`KT-23563`](https://youtrack.jetbrains.com/issue/KT-23563) null by org.jetbrains.kotlin.idea.refactoring.rename.KotlinMemberInplaceRenameHandler$RenamerImpl exception on trying in-place Rename of non-scratch functions
- [`KT-23613`](https://youtrack.jetbrains.com/issue/KT-23613) Kotlin safe delete processor handles java code when it should not
- [`KT-23644`](https://youtrack.jetbrains.com/issue/KT-23644) Named parameters in generated Kotlin Annotations
- [`KT-23714`](https://youtrack.jetbrains.com/issue/KT-23714) Add Parameter quickfix not working when the called method is in java.
- [`KT-23838`](https://youtrack.jetbrains.com/issue/KT-23838) Do not search for usages in other files when renaming local variable
- [`KT-24069`](https://youtrack.jetbrains.com/issue/KT-24069) 'Create from usage' doesn't use type info with smart casts
#### IDE. Scratch
- [`KT-6928`](https://youtrack.jetbrains.com/issue/KT-6928) Support Kotlin scratch files
- [`KT-23441`](https://youtrack.jetbrains.com/issue/KT-23441) Scratch options reset on IDE restart
- [`KT-23480`](https://youtrack.jetbrains.com/issue/KT-23480) java.util.NoSuchElementException: "Collection contains no element matching the predicate" on run of a scratch file with unresolved function parameter
- [`KT-23587`](https://youtrack.jetbrains.com/issue/KT-23587) Scratch: references from scratch file aren't taken into account
- [`KT-24016`](https://youtrack.jetbrains.com/issue/KT-24016) Make long scratch output lines readable
- [`KT-24315`](https://youtrack.jetbrains.com/issue/KT-24315) Checkbox labels aren't aligned in scratch panel
- [`KT-24636`](https://youtrack.jetbrains.com/issue/KT-24636) Run Scratch when there are compilation errors in module
#### Tools. J2K
- [`KT-22989`](https://youtrack.jetbrains.com/issue/KT-22989) Exception "Assertion failed: Refactorings should be invoked inside transaction" on creating UI Component/Notification
### Libraries
- [`KT-10456`](https://youtrack.jetbrains.com/issue/KT-10456) Common Int.toString(radix: Int) method
- [`KT-22298`](https://youtrack.jetbrains.com/issue/KT-22298) Improve docs for Array.copyOf(newSize: Int)
- [`KT-22400`](https://youtrack.jetbrains.com/issue/KT-22400) coroutineContext shall be in kotlin.coroutines.experimental package
- [`KT-23356`](https://youtrack.jetbrains.com/issue/KT-23356) Cross-platform function to convert CharArray slice to String
- [`KT-23920`](https://youtrack.jetbrains.com/issue/KT-23920) CharSequence.trimEnd calls substring instead of subSequence
- [`KT-24353`](https://youtrack.jetbrains.com/issue/KT-24353) Add support for junit 5 in kotlin.test
- [`KT-24371`](https://youtrack.jetbrains.com/issue/KT-24371) Invalid @returns tag does not display in Android Studio popup properly
### Gradle plugin
- [`KT-20214`](https://youtrack.jetbrains.com/issue/KT-20214) NoClassDefFound from Gradle (should report missing tools.jar)
- [`KT-20608`](https://youtrack.jetbrains.com/issue/KT-20608) Cannot reference operator overloads across submodules (.kotlin_module not loaded when a module name has a slash)
- [`KT-22431`](https://youtrack.jetbrains.com/issue/KT-22431) Inter-project incremental compilation does not work with Android plugin 2.3+
- [`KT-22510`](https://youtrack.jetbrains.com/issue/KT-22510) Common sources aren't added when compiling custom source set with Gradle multiplatform plugin
- [`KT-22623`](https://youtrack.jetbrains.com/issue/KT-22623) Kotlin JVM tasks in independent projects are not executed in parallel with Gradle 4.2+ and Kotlin 1.2.20+
- [`KT-23092`](https://youtrack.jetbrains.com/issue/KT-23092) Gradle plugin for MPP common modules should not remove the 'compileJava' task from `project.tasks`
- [`KT-23574`](https://youtrack.jetbrains.com/issue/KT-23574) 'archivesBaseName' does not affect module name in common modules
- [`KT-23719`](https://youtrack.jetbrains.com/issue/KT-23719) Incorrect Gradle Warning for expectedBy in kotlin-platform-android module
- [`KT-23878`](https://youtrack.jetbrains.com/issue/KT-23878) Kapt: Annotation processors are run when formatting is changed
- [`KT-24420`](https://youtrack.jetbrains.com/issue/KT-24420) Kapt plugin: Kapt task has overlapping outputs (and inputs) with Gradle's JavaCompile task
- [`KT-24440`](https://youtrack.jetbrains.com/issue/KT-24440) Gradle daemon OOM due to function descriptors stuck forever
### Tools. kapt
- [`KT-23286`](https://youtrack.jetbrains.com/issue/KT-23286) kapt + nonascii = weird pathes
- [`KT-23427`](https://youtrack.jetbrains.com/issue/KT-23427) kapt: for element with multiple annotations, annotation values erroneously use default when first annotation uses default
- [`KT-23721`](https://youtrack.jetbrains.com/issue/KT-23721) Warning informing user that 'tools.jar' is absent in the plugin classpath is not show when there is also an error
- [`KT-23898`](https://youtrack.jetbrains.com/issue/KT-23898) Kapt: Do now show a warning for APs from 'annotationProcessor' configuration also declared in 'kapt' configuration
- [`KT-23964`](https://youtrack.jetbrains.com/issue/KT-23964) Kotlin Gradle plugin does not define inputs and outputs of annotation processors
## 1.2.41
### Compiler Fixes
- [`KT-23901`](https://youtrack.jetbrains.com/issue/KT-23901) Incremental compilation fails on Java 9
- [`KT-23931`](https://youtrack.jetbrains.com/issue/KT-23931) Exception on optimizing eternal loops
- [`KT-23900`](https://youtrack.jetbrains.com/issue/KT-23900) Exception on some cases with nested arrays
- [`KT-23809`](https://youtrack.jetbrains.com/issue/KT-23809) Exception on processing complex hierarchies with `suspend` functions when `-Xdump-declarations-to` is active
### Other
- [`KT-23973`](https://youtrack.jetbrains.com/issue/KT-23973) New compiler behavior lead to ambiguous mappings in Spring Boot temporarily reverted
## 1.2.40
### Compiler
#### New Features
- [`KT-22703`](https://youtrack.jetbrains.com/issue/KT-22703) Allow expect/actual annotation constructors to have default values
- [`KT-19159`](https://youtrack.jetbrains.com/issue/KT-19159) Support `crossinline` lambda parameters of `suspend` function type
- [`KT-21913`](https://youtrack.jetbrains.com/issue/KT-21913) Support default arguments for expected declarations
- [`KT-19120`](https://youtrack.jetbrains.com/issue/KT-19120) Provide extra compiler arguments in `ScriptTemplateDefinition`
- [`KT-19415`](https://youtrack.jetbrains.com/issue/KT-19415) Introduce `@JvmDefault` annotation
- [`KT-21515`](https://youtrack.jetbrains.com/issue/KT-21515) Restrict visibility of classifiers inside `companion object`s
#### Performance Improvements
- [`KT-10057`](https://youtrack.jetbrains.com/issue/KT-10057) Use `lcmp` instruction instead of `kotlin/jvm/internal/Intrinsics.compare`
- [`KT-14258`](https://youtrack.jetbrains.com/issue/KT-14258) Suboptimal codegen for private fieldaccess to private field in companion object
- [`KT-18731`](https://youtrack.jetbrains.com/issue/KT-18731) `==` between enums should use reference equality, not `Intrinsics.areEqual()`.
- [`KT-22714`](https://youtrack.jetbrains.com/issue/KT-22714) Unnecessary checkcast to array of object from an array of specific type
- [`KT-5177`](https://youtrack.jetbrains.com/issue/KT-5177) Optimize code generation for `for` loop with `withIndex()`
- [`KT-19477`](https://youtrack.jetbrains.com/issue/KT-19477) Allow to implement several common modules with a single platform module
- [`KT-21347`](https://youtrack.jetbrains.com/issue/KT-21347) Add compiler warning about using kotlin-stdlib-jre7 or kotlin-stdlib-jre8 artifacts
#### Fixes
- [`KT-16424`](https://youtrack.jetbrains.com/issue/KT-16424) Broken bytecode for nullable generic methods
- [`KT-17171`](https://youtrack.jetbrains.com/issue/KT-17171) `ClassCastException` in case of SAM conversion with `out` variance
- [`KT-19399`](https://youtrack.jetbrains.com/issue/KT-19399) Incorrect bytecode generated for inline functions in some complex cases
- [`KT-21696`](https://youtrack.jetbrains.com/issue/KT-21696) Incorrect warning for use-site target on extension function
- [`KT-22031`](https://youtrack.jetbrains.com/issue/KT-22031) Non-`abstract` expect classes should not have `abstract` members
- [`KT-22260`](https://youtrack.jetbrains.com/issue/KT-22260) Never flag `inline suspend fun` with `NOTHING_TO_INLINE`
- [`KT-22352`](https://youtrack.jetbrains.com/issue/KT-22352) Expect/actual checker can't handle properties and functions with the same name
- [`KT-22652`](https://youtrack.jetbrains.com/issue/KT-22652) Interface with default overrides is not perceived as a SAM
- [`KT-22904`](https://youtrack.jetbrains.com/issue/KT-22904) Incorrect bytecode generated for withIndex iteration on `Array<Int>`
- [`KT-22906`](https://youtrack.jetbrains.com/issue/KT-22906) Invalid class name generated for lambda created from method reference in anonymous object
- [`KT-23044`](https://youtrack.jetbrains.com/issue/KT-23044) Overriden public property with internal setter cannot be found in runtime
- [`KT-23104`](https://youtrack.jetbrains.com/issue/KT-23104) Incorrect code generated for LHS of an intrinsified `in` operator in case of generic type substituted with `Character`
- [`KT-23309`](https://youtrack.jetbrains.com/issue/KT-23309) Minor spelling errors in JVM internal error messages
- [`KT-22001`](https://youtrack.jetbrains.com/issue/KT-22001) JS: compiler crashes on += with "complex" receiver
- [`KT-23239`](https://youtrack.jetbrains.com/issue/KT-23239) JS: Default arguments for non-final member function support is missing for MPP
- [`KT-17091`](https://youtrack.jetbrains.com/issue/KT-17091) Converting to SAM Java type appends non-deterministic hash to class name
- [`KT-21521`](https://youtrack.jetbrains.com/issue/KT-21521) Compilation exception when trying to compile a `suspend` function with `tailrec` keyword
- [`KT-21605`](https://youtrack.jetbrains.com/issue/KT-21605) Cross-inlined coroutine with captured outer receiver creates unverifiable code
- [`KT-21864`](https://youtrack.jetbrains.com/issue/KT-21864) Expect-actual matcher doesn't consider generic upper bounds
- [`KT-21906`](https://youtrack.jetbrains.com/issue/KT-21906) `ACTUAL_MISSING` is reported for actual constructor of non-actual class
- [`KT-21939`](https://youtrack.jetbrains.com/issue/KT-21939) Improve `ACTUAL_MISSING` diagnostics message
- [`KT-22513`](https://youtrack.jetbrains.com/issue/KT-22513) Flaky "JarURLConnection.getUseCaches" NPE during compilation when using compiler plugins
### Libraries
- [`KT-11208`](https://youtrack.jetbrains.com/issue/KT-11208) `readLine()` shouldn't use buffered reader
### IDE
#### New Features
- [`KT-10368`](https://youtrack.jetbrains.com/issue/KT-10368) Run Action for Kotlin Scratch Files
- [`KT-16892`](https://youtrack.jetbrains.com/issue/KT-16892) Shortcut to navigate between header and impl
- [`KT-23005`](https://youtrack.jetbrains.com/issue/KT-23005) Support `prefix`/`suffix` attributes for language injection in Kotlin with annotations and comments
#### Performance Improvements
- [`KT-19484`](https://youtrack.jetbrains.com/issue/KT-19484) KotlinBinaryClassCache retains a lot of memory
- [`KT-23183`](https://youtrack.jetbrains.com/issue/KT-23183) `ConfigureKotlinNotification.getNotificationString()` scans modules with Kotlin files twice
- [`KT-23380`](https://youtrack.jetbrains.com/issue/KT-23380) Improve IDE performance when working with Spring projects
#### Fixes
- [`KT-15482`](https://youtrack.jetbrains.com/issue/KT-15482) `KotlinNullPointerException` in IDE from expected class with nested class
- [`KT-15739`](https://youtrack.jetbrains.com/issue/KT-15739) Internal visibility across common and platform-dependent modules
- [`KT-19025`](https://youtrack.jetbrains.com/issue/KT-19025) Not imported `build.gradle.kts` is all red
- [`KT-19165`](https://youtrack.jetbrains.com/issue/KT-19165) IntelliJ should suggest to reload Gradle projects when `build.gradle.kts` changes
- [`KT-20282`](https://youtrack.jetbrains.com/issue/KT-20282) 'Move statement up' works incorrectly for statement after `finally` block if `try` block contains closure
- [`KT-20521`](https://youtrack.jetbrains.com/issue/KT-20521) Kotlin Gradle script: valid `build.gradle.kts` is red and becomes normal only after reopening the project
- [`KT-20592`](https://youtrack.jetbrains.com/issue/KT-20592) `KotlinNullPointerException`: nested class inside expect / actual interface
- [`KT-21013`](https://youtrack.jetbrains.com/issue/KT-21013) "Move statement up/down" fails for multiline declarations
- [`KT-21420`](https://youtrack.jetbrains.com/issue/KT-21420) `.gradle.kts` editor should do no semantic highlighting until the first successful dependency resolver response
- [`KT-21683`](https://youtrack.jetbrains.com/issue/KT-21683) Language injection: JPAQL. Injection should be present for "query" parameter of `@NamedNativeQueries`
- [`KT-21745`](https://youtrack.jetbrains.com/issue/KT-21745) Warning and quickfix about kotlin-stdlib-jre7/8 -> kotlin-stdlib-jdk7/8 in Maven
- [`KT-21746`](https://youtrack.jetbrains.com/issue/KT-21746) Warning and quickfix about kotlin-stdlib-jre7/8 -> kotlin-stdlib-jdk7/8 in Gradle
- [`KT-21753`](https://youtrack.jetbrains.com/issue/KT-21753) Language injection: SpEL. Not injected for key in `@Caching`
- [`KT-21771`](https://youtrack.jetbrains.com/issue/KT-21771) All annotations in `Annotations.kt` from kotlin-test-js module wrongly have ACTUAL_MISSING
- [`KT-21831`](https://youtrack.jetbrains.com/issue/KT-21831) Opening class from `kotlin-stdlib-jdk8.jar` fails with EE: "Stub list in ... length differs from PSI"
- [`KT-22229`](https://youtrack.jetbrains.com/issue/KT-22229) Kotlin local delegated property Import auto-removed with "Java: Optimize imports on the fly"
- [`KT-22724`](https://youtrack.jetbrains.com/issue/KT-22724) ISE: "psiFile must not be null" at `KotlinNodeJsRunConfigurationProducer.setupConfigurationFromContext()`
- [`KT-22817`](https://youtrack.jetbrains.com/issue/KT-22817) Hitting 'Propagate Parameters' in Change Signature throws `UnsupportedOperationException`
- [`KT-22851`](https://youtrack.jetbrains.com/issue/KT-22851) Apply button is always active on Kotlin compiler settings tab
- [`KT-22858`](https://youtrack.jetbrains.com/issue/KT-22858) Multiplatform: String constructor parameter is reported in Java file of jvm module on creation of a new instance of a class from common module
- [`KT-22865`](https://youtrack.jetbrains.com/issue/KT-22865) Support multiple expectedBy dependencies when importing project from Gradle or Maven
- [`KT-22873`](https://youtrack.jetbrains.com/issue/KT-22873) Common module-based light classes do not see JDK
- [`KT-22874`](https://youtrack.jetbrains.com/issue/KT-22874) Exception on surround with "if else" when resulting if should be wrapped with `()`
- [`KT-22925`](https://youtrack.jetbrains.com/issue/KT-22925) Unable to view Type Hierarchy from constructor call in expression
- [`KT-22926`](https://youtrack.jetbrains.com/issue/KT-22926) Confusing behavior of Type Hierarchy depending on the caret position at superclass constructor
- [`KT-23097`](https://youtrack.jetbrains.com/issue/KT-23097) Enhance multiplatform project wizard
- [`KT-23271`](https://youtrack.jetbrains.com/issue/KT-23271) Warn about using kotlin-stdlib-jre* libs in `dependencyManagement` section in Maven with `eap` and `dev` Kotlin versions
- [`KT-20672`](https://youtrack.jetbrains.com/issue/KT-20672) IDE can't resolve references to elements from files with `@JvmPackageName`
- [`KT-23546`](https://youtrack.jetbrains.com/issue/KT-23546) Variable name auto-completion popup gets in the way
- [`KT-23546`](https://youtrack.jetbrains.com/issue/KT-23546) Do not show duplicated names in variables completion list
- [`KT-19120`](https://youtrack.jetbrains.com/issue/KT-19120) Use script compiler options on script dependencies in the IDE as well
### IDE. Gradle. Script
- [`KT-23228`](https://youtrack.jetbrains.com/issue/KT-23228) Do not highlight `.gradle.kts` files in non-Gradle projects
### IDE. Inspections and Intentions
#### New Features
- [`KT-16382`](https://youtrack.jetbrains.com/issue/KT-16382) Intention to convert `expr.unsafeCast<Type>()` to `expr as Type` and vice versa
- [`KT-20439`](https://youtrack.jetbrains.com/issue/KT-20439) Intentions to add/remove labeled return to last expression in a lambda
- [`KT-22011`](https://youtrack.jetbrains.com/issue/KT-22011) Inspection to report the usage of Java Collections methods on immutable Kotlin Collections
- [`KT-22933`](https://youtrack.jetbrains.com/issue/KT-22933) Intention/inspection to convert Pair constructor to `to` function
- [`KT-19871`](https://youtrack.jetbrains.com/issue/KT-19871) Intentions for specifying use-site targets for an annotation
- [`KT-22971`](https://youtrack.jetbrains.com/issue/KT-22971) Inspection to highlight and remove unnecessary explicit companion object references
#### Fixes
- [`KT-12226`](https://youtrack.jetbrains.com/issue/KT-12226) "Convert concatenation to template" does not process `$` sign as a Char
- [`KT-15858`](https://youtrack.jetbrains.com/issue/KT-15858) "Replace with a `foreach` function call" intention breaks code
- [`KT-16332`](https://youtrack.jetbrains.com/issue/KT-16332) Add braces to 'if' statement intention does not put end-of-line comment properly into braces
- [`KT-17058`](https://youtrack.jetbrains.com/issue/KT-17058) "Create implementations from headers": each implementation gets own file
- [`KT-17306`](https://youtrack.jetbrains.com/issue/KT-17306) Don't report package name mismatch if there's no Java code in the module
- [`KT-19730`](https://youtrack.jetbrains.com/issue/KT-19730) Quickfix for delegated properties boilerplate generation doesn't work on locals
- [`KT-21005`](https://youtrack.jetbrains.com/issue/KT-21005) "Missing KDoc inspection" is broken
- [`KT-21082`](https://youtrack.jetbrains.com/issue/KT-21082) "Create actual declaration" of top-level subclass of expected `sealed class` in the same file as actual declaration of sealed class present
- [`KT-22110`](https://youtrack.jetbrains.com/issue/KT-22110) "Can be joined with assignment" inspection underlining extends into comment
- [`KT-22329`](https://youtrack.jetbrains.com/issue/KT-22329) "Create class" quickfix is not suggested in `when` branch
- [`KT-22428`](https://youtrack.jetbrains.com/issue/KT-22428) Create member function from usage shouldn't present type parameters as options
- [`KT-22492`](https://youtrack.jetbrains.com/issue/KT-22492) "Specify explicit lambda signature" intention is available only on lambda braces
- [`KT-22719`](https://youtrack.jetbrains.com/issue/KT-22719) Incorrect warning 'Redundant semicolon' when having method call before lambda expression
- [`KT-22861`](https://youtrack.jetbrains.com/issue/KT-22861) "Add annotation target" quickfix is not available on annotation with use site target
- [`KT-22862`](https://youtrack.jetbrains.com/issue/KT-22862) "Add annotation target" quickfix does not process existent annotations with use site target
- [`KT-22917`](https://youtrack.jetbrains.com/issue/KT-22917) Update order of containers for `create class` quickfix
- [`KT-22949`](https://youtrack.jetbrains.com/issue/KT-22949) NPE on conversion of `run`/`apply` with explicit lambda signature to `let`/`also`
- [`KT-22950`](https://youtrack.jetbrains.com/issue/KT-22950) Convert stdlib extension function to scoping function works incorrectly in case of explicit lambda signature
- [`KT-22954`](https://youtrack.jetbrains.com/issue/KT-22954) "Sort modifiers" quickfix works incorrectly when method is annotated
- [`KT-22970`](https://youtrack.jetbrains.com/issue/KT-22970) Add explicit this intention/inspection missing for lambda invocation
- [`KT-23109`](https://youtrack.jetbrains.com/issue/KT-23109) "Remove redundant 'if' statement" inspection breaks code with labeled return
- [`KT-23215`](https://youtrack.jetbrains.com/issue/KT-23215) "Add function to supertype" quickfix works incorrectly
- [`KT-14270`](https://youtrack.jetbrains.com/issue/KT-14270) Intentions "Add/Remove braces" should be applied to the statement where caret is if there several nested statements one into another
- [`KT-21743`](https://youtrack.jetbrains.com/issue/KT-21743) Method reference not correctly moved into parentheses
- [`KT-23045`](https://youtrack.jetbrains.com/issue/KT-23045) AE “Failed to create expression from text” on concatenating string with broken quote mark char literal
- [`KT-23046`](https://youtrack.jetbrains.com/issue/KT-23046) CCE ”KtBinaryExpression cannot be cast to KtStringTemplateExpression” on concatenating broken quote mark char literal with string
- [`KT-23227`](https://youtrack.jetbrains.com/issue/KT-23227) "Add annotation target" quickfix is not suggested for `field:` use-site target
### IDE. Refactorings
#### Fixes
- [`KT-13255`](https://youtrack.jetbrains.com/issue/KT-13255) Refactor / Rename: renaming local variable or class to existing name gives no warning
- [`KT-13284`](https://youtrack.jetbrains.com/issue/KT-13284) Refactor / Rename: superfluous imports and FQNs in Java using `@JvmOverloads` functions
- [`KT-13907`](https://youtrack.jetbrains.com/issue/KT-13907) Rename refactoring warns about name conflict if there is function with different signature but the same name
- [`KT-13986`](https://youtrack.jetbrains.com/issue/KT-13986) Full qualified names of classes in comments should be changed after class Move, if comment contains backquotes
- [`KT-14671`](https://youtrack.jetbrains.com/issue/KT-14671) `typealias`: refactor/rename should propose to rename occurrences in comments
- [`KT-15039`](https://youtrack.jetbrains.com/issue/KT-15039) Extra usage is found for a parameter in data class in destructuring construction
- [`KT-15228`](https://youtrack.jetbrains.com/issue/KT-15228) Extract function from inline function should create public function
- [`KT-15302`](https://youtrack.jetbrains.com/issue/KT-15302) Reference to typealias in SAM conversion is not found
- [`KT-16510`](https://youtrack.jetbrains.com/issue/KT-16510) Can't rename quoted identifier `is`
- [`KT-17827`](https://youtrack.jetbrains.com/issue/KT-17827) Refactor / Move corrupts bound references when containing class of member element is changed
- [`KT-19561`](https://youtrack.jetbrains.com/issue/KT-19561) Name conflict warning when renaming method to a name matching an extension method with the same name exists
- [`KT-20178`](https://youtrack.jetbrains.com/issue/KT-20178) Refactor → Rename can't make companion object name empty
- [`KT-22282`](https://youtrack.jetbrains.com/issue/KT-22282) Moving a Kotlin file to another package does not change imports in itself
- [`KT-22482`](https://youtrack.jetbrains.com/issue/KT-22482) Rename refactoring insert qualifier for non related property call
- [`KT-22661`](https://youtrack.jetbrains.com/issue/KT-22661) Refactor/Move: top level field reference is not imported automatically after move to the source root
- [`KT-22678`](https://youtrack.jetbrains.com/issue/KT-22678) Refactor / Copy: "Class uses constructor which will be inaccessible after move" when derived class has a protected constructor
- [`KT-22692`](https://youtrack.jetbrains.com/issue/KT-22692) Refactor/Move: unnecessary curly braces added on moving to a separate file a top level function with a top level field usage
- [`KT-22745`](https://youtrack.jetbrains.com/issue/KT-22745) Refactor/Move inserts FQ function name at the call site if there is a field same named as the function
- [`KT-22747`](https://youtrack.jetbrains.com/issue/KT-22747) Moving top-level function to a different (existing) file doesn't update references from Java
- [`KT-22751`](https://youtrack.jetbrains.com/issue/KT-22751) Refactor/Rename: type alias name clash is not reported
- [`KT-22769`](https://youtrack.jetbrains.com/issue/KT-22769) Refactor/Move: there is no warning on moving sealed class or its inheritors to another file
- [`KT-22771`](https://youtrack.jetbrains.com/issue/KT-22771) Refactor/Move: there is no warning on moving nested class to another class with stricter visibility
- [`KT-22812`](https://youtrack.jetbrains.com/issue/KT-22812) Refactor/Rename extension functions incorrectly conflicts with other extension functions
- [`KT-23065`](https://youtrack.jetbrains.com/issue/KT-23065) Refactor/Move: Specify the warning message on moving sealed class inheritors without moving the sealed class itself
### IDE. Script
- [`KT-22647`](https://youtrack.jetbrains.com/issue/KT-22647) Run script Action in IDE should use Kotlin compiler from the IDE plugin
- [`KT-18930`](https://youtrack.jetbrains.com/issue/KT-18930) IDEA is unstable With Gradle Kotlin DSL
- [`KT-21042`](https://youtrack.jetbrains.com/issue/KT-21042) Gradle Script Kotlin project is full-red
- [`KT-11618`](https://youtrack.jetbrains.com/issue/KT-11618) Running .kts file from IntelliJ IDEA doesn't allow to import classes in other files which are also part of the project
### IDE. Debugger
- [`KT-22205`](https://youtrack.jetbrains.com/issue/KT-22205) Breakpoints won't work for Kotlin testing with JUnit
### JavaScript
- [`KT-22019`](https://youtrack.jetbrains.com/issue/KT-22019) Fix wrong list sorting order
### Tools. CLI
- [`KT-22777`](https://youtrack.jetbrains.com/issue/KT-22777) Unstable language version setting has no effect when attached runtime has lower version
### Tools. Gradle
- [`KT-22824`](https://youtrack.jetbrains.com/issue/KT-22824) `expectedBy` dependency should be expressed as `compile` dependency in POM
- [`KT-15371`](https://youtrack.jetbrains.com/issue/KT-15371) Multiplatform: setting free compiler args can break build
- [`KT-22864`](https://youtrack.jetbrains.com/issue/KT-22864) Allow multiple expectedBy configuration dependencies in Gradle
- [`KT-22895`](https://youtrack.jetbrains.com/issue/KT-22895) 'kotlin-runtime' library is missing in the compiler classpath sometimes
- [`KT-23085`](https://youtrack.jetbrains.com/issue/KT-23085) Use proper names for the Gradle task inputs/outputs added at runtime
- [`KT-23694`](https://youtrack.jetbrains.com/issue/KT-23694) Fix parallel build in Kotlin IC invalid KotlinCoreEnvironment disposal
### Tools. Android
- Android Extensions: Support fragments from kotlinx package;
### Tools. Incremental Compile
- [`KT-20516`](https://youtrack.jetbrains.com/issue/KT-20516) "Unresolved reference" when project declares same class as its dependency
- [`KT-22542`](https://youtrack.jetbrains.com/issue/KT-22542) "Source file or directory not found" for incremental compilation with Kobalt
- [`KT-23165`](https://youtrack.jetbrains.com/issue/KT-23165) Incremental compilation is sometimes broken after moving one class
### Tools. JPS
- [`KT-16091`](https://youtrack.jetbrains.com/issue/KT-16091) Incremental compilation ignores changes in Java static field
- [`KT-22995`](https://youtrack.jetbrains.com/issue/KT-22995) EA-91869 - NA: `LookupStorage.<init>`
### Tools. kapt
- [`KT-21735`](https://youtrack.jetbrains.com/issue/KT-21735) Kapt cache was not cleared sometimes
### Tools. REPL
- [`KT-21611`](https://youtrack.jetbrains.com/issue/KT-21611) REPL: Empty lines should be ignored
## 1.2.30
### Android

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.incremental.storage
import org.jetbrains.kotlin.utils.keysToMap
import java.io.File
internal class FileToIdMap(file: File) : BasicMap<File, Int>(file, FileKeyDescriptor, IntExternalizer) {
@@ -34,5 +33,12 @@ internal class FileToIdMap(file: File) : BasicMap<File, Int>(file, FileKeyDescri
storage.remove(file)
}
fun toMap(): Map<File, Int> = storage.keys.keysToMap { storage[it]!! }
fun toMap(): Map<File, Int> {
val result = HashMap<File, Int>()
for (key in storage.keys) {
val value = storage[key] ?: continue
result[key] = value
}
return result
}
}

View File

@@ -12,7 +12,7 @@ import proguard.gradle.ProGuardTask
buildscript {
extra["defaultSnapshotVersion"] = "1.2-SNAPSHOT"
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.2.50-dev-880", onlySuccessBootstrap = false))
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.2.51-eap-115", projectExtId = "Kotlin_1250_Compiler", onlySuccessBootstrap = false))
val mirrorRepo: String? = findProperty("maven.repository.mirror")?.toString()
@@ -22,7 +22,7 @@ buildscript {
"https://jcenter.bintray.com/",
"https://plugins.gradle.org/m2",
"http://dl.bintray.com/kotlin/kotlinx",
"https://repo.gradle.org/gradle/libs-releases-local", // for native-platform
"https://repo.gradle.org/gradle/ext-releases-local", // for native-platform
"https://jetbrains.bintray.com/intellij-third-party-dependencies", // for jflex
"https://dl.bintray.com/jetbrains/markdown" // for org.jetbrains:markdown
)
@@ -48,6 +48,15 @@ plugins {
id("jps-compatible")
}
pill {
excludedDirs(
"out",
"buildSrc/build",
"buildSrc/prepare-deps/android-dx/build",
"buildSrc/prepare-deps/intellij-sdk/build"
)
}
buildScan {
setTermsOfServiceUrl("https://gradle.com/terms-of-service")
setTermsOfServiceAgree("yes")
@@ -223,6 +232,7 @@ val coreLibProjects = listOf(
":kotlin-test:kotlin-test-common",
":kotlin-test:kotlin-test-jvm",
":kotlin-test:kotlin-test-junit",
":kotlin-test:kotlin-test-junit5",
":kotlin-test:kotlin-test-testng",
":kotlin-test:kotlin-test-js",
":kotlin-reflect"
@@ -565,28 +575,13 @@ val zipPlugin by task<Zip> {
val cidrPlugin by task<Copy> {
dependsOn(ideaPlugin)
into(cidrPluginDir)
from(ideaPluginDir) {
exclude("lib/kotlin-plugin.jar")
exclude("lib/uast-kotlin.jar")
exclude("lib/uast-kotlin-ide.jar")
exclude("lib/android-ide.jar")
exclude("lib/android-output-parser-ide.jar")
exclude("lib/android-extensions-ide.jar")
exclude("lib/android-extensions-compiler.jar")
exclude("lib/kapt3-idea.jar")
exclude("lib/j2k.jar")
exclude("lib/jps-ide.jar")
exclude("lib/jps/**")
exclude("kotlinc/**")
exclude("lib/maven-ide.jar")
}
from(ideaPluginDir) { exclude("lib/kotlin-plugin.jar") }
from(cidrKotlinPlugin) { into("lib") }
}
val zipCidrPlugin by task<Zip> {
val destPath = project.findProperty("pluginZipPath") as String?
?: "$distDir/artifacts/kotlin-plugin-$kotlinVersion-CIDR.zip"
?: "$distDir/artifacts/kotlin-plugin-$kotlinVersion-CIDR"
val destFile = File(destPath)
destinationDir = destFile.parentFile

View File

@@ -12,7 +12,7 @@ import proguard.gradle.ProGuardTask
buildscript {
extra["defaultSnapshotVersion"] = "1.2-SNAPSHOT"
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.2.50-dev-880", onlySuccessBootstrap = false))
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.2.50-eap-85", projectExtId = "Kotlin_1250_Compiler", onlySuccessBootstrap = false))
val mirrorRepo: String? = findProperty("maven.repository.mirror")?.toString()
@@ -22,7 +22,7 @@ buildscript {
"https://jcenter.bintray.com/",
"https://plugins.gradle.org/m2",
"http://dl.bintray.com/kotlin/kotlinx",
"https://repo.gradle.org/gradle/libs-releases-local", // for native-platform
"https://repo.gradle.org/gradle/ext-releases-local", // for native-platform
"https://jetbrains.bintray.com/intellij-third-party-dependencies", // for jflex
"https://dl.bintray.com/jetbrains/markdown" // for org.jetbrains:markdown
)
@@ -48,6 +48,15 @@ plugins {
id("jps-compatible")
}
pill {
excludedDirs(
"out",
"buildSrc/build",
"buildSrc/prepare-deps/android-dx/build",
"buildSrc/prepare-deps/intellij-sdk/build"
)
}
buildScan {
setTermsOfServiceUrl("https://gradle.com/terms-of-service")
setTermsOfServiceAgree("yes")
@@ -222,6 +231,7 @@ val coreLibProjects = listOf(
":kotlin-test:kotlin-test-common",
":kotlin-test:kotlin-test-jvm",
":kotlin-test:kotlin-test-junit",
":kotlin-test:kotlin-test-junit5",
":kotlin-test:kotlin-test-testng",
":kotlin-test:kotlin-test-js",
":kotlin-reflect"
@@ -564,28 +574,13 @@ val zipPlugin by task<Zip> {
val cidrPlugin by task<Copy> {
dependsOn(ideaPlugin)
into(cidrPluginDir)
from(ideaPluginDir) {
exclude("lib/kotlin-plugin.jar")
exclude("lib/uast-kotlin.jar")
exclude("lib/uast-kotlin-ide.jar")
exclude("lib/android-ide.jar")
exclude("lib/android-output-parser-ide.jar")
exclude("lib/android-extensions-ide.jar")
exclude("lib/android-extensions-compiler.jar")
exclude("lib/kapt3-idea.jar")
exclude("lib/j2k.jar")
exclude("lib/jps-ide.jar")
exclude("lib/jps/**")
exclude("kotlinc/**")
exclude("lib/maven-ide.jar")
}
from(ideaPluginDir) { exclude("lib/kotlin-plugin.jar") }
from(cidrKotlinPlugin) { into("lib") }
}
val zipCidrPlugin by task<Zip> {
val destPath = project.findProperty("pluginZipPath") as String?
?: "$distDir/artifacts/kotlin-plugin-$kotlinVersion-CIDR.zip"
?: "$distDir/artifacts/kotlin-plugin-$kotlinVersion-CIDR"
val destFile = File(destPath)
destinationDir = destFile.parentFile

View File

@@ -33,9 +33,9 @@ plugins {
gradlePlugin {
(plugins) {
"jps-compatible-base" {
id = "jps-compatible-base"
implementationClass = "org.jetbrains.kotlin.pill.JpsCompatibleBasePlugin"
"pill-configurable" {
id = "pill-configurable"
implementationClass = "org.jetbrains.kotlin.pill.PillConfigurablePlugin"
}
"jps-compatible" {
id = "jps-compatible"
@@ -68,7 +68,7 @@ repositories {
extra["buildSrcKotlinRepo"]?.let {
maven(url = it)
}
maven(url = "https://repo.gradle.org/gradle/libs-releases-local") // for native-platform
maven(url = "https://repo.gradle.org/gradle/ext-releases-local") // for native-platform
jcenter()
}

View File

@@ -1,94 +0,0 @@
buildscript {
val buildSrcKotlinVersion: String by extra(findProperty("buildSrc.kotlin.version")?.toString() ?: embeddedKotlinVersion)
val buildSrcKotlinRepo: String? by extra(findProperty("buildSrc.kotlin.repo") as String?)
extra["versions.shadow"] = "2.0.2"
extra["versions.native-platform"] = "0.14"
repositories {
buildSrcKotlinRepo?.let {
maven(url = it)
}
}
dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$buildSrcKotlinVersion")
classpath("org.jetbrains.kotlin:kotlin-sam-with-receiver:$buildSrcKotlinVersion")
}
}
logger.info("buildSrcKotlinVersion: " + extra["buildSrcKotlinVersion"])
logger.info("buildSrc kotlin compiler version: " + org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION)
logger.info("buildSrc stdlib version: " + KotlinVersion.CURRENT)
apply {
plugin("kotlin")
plugin("kotlin-sam-with-receiver")
}
plugins {
`kotlin-dsl`
`java-gradle-plugin`
}
gradlePlugin {
(plugins) {
"jps-compatible-base" {
id = "jps-compatible-base"
implementationClass = "org.jetbrains.kotlin.pill.JpsCompatibleBasePlugin"
}
"jps-compatible" {
id = "jps-compatible"
implementationClass = "org.jetbrains.kotlin.pill.JpsCompatiblePlugin"
}
}
}
fun Project.getBooleanProperty(name: String): Boolean? = this.findProperty(name)?.let {
val v = it.toString()
if (v.isBlank()) true
else v.toBoolean()
}
rootProject.apply {
from(rootProject.file("../versions.gradle.kts"))
}
val isTeamcityBuild = project.hasProperty("teamcity") || System.getenv("TEAMCITY_VERSION") != null
val intellijUltimateEnabled by extra(project.getBooleanProperty("intellijUltimateEnabled") ?: isTeamcityBuild)
val intellijSeparateSdks by extra(project.getBooleanProperty("intellijSeparateSdks") ?: false)
extra["intellijRepo"] = "https://www.jetbrains.com/intellij-repository"
extra["intellijReleaseType"] = "snapshots" // or "snapshots"
extra["versions.androidDxSources"] = "5.0.0_r2"
extra["customDepsOrg"] = "kotlin.build.custom.deps"
repositories {
extra["buildSrcKotlinRepo"]?.let {
maven(url = it)
}
maven(url = "https://repo.gradle.org/gradle/libs-releases-local") // for native-platform
jcenter()
}
dependencies {
compile("net.rubygrapefruit:native-platform:${property("versions.native-platform")}")
compile("net.rubygrapefruit:native-platform-windows-amd64:${property("versions.native-platform")}")
compile("net.rubygrapefruit:native-platform-windows-i386:${property("versions.native-platform")}")
compile("com.jakewharton.dex:dex-method-list:3.0.0")
// TODO: adding the dep to the plugin breaks the build unexpectedly, resolve and uncomment
// compile("org.jetbrains.kotlin:kotlin-gradle-plugin:${rootProject.extra["bootstrap_kotlin_version"]}")
// Shadow plugin is used in many projects of the main build. Once it's no longer used in buildSrc, please move this dependency to the root project
compile("com.github.jengelman.gradle.plugins:shadow:${property("versions.shadow")}")
compile("org.ow2.asm:asm-all:6.0_BETA")
}
samWithReceiver {
annotation("org.gradle.api.HasImplicitReceiver")
}
fun Project.`samWithReceiver`(configure: org.jetbrains.kotlin.samWithReceiver.gradle.SamWithReceiverExtension.() -> Unit): Unit =
extensions.configure("samWithReceiver", configure)
tasks["build"].dependsOn(":prepare-deps:android-dx:build", ":prepare-deps:intellij-sdk:build")

View File

@@ -12,4 +12,4 @@ class DependencyMapper(
class MappedDependency(val main: PDependency, val deferred: List<PDependency> = emptyList())
class ParserContext(val dependencyMappers: List<DependencyMapper>)
class ParserContext(val dependencyMappers: List<DependencyMapper>, val variant: PillExtension.Variant)

View File

@@ -0,0 +1,39 @@
@file:Suppress("PackageDirectoryMismatch")
package org.jetbrains.kotlin.pill
import java.io.File
import org.gradle.api.Project
open class PillExtension {
enum class Variant {
// Default variant (./gradlew pill)
BASE() { override val includes = setOf(BASE) },
// Full variant (./gradlew pill -Dpill.variant=full)
FULL() { override val includes = setOf(BASE, FULL) },
// Do not import the project to JPS model, but set some options for it
NONE() { override val includes = emptySet<Variant>() },
// 'BASE' if the "jps-compatible" plugin is applied, 'NONE' otherwise
DEFAULT() { override val includes = emptySet<Variant>() };
abstract val includes: Set<Variant>
}
open var variant: Variant = Variant.DEFAULT
open var importAsLibrary: Boolean = false
open var excludedDirs: List<File> = emptyList()
fun Project.excludedDirs(vararg dirs: String) {
excludedDirs = excludedDirs + dirs.map { File(projectDir, it) }
}
open var libraryPath: File? = null
set(v) {
importAsLibrary = true
field = v
}
}

View File

@@ -153,7 +153,10 @@ fun generateKotlinPluginArtifactFile(rootProject: Project): PFile {
.findByName(EmbeddedComponents.CONFIGURATION_NAME)?.resolvedConfiguration
if (embeddedComponents != null) {
for ((_, _, dependency) in listOf(embeddedComponents to Scope.COMPILE).collectDependencies()) {
val configuration = CollectedConfiguration(embeddedComponents, Scope.COMPILE)
for (dependencyInfo in listOf(configuration).collectDependencies()) {
val dependency = (dependencyInfo as? DependencyInfo.ResolvedDependencyInfo)?.dependency ?: continue
if (dependency.configuration == "runtimeElements") {
archiveForJar.add(ModuleOutput(dependency.moduleName + ".src"))
} else if (dependency.configuration == "tests-jar" || dependency.configuration == "jpsTest") {

View File

@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.pill
import org.gradle.api.Project
import org.gradle.api.artifacts.*
import org.gradle.api.tasks.*
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.kotlin.dsl.configure
@@ -11,6 +12,7 @@ import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.internal.HasConvention
import org.jetbrains.kotlin.pill.POrderRoot.*
import org.jetbrains.kotlin.pill.PSourceRoot.*
import org.jetbrains.kotlin.pill.PillExtension.*
import java.io.File
import java.util.LinkedList
@@ -41,13 +43,34 @@ data class PContentRoot(
data class PSourceRoot(
val path: File,
val kind: Kind
val kind: Kind,
val kotlinOptions: PSourceRootKotlinOptions?
) {
enum class Kind {
PRODUCTION, TEST, RESOURCES, TEST_RESOURCES;
enum class Kind { PRODUCTION, TEST, RESOURCES, TEST_RESOURCES }
}
val isResources get() = this == RESOURCES || this == TEST_RESOURCES
}
data class PSourceRootKotlinOptions(
val noStdlib: Boolean?,
val noReflect: Boolean?,
val moduleName: String?,
val apiVersion: String?,
val languageVersion: String?,
val jvmTarget: String?,
val addCompilerBuiltIns: Boolean?,
val loadBuiltInsFromDependencies: Boolean?,
val extraArguments: List<String>
) {
fun intersect(other: PSourceRootKotlinOptions) = PSourceRootKotlinOptions(
if (noStdlib == other.noStdlib) noStdlib else null,
if (noReflect == other.noReflect) noReflect else null,
if (moduleName == other.moduleName) moduleName else null,
if (apiVersion == other.apiVersion) apiVersion else null,
if (languageVersion == other.languageVersion) languageVersion else null,
if (jvmTarget == other.jvmTarget) jvmTarget else null,
if (addCompilerBuiltIns == other.addCompilerBuiltIns) addCompilerBuiltIns else null,
if (loadBuiltInsFromDependencies == other.loadBuiltInsFromDependencies) loadBuiltInsFromDependencies else null,
extraArguments.intersect(other.extraArguments).toList()
)
}
data class POrderRoot(
@@ -83,9 +106,16 @@ fun parse(project: Project, libraries: List<PLibrary>, context: ParserContext):
error("$project is not a root project")
}
val modules = project.allprojects
.filter { it.plugins.hasPlugin(JpsCompatiblePlugin::class.java) }
.flatMap { parseModules(it) }
fun Project.matchesSelectedVariant(): Boolean {
val extension = this.extensions.findByType(PillExtension::class.java) ?: return true
val projectVariant = extension.variant.takeUnless { it == Variant.DEFAULT } ?: Variant.BASE
return projectVariant in context.variant.includes
}
val (includedProjects, excludedProjects) = project.allprojects
.partition { it.plugins.hasPlugin(JpsCompatiblePlugin::class.java) && it.matchesSelectedVariant() }
val modules = includedProjects.flatMap { parseModules(it, excludedProjects) }
return PProject("Kotlin", project.projectDir, modules, libraries)
}
@@ -108,12 +138,7 @@ private val TEST_CONFIGURATION_MAPPING = mapOf(
listOf("jpsTest") to Scope.TEST
)
private val SOURCE_SET_MAPPING = mapOf(
"main" to Kind.PRODUCTION,
"test" to Kind.TEST
)
private fun ParserContext.parseModules(project: Project): List<PModule> {
private fun ParserContext.parseModules(project: Project, excludedProjects: List<Project>): List<PModule> {
val (productionContentRoots, testContentRoots) = parseContentRoots(project).partition { !it.forTests }
val modules = mutableListOf<PModule>()
@@ -121,7 +146,10 @@ private fun ParserContext.parseModules(project: Project): List<PModule> {
fun getJavaExcludedDirs() = project.plugins.findPlugin(IdeaPlugin::class.java)
?.model?.module?.excludeDirs?.toList() ?: emptyList()
val allExcludedDirs = getJavaExcludedDirs() + project.buildDir
fun getPillExcludedDirs() = project.extensions.getByType(PillExtension::class.java).excludedDirs
val allExcludedDirs = getPillExcludedDirs() + getJavaExcludedDirs() + project.buildDir +
(if (project == project.rootProject) excludedProjects.map { it.buildDir } else emptyList())
var productionSourcesModule: PModule? = null
@@ -162,8 +190,8 @@ private fun ParserContext.parseModules(project: Project): List<PModule> {
}
}
val mainModuleFileRelativePath = when {
project == project.rootProject -> File(project.rootProject.projectDir, project.name + ".iml")
val mainModuleFileRelativePath = when (project) {
project.rootProject -> File(project.rootProject.projectDir, project.name + ".iml")
else -> getModuleFile()
}
@@ -199,55 +227,97 @@ private fun parseSourceRoots(project: Project): List<PSourceRoot> {
return emptyList()
}
val kotlinTasksBySourceSet = project.tasks
.filter { it.name.startsWith("compile") && it.name.endsWith("Kotlin") }
.associateBy { it.invokeInternal("getSourceSetName") }
val sourceRoots = mutableListOf<PSourceRoot>()
project.configure<JavaPluginConvention> {
for ((sourceSetName, kind) in SOURCE_SET_MAPPING) {
val sourceSet = sourceSets.findByName(sourceSetName) ?: continue
for (sourceSet in project.sourceSets) {
val kotlinCompileTask = kotlinTasksBySourceSet[sourceSet.name]
val kind = if (sourceSet.name == SourceSet.TEST_SOURCE_SET_NAME) Kind.TEST else Kind.PRODUCTION
fun Any.getKotlin(): SourceDirectorySet {
val kotlinMethod = javaClass.getMethod("getKotlin")
val oldIsAccessible = kotlinMethod.isAccessible
try {
kotlinMethod.isAccessible = true
return kotlinMethod(this) as SourceDirectorySet
} finally {
kotlinMethod.isAccessible = oldIsAccessible
}
fun Any.getKotlin(): SourceDirectorySet {
val kotlinMethod = javaClass.getMethod("getKotlin")
val oldIsAccessible = kotlinMethod.isAccessible
try {
kotlinMethod.isAccessible = true
return kotlinMethod(this) as SourceDirectorySet
} finally {
kotlinMethod.isAccessible = oldIsAccessible
}
}
val kotlinSourceDirectories = (sourceSet as HasConvention).convention
.plugins["kotlin"]?.getKotlin()?.srcDirs
?: emptySet()
val directories = (sourceSet.java.sourceDirectories.files + kotlinSourceDirectories).toList()
.filter { it.exists() }
.takeIf { it.isNotEmpty() }
?: continue
val kotlinOptions = kotlinCompileTask?.let { getKotlinOptions(it) }
for (resourceRoot in sourceSet.resources.sourceDirectories.files) {
if (!resourceRoot.exists() || resourceRoot in directories) {
continue
}
val kotlinSourceDirectories = (sourceSet as HasConvention).convention
.plugins["kotlin"]?.getKotlin()?.srcDirs
?: emptySet()
val directories = (sourceSet.java.sourceDirectories.files + kotlinSourceDirectories).toList()
.filter { it.exists() }
.takeIf { it.isNotEmpty() }
?: continue
for (resourceRoot in sourceSet.resources.sourceDirectories.files) {
if (!resourceRoot.exists() || resourceRoot in directories) {
continue
}
val resourceRootKind = when (kind) {
Kind.PRODUCTION -> Kind.RESOURCES
Kind.TEST -> Kind.TEST_RESOURCES
else -> error("Invalid source root kind $kind")
}
sourceRoots += PSourceRoot(resourceRoot, resourceRootKind)
val resourceRootKind = when (kind) {
Kind.PRODUCTION -> Kind.RESOURCES
Kind.TEST -> Kind.TEST_RESOURCES
else -> error("Invalid source root kind $kind")
}
for (directory in directories) {
sourceRoots += PSourceRoot(directory, kind)
}
sourceRoots += PSourceRoot(resourceRoot, resourceRootKind, kotlinOptions)
}
for (directory in directories) {
sourceRoots += PSourceRoot(directory, kind, kotlinOptions)
}
}
return sourceRoots
}
private fun getKotlinOptions(kotlinCompileTask: Any): PSourceRootKotlinOptions? {
val compileArguments = kotlinCompileTask.invokeInternal("getSerializedCompilerArguments") as List<String>
fun parseBoolean(name: String) = compileArguments.contains("-$name")
fun parseString(name: String) = compileArguments.dropWhile { it != "-$name" }.drop(1).firstOrNull()
val addCompilerBuiltins = "Xadd-compiler-builtins"
val loadBuiltinsFromDependencies = "Xload-builtins-from-dependencies"
val extraArguments = compileArguments.filter {
it.startsWith("-X") && it != "-$addCompilerBuiltins" && it != "-$loadBuiltinsFromDependencies"
}
return PSourceRootKotlinOptions(
parseBoolean("no-stdlib"),
parseBoolean("no-reflect"),
parseString("module-name"),
parseString("api-version"),
parseString("language-version"),
parseString("jvm-target"),
parseBoolean(addCompilerBuiltins),
parseBoolean(loadBuiltinsFromDependencies),
extraArguments
)
}
private fun Any.invokeInternal(name: String, instance: Any = this): Any? {
val method = javaClass.methods.single { it.name.startsWith(name) && it.parameterTypes.isEmpty() }
val oldIsAccessible = method.isAccessible
try {
method.isAccessible = true
return method.invoke(instance)
} finally {
method.isAccessible = oldIsAccessible
}
}
private fun ParserContext.parseDependencies(project: Project, forTests: Boolean): List<POrderRoot> {
val configurationMapping = if (forTests) TEST_CONFIGURATION_MAPPING else CONFIGURATION_MAPPING
@@ -255,20 +325,34 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
val mainRoots = mutableListOf<POrderRoot>()
val deferredRoots = mutableListOf<POrderRoot>()
fun collectConfigurations(): List<Pair<ResolvedConfiguration, Scope>> {
val configurations = mutableListOf<Pair<ResolvedConfiguration, Scope>>()
fun collectConfigurations(): List<CollectedConfiguration> {
val configurations = mutableListOf<CollectedConfiguration>()
for ((configurationNames, scope) in configurationMapping) {
for (configurationName in configurationNames) {
val configuration = findByName(configurationName)?.also { it.resolve() } ?: continue
configurations += Pair(configuration.resolvedConfiguration, scope)
val extraDependencies = resolveExtraDependencies(configuration)
configurations += CollectedConfiguration(configuration.resolvedConfiguration, scope, extraDependencies)
}
}
return configurations
}
nextDependency@ for ((configuration, scope, dependency) in collectConfigurations().collectDependencies()) {
nextDependency@ for (dependencyInfo in collectConfigurations().collectDependencies()) {
val scope = dependencyInfo.scope
if (dependencyInfo is DependencyInfo.CustomDependencyInfo) {
val files = dependencyInfo.files
val library = PLibrary(files.firstOrNull()?.nameWithoutExtension ?: "unnamed", classes = files)
mainRoots += POrderRoot(PDependency.ModuleLibrary(library), scope)
continue
}
val dependency = (dependencyInfo as DependencyInfo.ResolvedDependencyInfo).dependency
for (mapper in dependencyMappers) {
if (dependency.moduleGroup == mapper.group
&& dependency.moduleName == mapper.module
@@ -277,12 +361,7 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
val mappedDependency = mapper.mapping(dependency)
if (mappedDependency != null) {
val orderRoot = POrderRoot(mappedDependency.main, scope)
if (mappedDependency.main is PDependency.Module) {
mainRoots += orderRoot
} else {
mainRoots += orderRoot
}
mainRoots += POrderRoot(mappedDependency.main, scope)
for (deferredDep in mappedDependency.deferred) {
deferredRoots += POrderRoot(deferredDep, scope)
@@ -293,10 +372,10 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
}
}
if (dependency.configuration == "runtimeElements" && scope != Scope.TEST) {
mainRoots += POrderRoot(PDependency.Module(dependency.moduleName + ".src"), scope)
mainRoots += if (dependency.configuration == "runtimeElements" && scope != Scope.TEST) {
POrderRoot(PDependency.Module(dependency.moduleName + ".src"), scope)
} else if (dependency.configuration == "tests-jar" || dependency.configuration == "jpsTest") {
mainRoots += POrderRoot(
POrderRoot(
PDependency.Module(dependency.moduleName + ".test"),
scope,
isProductionOnTestDependency = true
@@ -304,7 +383,7 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
} else {
val classes = dependency.moduleArtifacts.map { it.file }
val library = PLibrary(dependency.moduleName, classes)
mainRoots += POrderRoot(PDependency.ModuleLibrary(library), scope)
POrderRoot(PDependency.ModuleLibrary(library), scope)
}
}
@@ -312,9 +391,23 @@ private fun ParserContext.parseDependencies(project: Project, forTests: Boolean)
}
}
private fun resolveExtraDependencies(configuration: Configuration): List<File> {
return configuration.dependencies
.filterIsInstance<SelfResolvingDependency>()
.map { it.resolve() }
.filter { isGradleApiDependency(it) }
.flatMap { it }
}
private fun isGradleApiDependency(files: Iterable<File>): Boolean {
return listOf("gradle-api", "groovy-all").all { dep ->
files.any { it.extension == "jar" && it.name.startsWith("$dep-") }
}
}
private fun removeDuplicates(roots: List<POrderRoot>): List<POrderRoot> {
val dependenciesByScope = roots.groupBy { it.scope }.mapValues { it.value.mapTo(mutableSetOf()) { it.dependency } }
fun depenciesFor(scope: Scope) = dependenciesByScope[scope] ?: emptySet<PDependency>()
fun dependenciesFor(scope: Scope) = dependenciesByScope[scope] ?: emptySet<PDependency>()
val result = mutableSetOf<POrderRoot>()
for (root in roots.distinct()) {
@@ -325,16 +418,16 @@ private fun removeDuplicates(roots: List<POrderRoot>): List<POrderRoot> {
continue
}
if ((scope == Scope.PROVIDED || scope == Scope.RUNTIME) && dependency in depenciesFor(Scope.COMPILE)) {
if ((scope == Scope.PROVIDED || scope == Scope.RUNTIME) && dependency in dependenciesFor(Scope.COMPILE)) {
continue
}
if (scope == Scope.PROVIDED && dependency in depenciesFor(Scope.RUNTIME)) {
if (scope == Scope.PROVIDED && dependency in dependenciesFor(Scope.RUNTIME)) {
result += POrderRoot(dependency, Scope.COMPILE)
continue
}
if (scope == Scope.RUNTIME && dependency in depenciesFor(Scope.PROVIDED)) {
if (scope == Scope.RUNTIME && dependency in dependenciesFor(Scope.PROVIDED)) {
result += POrderRoot(dependency, Scope.COMPILE)
continue
}
@@ -345,17 +438,29 @@ private fun removeDuplicates(roots: List<POrderRoot>): List<POrderRoot> {
return result.toList()
}
data class DependencyInfo(val configuration: ResolvedConfiguration, val scope: Scope, val dependency: ResolvedDependency)
data class CollectedConfiguration(
val configuration: ResolvedConfiguration,
val scope: Scope,
val extraDependencies: List<File> = emptyList())
fun List<Pair<ResolvedConfiguration, Scope>>.collectDependencies(): List<DependencyInfo> {
sealed class DependencyInfo(val scope: Scope) {
class ResolvedDependencyInfo(scope: Scope, val dependency: ResolvedDependency) : DependencyInfo(scope)
class CustomDependencyInfo(scope: Scope, val files: List<File>) : DependencyInfo(scope)
}
fun List<CollectedConfiguration>.collectDependencies(): List<DependencyInfo> {
val dependencies = mutableListOf<DependencyInfo>()
val unprocessed = LinkedList<DependencyInfo>()
val existing = mutableSetOf<Pair<Scope, ResolvedDependency>>()
for ((configuration, scope) in this) {
for ((configuration, scope, extraDependencies) in this) {
for (dependency in configuration.firstLevelModuleDependencies) {
unprocessed += DependencyInfo(configuration, scope, dependency)
unprocessed += DependencyInfo.ResolvedDependencyInfo(scope, dependency)
}
if (!extraDependencies.isEmpty()) {
unprocessed += DependencyInfo.CustomDependencyInfo(scope, extraDependencies)
}
}
@@ -363,6 +468,8 @@ fun List<Pair<ResolvedConfiguration, Scope>>.collectDependencies(): List<Depende
val info = unprocessed.removeAt(0)
dependencies += info
info as? DependencyInfo.ResolvedDependencyInfo ?: continue
val data = Pair(info.scope, info.dependency)
existing += data
@@ -371,9 +478,16 @@ fun List<Pair<ResolvedConfiguration, Scope>>.collectDependencies(): List<Depende
continue
}
unprocessed += DependencyInfo(info.configuration, info.scope, child)
unprocessed += DependencyInfo.ResolvedDependencyInfo(info.scope, child)
}
}
return dependencies
}
}
private val Project.sourceSets: SourceSetContainer
get() {
lateinit var result: SourceSetContainer
project.configure<JavaPluginConvention> { result = sourceSets }
return result
}

View File

@@ -17,7 +17,7 @@ interface PathContext {
}
}
class ProjectContext private constructor(val projectDir: File) : PathContext {
class ProjectContext private constructor(private val projectDir: File) : PathContext {
constructor(project: PProject) : this(project.rootDirectory)
constructor(project: Project) : this(project.projectDir)

View File

@@ -1,3 +1,4 @@
@file:Suppress("PackageDirectoryMismatch")
package org.jetbrains.kotlin.pill
import org.gradle.api.Plugin
@@ -10,16 +11,15 @@ import shadow.org.jdom2.output.Format
import shadow.org.jdom2.output.XMLOutputter
import java.io.File
class JpsCompatibleBasePlugin : Plugin<Project> {
class PillConfigurablePlugin : Plugin<Project> {
override fun apply(project: Project) {
project.configurations.create(EmbeddedComponents.CONFIGURATION_NAME)
project.extensions.create("pill", PillExtension::class.java)
}
}
class JpsCompatiblePlugin : Plugin<Project> {
companion object {
private const val JPS_LIBRARY_PATH = "jpsLibraryPath"
private fun mapper(module: String, vararg configurations: String): DependencyMapper {
return DependencyMapper("org.jetbrains.kotlin", module, *configurations) { MappedDependency(PDependency.Library(module)) }
}
@@ -47,21 +47,24 @@ class JpsCompatiblePlugin : Plugin<Project> {
}
fun getProjectLibraries(rootProject: Project): List<PLibrary> {
val distLibDir = File(rootProject.extra["distLibDir"].toString())
fun distJar(name: String) = File(rootProject.projectDir, "dist/kotlinc/lib/$name.jar")
fun projectFile(path: String) = File(rootProject.projectDir, path)
val libraries = rootProject.allprojects
.filter { it.extra.has(JPS_LIBRARY_PATH) }
.map { library ->
val libraryPath = library.extra.get(JPS_LIBRARY_PATH).toString()
.mapNotNull { library ->
val libraryExtension = library.extensions.findByType(PillExtension::class.java)
?.takeIf { it.importAsLibrary }
?: return@mapNotNull null
val libraryPath = libraryExtension.libraryPath ?: distLibDir
val archivesBaseName = library.convention.findPlugin(BasePluginConvention::class.java)?.archivesBaseName ?: library.name
fun List<File>.filterExisting() = filter { it.exists() }
PLibrary(
library.name,
classes = listOf(File(libraryPath, archivesBaseName + ".jar")).filterExisting(),
sources = listOf(File(libraryPath, archivesBaseName + "-sources.jar")).filterExisting()
classes = listOf(File(libraryPath, "$archivesBaseName.jar")).filterExisting(),
sources = listOf(File(libraryPath, "$archivesBaseName-sources.jar")).filterExisting()
)
}
@@ -70,15 +73,18 @@ class JpsCompatiblePlugin : Plugin<Project> {
}
override fun apply(project: Project) {
project.plugins.apply(JpsCompatibleBasePlugin::class.java)
project.plugins.apply(PillConfigurablePlugin::class.java)
// 'jpsTest' does not require the 'tests-jar' artifact
project.configurations.create("jpsTest")
if (project == project.rootProject) {
project.tasks.create("pill") {
doLast { pill(project) }
TaskUtils.useAndroidSdk(this)
TaskUtils.useAndroidJar(this)
if (System.getProperty("pill.android.tests", "false") == "true") {
TaskUtils.useAndroidSdk(this)
TaskUtils.useAndroidJar(this)
}
}
project.tasks.create("unpill") {
@@ -103,8 +109,22 @@ class JpsCompatiblePlugin : Plugin<Project> {
private fun pill(rootProject: Project) {
initEnvironment(rootProject)
val variantOptionValue = System.getProperty("pill.variant", "base").toUpperCase()
val variant = PillExtension.Variant.values().firstOrNull { it.name == variantOptionValue }
?: run {
rootProject.logger.error("Invalid variant name: $variantOptionValue")
return
}
rootProject.logger.lifecycle("Pill: Setting up project for the '${variant.name.toLowerCase()}' variant...")
if (variant == PillExtension.Variant.NONE || variant == PillExtension.Variant.DEFAULT) {
rootProject.logger.error("'none' and 'default' should not be passed as a Pill variant property value")
return
}
val projectLibraries = getProjectLibraries(rootProject)
val parserContext = ParserContext(getDependencyMappers(projectLibraries))
val parserContext = ParserContext(getDependencyMappers(projectLibraries), variant)
val jpsProject = parse(rootProject, projectLibraries, parserContext)
.mapLibraries(this::attachPlatformSources, this::attachAsmSources)
@@ -202,8 +222,9 @@ class JpsCompatiblePlugin : Plugin<Project> {
.map { it.trim() }
.filter { it.isNotEmpty() }
fun addOrReplaceOptionValue(name: String, value: Any) {
options = options.filter { !it.startsWith("-D$name=") } + listOf("-D$name=$value")
fun addOrReplaceOptionValue(name: String, value: Any?) {
val optionsWithoutNewValue = options.filter { !it.startsWith("-D$name=") }
options = if (value == null) optionsWithoutNewValue else (optionsWithoutNewValue + listOf("-D$name=$value"))
}
val robolectricClasspath = project.rootProject
@@ -211,16 +232,21 @@ class JpsCompatiblePlugin : Plugin<Project> {
.configurations.getByName("robolectricClasspath")
.files.joinToString(File.pathSeparator)
val androidJarPath = project.configurations.getByName("androidJar").singleFile
val androidSdkPath = project.configurations.getByName("androidSdk").singleFile
addOrReplaceOptionValue("idea.home.path", platformDirProjectRelative)
addOrReplaceOptionValue("ideaSdk.androidPlugin.path", platformDirProjectRelative + "/plugins/android/lib")
addOrReplaceOptionValue("robolectric.classpath", robolectricClasspath)
addOrReplaceOptionValue("use.pill", "true")
addOrReplaceOptionValue("android.sdk", "\$PROJECT_DIR\$/" + androidSdkPath.toRelativeString(projectDir))
addOrReplaceOptionValue("android.jar", "\$PROJECT_DIR\$/" + androidJarPath.toRelativeString(projectDir))
val isAndroidStudioBunch = project.findProperty("versions.androidStudioRelease") != null
addOrReplaceOptionValue("idea.platform.prefix", if (isAndroidStudioBunch) "AndroidStudio" else null)
val androidJarPath = project.configurations.findByName("androidJar")?.singleFile
val androidSdkPath = project.configurations.findByName("androidSdk")?.singleFile
if (androidJarPath != null && androidSdkPath != null) {
addOrReplaceOptionValue("android.sdk", "\$PROJECT_DIR\$/" + androidSdkPath.toRelativeString(projectDir))
addOrReplaceOptionValue("android.jar", "\$PROJECT_DIR\$/" + androidJarPath.toRelativeString(projectDir))
}
vmParams.setAttribute("value", options.joinToString(" "))
}

View File

@@ -54,10 +54,57 @@ private fun renderModule(project: PProject, module: PModule) = PFile(
xml("component", "name" to "TestModuleProperties", "production-module" to moduleForProductionSources.name)
}
xml("component", "name" to "NewModuleRootManager", "inherit-compiler-output" to "true") {
xml("exclude-output")
val kotlinCompileOptionsList = module.contentRoots.flatMap { it.sourceRoots }.mapNotNull { it.kotlinOptions }
var kotlinCompileOptions = kotlinCompileOptionsList.firstOrNull()
for (otherOptions in kotlinCompileOptionsList.drop(1)) {
kotlinCompileOptions = kotlinCompileOptions?.intersect(otherOptions)
}
val pathContext = ModuleContext(project, module)
val pathContext = ModuleContext(project, module)
val platformVersion = (kotlinCompileOptions?.jvmTarget ?: "1.8")
val classesDirectory = File(project.rootDirectory, "out/production/${module.name}")
if (kotlinCompileOptions != null) {
xml("component", "name" to "FacetManager") {
xml("facet", "type" to "kotlin-language", "name" to "Kotlin") {
xml("configuration", "version" to 3, "platform" to "JVM $platformVersion", "useProjectSettings" to "false") {
xml("compilerSettings") {
xml(
"option",
"name" to "additionalArguments",
"value" to kotlinCompileOptions.extraArguments.joinToString(" ")
)
}
xml("compilerArguments") {
xml("option", "name" to "destination", "value" to pathContext(classesDirectory))
fun Any?.option(name: String) {
if (this != null) xml("option", "name" to name, "value" to this.toString())
}
kotlinCompileOptions.noStdlib.option("noStdlib")
kotlinCompileOptions.noReflect.option("noReflect")
kotlinCompileOptions.moduleName.option("moduleName")
kotlinCompileOptions.languageVersion.option("languageVersion")
kotlinCompileOptions.apiVersion.option("apiVersion")
kotlinCompileOptions.addCompilerBuiltIns.option("addCompilerBuiltIns")
kotlinCompileOptions.loadBuiltInsFromDependencies.option("loadBuiltInsFromDependencies")
xml("option", "name" to "pluginOptions") { xml("array") }
xml("option", "name" to "pluginClasspaths") { xml("array") }
}
}
}
}
}
xml("component",
"name" to "NewModuleRootManager",
"LANGUAGE_LEVEL" to "JDK_${platformVersion.replace('.', '_')}",
"inherit-compiler-output" to "true"
) {
xml("exclude-output")
for (contentRoot in module.contentRoots) {
xml("content", pathContext.url(contentRoot.path)) {
@@ -98,7 +145,6 @@ private fun renderModule(project: PProject, module: PModule) = PFile(
"name" to dependency.name,
"level" to "project"
)
else -> error("Unsupported dependency type: $dependency")
}
if (dependency is PDependency.Module && orderRoot.isProductionOnTestDependency) {

View File

@@ -6,7 +6,7 @@ import shadow.org.jdom2.Element
import shadow.org.jdom2.output.Format
import shadow.org.jdom2.output.XMLOutputter
class xml(val name: String, vararg val args: Pair<String, Any>, block: xml.() -> Unit = {}) {
class xml(val name: String, private vararg val args: Pair<String, Any>, block: xml.() -> Unit = {}) {
private companion object {
fun makeXml(name: String, vararg args: Pair<String, Any>, block: xml.() -> Unit = {}): xml {
return xml(name, *args, block = block)

View File

@@ -3,7 +3,7 @@
<log_file alias="idea.log" path="$PROJECT_DIR$/ideaSDK/system-idea/log/idea.log" />
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
<module name="idea-runner" />
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=$IDEA_HOME_PATH$/system -Didea.config.path=$IDEA_HOME_PATH$/config -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true" />
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=$PROJECT_DIR$/local/ideaSandbox -Didea.config.path=$PROJECT_DIR$/local/ideaSandbox/config -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true" />
<option name="WORKING_DIRECTORY" value="file://$IDEA_HOME_PATH$" />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="" />

View File

@@ -3,7 +3,7 @@
<log_file alias="idea.log" path="$PROJECT_DIR$/ideaSDK/system-idea/log/idea.log" />
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
<module name="idea-runner" />
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=$IDEA_HOME_PATH$/system -Didea.config.path=$IDEA_HOME_PATH$/config -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.ProcessCanceledException=disabled" />
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=240m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=$PROJECT_DIR$/local/ideaSandbox -Didea.config.path=$PROJECT_DIR$/local/ideaSandbox/config -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.ProcessCanceledException=disabled" />
<option name="WORKING_DIRECTORY" value="file://$IDEA_HOME_PATH$" />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="" />

View File

@@ -14,17 +14,15 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen;
package org.jetbrains.kotlin.codegen
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
public interface AccessorForCallableDescriptor<T extends CallableMemberDescriptor> {
@NotNull
T getCalleeDescriptor();
interface AccessorForCallableDescriptor<T : CallableMemberDescriptor> {
val calleeDescriptor: T
@Nullable
ClassDescriptor getSuperCallTarget();
val superCallTarget: ClassDescriptor?
val accessorKind: AccessorKind
}

View File

@@ -23,13 +23,13 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeSubstitutor
class AccessorForConstructorDescriptor(
private val calleeDescriptor: ClassConstructorDescriptor,
containingDeclaration: DeclarationDescriptor,
private val superCallTarget: ClassDescriptor?
override val calleeDescriptor: ClassConstructorDescriptor,
containingDeclaration: DeclarationDescriptor,
override val superCallTarget: ClassDescriptor?,
override val accessorKind: AccessorKind
) : AbstractAccessorForFunctionDescriptor(containingDeclaration, Name.special("<init>")),
ClassConstructorDescriptor,
AccessorForCallableDescriptor<ConstructorDescriptor> {
override fun getCalleeDescriptor(): ConstructorDescriptor = calleeDescriptor
ClassConstructorDescriptor,
AccessorForCallableDescriptor<ConstructorDescriptor> {
override fun getContainingDeclaration(): ClassDescriptor = calleeDescriptor.containingDeclaration
@@ -39,16 +39,15 @@ class AccessorForConstructorDescriptor(
override fun getReturnType(): KotlinType = super.getReturnType()!!
override fun getSuperCallTarget(): ClassDescriptor? = superCallTarget
override fun substitute(substitutor: TypeSubstitutor) = super.substitute(substitutor) as ClassConstructorDescriptor
override fun copy(
newOwner: DeclarationDescriptor,
modality: Modality,
visibility: Visibility,
kind: CallableMemberDescriptor.Kind,
copyOverrides: Boolean
newOwner: DeclarationDescriptor,
modality: Modality,
visibility: Visibility,
kind: CallableMemberDescriptor.Kind,
copyOverrides: Boolean
): AccessorForConstructorDescriptor {
throw UnsupportedOperationException()
}
@@ -57,13 +56,13 @@ class AccessorForConstructorDescriptor(
init {
initialize(
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),
calleeDescriptor.dispatchReceiverParameter,
copyTypeParameters(calleeDescriptor),
copyValueParameters(calleeDescriptor),
calleeDescriptor.returnType,
Modality.FINAL,
Visibilities.LOCAL
DescriptorUtils.getReceiverParameterType(extensionReceiverParameter),
calleeDescriptor.dispatchReceiverParameter,
copyTypeParameters(calleeDescriptor),
copyValueParameters(calleeDescriptor),
calleeDescriptor.returnType,
Modality.FINAL,
Visibilities.LOCAL
)
}
}

View File

@@ -1,90 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import java.util.LinkedHashMap;
public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDescriptor implements AccessorForCallableDescriptor<FunctionDescriptor> {
private final FunctionDescriptor calleeDescriptor;
private final ClassDescriptor superCallTarget;
private final String nameSuffix;
public AccessorForFunctionDescriptor(
@NotNull FunctionDescriptor descriptor,
@NotNull DeclarationDescriptor containingDeclaration,
@Nullable ClassDescriptor superCallTarget,
@NotNull String nameSuffix
) {
super(containingDeclaration,
Name.identifier("access$" + nameSuffix));
this.calleeDescriptor = descriptor;
this.superCallTarget = superCallTarget;
this.nameSuffix = nameSuffix;
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()),
descriptor instanceof ConstructorDescriptor || CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(descriptor)
? null
: descriptor.getDispatchReceiverParameter(),
copyTypeParameters(descriptor),
copyValueParameters(descriptor),
descriptor.getReturnType(),
Modality.FINAL,
Visibilities.LOCAL);
setSuspend(descriptor.isSuspend());
if (descriptor.getUserData(CoroutineCodegenUtilKt.INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) != null) {
userDataMap = new LinkedHashMap<>();
userDataMap.put(
CoroutineCodegenUtilKt.INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION,
descriptor.getUserData(CoroutineCodegenUtilKt.INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)
);
}
}
@NotNull
@Override
protected FunctionDescriptorImpl createSubstitutedCopy(
@NotNull DeclarationDescriptor newOwner,
@Nullable FunctionDescriptor original,
@NotNull Kind kind,
@Nullable Name newName,
@NotNull Annotations annotations,
@NotNull SourceElement source
) {
return new AccessorForFunctionDescriptor(calleeDescriptor, newOwner, superCallTarget, nameSuffix);
}
@NotNull
@Override
public FunctionDescriptor getCalleeDescriptor() {
return calleeDescriptor;
}
@Override
public ClassDescriptor getSuperCallTarget() {
return superCallTarget;
}
}

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.coroutines.*
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import java.util.LinkedHashMap
class AccessorForFunctionDescriptor(
override val calleeDescriptor: FunctionDescriptor,
containingDeclaration: DeclarationDescriptor,
override val superCallTarget: ClassDescriptor?,
private val nameSuffix: String,
override val accessorKind: AccessorKind
) : AbstractAccessorForFunctionDescriptor(containingDeclaration, Name.identifier("access$$nameSuffix")),
AccessorForCallableDescriptor<FunctionDescriptor> {
init {
initialize(
DescriptorUtils.getReceiverParameterType(calleeDescriptor.extensionReceiverParameter),
if (calleeDescriptor is ConstructorDescriptor || calleeDescriptor.isJvmStaticInObjectOrClassOrInterface())
null
else
calleeDescriptor.dispatchReceiverParameter,
copyTypeParameters(calleeDescriptor),
copyValueParameters(calleeDescriptor),
calleeDescriptor.returnType,
Modality.FINAL,
Visibilities.LOCAL
)
isSuspend = calleeDescriptor.isSuspend
if (calleeDescriptor.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION) != null) {
userDataMap = LinkedHashMap<FunctionDescriptor.UserDataKey<*>, Any>()
userDataMap[INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION] =
calleeDescriptor.getUserData(INITIAL_DESCRIPTOR_FOR_SUSPEND_FUNCTION)
}
}
override fun createSubstitutedCopy(
newOwner: DeclarationDescriptor,
original: FunctionDescriptor?,
kind: CallableMemberDescriptor.Kind,
newName: Name?,
annotations: Annotations,
source: SourceElement
): FunctionDescriptorImpl {
return AccessorForFunctionDescriptor(calleeDescriptor, newOwner, superCallTarget, nameSuffix, accessorKind)
}
}

View File

@@ -22,19 +22,20 @@ import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.types.KotlinType
class AccessorForPropertyBackingField(
property: PropertyDescriptor,
containingDeclaration: DeclarationDescriptor,
delegateType: KotlinType?,
extensionReceiverParameter: ReceiverParameterDescriptor?,
dispatchReceiverParameter: ReceiverParameterDescriptor?,
nameSuffix: String,
val fieldAccessorKind: FieldAccessorKind
property: PropertyDescriptor,
containingDeclaration: DeclarationDescriptor,
delegateType: KotlinType?,
extensionReceiverParameter: ReceiverParameterDescriptor?,
dispatchReceiverParameter: ReceiverParameterDescriptor?,
nameSuffix: String,
fieldAccessorKind: AccessorKind
) : AccessorForPropertyDescriptor(
property,
delegateType ?: property.type,
extensionReceiverParameter?.type,
dispatchReceiverParameter,
containingDeclaration,
null,
nameSuffix
property,
delegateType ?: property.type,
extensionReceiverParameter?.type,
dispatchReceiverParameter,
containingDeclaration,
null,
nameSuffix,
fieldAccessorKind
)

View File

@@ -1,163 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.types.KotlinType;
import java.util.Collections;
public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implements AccessorForCallableDescriptor<PropertyDescriptor> {
private final PropertyDescriptor calleeDescriptor;
private final ClassDescriptor superCallTarget;
private final String nameSuffix;
private final boolean withSyntheticGetterAccessor;
private final boolean withSyntheticSetterAccessor;
public AccessorForPropertyDescriptor(
@NotNull PropertyDescriptor property,
@NotNull DeclarationDescriptor containingDeclaration,
@Nullable ClassDescriptor superCallTarget,
@NotNull String nameSuffix,
boolean getterAccessorRequired,
boolean setterAccessorRequired
) {
this(property, property.getType(), DescriptorUtils.getReceiverParameterType(property.getExtensionReceiverParameter()),
/* dispatchReceiverParameter = */
CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(property) ? null : property.getDispatchReceiverParameter(),
containingDeclaration, superCallTarget, nameSuffix,
getterAccessorRequired, setterAccessorRequired);
}
protected AccessorForPropertyDescriptor(
@NotNull PropertyDescriptor original,
@NotNull KotlinType propertyType,
@Nullable KotlinType receiverType,
@Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
@NotNull DeclarationDescriptor containingDeclaration,
@Nullable ClassDescriptor superCallTarget,
@NotNull String nameSuffix
) {
this(original, propertyType, receiverType, dispatchReceiverParameter, containingDeclaration, superCallTarget, nameSuffix, true, true);
}
private AccessorForPropertyDescriptor(
@NotNull PropertyDescriptor original,
@NotNull KotlinType propertyType,
@Nullable KotlinType receiverType,
@Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
@NotNull DeclarationDescriptor containingDeclaration,
@Nullable ClassDescriptor superCallTarget,
@NotNull String nameSuffix,
boolean getterAccessorRequired,
boolean setterAccessorRequired
) {
super(containingDeclaration, null, Annotations.Companion.getEMPTY(), Modality.FINAL, Visibilities.LOCAL,
original.isVar(), Name.identifier("access$" + nameSuffix), Kind.DECLARATION, SourceElement.NO_SOURCE,
false, false, false, false, false, false);
this.calleeDescriptor = original;
this.superCallTarget = superCallTarget;
this.nameSuffix = nameSuffix;
setType(propertyType, Collections.<TypeParameterDescriptorImpl>emptyList(), dispatchReceiverParameter, receiverType);
this.withSyntheticGetterAccessor = getterAccessorRequired;
this.withSyntheticSetterAccessor = setterAccessorRequired;
PropertyGetterDescriptorImpl getterDescriptor =
getterAccessorRequired ? new Getter(this) : (PropertyGetterDescriptorImpl) original.getGetter();
PropertySetterDescriptor setterDescriptor =
setterAccessorRequired ? new Setter(this) : original.getSetter();
initialize(getterDescriptor, setterDescriptor);
}
public static class Getter extends PropertyGetterDescriptorImpl implements AccessorForCallableDescriptor<PropertyGetterDescriptor> {
public Getter(AccessorForPropertyDescriptor property) {
super(property, Annotations.Companion.getEMPTY(), Modality.FINAL, Visibilities.LOCAL,
/* isDefault = */ false, /* isExternal = */ false, /* isInline = */false, Kind.DECLARATION, null, SourceElement.NO_SOURCE);
initialize(property.getType());
}
@NotNull
@Override
public PropertyGetterDescriptor getCalleeDescriptor() {
//noinspection ConstantConditions
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getCalleeDescriptor().getGetter();
}
@Override
@Nullable
public ClassDescriptor getSuperCallTarget() {
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getSuperCallTarget();
}
}
public static class Setter extends PropertySetterDescriptorImpl implements AccessorForCallableDescriptor<PropertySetterDescriptor>{
public Setter(AccessorForPropertyDescriptor property) {
super(property, Annotations.Companion.getEMPTY(), Modality.FINAL, Visibilities.LOCAL,
/* isDefault = */ false, /* isExternal = */ false, /* isInline = */ false, Kind.DECLARATION, null, SourceElement.NO_SOURCE);
initializeDefault();
}
@NotNull
@Override
public PropertySetterDescriptor getCalleeDescriptor() {
//noinspection ConstantConditions
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getCalleeDescriptor().getSetter();
}
@Override
@Nullable
public ClassDescriptor getSuperCallTarget() {
return ((AccessorForPropertyDescriptor) getCorrespondingProperty()).getSuperCallTarget();
}
}
@NotNull
@Override
public PropertyDescriptor getCalleeDescriptor() {
return calleeDescriptor;
}
@Override
public ClassDescriptor getSuperCallTarget() {
return superCallTarget;
}
@NotNull
public String getAccessorSuffix() {
return nameSuffix;
}
public boolean isWithSyntheticGetterAccessor() {
return withSyntheticGetterAccessor;
}
public boolean isWithSyntheticSetterAccessor() {
return withSyntheticSetterAccessor;
}
}

View File

@@ -0,0 +1,154 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyGetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.KotlinType
open class AccessorForPropertyDescriptor private constructor(
override val calleeDescriptor: PropertyDescriptor,
propertyType: KotlinType,
receiverType: KotlinType?,
dispatchReceiverParameter: ReceiverParameterDescriptor?,
containingDeclaration: DeclarationDescriptor,
override val superCallTarget: ClassDescriptor?,
val accessorSuffix: String,
val isWithSyntheticGetterAccessor: Boolean,
val isWithSyntheticSetterAccessor: Boolean,
final override val accessorKind: AccessorKind
) : PropertyDescriptorImpl(
containingDeclaration,
null,
Annotations.EMPTY,
Modality.FINAL,
Visibilities.LOCAL,
calleeDescriptor.isVar,
Name.identifier("access$$accessorSuffix"),
CallableMemberDescriptor.Kind.DECLARATION,
SourceElement.NO_SOURCE,
false,
false,
false,
false,
false,
false
), AccessorForCallableDescriptor<PropertyDescriptor> {
constructor(
property: PropertyDescriptor,
containingDeclaration: DeclarationDescriptor,
superCallTarget: ClassDescriptor?,
nameSuffix: String,
getterAccessorRequired: Boolean,
setterAccessorRequired: Boolean,
accessorKind: AccessorKind
) : this(
property, property.type, DescriptorUtils.getReceiverParameterType(property.extensionReceiverParameter),
/* dispatchReceiverParameter = */
if (property.isJvmStaticInObjectOrClassOrInterface()) null else property.dispatchReceiverParameter,
containingDeclaration, superCallTarget, nameSuffix,
getterAccessorRequired, setterAccessorRequired,
accessorKind
)
protected constructor(
original: PropertyDescriptor,
propertyType: KotlinType,
receiverType: KotlinType?,
dispatchReceiverParameter: ReceiverParameterDescriptor?,
containingDeclaration: DeclarationDescriptor,
superCallTarget: ClassDescriptor?,
nameSuffix: String,
accessorKind: AccessorKind
) : this(
original,
propertyType,
receiverType,
dispatchReceiverParameter,
containingDeclaration,
superCallTarget,
nameSuffix,
true,
true,
accessorKind
)
init {
setType(propertyType, emptyList<TypeParameterDescriptorImpl>(), dispatchReceiverParameter, receiverType)
val getterDescriptor =
if (isWithSyntheticGetterAccessor) Getter(this, accessorKind) else calleeDescriptor.getter as PropertyGetterDescriptorImpl?
val setterDescriptor = if (isWithSyntheticSetterAccessor) Setter(this, accessorKind) else calleeDescriptor.setter
initialize(getterDescriptor, setterDescriptor)
}
class Getter(property: AccessorForPropertyDescriptor, override val accessorKind: AccessorKind) : PropertyGetterDescriptorImpl(
property,
Annotations.EMPTY,
Modality.FINAL,
Visibilities.LOCAL,
false,
false,
false,
CallableMemberDescriptor.Kind.DECLARATION,
null,
SourceElement.NO_SOURCE
), AccessorForCallableDescriptor<PropertyGetterDescriptor> {
override val calleeDescriptor: PropertyGetterDescriptor
get() = (correspondingProperty as AccessorForPropertyDescriptor).calleeDescriptor.getter!!
override val superCallTarget: ClassDescriptor?
get() = (correspondingProperty as AccessorForPropertyDescriptor).superCallTarget
init {
initialize(property.type)
}
}
class Setter(property: AccessorForPropertyDescriptor, override val accessorKind: AccessorKind) : PropertySetterDescriptorImpl(
property,
Annotations.EMPTY,
Modality.FINAL,
Visibilities.LOCAL,
false,
false,
false,
CallableMemberDescriptor.Kind.DECLARATION,
null,
SourceElement.NO_SOURCE
), AccessorForCallableDescriptor<PropertySetterDescriptor> {
override val calleeDescriptor: PropertySetterDescriptor
get() = (correspondingProperty as AccessorForPropertyDescriptor).calleeDescriptor.setter!!
override val superCallTarget: ClassDescriptor?
get() = (correspondingProperty as AccessorForPropertyDescriptor).superCallTarget
init {
initializeDefault()
}
}
}

View File

@@ -300,6 +300,10 @@ public abstract class AnnotationCodegen {
return null;
}
if (classDescriptor.isExpect()) {
return null;
}
innerClassConsumer.addInnerClassInfoFromAnnotation(classDescriptor);
String asmTypeDescriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor();

View File

@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
import org.jetbrains.kotlin.resolve.inline.InlineUtil;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
import org.jetbrains.kotlin.resolve.jvm.RuntimeAssertionInfo;
@@ -509,7 +508,7 @@ public class AsmUtil {
});
}
static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type, JvmTarget jvmTarget, boolean isInterface) {
static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type, JvmTarget jvmTarget) {
if (type.getSort() == Type.ARRAY) {
Type elementType = correctElementType(type);
if (elementType.getSort() == Type.OBJECT || elementType.getSort() == Type.ARRAY) {
@@ -520,7 +519,7 @@ public class AsmUtil {
}
}
else if (type.getSort() == Type.OBJECT) {
iv.invokevirtual((isInterface ? AsmTypes.OBJECT_TYPE : type).getInternalName(), "hashCode", "()I", false);
iv.invokevirtual("java/lang/Object", "hashCode", "()I", false);
}
else if (type.getSort() == Type.BOOLEAN) {
Label end = new Label();

View File

@@ -1942,7 +1942,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
private CodegenContext getBackingFieldContext(
@NotNull FieldAccessorKind accessorKind,
@NotNull AccessorKind accessorKind,
@NotNull DeclarationDescriptor containingDeclaration
) {
switch (accessorKind) {
@@ -1992,22 +1992,22 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
boolean isBackingFieldInClassCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
FieldAccessorKind fieldAccessorKind;
AccessorKind fieldAccessorKind;
if (skipLateinitAssertion) {
fieldAccessorKind = FieldAccessorKind.LATEINIT_INTRINSIC;
fieldAccessorKind = AccessorKind.LATEINIT_INTRINSIC;
}
else if (isBackingFieldInClassCompanion &&
(forceField ||
(Visibilities.isPrivate(propertyDescriptor.getVisibility()) &&
isDefaultAccessor(propertyDescriptor.getGetter()) && isDefaultAccessor(propertyDescriptor.getSetter())))) {
fieldAccessorKind = FieldAccessorKind.IN_CLASS_COMPANION;
fieldAccessorKind = AccessorKind.IN_CLASS_COMPANION;
}
else if ((syntheticBackingField &&
context.getFirstCrossInlineOrNonInlineContext().getParentContext().getContextDescriptor() != containingDeclaration)) {
fieldAccessorKind = FieldAccessorKind.FIELD_FROM_LOCAL;
fieldAccessorKind = AccessorKind.FIELD_FROM_LOCAL;
}
else {
fieldAccessorKind = FieldAccessorKind.NORMAL;
fieldAccessorKind = AccessorKind.NORMAL;
}
boolean isStaticBackingField = DescriptorUtils.isStaticDeclaration(propertyDescriptor) ||
AsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor);
@@ -2022,7 +2022,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
CodegenContext backingFieldContext = getBackingFieldContext(fieldAccessorKind, containingDeclaration);
boolean isPrivateProperty =
fieldAccessorKind != FieldAccessorKind.NORMAL &&
fieldAccessorKind != AccessorKind.NORMAL &&
(AsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty) & ACC_PRIVATE) != 0;
DeclarationDescriptor ownerDescriptor;
boolean skipPropertyAccessors;
@@ -2033,7 +2033,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
boolean directAccessToSetter = couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context,
state.getShouldInlineConstVals());
if (fieldAccessorKind == FieldAccessorKind.LATEINIT_INTRINSIC) {
if (fieldAccessorKind == AccessorKind.LATEINIT_INTRINSIC) {
skipPropertyAccessors = !isPrivateProperty || context.getClassOrPackageParentContext() == backingFieldContext;
if (!skipPropertyAccessors) {
@@ -2042,7 +2042,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
ownerDescriptor = propertyDescriptor;
}
else if (fieldAccessorKind == FieldAccessorKind.IN_CLASS_COMPANION || fieldAccessorKind == FieldAccessorKind.FIELD_FROM_LOCAL) {
else if (fieldAccessorKind == AccessorKind.IN_CLASS_COMPANION || fieldAccessorKind == AccessorKind.FIELD_FROM_LOCAL) {
// Do not use accessor 'access<property name>$cp' when the property can be accessed directly by its backing field.
skipPropertyAccessors = skipAccessorsForPrivateFieldInOuterClass ||
(directAccessToGetter && (!propertyDescriptor.isVar() || directAccessToSetter));

View File

@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
import org.jetbrains.kotlin.codegen.coroutines.SuspendFunctionGenerationStrategy;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.JvmDefaultMode;
import org.jetbrains.kotlin.config.JvmTarget;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.descriptors.*;
@@ -179,7 +180,10 @@ public class FunctionCodegen {
) {
OwnerKind contextKind = methodContext.getContextKind();
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
if (isInterface(containingDeclaration) && !processInterfaceMethod(functionDescriptor, contextKind, false)) return;
if (isInterface(containingDeclaration) &&
!processInterfaceMethod(functionDescriptor, contextKind, false, false, state.getJvmDefaultMode())) {
return;
}
boolean hasSpecialBridge = hasSpecialBridgeMethod(functionDescriptor);
JvmMethodGenericSignature jvmSignature = strategy.mapMethodSignature(functionDescriptor, typeMapper, contextKind, hasSpecialBridge);
@@ -392,7 +396,7 @@ public class FunctionCodegen {
}
if (!functionDescriptor.isExternal()) {
generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy, memberCodegen);
generateMethodBody(mv, functionDescriptor, methodContext, jvmSignature, strategy, memberCodegen, state.getJvmDefaultMode());
}
else if (staticInCompanionObject) {
// native @JvmStatic foo() in companion object should delegate to the static native function moved to the outer class
@@ -402,7 +406,7 @@ public class FunctionCodegen {
Method accessorMethod =
typeMapper.mapAsmMethod(memberCodegen.getContext().accessibleDescriptor(staticFunctionDescriptor, null));
Type owningType = typeMapper.mapClass((ClassifierDescriptor) staticFunctionDescriptor.getContainingDeclaration());
generateDelegateToStaticMethodBody(false, mv, accessorMethod, owningType.getInternalName());
generateDelegateToStaticMethodBody(false, mv, accessorMethod, owningType.getInternalName(), false);
}
endVisit(mv, null, origin.getElement());
@@ -574,7 +578,8 @@ public class FunctionCodegen {
@NotNull MethodContext context,
@NotNull JvmMethodSignature signature,
@NotNull FunctionGenerationStrategy strategy,
@NotNull MemberCodegen<?> parentCodegen
@NotNull MemberCodegen<?> parentCodegen,
@NotNull JvmDefaultMode jvmDefaultMode
) {
mv.visitCode();
@@ -596,6 +601,20 @@ public class FunctionCodegen {
generateFacadeDelegateMethodBody(mv, signature.getAsmMethod(), (MultifileClassFacadeContext) context.getParentContext());
methodEnd = new Label();
}
else if (isCompatibilityStubInDefaultImpls(functionDescriptor, context, jvmDefaultMode)) {
FunctionDescriptor compatibility = ((DefaultImplsClassContext) context.getParentContext()).getInterfaceContext()
.getAccessorForJvmDefaultCompatibility(functionDescriptor);
int flags = AsmUtil.getMethodAsmFlags(functionDescriptor, OwnerKind.DEFAULT_IMPLS, context.getState());
assert (flags & Opcodes.ACC_ABSTRACT) == 0 : "Interface method with body should be non-abstract" + functionDescriptor;
CallableMethod method = typeMapper.mapToCallableMethod(compatibility, false);
generateDelegateToStaticMethodBody(
true, mv,
method.getAsmMethod(),
method.getOwner().getInternalName(),
true);
methodEnd = new Label();
}
else {
FrameMap frameMap = createFrameMap(
parentCodegen.state, signature, functionDescriptor.getExtensionReceiverParameter(),
@@ -690,6 +709,16 @@ public class FunctionCodegen {
}
}
private static boolean isCompatibilityStubInDefaultImpls(
@NotNull FunctionDescriptor functionDescriptor,
@NotNull MethodContext context,
@NotNull JvmDefaultMode jvmDefaultMode
) {
return OwnerKind.DEFAULT_IMPLS == context.getContextKind() &&
hasJvmDefaultAnnotation(functionDescriptor) &&
jvmDefaultMode.isCompatibility();
}
private static void generateLocalVariableTable(
@NotNull MethodVisitor mv,
@NotNull JvmMethodSignature jvmMethodSignature,
@@ -869,7 +898,7 @@ public class FunctionCodegen {
@NotNull Method asmMethod,
@NotNull MultifileClassFacadeContext context
) {
generateDelegateToStaticMethodBody(true, mv, asmMethod, context.getFilePartType().getInternalName());
generateDelegateToStaticMethodBody(true, mv, asmMethod, context.getFilePartType().getInternalName(), false);
}
private static void generateDelegateToMethodBody(
@@ -937,9 +966,10 @@ public class FunctionCodegen {
boolean isStatic,
@NotNull MethodVisitor mv,
@NotNull Method asmMethod,
@NotNull String classToDelegateTo
@NotNull String classToDelegateTo,
boolean isInterfaceMethodCall
) {
generateDelegateToMethodBody(isStatic ? 0 : 1, mv, asmMethod, classToDelegateTo, Opcodes.INVOKESTATIC, false);
generateDelegateToMethodBody(isStatic ? 0 : 1, mv, asmMethod, classToDelegateTo, Opcodes.INVOKESTATIC, isInterfaceMethodCall);
}
private static boolean needIndexForVar(JvmMethodParameterKind kind) {
@@ -1119,7 +1149,7 @@ public class FunctionCodegen {
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
if (isInterface(contextClass) &&
!processInterfaceMethod(functionDescriptor, kind, true)) {
!processInterfaceMethod(functionDescriptor, kind, true, false, state.getJvmDefaultMode())) {
return;
}
@@ -1164,6 +1194,17 @@ public class FunctionCodegen {
generateFacadeDelegateMethodBody(mv, defaultMethod, (MultifileClassFacadeContext) this.owner);
endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
}
else if (isCompatibilityStubInDefaultImpls(functionDescriptor, owner, state.getJvmDefaultMode())) {
mv.visitCode();
Method interfaceDefaultMethod = typeMapper.mapDefaultMethod(functionDescriptor, OwnerKind.IMPLEMENTATION);
generateDelegateToStaticMethodBody(
true, mv,
interfaceDefaultMethod,
typeMapper.mapOwner(functionDescriptor).getInternalName(),
true
);
endVisit(mv, "default method delegation to interface one", getSourceFromDescriptor(functionDescriptor));
}
else {
mv.visitCode();
generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen, defaultMethod);
@@ -1538,18 +1579,21 @@ public class FunctionCodegen {
public static boolean processInterfaceMethod(
@NotNull CallableMemberDescriptor memberDescriptor,
@NotNull OwnerKind kind,
boolean isDefaultOrSynthetic
boolean isDefault,
boolean isSynthetic,
JvmDefaultMode mode
) {
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
assert isInterface(containingDeclaration) : "'processInterfaceMethod' method should be called only for interfaces, but: " +
containingDeclaration;
if (hasJvmDefaultAnnotation(memberDescriptor)) {
return kind != OwnerKind.DEFAULT_IMPLS;
return (kind != OwnerKind.DEFAULT_IMPLS && !isSynthetic) ||
(kind == OwnerKind.DEFAULT_IMPLS && (isSynthetic || mode.isCompatibility()));
} else {
switch (kind) {
case DEFAULT_IMPLS: return true;
case IMPLEMENTATION: return !Visibilities.isPrivate(memberDescriptor.getVisibility()) && !isDefaultOrSynthetic;
case IMPLEMENTATION: return !Visibilities.isPrivate(memberDescriptor.getVisibility()) && !isDefault && !isSynthetic;
default: return false;
}
}

View File

@@ -41,7 +41,6 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature;
@@ -52,7 +51,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeUtils;
import org.jetbrains.org.objectweb.asm.FieldVisitor;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
@@ -575,23 +573,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.ifne(ne);
}
else {
if (isPrimitive(asmType)) {
StackValue value = StackValue.cmp(KtTokens.EQEQ, asmType, StackValue.onStack(asmType), StackValue.onStack(asmType));
value.put(Type.BOOLEAN_TYPE, iv);
}
else if (TypeUtils.isNullableType(propertyDescriptor.getType())) {
StackValue value =
genEqualsForExpressionsOnStack(KtTokens.EQEQ, StackValue.onStack(asmType), StackValue.onStack(asmType));
value.put(Type.BOOLEAN_TYPE, iv);
}
else {
Type owner =
DescriptorUtils.isInterface(propertyDescriptor.getType().getConstructor().getDeclarationDescriptor())
? AsmTypes.OBJECT_TYPE
: asmType;
iv.invokevirtual(owner.getInternalName(), "equals",
Type.getMethodDescriptor(Type.BOOLEAN_TYPE, AsmTypes.OBJECT_TYPE), false);
}
StackValue value = genEqualsForExpressionsOnStack(KtTokens.EQEQ, StackValue.onStack(asmType), StackValue.onStack(asmType));
value.put(Type.BOOLEAN_TYPE, iv);
iv.ifeq(ne);
}
}
@@ -632,8 +615,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.ifnull(ifNull);
}
genHashCode(mv, iv, asmType, state.getTarget(),
DescriptorUtils.isInterface(propertyDescriptor.getType().getConstructor().getDeclarationDescriptor()));
genHashCode(mv, iv, asmType, state.getTarget());
if (ifNull != null) {
Label end = new Label();
@@ -1422,7 +1404,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
private void generateTraitMethods() {
if (isInterface(descriptor)) return;
if (isJvmInterface(descriptor)) return;
for (Map.Entry<FunctionDescriptor, FunctionDescriptor> entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) {
FunctionDescriptor interfaceFun = entry.getKey();

View File

@@ -72,21 +72,17 @@ class InterfaceImplBodyCodegen(
// If implementation is a default interface method (JVM 8 only)
if (implementation.isDefinitelyNotDefaultImplsMethod()) continue
// We create a copy of the function with kind = DECLARATION so that FunctionCodegen will generate its body
val copy = memberDescriptor.copy(memberDescriptor.containingDeclaration, Modality.OPEN, memberDescriptor.visibility,
CallableMemberDescriptor.Kind.DECLARATION, true)
if (memberDescriptor is FunctionDescriptor) {
generateDelegationToSuperDefaultImpls(copy as FunctionDescriptor, implementation as FunctionDescriptor)
generateDelegationToSuperDefaultImpls(memberDescriptor, implementation as FunctionDescriptor)
}
else if (memberDescriptor is PropertyDescriptor) {
implementation as PropertyDescriptor
val getter = (copy as PropertyDescriptor).getter
val getter = memberDescriptor.getter
val implGetter = implementation.getter
if (getter != null && implGetter != null) {
generateDelegationToSuperDefaultImpls(getter, implGetter)
}
val setter = copy.setter
val setter = memberDescriptor.setter
val implSetter = implementation.setter
if (setter != null && implSetter != null) {
generateDelegationToSuperDefaultImpls(setter, implSetter)

View File

@@ -723,8 +723,18 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
markLineNumberForElement(element.getPsiOrParent(), codegen.v);
generateMethodCallTo(original, accessor, codegen.v).coerceTo(signature.getReturnType(), null, codegen.v);
if (accessorForCallableDescriptor.getAccessorKind() == AccessorKind.JVM_DEFAULT_COMPATIBILITY) {
FunctionDescriptor descriptor = unwrapFakeOverrideToAnyDeclaration(original).getOriginal();
if (descriptor != original) {
descriptor = descriptor
.copy(original.getContainingDeclaration(), descriptor.getModality(), descriptor.getVisibility(),
descriptor.getKind(), false);
}
generateMethodCallTo(descriptor, accessor, codegen.v).coerceTo(signature.getReturnType(), null, codegen.v);
}
else {
generateMethodCallTo(original, accessor, codegen.v).coerceTo(signature.getReturnType(), null, codegen.v);
}
codegen.v.areturn(signature.getReturnType());
}
@@ -745,9 +755,26 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
FieldAccessorKind fieldAccessorKind = accessor instanceof AccessorForPropertyBackingField
? ((AccessorForPropertyBackingField) accessor).getFieldAccessorKind() : null;
boolean syntheticBackingField = fieldAccessorKind == FieldAccessorKind.FIELD_FROM_LOCAL;
if (accessorForCallableDescriptor.getAccessorKind() == AccessorKind.JVM_DEFAULT_COMPATIBILITY) {
markLineNumberForElement(element.getPsiOrParent(), codegen.v);
PropertyDescriptor descriptor = unwrapFakeOverrideToAnyDeclaration(original).getOriginal();
if (descriptor != original) {
descriptor = (PropertyDescriptor) descriptor
.copy(original.getContainingDeclaration(), descriptor.getModality(), descriptor.getVisibility(),
descriptor.getKind(), false);
}
boolean isGetter = callableDescriptor instanceof PropertyGetterDescriptor;
PropertyAccessorDescriptor originalAccessor = isGetter ? descriptor.getGetter(): descriptor.getSetter();
PropertyAccessorDescriptor accessorDescriptor = isGetter ? accessor.getGetter() : accessor.getSetter();
generateMethodCallTo(originalAccessor, accessorDescriptor, codegen.v)
.coerceTo(signature.getReturnType(), null, codegen.v);
codegen.v.areturn(signature.getReturnType());
return;
}
AccessorKind fieldAccessorKind = accessor instanceof AccessorForPropertyBackingField
? accessor.getAccessorKind() : null;
boolean syntheticBackingField = fieldAccessorKind == AccessorKind.FIELD_FROM_LOCAL;
boolean forceFieldForCompanionProperty = JvmAbi.isPropertyWithBackingFieldInOuterClass(original) &&
!isCompanionObject(accessor.getContainingDeclaration());
boolean forceField = forceFieldForCompanionProperty ||
@@ -756,7 +783,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
StackValue property = codegen.intermediateValueForProperty(
original, forceField, syntheticBackingField, accessor.getSuperCallTarget(),
forceFieldForCompanionProperty, StackValue.none(), null,
fieldAccessorKind == FieldAccessorKind.LATEINIT_INTRINSIC
fieldAccessorKind == AccessorKind.LATEINIT_INTRINSIC
);
InstructionAdapter iv = codegen.v;
@@ -815,7 +842,8 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
CallableMethod callableMethod = typeMapper.mapToCallableMethod(
functionDescriptor,
accessorDescriptor instanceof AccessorForCallableDescriptor &&
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallTarget() != null
(((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallTarget() != null ||
((AccessorForCallableDescriptor) accessorDescriptor).getAccessorKind() == AccessorKind.JVM_DEFAULT_COMPATIBILITY)
);
boolean isJvmStaticInObjectOrClass = CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);

View File

@@ -52,6 +52,7 @@ 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.FunctionCodegen.processInterfaceMethod;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTIES;
@@ -352,7 +353,7 @@ public class PropertyCodegen {
if (annotations.getAllAnnotations().isEmpty()) return;
DeclarationDescriptor contextDescriptor = context.getContextDescriptor();
if (!isInterface(contextDescriptor) || FunctionCodegen.processInterfaceMethod(descriptor, kind, true)) {
if (!isInterface(contextDescriptor) || processInterfaceMethod(descriptor, kind, false, true, state.getJvmDefaultMode())) {
memberCodegen.generateSyntheticAnnotationsMethod(
descriptor, getSyntheticMethodSignature(descriptor), annotations, AnnotationUseSiteTarget.PROPERTY
);

View File

@@ -9,6 +9,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.stubs.StubElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.SmartList;
import com.intellij.util.containers.Stack;
import kotlin.Pair;
import kotlin.collections.CollectionsKt;
@@ -44,6 +45,8 @@ import org.jetbrains.kotlin.resolve.calls.model.ExpressionValueArgument;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall;
import org.jetbrains.kotlin.resolve.calls.tower.NewResolvedCallImpl;
import org.jetbrains.kotlin.resolve.calls.tower.NewVariableAsFunctionResolvedCallImpl;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.EnumValue;
import org.jetbrains.kotlin.resolve.constants.NullValue;
@@ -694,18 +697,54 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
CallableDescriptor descriptor = call.getResultingDescriptor();
if (!(descriptor instanceof FunctionDescriptor)) return;
recordSamValueForNewInference(call);
recordSamConstructorIfNeeded(expression, call);
FunctionDescriptor original = SamCodegenUtil.getOriginalIfSamAdapter((FunctionDescriptor) descriptor);
if (original == null) return;
List<ResolvedValueArgument> valueArguments = call.getValueArgumentsByIndex();
if (valueArguments == null) return;
List<ValueParameterDescriptor> valueParametersWithSAMConversion = new SmartList<>();
for (ValueParameterDescriptor valueParameter : original.getValueParameters()) {
ValueParameterDescriptor adaptedParameter = descriptor.getValueParameters().get(valueParameter.getIndex());
if (KotlinTypeChecker.DEFAULT.equalTypes(adaptedParameter.getType(), valueParameter.getType())) continue;
valueParametersWithSAMConversion.add(valueParameter);
}
writeSamValueForValueParameters(valueParametersWithSAMConversion, call.getValueArgumentsByIndex());
}
private void recordSamValueForNewInference(@NotNull ResolvedCall<?> call) {
NewResolvedCallImpl<?> newResolvedCall = null;
if (call instanceof NewVariableAsFunctionResolvedCallImpl) {
newResolvedCall = ((NewVariableAsFunctionResolvedCallImpl) call).getFunctionCall();
}
else if(call instanceof NewResolvedCallImpl) {
newResolvedCall = (NewResolvedCallImpl<?>) call;
}
if (newResolvedCall == null) return;
List<ValueParameterDescriptor> valueParametersWithSAMConversion = new SmartList<>();
Map<ValueParameterDescriptor, ResolvedValueArgument> arguments = newResolvedCall.getValueArguments();
for (ValueParameterDescriptor valueParameter : arguments.keySet()) {
ResolvedValueArgument argument = arguments.get(valueParameter);
if (!(argument instanceof ExpressionValueArgument)) continue;
ValueArgument valueArgument = ((ExpressionValueArgument) argument).getValueArgument();
if (valueArgument == null || newResolvedCall.getExpectedTypeForSamConvertedArgument(valueArgument) == null) continue;
valueParametersWithSAMConversion.add(valueParameter.getOriginal());
}
writeSamValueForValueParameters(valueParametersWithSAMConversion, newResolvedCall.getValueArgumentsByIndex());
}
private void writeSamValueForValueParameters(
@NotNull Collection<ValueParameterDescriptor> valueParametersWithSAMConversion,
@Nullable List<ResolvedValueArgument> valueArguments
) {
if (valueArguments == null) return;
for (ValueParameterDescriptor valueParameter : valueParametersWithSAMConversion) {
SamType samType = SamType.createByValueParameter(valueParameter);
if (samType == null) continue;

View File

@@ -48,11 +48,11 @@ import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.util.Textifier
import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import java.io.StringWriter
import java.io.PrintWriter
import java.io.StringWriter
import java.util.*
fun generateIsCheck(
@@ -271,6 +271,7 @@ fun Collection<Type>.withVariableIndices(): List<Pair<Int, Type>> = mutableListO
}
fun FunctionDescriptor.isGenericToArray(): Boolean {
if (name.asString() != "toArray") return false
if (valueParameters.size != 1 || typeParameters.size != 1) return false
val returnType = returnType ?: throw AssertionError(toString())
@@ -284,6 +285,7 @@ fun FunctionDescriptor.isGenericToArray(): Boolean {
}
fun FunctionDescriptor.isNonGenericToArray(): Boolean {
if (name.asString() != "toArray") return false
if (!valueParameters.isEmpty() || !typeParameters.isEmpty()) return false
val returnType = returnType

View File

@@ -48,16 +48,16 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
private static class AccessorKey {
public final DeclarationDescriptor descriptor;
public final ClassDescriptor superCallLabelTarget;
public final FieldAccessorKind fieldAccessorKind;
public final AccessorKind accessorKind;
public AccessorKey(
@NotNull DeclarationDescriptor descriptor,
@Nullable ClassDescriptor superCallLabelTarget,
@NotNull FieldAccessorKind fieldAccessorKind
@NotNull AccessorKind accessorKind
) {
this.descriptor = descriptor;
this.superCallLabelTarget = superCallLabelTarget;
this.fieldAccessorKind = fieldAccessorKind;
this.accessorKind = accessorKind;
}
@Override
@@ -65,7 +65,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
if (!(obj instanceof AccessorKey)) return false;
AccessorKey other = (AccessorKey) obj;
return descriptor.equals(other.descriptor) &&
fieldAccessorKind == other.fieldAccessorKind &&
accessorKind == other.accessorKind &&
(superCallLabelTarget == null ? other.superCallLabelTarget == null
: superCallLabelTarget.equals(other.superCallLabelTarget));
}
@@ -73,7 +73,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@Override
public int hashCode() {
return 31 * descriptor.hashCode() +
fieldAccessorKind.hashCode() +
accessorKind.hashCode() +
(superCallLabelTarget == null ? 0 : superCallLabelTarget.hashCode());
}
@@ -88,6 +88,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
private final @NotNull DeclarationDescriptor containingDeclaration;
private final @Nullable ClassDescriptor superCallTarget;
private final @NotNull String nameSuffix;
private final @NotNull AccessorKind accessorKind;
private AccessorForPropertyDescriptor withSyntheticGetterAndSetter = null;
private AccessorForPropertyDescriptor withSyntheticGetter = null;
@@ -97,12 +98,14 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull PropertyDescriptor property,
@NotNull DeclarationDescriptor containingDeclaration,
@Nullable ClassDescriptor superCallTarget,
@NotNull String nameSuffix
@NotNull String nameSuffix,
@NotNull AccessorKind accessorKind
) {
this.property = property;
this.containingDeclaration = containingDeclaration;
this.superCallTarget = superCallTarget;
this.nameSuffix = nameSuffix;
this.accessorKind = accessorKind;
}
@SuppressWarnings("ConstantConditions")
@@ -114,7 +117,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
if (withSyntheticGetter == null) {
withSyntheticGetter = new AccessorForPropertyDescriptor(
property, containingDeclaration, superCallTarget, nameSuffix,
true, false);
true, false, accessorKind);
}
return withSyntheticGetter;
}
@@ -122,7 +125,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
if (withSyntheticSetter == null) {
withSyntheticSetter = new AccessorForPropertyDescriptor(
property, containingDeclaration, superCallTarget, nameSuffix,
false, true);
false, true, accessorKind);
}
return withSyntheticSetter;
}
@@ -136,7 +139,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
if (withSyntheticGetterAndSetter == null) {
withSyntheticGetterAndSetter = new AccessorForPropertyDescriptor(
property, containingDeclaration, superCallTarget, nameSuffix,
true, true);
true, true, accessorKind);
}
return withSyntheticGetterAndSetter;
}
@@ -402,12 +405,24 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
boolean getterAccessorRequired,
boolean setterAccessorRequired
) {
return getAccessor(propertyDescriptor, FieldAccessorKind.NORMAL, null, superCallTarget, getterAccessorRequired, setterAccessorRequired);
return getAccessor(propertyDescriptor, AccessorKind.NORMAL, null, superCallTarget, getterAccessorRequired, setterAccessorRequired);
}
public <D extends CallableMemberDescriptor> D getAccessorForJvmDefaultCompatibility(@NotNull D descriptor) {
if (descriptor instanceof PropertyAccessorDescriptor) {
PropertyDescriptor propertyAccessor = getAccessor(((PropertyAccessorDescriptor) descriptor).getCorrespondingProperty(),
AccessorKind.JVM_DEFAULT_COMPATIBILITY, null, null,
descriptor instanceof PropertyGetterDescriptor,
descriptor instanceof PropertySetterDescriptor);
return descriptor instanceof PropertyGetterDescriptor ? (D) propertyAccessor.getGetter() : (D) propertyAccessor.getSetter();
}
return getAccessor(descriptor, AccessorKind.JVM_DEFAULT_COMPATIBILITY, null, null);
}
@NotNull
private <D extends CallableMemberDescriptor> D getAccessor(@NotNull D descriptor, @Nullable ClassDescriptor superCallTarget) {
return getAccessor(descriptor, FieldAccessorKind.NORMAL, null, superCallTarget);
return getAccessor(descriptor, AccessorKind.NORMAL, null, superCallTarget);
}
@SuppressWarnings("unchecked")
@@ -430,7 +445,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull
public <D extends CallableMemberDescriptor> D getAccessor(
@NotNull D possiblySubstitutedDescriptor,
@NotNull FieldAccessorKind accessorKind,
@NotNull AccessorKind accessorKind,
@Nullable KotlinType delegateType,
@Nullable ClassDescriptor superCallTarget
) {
@@ -445,7 +460,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull
private <D extends CallableMemberDescriptor> D getAccessor(
@NotNull D possiblySubstitutedDescriptor,
@NotNull FieldAccessorKind accessorKind,
@NotNull AccessorKind accessorKind,
@Nullable KotlinType delegateType,
@Nullable ClassDescriptor superCallTarget,
boolean getterAccessorRequired,
@@ -468,7 +483,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
if (accessors.containsKey(key)) {
AccessorForCallableDescriptor<?> accessor = accessors.get(key);
assert accessorKind == FieldAccessorKind.NORMAL ||
assert accessorKind == AccessorKind.NORMAL ||
accessor instanceof AccessorForPropertyBackingField : "There is already exists accessor with isForBackingField = false in this context";
return (D) accessor;
}
@@ -476,16 +491,16 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
String nameSuffix = SyntheticAccessorUtilKt.getAccessorNameSuffix(descriptor, key.superCallLabelTarget, accessorKind);
AccessorForCallableDescriptor<?> accessor;
if (descriptor instanceof SimpleFunctionDescriptor) {
accessor = new AccessorForFunctionDescriptor((FunctionDescriptor) descriptor, contextDescriptor, superCallTarget, nameSuffix);
accessor = new AccessorForFunctionDescriptor((FunctionDescriptor) descriptor, contextDescriptor, superCallTarget, nameSuffix, accessorKind);
}
else if (descriptor instanceof ClassConstructorDescriptor) {
accessor = new AccessorForConstructorDescriptor((ClassConstructorDescriptor) descriptor, contextDescriptor, superCallTarget);
accessor = new AccessorForConstructorDescriptor((ClassConstructorDescriptor) descriptor, contextDescriptor, superCallTarget, accessorKind);
}
else if (descriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
if (accessorKind == FieldAccessorKind.NORMAL) {
if (accessorKind == AccessorKind.NORMAL || accessorKind == AccessorKind.JVM_DEFAULT_COMPATIBILITY) {
AccessorForPropertyDescriptorFactory factory =
new AccessorForPropertyDescriptorFactory(propertyDescriptor, contextDescriptor, superCallTarget, nameSuffix);
new AccessorForPropertyDescriptorFactory(propertyDescriptor, contextDescriptor, superCallTarget, nameSuffix, accessorKind);
propertyAccessorFactories.put(key, factory);
// Record worst case accessor for accessor methods generation.
@@ -496,8 +511,8 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
accessor = new AccessorForPropertyBackingField(
propertyDescriptor, contextDescriptor, delegateType,
accessorKind == FieldAccessorKind.IN_CLASS_COMPANION ? null : propertyDescriptor.getExtensionReceiverParameter(),
accessorKind == FieldAccessorKind.IN_CLASS_COMPANION ? null : propertyDescriptor.getDispatchReceiverParameter(),
accessorKind == AccessorKind.IN_CLASS_COMPANION ? null : propertyDescriptor.getExtensionReceiverParameter(),
accessorKind == AccessorKind.IN_CLASS_COMPANION ? null : propertyDescriptor.getDispatchReceiverParameter(),
nameSuffix, accessorKind
);
}

View File

@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.backend.jvm.codegen.IrExpressionLambda
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.ClosureCodegen
import org.jetbrains.kotlin.codegen.StackValue
@@ -370,14 +369,7 @@ class MethodInliner(
)
val transformationVisitor = object : MethodVisitor(API, transformedNode) {
/*
Ignore simple @InlineOnly functions such as 'error()' or 'assert()' without lambda parameters,
as we likely to want to have a line number from the call site in a stack trace.
*/
private val GENERATE_LINE_NUMBERS = GENERATE_SMAP && (inlineOnlySmapSkipper == null || run {
val callableDescriptor = inliningContext.root.sourceCompilerForInline.callableDescriptor
callableDescriptor != null && callableDescriptor.valueParameters.any { it.type.isFunctionType }
})
private val GENERATE_DEBUG_INFO = GENERATE_SMAP && inlineOnlySmapSkipper == null
private val isInliningLambda = nodeRemapper.isInsideInliningLambda
@@ -409,7 +401,7 @@ class MethodInliner(
}
override fun visitLineNumber(line: Int, start: Label) {
if (isInliningLambda || GENERATE_LINE_NUMBERS) {
if (isInliningLambda || GENERATE_DEBUG_INFO) {
super.visitLineNumber(line, start)
}
}
@@ -437,7 +429,7 @@ class MethodInliner(
override fun visitLocalVariable(
name: String, desc: String, signature: String?, start: Label, end: Label, index: Int
) {
if (isInliningLambda || (GENERATE_SMAP && inlineOnlySmapSkipper == null)) {
if (isInliningLambda || GENERATE_DEBUG_INFO) {
val varSuffix = if (inliningContext.isRoot && !isFakeLocalVariableForInline(name)) INLINE_FUN_VAR_SUFFIX else ""
val varName = if (!varSuffix.isEmpty() && name == "this") name + "_" else name
super.visitLocalVariable(varName + varSuffix, desc, signature, start, end, getNewIndex(index))

View File

@@ -48,8 +48,6 @@ interface SourceCompilerForInline {
val callElement: Any
val callableDescriptor: CallableDescriptor?
val lookupLocation: LookupLocation
val callElementText: String
@@ -105,8 +103,6 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
override val lookupLocation = KotlinLookupLocation(callElement)
override val callableDescriptor: CallableDescriptor?
get() = (this.context as? MethodContext)?.functionDescriptor
override val callElementText by lazy {
callElement.text
@@ -203,7 +199,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
else -> FunctionGenerationStrategy.FunctionDefault(state, expression as KtDeclarationWithBody)
}
FunctionCodegen.generateMethodBody(adapter, descriptor, context, jvmMethodSignature, strategy, parentCodegen)
FunctionCodegen.generateMethodBody(adapter, descriptor, context, jvmMethodSignature, strategy, parentCodegen, state.jvmDefaultMode)
if (isLambda) {
codegen.propagateChildReifiedTypeParametersUsages(parentCodegen.reifiedTypeParametersUsages)

View File

@@ -26,6 +26,7 @@ import java.util.*
private val EXTERNAL_SOURCES_KINDS = arrayOf(
JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL,
JvmDeclarationOriginKind.DEFAULT_IMPL_DELEGATION_TO_SUPERINTERFACE_DEFAULT_IMPL,
JvmDeclarationOriginKind.DELEGATION,
JvmDeclarationOriginKind.BRIDGE
)

View File

@@ -226,6 +226,8 @@ class GenerationState private constructor(
JVMConstructorCallNormalizationMode.DEFAULT
)
val jvmDefaultMode = languageVersionSettings.getFlag(AnalysisFlag.jvmDefaultMode)
init {
val disableOptimization = configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false)

View File

@@ -150,6 +150,16 @@ public class KotlinTypeMapper {
}
};
public KotlinTypeMapper(
@NotNull BindingContext bindingContext,
@NotNull ClassBuilderMode classBuilderMode,
@NotNull IncompatibleClassTracker incompatibleClassTracker,
@NotNull String moduleName,
boolean isJvm8Target
) {
this(bindingContext, classBuilderMode, incompatibleClassTracker, moduleName, isJvm8Target, false);
}
public KotlinTypeMapper(
@NotNull BindingContext bindingContext,
@NotNull ClassBuilderMode classBuilderMode,

View File

@@ -19,19 +19,22 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.resolve.DescriptorUtils
enum class FieldAccessorKind(val suffix: String) {
enum class AccessorKind(val suffix: String) {
NORMAL("p"),
IN_CLASS_COMPANION("cp"),
FIELD_FROM_LOCAL("lp"),
LATEINIT_INTRINSIC("li"),
JVM_DEFAULT_COMPATIBILITY("jd")
}
private fun CallableMemberDescriptor.getJvmName() =
DescriptorUtils.getJvmName(this) ?: name.asString()
DescriptorUtils.getJvmName(this) ?: name.asString()
fun getAccessorNameSuffix(
descriptor: CallableMemberDescriptor, superCallDescriptor: ClassDescriptor?, accessorKind: FieldAccessorKind
descriptor: CallableMemberDescriptor, superCallDescriptor: ClassDescriptor?, accessorKind: AccessorKind
): String {
if (accessorKind == AccessorKind.JVM_DEFAULT_COMPATIBILITY) return descriptor.getJvmName() + "$" + AccessorKind.JVM_DEFAULT_COMPATIBILITY.suffix
val suffix = when (descriptor) {
is ConstructorDescriptor ->
return "will be ignored"
@@ -40,8 +43,7 @@ fun getAccessorNameSuffix(
is PropertyDescriptor ->
descriptor.getJvmName() + "$" + accessorKind.suffix
else ->
throw UnsupportedOperationException("Do not know how to create accessor for descriptor " + descriptor)
throw UnsupportedOperationException("Do not know how to create accessor for descriptor $descriptor")
}
return if (superCallDescriptor == null) suffix else "$suffix\$s${superCallDescriptor.name.asString().hashCode()}"
}

View File

@@ -74,6 +74,9 @@ dependencies {
testCompile(projectTests(":generators:test-generator"))
testCompile(project(":compiler:ir.ir2cfg"))
testCompile(project(":compiler:ir.tree")) // used for deepCopyWithSymbols call that is removed by proguard from the compiler TODO: make it more straightforward
testCompile(project(":kotlin-scripting-compiler"))
testCompile(project(":kotlin-scripting-misc"))
testCompile(project(":kotlin-script-util"))
testCompileOnly(projectRuntimeJar(":kotlin-daemon-client"))
testCompileOnly(project(":kotlin-reflect-api"))
otherCompilerModules.forEach {

View File

@@ -25,7 +25,8 @@ import java.util.*
@SuppressWarnings("WeakerAccess")
abstract class CommonCompilerArguments : CommonToolArguments() {
companion object {
@JvmStatic private val serialVersionUID = 0L
@JvmStatic
private val serialVersionUID = 0L
const val PLUGIN_OPTION_FORMAT = "plugin:<pluginId>:<optionName>=<value>"
@@ -39,9 +40,9 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
@GradleOption(DefaultValues.LanguageVersions::class)
@Argument(
value = "-language-version",
valueDescription = "<version>",
description = "Provide source compatibility with specified language version"
value = "-language-version",
valueDescription = "<version>",
description = "Provide source compatibility with specified language version"
)
var languageVersion: String? by FreezableVar(null)
@@ -50,16 +51,16 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
@GradleOption(DefaultValues.LanguageVersions::class)
@Argument(
value = "-api-version",
valueDescription = "<version>",
description = "Allow to use declarations only from the specified version of bundled libraries"
value = "-api-version",
valueDescription = "<version>",
description = "Allow to use declarations only from the specified version of bundled libraries"
)
var apiVersion: String? by FreezableVar(null)
@Argument(
value = "-kotlin-home",
valueDescription = "<path>",
description = "Path to Kotlin compiler home directory, used for runtime libraries discovery"
value = "-kotlin-home",
valueDescription = "<path>",
description = "Path to Kotlin compiler home directory, used for runtime libraries discovery"
)
var kotlinHome: String? by FreezableVar(null)
@@ -72,12 +73,15 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
var noInline: Boolean by FreezableVar(false)
@Argument(
value = "-Xskip-metadata-version-check",
description = "Load classes with bad metadata version anyway (incl. pre-release classes)"
value = "-Xskip-metadata-version-check",
description = "Load classes with bad metadata version anyway (incl. pre-release classes)"
)
var skipMetadataVersionCheck: Boolean by FreezableVar(false)
@Argument(value = "-Xallow-kotlin-package", description = "Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info")
@Argument(
value = "-Xallow-kotlin-package",
description = "Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info"
)
var allowKotlinPackage: Boolean by FreezableVar(false)
@Argument(value = "-Xreport-output-files", description = "Report source to output files mapping")
@@ -93,34 +97,34 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
var noCheckActual: Boolean by FreezableVar(false)
@Argument(
value = "-Xintellij-plugin-root",
valueDescription = "<path>",
description = "Path to the kotlin-compiler.jar or directory where IntelliJ configuration files can be found"
value = "-Xintellij-plugin-root",
valueDescription = "<path>",
description = "Path to the kotlin-compiler.jar or directory where IntelliJ configuration files can be found"
)
var intellijPluginRoot: String? by FreezableVar(null)
@Argument(
value = "-Xcoroutines",
valueDescription = "{enable|warn|error}",
description = "Enable coroutines or report warnings or errors on declarations and use sites of 'suspend' modifier"
value = "-Xcoroutines",
valueDescription = "{enable|warn|error}",
description = "Enable coroutines or report warnings or errors on declarations and use sites of 'suspend' modifier"
)
var coroutinesState: String? by FreezableVar(WARN)
@Argument(
value = "-Xnew-inference",
description = "Enable new experimental generic type inference algorithm"
value = "-Xnew-inference",
description = "Enable new experimental generic type inference algorithm"
)
var newInference: Boolean by FreezableVar(false)
@Argument(
value = "-Xlegacy-smart-cast-after-try",
description = "Allow var smart casts despite assignment in try block"
value = "-Xlegacy-smart-cast-after-try",
description = "Allow var smart casts despite assignment in try block"
)
var legacySmartCastAfterTry: Boolean by FreezableVar(false)
@Argument(
value = "-Xeffect-system",
description = "Enable experimental language feature: effect system"
value = "-Xeffect-system",
description = "Enable experimental language feature: effect system"
)
var effectSystem: Boolean by FreezableVar(false)
@@ -131,9 +135,9 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
var readDeserializedContracts: Boolean by FreezableVar(false)
@Argument(
value = "-Xexperimental",
valueDescription = "<fq.name>",
description = "Enable and propagate usages of experimental API for marker annotation with the given fully qualified name"
value = "-Xexperimental",
valueDescription = "<fq.name>",
description = "Enable and propagate usages of experimental API for marker annotation with the given fully qualified name"
)
var experimental: Array<String>? by FreezableVar(null)
@@ -160,6 +164,16 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
var dumpPerf: String? by FreezableVar(null)
@Argument(
value = "-Xprogressive",
description = "Enable compiler progressive mode.\n" +
"In this mode, deprecations and bug fixes for unstable code take effect immediately,\n" +
"instead of going through graceful migration cycle.\n" +
"Code, written in progressive mode is backward compatible; however, code written in\n" +
"non-progressive mode may cause compilation errors in progressive mode."
)
var progressiveMode by FreezableVar(false)
open fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
return HashMap<AnalysisFlag<*>, Any>().apply {
put(AnalysisFlag.skipMetadataVersionCheck, skipMetadataVersionCheck)
@@ -180,7 +194,8 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
when (coroutinesState) {
CommonCompilerArguments.ERROR -> put(LanguageFeature.Coroutines, LanguageFeature.State.ENABLED_WITH_ERROR)
CommonCompilerArguments.ENABLE -> put(LanguageFeature.Coroutines, LanguageFeature.State.ENABLED)
CommonCompilerArguments.WARN -> {}
CommonCompilerArguments.WARN -> {
}
else -> {
val message = "Invalid value of -Xcoroutines (should be: enable, warn or error): " + coroutinesState
collector.report(CompilerMessageSeverity.ERROR, message, null)
@@ -207,8 +222,42 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
if (properIeee754Comparisons) {
put(LanguageFeature.ProperIeee754Comparisons, LanguageFeature.State.ENABLED)
}
if (progressiveMode) {
LanguageFeature.values().filter { it.kind.enabledInProgressiveMode }.forEach {
// Don't overwrite other settings: users may want to turn off some particular
// breaking change manually instead of turning off whole progressive mode
if (!contains(it)) put(it, LanguageFeature.State.ENABLED)
}
}
// Internal arguments should go last, because it may be useful to override
// some feature state via -XX (even if some -X flags were passed)
if (internalArguments.isNotEmpty()) {
configureLanguageFeaturesFromInternalArgs(collector)
}
}
private fun HashMap<LanguageFeature, LanguageFeature.State>.configureLanguageFeaturesFromInternalArgs(collector: MessageCollector) {
val languageSettingsParser = LanguageSettingsParser()
val featuresThatForcePreReleaseBinaries = mutableListOf<LanguageFeature>()
for (argument in internalArguments) {
val (feature, state) = languageSettingsParser.parseInternalArgument(argument, collector) ?: continue
put(feature, state)
if (state == LanguageFeature.State.ENABLED && feature.forcesPreReleaseBinariesIfEnabled()) {
featuresThatForcePreReleaseBinaries += feature
}
}
if (featuresThatForcePreReleaseBinaries.isNotEmpty()) {
collector.report(
CompilerMessageSeverity.STRONG_WARNING,
"Following manually enabled features will force generation of pre-release binaries: ${featuresThatForcePreReleaseBinaries.joinToString()}"
)
}
}
fun configureLanguageVersionSettings(collector: MessageCollector): LanguageVersionSettings {
// If only "-api-version" is specified, language version is assumed to be the latest stable
@@ -232,6 +281,14 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
)
}
if (progressiveMode && languageVersion < LanguageVersion.LATEST_STABLE) {
collector.report(
CompilerMessageSeverity.STRONG_WARNING,
"'-Xprogressive' meaningful only for latest language version (${LanguageVersion.LATEST_STABLE}), while this build uses $languageVersion\n" +
"Behaviour of compiler in such mode is undefined; please, consider moving to the latest stable version or turning off progressive mode."
)
}
return LanguageVersionSettingsImpl(
languageVersion,
ApiVersion.createByLanguageVersion(apiVersion),

View File

@@ -20,12 +20,14 @@ import java.io.Serializable
abstract class CommonToolArguments : Freezable(), Serializable {
companion object {
@JvmStatic private val serialVersionUID = 0L
@JvmStatic
private val serialVersionUID = 0L
}
var freeArgs: List<String> by FreezableVar(emptyList())
@Transient var errors: ArgumentParseErrors = ArgumentParseErrors()
@Transient
var errors: ArgumentParseErrors = ArgumentParseErrors()
@Argument(value = "-help", shortName = "-h", description = "Print a synopsis of standard options")
var help: Boolean by FreezableVar(false)
@@ -47,4 +49,6 @@ abstract class CommonToolArguments : Freezable(), Serializable {
@GradleOption(DefaultValues.BooleanFalseDefault::class)
@Argument(value = "-Werror", description = "Report an error if there are any warnings")
var allWarningsAsErrors: Boolean by FreezableVar(false)
var internalArguments: List<String> by FreezableVar(emptyList())
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.cli.common.arguments
import org.jetbrains.kotlin.cli.common.arguments.InternalArgumentParser.Companion.INTERNAL_ARGUMENT_PREFIX
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.LanguageFeature
/**
* Arguments that can drastically change compiler behavior,
* breaking stability/compatibility.
*
* Internal arguments are split into 'families', each family
* with its own set of arguments, settings and parsing rules
*
* Internal arguments start with '-XX' prefix, followed by
* family name. Everything after that is handled by the corresponding
* parser of that particular family.
*/
interface InternalArgumentParser<A : InternalArgument> {
// Should be fast
fun canParse(arg: String): Boolean
fun parseInternalArgument(arg: String, messageCollector: MessageCollector): A?
companion object {
internal const val INTERNAL_ARGUMENT_PREFIX = "-XX"
internal val PARSERS: List<InternalArgumentParser<*>> = listOf(
LanguageSettingsParser()
)
}
}
abstract class AbstractInternalArgumentParser<A : InternalArgument>(familyName: String) : InternalArgumentParser<A> {
private val wholePrefix: String = INTERNAL_ARGUMENT_PREFIX + familyName
override fun canParse(arg: String): Boolean = arg.startsWith(wholePrefix)
override fun parseInternalArgument(arg: String, messageCollector: MessageCollector): A? {
if (!arg.startsWith(wholePrefix)) return null
return parseTail(arg.removePrefix(wholePrefix), arg, messageCollector)
}
abstract fun parseTail(tail: String, wholeArgument: String, messageCollector: MessageCollector): A?
}
// Arguments of form '-XXLanguage:+LanguageFeature' or '-XXLanguage:-LanguageFeature', which enable or disable corresponding LanguageFeature.
class LanguageSettingsParser : AbstractInternalArgumentParser<ManualLanguageFeatureSetting>("Language") {
// Expected tail form: ':(+|-)<language feature name>'
override fun parseTail(tail: String, wholeArgument: String, messageCollector: MessageCollector): ManualLanguageFeatureSetting? {
fun reportAndReturnNull(message: String): Nothing? {
messageCollector.report(CompilerMessageSeverity.STRONG_WARNING, message)
return null
}
val colon = tail.getOrNull(0) ?: return reportAndReturnNull("Incorrect internal argument syntax, missing colon: $wholeArgument")
val modificator = tail.getOrNull(1)
val languageFeatureState = when (modificator) {
'+' -> LanguageFeature.State.ENABLED
'-' -> LanguageFeature.State.DISABLED
else -> return reportAndReturnNull("Incorrect internal argument syntax, missing modificator: $wholeArgument")
}
val languageFeatureName = tail.substring(2)
if (languageFeatureName.isEmpty()) return reportAndReturnNull("Empty language feature name for internal argument '$wholeArgument'")
val languageFeature = LanguageFeature.fromString(languageFeatureName)
?: return reportAndReturnNull("Unknown language feature '$languageFeatureName' in passed internal argument '$wholeArgument'")
return ManualLanguageFeatureSetting(languageFeature, languageFeatureState)
}
}
interface InternalArgument
data class ManualLanguageFeatureSetting(val languageFeature: LanguageFeature, val state: LanguageFeature.State) : InternalArgument

View File

@@ -16,11 +16,9 @@
package org.jetbrains.kotlin.cli.common.arguments
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.AnalysisFlag
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.*
class K2JVMCompilerArguments : CommonCompilerArguments() {
companion object {
@@ -225,8 +223,17 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
)
var noExceptionOnExplicitEqualsForBoxedNull by FreezableVar(false)
@Argument(value = "-Xenable-jvm-default", description = "Allow to use '@JvmDefault' for JVM default method support")
var enableJvmDefault: Boolean by FreezableVar(false)
@Argument(
value = "-Xjvm-default",
valueDescription = "{disable|enable|compatibility}",
description = "Allow to use '@JvmDefault' annotation for JVM default method support.\n" +
"-Xjvm-default=disable Prohibit usages of @JvmDefault\n" +
"-Xjvm-default=enable Allow usages of @JvmDefault; only generate the default method\n" +
" in the interface (annotating an existing method can break binary compatibility)\n" +
"-Xjvm-default=compatibility Allow usages of @JvmDefault; generate a compatibility accessor\n" +
" in the 'DefaultImpls' class in addition to the interface method"
)
var jvmDefault: String by FreezableVar(JvmDefaultMode.DEFAULT.description)
@Argument(value = "-Xdisable-default-scripting-plugin", description = "Do not enable scripting plugin by default")
var disableDefaultScriptingPlugin: Boolean by FreezableVar(false)
@@ -243,7 +250,12 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
jsr305,
supportCompatqualCheckerFrameworkAnnotations
)
result[AnalysisFlag.enableJvmDefault] = enableJvmDefault
JvmDefaultMode.fromStringOrNull(jvmDefault)?.let { result[AnalysisFlag.jvmDefaultMode] = it }
?: collector.report(
CompilerMessageSeverity.ERROR,
"Unknown @JvmDefault mode: $jvmDefault, " +
"supported modes: ${JvmDefaultMode.values().map { it.description }}"
)
return result
}

View File

@@ -19,24 +19,23 @@ package org.jetbrains.kotlin.cli.common.arguments
import org.jetbrains.kotlin.utils.SmartList
import kotlin.reflect.KClass
import kotlin.reflect.KMutableProperty1
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.memberProperties
@Target(AnnotationTarget.PROPERTY)
annotation class Argument(
val value: String,
val shortName: String = "",
val deprecatedName: String = "",
val delimiter: String = ",",
val valueDescription: String = "",
val description: String
val value: String,
val shortName: String = "",
val deprecatedName: String = "",
val delimiter: String = ",",
val valueDescription: String = "",
val description: String
)
val Argument.isAdvanced: Boolean
get() = value.startsWith(ADVANCED_ARGUMENT_PREFIX) && value.length > ADVANCED_ARGUMENT_PREFIX.length
private val ADVANCED_ARGUMENT_PREFIX = "-X"
private val FREE_ARGS_DELIMITER = "--"
private const val ADVANCED_ARGUMENT_PREFIX = "-X"
private const val FREE_ARGS_DELIMITER = "--"
data class ArgumentParseErrors(
val unknownArgs: MutableList<String> = SmartList<String>(),
@@ -53,11 +52,18 @@ data class ArgumentParseErrors(
// Arguments where [Argument.deprecatedName] was used; the key is the deprecated name, the value is the new name ([Argument.value])
val deprecatedArguments: MutableMap<String, String> = mutableMapOf(),
var argumentWithoutValue: String? = null
var argumentWithoutValue: String? = null,
val argfileErrors: MutableList<String> = SmartList()
)
// Parses arguments into the passed [result] object. Errors related to the parsing will be collected into [CommonToolArguments.errors].
fun <A : CommonToolArguments> parseCommandLineArguments(args: List<String>, result: A) {
val preprocessed = preprocessCommandLineArguments(args, result.errors)
parsePreprocessedCommandLineArguments(preprocessed, result)
}
private fun <A : CommonToolArguments> parsePreprocessedCommandLineArguments(args: List<String>, result: A) {
data class ArgumentField(val property: KMutableProperty1<A, Any?>, val argument: Argument)
@Suppress("UNCHECKED_CAST")
@@ -90,7 +96,7 @@ fun <A : CommonToolArguments> parseCommandLineArguments(args: List<String>, resu
return true
}
if (deprecatedName != null && arg.startsWith(deprecatedName + "=")) {
if (deprecatedName != null && arg.startsWith("$deprecatedName=")) {
errors.deprecatedArguments[deprecatedName] = argument.value
return true
}
@@ -102,6 +108,7 @@ fun <A : CommonToolArguments> parseCommandLineArguments(args: List<String>, resu
}
val freeArgs = ArrayList<String>()
val internalArguments = ArrayList<String>()
var i = 0
loop@ while (i < args.size) {
@@ -116,6 +123,21 @@ fun <A : CommonToolArguments> parseCommandLineArguments(args: List<String>, resu
continue
}
if (arg.startsWith(InternalArgumentParser.INTERNAL_ARGUMENT_PREFIX)) {
val matchingParsers = InternalArgumentParser.PARSERS.filter { it.canParse(arg) }
assert(matchingParsers.size <= 1) { "Internal error: internal argument $arg can be ambiguously parsed by parsers ${matchingParsers.joinToString()}" }
val parser = matchingParsers.firstOrNull()
if (parser == null) {
errors.unknownExtraFlags += arg
} else {
internalArguments.add(arg)
}
continue
}
val argumentField = properties.firstOrNull { it.matches(arg) }
if (argumentField == null) {
when {
@@ -145,14 +167,16 @@ fun <A : CommonToolArguments> parseCommandLineArguments(args: List<String>, resu
}
if ((argumentField.property.returnType.classifier as? KClass<*>)?.java?.isArray == false
&& !visitedArgs.add(argument.value) && value is String && property.get(result) != value) {
errors.duplicateArguments.put(argument.value, value)
&& !visitedArgs.add(argument.value) && value is String && property.get(result) != value
) {
errors.duplicateArguments[argument.value] = value
}
updateField(property, result, value, argument.delimiter)
}
result.freeArgs += freeArgs
result.internalArguments += internalArguments
}
private fun <A : CommonToolArguments> updateField(property: KMutableProperty1<A, Any?>, result: A, value: Any, delimiter: String) {

View File

@@ -0,0 +1,87 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.cli.common.arguments
import java.io.File
import java.io.FileNotFoundException
import java.io.IOException
import java.io.Reader
private const val EXPERIMENTAL_ARGFILE_ARGUMENT = "-Xargfile"
private const val QUOTATION_MARK = '"'
private const val BACKSLASH = '\\'
private const val WHITESPACE = ' '
private const val NEWLINE = '\n'
/**
* Performs initial preprocessing of arguments, passed to the compiler.
* This is done prior to *any* arguments parsing, and result of preprocessing
* will be used instead of actual passed arguments.
*/
internal fun preprocessCommandLineArguments(args: List<String>, errors: ArgumentParseErrors): List<String> =
args.flatMap {
if (it.isArgumentForArgfile)
File(it.argfilePath).expand(errors)
else
listOf(it)
}
private fun File.expand(errors: ArgumentParseErrors): List<String> {
return try {
bufferedReader(Charsets.UTF_8).use {
generateSequence { it.parseNextArgument() }.toList()
}
} catch (e: FileNotFoundException) {
// Process FNFE separately to render absolutePath in error message
errors.argfileErrors += "Argfile not found: $absolutePath"
emptyList()
} catch (e: IOException) {
errors.argfileErrors += "Error while reading argfile: $e"
emptyList()
}
}
private fun Reader.parseNextArgument(): String? {
val sb = StringBuilder()
var r = nextChar()
while (r != null && (r == WHITESPACE || r == NEWLINE)) {
r = nextChar()
}
loop@ while (r != null) {
when (r) {
WHITESPACE, NEWLINE -> break@loop
QUOTATION_MARK -> consumeRestOfEscapedSequence(sb)
BACKSLASH -> nextChar()?.apply(sb::append)
else -> sb.append(r)
}
r = nextChar()
}
return sb.toString().takeIf { it.isNotEmpty() }
}
private fun Reader.consumeRestOfEscapedSequence(sb: StringBuilder) {
var ch = nextChar()
while (ch != null && ch != QUOTATION_MARK) {
if (ch == BACKSLASH) nextChar()?.apply(sb::append) else sb.append(ch)
ch = nextChar()
}
}
private fun Reader.nextChar(): Char? =
read().takeUnless { it == -1 }?.toChar()
private val String.argfilePath: String
get() = removePrefix("$EXPERIMENTAL_ARGFILE_ARGUMENT=")
// Note that currently we use only experimental syntax for passing argfiles
// In 1.3 we can support also javac-like syntax `@argfile`
private val String.isArgumentForArgfile: Boolean
get() = startsWith("$EXPERIMENTAL_ARGFILE_ARGUMENT=")

View File

@@ -17,10 +17,7 @@
package org.jetbrains.kotlin.cli.common
import org.fusesource.jansi.AnsiConsole
import org.jetbrains.kotlin.cli.common.arguments.ArgumentParseErrors
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
import org.jetbrains.kotlin.cli.common.arguments.validateArguments
import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.cli.common.messages.*
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
@@ -38,10 +35,10 @@ abstract class CLITool<A : CommonToolArguments> {
}
protected fun exec(
errStream: PrintStream,
services: Services,
messageRenderer: MessageRenderer,
args: Array<out String>
errStream: PrintStream,
services: Services,
messageRenderer: MessageRenderer,
args: Array<out String>
): ExitCode {
val arguments = createArguments()
parseCommandLineArguments(args.asList(), arguments)
@@ -67,8 +64,7 @@ abstract class CLITool<A : CommonToolArguments> {
}
return exec(collector, services, arguments)
}
finally {
} finally {
errStream.print(messageRenderer.renderConclusion())
if (PlainTextMessageRenderer.COLOR_ENABLED) {
@@ -84,12 +80,11 @@ abstract class CLITool<A : CommonToolArguments> {
val fixedMessageCollector = if (arguments.suppressWarnings && !arguments.allWarningsAsErrors) {
FilteringMessageCollector(messageCollector, Predicate.isEqual(CompilerMessageSeverity.WARNING))
}
else {
} else {
messageCollector
}
reportArgumentParseProblems(fixedMessageCollector, arguments.errors)
reportArgumentParseProblems(fixedMessageCollector, arguments)
return execImpl(fixedMessageCollector, services, arguments)
}
@@ -117,13 +112,16 @@ abstract class CLITool<A : CommonToolArguments> {
}
}
private fun reportArgumentParseProblems(collector: MessageCollector, errors: ArgumentParseErrors) {
private fun reportArgumentParseProblems(collector: MessageCollector, arguments: A) {
val errors = arguments.errors
for (flag in errors.unknownExtraFlags) {
collector.report(STRONG_WARNING, "Flag is not supported by this version of the compiler: $flag")
}
for (argument in errors.extraArgumentsPassedInObsoleteForm) {
collector.report(STRONG_WARNING, "Advanced option value is passed in an obsolete form. Please use the '=' character " +
"to specify the value: $argument=...")
collector.report(
STRONG_WARNING, "Advanced option value is passed in an obsolete form. Please use the '=' character " +
"to specify the value: $argument=..."
)
}
for ((key, value) in errors.duplicateArguments) {
collector.report(STRONG_WARNING, "Argument $key is passed multiple times. Only the last value will be used: $value")
@@ -131,6 +129,20 @@ abstract class CLITool<A : CommonToolArguments> {
for ((deprecatedName, newName) in errors.deprecatedArguments) {
collector.report(STRONG_WARNING, "Argument $deprecatedName is deprecated. Please use $newName instead")
}
if (arguments.internalArguments.isNotEmpty()) {
collector.report(
STRONG_WARNING,
"ATTENTION!\n" +
"This build uses internal compiler arguments:\n" +
arguments.internalArguments.joinToString(prefix = "\n", postfix = "\n\n", separator = "\n") +
"This mode is strictly prohibited for production use,\n" +
"as no stability/compatibility guarantees are given on\n" +
"compiler or generated code. Use it at your own risk!\n"
)
}
for (argfileError in errors.argfileErrors) {
collector.report(STRONG_WARNING, argfileError)
}
}
private fun <A : CommonToolArguments> printVersionIfNeeded(messageCollector: MessageCollector, arguments: A) {
@@ -166,11 +178,10 @@ abstract class CLITool<A : CommonToolArguments> {
fun doMainNoExit(compiler: CLITool<*>, args: Array<String>): ExitCode {
try {
return compiler.exec(System.err, *args)
}
catch (e: CompileEnvironmentException) {
} catch (e: CompileEnvironmentException) {
System.err.println(e.message)
return ExitCode.INTERNAL_ERROR
}
}
}
}
}

View File

@@ -16,10 +16,10 @@
package org.jetbrains.kotlin.cli.common.script
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.script.findScriptDefinition
import org.jetbrains.kotlin.script.*
import java.io.File
import java.util.concurrent.locks.ReentrantReadWriteLock
@@ -28,7 +28,7 @@ import kotlin.concurrent.write
import kotlin.script.experimental.dependencies.ScriptDependencies
class CliScriptDependenciesProvider(
project: Project,
private val project: Project,
private val scriptDefinitionProvider: ScriptDefinitionProvider
) : ScriptDependenciesProvider {
@@ -47,9 +47,11 @@ class CliScriptDependenciesProvider(
else {
val scriptDef = scriptDefinitionProvider.findScriptDefinition(file)
if (scriptDef != null) {
val deps = scriptContentLoader
.loadContentsAndResolveDependencies(scriptDef, file)
.dependencies?.adjustByDefinition(scriptDef)
val result = scriptContentLoader.loadContentsAndResolveDependencies(scriptDef, file)
ServiceManager.getService(project, ScriptReportSink::class.java)?.attachReports(file, result.reports)
val deps = result.dependencies?.adjustByDefinition(scriptDef)
if (deps != null) {
log.info("[kts] new cached deps for $path: ${deps.classpath.joinToString(File.pathSeparator)}")

View File

@@ -218,7 +218,7 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
override fun getPerformanceManager(): CommonCompilerPerformanceManager = performanceManager
private fun loadPlugins(paths: KotlinPaths?, arguments: K2JVMCompilerArguments, configuration: CompilerConfiguration): ExitCode {
val pluginClasspaths = arguments.pluginClasspaths?.toMutableList() ?: ArrayList()
var pluginClasspaths: Iterable<String> = arguments.pluginClasspaths?.asIterable() ?: emptyList()
val pluginOptions = arguments.pluginOptions?.toMutableList() ?: ArrayList()
if (!arguments.disableDefaultScriptingPlugin) {
@@ -235,10 +235,12 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
if (!explicitOrLoadedScriptingPlugin) {
val libPath = paths?.libPath?.takeIf { it.exists() } ?: File(".")
with(PathUtil) {
val jars = arrayOf(KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR, KOTLIN_SCRIPTING_JVM_JAR)
.mapNotNull { File(libPath, it).takeIf { it.exists() }?.canonicalPath }
if (jars.size == 3) {
pluginClasspaths.addAll(jars)
val jars = arrayOf(
KOTLIN_SCRIPTING_COMPILER_PLUGIN_JAR, KOTLIN_SCRIPTING_COMMON_JAR,
KOTLIN_SCRIPTING_JVM_JAR, KOTLIN_SCRIPTING_MISC_JAR
).mapNotNull { File(libPath, it).takeIf { it.exists() }?.canonicalPath }
if (jars.size == 4) {
pluginClasspaths = jars + pluginClasspaths
}
}
}

View File

@@ -158,7 +158,7 @@ open class MetadataSerializer(private val dependOnOldBuiltIns: Boolean) {
}
private fun serializeClass(classDescriptor: ClassDescriptor) {
val classProto = DescriptorSerializer.createTopLevel(extension).classProto(classDescriptor).build()
val classProto = DescriptorSerializer.create(classDescriptor, extension).classProto(classDescriptor).build()
proto.addClass_(classProto)
serializeClasses(classDescriptor.unsubstitutedInnerClassesScope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS))

View File

@@ -47,11 +47,13 @@ messages/**)
-dontwarn javax.crypto.**
-dontwarn java.lang.invoke.MethodHandle
-dontwarn org.jline.builtins.Nano$Buffer
-dontwarn net.jpountz.lz4.LZ4Factory
-dontwarn org.jetbrains.annotations.ReadOnly
-dontwarn org.jetbrains.annotations.Mutable
-dontwarn com.intellij.util.io.TarUtil
# Depends on apache batik which has lots of dependencies
-dontwarn com.intellij.util.SVGLoader*
#-libraryjars '<rtjar>'
#-libraryjars '<jssejar>'
#-libraryjars '<bootstrap.runtime>'
@@ -195,6 +197,10 @@ messages/**)
*** SKIP_FRAMES;
}
-keepclassmembers class com.intellij.openapi.project.Project {
** getBasePath();
}
# for kotlin-android-extensions in maven
-keep class com.intellij.openapi.module.ModuleServiceManager { public *; }
@@ -216,3 +222,5 @@ messages/**)
# remove when KT-18563 would be fixed
-keep class org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt { *; }
-keep class net.jpountz.lz4.* { *; }

View File

@@ -194,6 +194,10 @@ messages/**)
*** SKIP_FRAMES;
}
-keepclassmembers class com.intellij.openapi.project.Project {
** getBasePath();
}
# for kotlin-android-extensions in maven
-keep class com.intellij.openapi.module.ModuleServiceManager { public *; }

View File

@@ -47,7 +47,6 @@ messages/**)
-dontwarn javax.crypto.**
-dontwarn java.lang.invoke.MethodHandle
-dontwarn org.jline.builtins.Nano$Buffer
-dontwarn net.jpountz.lz4.LZ4Factory
-dontwarn org.jetbrains.annotations.ReadOnly
-dontwarn org.jetbrains.annotations.Mutable
-dontwarn com.intellij.util.io.TarUtil
@@ -59,6 +58,12 @@ messages/**)
# Depends on apache batick which has lots of dependencies
-dontwarn com.intellij.util.SVGLoader*
-dontwarn org.jdom.xpath.jaxen.*
-dontwarn com.intellij.util.io.Decompressor*
-dontwarn org.w3c.dom.Location
-dontwarn org.w3c.dom.Window
#-libraryjars '<rtjar>'
#-libraryjars '<jssejar>'
#-libraryjars '<bootstrap.runtime>'
@@ -202,6 +207,10 @@ messages/**)
*** SKIP_FRAMES;
}
-keepclassmembers class com.intellij.openapi.project.Project {
** getBasePath();
}
# for kotlin-android-extensions in maven
-keep class com.intellij.openapi.module.ModuleServiceManager { public *; }
@@ -223,3 +232,5 @@ messages/**)
# remove when KT-18563 would be fixed
-keep class org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt { *; }
-keep class net.jpountz.lz4.* { *; }

View File

@@ -198,6 +198,10 @@ messages/**)
*** SKIP_FRAMES;
}
-keepclassmembers class com.intellij.openapi.project.Project {
** getBasePath();
}
# for kotlin-android-extensions in maven
-keep class com.intellij.openapi.module.ModuleServiceManager { public *; }

View File

@@ -60,13 +60,13 @@ class IncrementalCompilationOptions(
reportSeverity: Int,
/** @See [CompilationResultCategory]] */
requestedCompilationResults: Array<Int>,
val resultDifferenceFile: File? = null,
val friendDifferenceFile: File? = null,
val usePreciseJavaTracking: Boolean,
/**
* Directories that should be cleared when IC decides to rebuild
*/
val localStateDirs: List<File>
val localStateDirs: List<File>,
val multiModuleICSettings: MultiModuleICSettings,
val modulesInfo: IncrementalModuleInfo
) : CompilationOptions(compilerMode, targetPlatform, reportCategories, reportSeverity, requestedCompilationResults) {
companion object {
const val serialVersionUID: Long = 0
@@ -81,14 +81,22 @@ class IncrementalCompilationOptions(
"workingDir=$workingDir, " +
"customCacheVersionFileName='$customCacheVersionFileName', " +
"customCacheVersion=$customCacheVersion, " +
"resultDifferenceFile=$resultDifferenceFile, " +
"friendDifferenceFile=$friendDifferenceFile, " +
"multiModuleICSettings=$multiModuleICSettings, " +
"usePreciseJavaTracking=$usePreciseJavaTracking" +
"localStateDirs=$localStateDirs" +
")"
}
}
data class MultiModuleICSettings(
val buildHistoryFile: File,
val useModuleDetection: Boolean
) : Serializable {
companion object {
const val serialVersionUID: Long = 0
}
}
enum class CompilerMode : Serializable {
NON_INCREMENTAL_COMPILER,
INCREMENTAL_COMPILER,

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.daemon.common
import java.io.File
import java.rmi.RemoteException
interface IncrementalCompilerServicesFacade : CompilerServicesFacadeBase {
@@ -29,14 +28,4 @@ interface IncrementalCompilerServicesFacade : CompilerServicesFacadeBase {
@Throws(RemoteException::class)
fun revert()
// ChangesRegistry
@Throws(RemoteException::class)
fun registerChanges(timestamp: Long, dirtyData: SimpleDirtyData)
@Throws(RemoteException::class)
fun unknownChanges(timestamp: Long)
@Throws(RemoteException::class)
fun getChanges(artifact: File, sinceTS: Long): Iterable<SimpleDirtyData>?
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.daemon.common
import java.io.File
import java.io.Serializable
data class IncrementalModuleEntry(
private val projectPath: String,
val name: String,
val buildDir: File,
val buildHistoryFile: File
) : Serializable {
companion object {
private const val serialVersionUID = 0L
}
}
class IncrementalModuleInfo(
val projectRoot: File,
val dirToModule: Map<File, IncrementalModuleEntry>,
val nameToModules: Map<String, Set<IncrementalModuleEntry>>,
val jarToClassListFile: Map<File, File>
) : Serializable {
companion object {
private const val serialVersionUID = 0L
}
}

View File

@@ -41,8 +41,6 @@ import org.jetbrains.kotlin.cli.metadata.K2MetadataCompiler
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.daemon.incremental.RemoteAnnotationsFileUpdater
import org.jetbrains.kotlin.daemon.incremental.RemoteArtifactChangesProvider
import org.jetbrains.kotlin.daemon.incremental.RemoteChangesRegistry
import org.jetbrains.kotlin.daemon.report.CompileServicesFacadeMessageCollector
import org.jetbrains.kotlin.daemon.report.DaemonMessageReporter
import org.jetbrains.kotlin.daemon.report.DaemonMessageReporterPrintStreamAdapter
@@ -50,6 +48,8 @@ import org.jetbrains.kotlin.daemon.report.RemoteICReporter
import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.parsing.classesFqNames
import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistoryAndroid
import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistoryJvm
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.modules.Module
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
@@ -517,9 +517,6 @@ class CompileServiceImpl(
ChangedFiles.Unknown()
}
val artifactChanges = RemoteArtifactChangesProvider(servicesFacade)
val changesRegistry = RemoteChangesRegistry(servicesFacade)
val workingDir = incrementalCompilationOptions.workingDir
val versions = commonCacheVersions(workingDir) +
customCacheVersion(incrementalCompilationOptions.customCacheVersion,
@@ -527,13 +524,23 @@ class CompileServiceImpl(
workingDir,
enabled = true)
val compiler = IncrementalJvmCompilerRunner(workingDir, javaSourceRoots, versions,
reporter, annotationFileUpdater,
artifactChanges, changesRegistry,
buildHistoryFile = incrementalCompilationOptions.resultDifferenceFile,
friendBuildHistoryFile = incrementalCompilationOptions.friendDifferenceFile,
usePreciseJavaTracking = incrementalCompilationOptions.usePreciseJavaTracking,
localStateDirs = incrementalCompilationOptions.localStateDirs
val modulesApiHistory = incrementalCompilationOptions.run {
if (!multiModuleICSettings.useModuleDetection) {
ModulesApiHistoryJvm(modulesInfo)
} else {
ModulesApiHistoryAndroid(modulesInfo)
}
}
val compiler = IncrementalJvmCompilerRunner(
workingDir,
javaSourceRoots,
versions,
reporter, annotationFileUpdater,
buildHistoryFile = incrementalCompilationOptions.multiModuleICSettings.buildHistoryFile,
localStateDirs = incrementalCompilationOptions.localStateDirs,
usePreciseJavaTracking = incrementalCompilationOptions.usePreciseJavaTracking,
modulesApiHistory = modulesApiHistory
)
return compiler.compile(allKotlinFiles, k2jvmArgs, compilerMessageCollector, changedFiles)
}

View File

@@ -1,27 +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.daemon.incremental
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacade
import org.jetbrains.kotlin.incremental.DirtyData
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
import java.io.File
class RemoteArtifactChangesProvider(private val servicesFacade: IncrementalCompilerServicesFacade) : ArtifactChangesProvider {
override fun getChanges(artifact: File, sinceTS: Long): Iterable<DirtyData>? =
servicesFacade.getChanges(artifact, sinceTS)?.map { it.toDirtyData() }
}

View File

@@ -1,31 +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.daemon.incremental
import org.jetbrains.kotlin.daemon.common.IncrementalCompilerServicesFacade
import org.jetbrains.kotlin.incremental.DirtyData
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
internal class RemoteChangesRegistry(private val servicesFacade: IncrementalCompilerServicesFacade) : ChangesRegistry {
override fun unknownChanges(timestamp: Long) {
servicesFacade.unknownChanges(timestamp)
}
override fun registerChanges(timestamp: Long, dirtyData: DirtyData) {
servicesFacade.registerChanges(timestamp, dirtyData.toSimpleDirtyData())
}
}

View File

@@ -103,7 +103,7 @@ public class JVMConfigurationKeys {
public static final CompilerConfigurationKey<Boolean> PARAMETERS_METADATA =
CompilerConfigurationKey.create("Parameters metadata for java 1.8 reflection");
public static final CompilerConfigurationKey<IncrementalCompilationComponents> INCREMENTAL_COMPILATION_COMPONENTS =
CompilerConfigurationKey.create("incremental cache provider");

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.load.java.sam
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.load.java.components.SamConversionResolver
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
import org.jetbrains.kotlin.resolve.calls.components.SamConversionTransformer
import org.jetbrains.kotlin.synthetic.hasJavaOriginInHierarchy
import org.jetbrains.kotlin.types.UnwrappedType
class JvmSamConversionTransformer(
private val samResolver: SamConversionResolver,
private val languageVersionSettings: LanguageVersionSettings
) : SamConversionTransformer {
override fun getFunctionTypeForPossibleSamType(possibleSamType: UnwrappedType): UnwrappedType? =
SingleAbstractMethodUtils.getFunctionTypeForSamType(possibleSamType, samResolver)?.unwrap()
override fun shouldRunSamConversionForFunction(candidate: CallableDescriptor): Boolean {
if (languageVersionSettings.supportsFeature(LanguageFeature.SamConversionForKotlinFunctions)) return true
val functionDescriptor = candidate.original as? FunctionDescriptor ?: return false
if (functionDescriptor is TypeAliasConstructorDescriptor &&
functionDescriptor.underlyingConstructorDescriptor is JavaClassConstructorDescriptor) return true
return functionDescriptor.hasJavaOriginInHierarchy()
}
}

View File

@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker {
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
val enableJvmDefault = context.languageVersionSettings.getFlag(AnalysisFlag.enableJvmDefault)
val jvmDefaultMode = context.languageVersionSettings.getFlag(AnalysisFlag.jvmDefaultMode)
descriptor.annotations.findAnnotation(JVM_DEFAULT_FQ_NAME)?.let { annotationDescriptor ->
val reportOn = DescriptorToSourceUtils.getSourceFromAnnotation(annotationDescriptor) ?: declaration
@@ -31,7 +31,7 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker {
context.trace.report(ErrorsJvm.JVM_DEFAULT_NOT_IN_INTERFACE.on(reportOn))
} else if (jvmTarget == JvmTarget.JVM_1_6) {
context.trace.report(ErrorsJvm.JVM_DEFAULT_IN_JVM6_TARGET.on(reportOn))
} else if (!enableJvmDefault) {
} else if (!jvmDefaultMode.isEnabled) {
context.trace.report(ErrorsJvm.JVM_DEFAULT_IN_DECLARATION.on(declaration))
}
return@check
@@ -42,7 +42,7 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker {
descriptor.unsubstitutedMemberScope.getContributedDescriptors().filterIsInstance<CallableMemberDescriptor>().any {
it.kind.isReal && it.hasJvmDefaultAnnotation()
}
if (!hasDeclaredJvmDefaults && !checkJvmDefaultsInHierarchy(descriptor, enableJvmDefault)) {
if (!hasDeclaredJvmDefaults && !checkJvmDefaultsInHierarchy(descriptor, jvmDefaultMode.isEnabled)) {
context.trace.report(ErrorsJvm.JVM_DEFAULT_THROUGH_INHERITANCE.on(declaration))
}
}
@@ -54,7 +54,7 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker {
if (memberDescriptor.overriddenDescriptors.any { it.annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME) }) {
context.trace.report(ErrorsJvm.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE.on(declaration))
} else if (enableJvmDefault) {
} else if (jvmDefaultMode.isEnabled) {
descriptor.overriddenDescriptors.flatMap { OverridingUtil.getOverriddenDeclarations(it) }.toSet().let {
for (realDescriptor in OverridingUtil.filterOutOverridden(it)) {
if (realDescriptor is JavaMethodDescriptor && realDescriptor.modality != Modality.ABSTRACT) {

View File

@@ -137,9 +137,9 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
MAP.put(JVM_DEFAULT_NOT_IN_INTERFACE,"'@JvmDefault' is only supported on interface members");
MAP.put(JVM_DEFAULT_IN_JVM6_TARGET,"'@JvmDefault' is only supported since JVM target 1.8. Recompile with '-jvm-target 1.8'");
MAP.put(JVM_DEFAULT_REQUIRED_FOR_OVERRIDE, "'@JvmDefault' is required for an override of a '@JvmDefault' member");
MAP.put(JVM_DEFAULT_IN_DECLARATION, "Usage of '@JvmDefault' is only allowed if the flag -Xenable-jvm-default is enabled");
MAP.put(JVM_DEFAULT_THROUGH_INHERITANCE, "Inheritance from an interface with '@JvmDefault' members is only allowed if the flag -Xenable-jvm-default is enabled");
MAP.put(USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL, "Super calls of '@JvmDefault' members are only allowed if the flag -Xenable-jvm-default is enabled");
MAP.put(JVM_DEFAULT_IN_DECLARATION, "Usage of '@JvmDefault' is only allowed with -Xjvm-default option");
MAP.put(JVM_DEFAULT_THROUGH_INHERITANCE, "Inheritance from an interface with '@JvmDefault' members is only allowed with -Xjvm-default option");
MAP.put(USAGE_OF_JVM_DEFAULT_THROUGH_SUPER_CALL, "Super calls of '@JvmDefault' members are only allowed with -Xjvm-default option");
MAP.put(NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT, "Non-@JvmDefault interface method cannot override default Java method. Please annotate this method with @JvmDefault");
}

View File

@@ -19,8 +19,8 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
class JvmDefaultSuperCallChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
val enableJvmDefault = context.languageVersionSettings.getFlag(AnalysisFlag.enableJvmDefault)
if (enableJvmDefault) return
val jvmDefaultMode = context.languageVersionSettings.getFlag(AnalysisFlag.jvmDefaultMode)
if (jvmDefaultMode.isEnabled) return
val superExpression = getSuperCallExpression(resolvedCall.call) ?: return
val resultingDescriptor = resolvedCall.resultingDescriptor as? CallableMemberDescriptor ?: return
if (!resultingDescriptor.hasJvmDefaultAnnotation()) return

View File

@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.jvm.platform
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.useImpl
import org.jetbrains.kotlin.container.useInstance
import org.jetbrains.kotlin.load.java.sam.JvmSamConversionTransformer
import org.jetbrains.kotlin.load.java.sam.SamConversionResolverImpl
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.PlatformConfigurator
@@ -97,5 +98,6 @@ object JvmPlatformConfigurator : PlatformConfigurator(
container.useImpl<JvmModuleAccessibilityChecker.ClassifierUsage>()
container.useInstance(JvmTypeSpecificityComparator)
container.useImpl<JvmDefaultSuperCallChecker>()
container.useImpl<JvmSamConversionTransformer>()
}
}

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.synthetic
import com.intellij.util.SmartList
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -59,6 +60,8 @@ class SamAdapterFunctionsScope(
private val deprecationResolver: DeprecationResolver,
private val lookupTracker: LookupTracker
) : SyntheticScope {
private val samViaSyntheticScopeDisabled = languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
private val extensionForFunction =
storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function ->
extensionForFunctionNotCached(function)
@@ -95,6 +98,8 @@ class SamAdapterFunctionsScope(
}
override fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
if (samViaSyntheticScopeDisabled) return emptyList()
var result: SmartList<FunctionDescriptor>? = null
for (type in receiverTypes) {
for (function in type.memberScope.getContributedFunctions(name, location)) {
@@ -134,6 +139,8 @@ class SamAdapterFunctionsScope(
}
override fun getSyntheticMemberFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> {
if (samViaSyntheticScopeDisabled) return emptyList()
return receiverTypes.flatMapTo(LinkedHashSet<FunctionDescriptor>()) { type ->
type.memberScope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS)
.filterIsInstance<FunctionDescriptor>()
@@ -148,12 +155,17 @@ class SamAdapterFunctionsScope(
override fun getSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> = emptyList()
override fun getSyntheticStaticFunctions(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
if (samViaSyntheticScopeDisabled) return emptyList()
return getSamFunctions(scope.getContributedFunctions(name, location), location)
}
override fun getSyntheticConstructors(scope: ResolutionScope, name: Name, location: LookupLocation): Collection<FunctionDescriptor> {
val classifier = scope.getContributedClassifier(name, location) ?: return emptyList()
recordSamLookupsToClassifier(classifier, location)
if (samViaSyntheticScopeDisabled) return listOfNotNull(getSamConstructor(classifier))
return getAllSamConstructors(classifier)
}
@@ -166,16 +178,22 @@ class SamAdapterFunctionsScope(
}
override fun getSyntheticStaticFunctions(scope: ResolutionScope): Collection<FunctionDescriptor> {
if (samViaSyntheticScopeDisabled) return emptyList()
return getSamFunctions(scope.getContributedDescriptors(DescriptorKindFilter.FUNCTIONS), location = null)
}
override fun getSyntheticConstructors(scope: ResolutionScope): Collection<FunctionDescriptor> {
return scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS)
.filterIsInstance<ClassifierDescriptor>()
.flatMap { getAllSamConstructors(it) }
val classifiers = scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS).filterIsInstance<ClassifierDescriptor>()
if (samViaSyntheticScopeDisabled) return classifiers.mapNotNull { getSamConstructor(it) }
return classifiers.flatMap { getAllSamConstructors(it) }
}
override fun getSyntheticConstructor(constructor: ConstructorDescriptor): ConstructorDescriptor? {
if (samViaSyntheticScopeDisabled) return null
return when (constructor) {
is JavaClassConstructorDescriptor -> createJavaSamAdapterConstructor(constructor)
is TypeAliasConstructorDescriptor -> {

View File

@@ -41,7 +41,7 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
val environment: Map<String, Any?>? = null,
val templateClasspath: List<File> = emptyList()
) : KotlinScriptDefinition(template) {
val scriptFilePattern by lazy {
val scriptFilePattern by lazy(LazyThreadSafetyMode.PUBLICATION) {
val pattern =
takeUnlessError {
val ann = template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateDefinition>()
@@ -52,7 +52,7 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
Regex(pattern)
}
override val dependencyResolver: DependenciesResolver by lazy {
override val dependencyResolver: DependenciesResolver by lazy(LazyThreadSafetyMode.PUBLICATION) {
resolverFromAnnotation(template) ?:
resolverFromLegacyAnnotation(template) ?:
DependenciesResolver.NoDependencies
@@ -99,12 +99,12 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
}
}
private val samWithReceiverAnnotations: List<String>? by lazy {
private val samWithReceiverAnnotations: List<String>? by lazy(LazyThreadSafetyMode.PUBLICATION) {
takeUnlessError { template.annotations.firstIsInstanceOrNull<kotlin.script.extensions.SamWithReceiverAnnotations>()?.annotations?.toList() }
?: takeUnlessError { template.annotations.firstIsInstanceOrNull<org.jetbrains.kotlin.script.SamWithReceiverAnnotations>()?.annotations?.toList() }
}
override val acceptedAnnotations: List<KClass<out Annotation>> by lazy {
override val acceptedAnnotations: List<KClass<out Annotation>> by lazy(LazyThreadSafetyMode.PUBLICATION) {
fun sameSignature(left: KFunction<*>, right: KFunction<*>): Boolean =
left.name == right.name &&
@@ -134,7 +134,7 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
}
}
override val scriptExpectedLocations: List<ScriptExpectedLocation> by lazy {
override val scriptExpectedLocations: List<ScriptExpectedLocation> by lazy(LazyThreadSafetyMode.PUBLICATION) {
takeUnlessError {
template.annotations.firstIsInstanceOrNull<ScriptExpectedLocations>()
}?.value?.toList() ?: super.scriptExpectedLocations
@@ -153,7 +153,7 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
override val annotationsForSamWithReceivers: List<String>
get() = samWithReceiverAnnotations ?: super.annotationsForSamWithReceivers
override val additionalCompilerArguments: Iterable<String>? by lazy {
override val additionalCompilerArguments: Iterable<String>? by lazy(LazyThreadSafetyMode.PUBLICATION) {
takeUnlessError {
template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateAdditionalCompilerArguments>()?.let {
val res = it.provider.primaryConstructor?.call(it.arguments.asIterable())

View File

@@ -58,8 +58,8 @@ class ScriptContentLoader(private val project: Project) {
class BasicScriptContents(virtualFile: VirtualFile, getAnnotations: () -> Iterable<Annotation>) : ScriptContents {
override val file: File = File(virtualFile.path)
override val annotations: Iterable<Annotation> by lazy { getAnnotations() }
override val text: CharSequence? by lazy { virtualFile.inputStream.reader(charset = virtualFile.charset).readText() }
override val annotations: Iterable<Annotation> by lazy(LazyThreadSafetyMode.PUBLICATION) { getAnnotations() }
override val text: CharSequence? by lazy(LazyThreadSafetyMode.PUBLICATION) { virtualFile.inputStream.reader(charset = virtualFile.charset).readText() }
}
fun loadContentsAndResolveDependencies(

View File

@@ -132,6 +132,9 @@ public class CompilerConfiguration {
else if (object instanceof Map) {
return (T) Collections.unmodifiableMap((Map) object);
}
else if (object instanceof Set) {
return (T) Collections.unmodifiableSet((Set) object);
}
else if (object instanceof Collection) {
return (T) Collections.unmodifiableCollection((Collection) object);
}

View File

@@ -619,6 +619,9 @@ public interface Errors {
DiagnosticFactory2.create(ERROR, ACTUAL_DECLARATION_NAME);
DiagnosticFactory0<KtNamedDeclaration> ACTUAL_MISSING = DiagnosticFactory0.create(ERROR, ACTUAL_DECLARATION_NAME);
DiagnosticFactory0<PsiElement> OPTIONAL_EXPECTATION_NOT_ON_EXPECTED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY = DiagnosticFactory0.create(ERROR);
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Errors/warnings inside code blocks

View File

@@ -284,6 +284,9 @@ public class DefaultErrorMessages {
NAME, IncompatibleExpectedActualClassScopesRenderer.TEXT);
MAP.put(ACTUAL_MISSING, "Declaration must be marked with 'actual'");
MAP.put(OPTIONAL_EXPECTATION_NOT_ON_EXPECTED, "'@OptionalExpectation' can only be used on an expected annotation class");
MAP.put(OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY, "Declaration annotated with '@OptionalExpectation' can only be used inside an annotation entry");
MAP.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties");
MAP.put(SUPERTYPE_NOT_INITIALIZED, "This type has a constructor, and thus must be initialized here");
MAP.put(NOTHING_TO_OVERRIDE, "''{0}'' overrides nothing", NAME);

View File

@@ -19,10 +19,7 @@ import org.jetbrains.kotlin.lexer.KtKeywordToken;
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker;
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext;
import org.jetbrains.kotlin.resolve.checkers.PublishedApiUsageChecker;
import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker;
import org.jetbrains.kotlin.resolve.checkers.*;
import java.util.Collection;
import java.util.List;
@@ -275,6 +272,7 @@ public class ModifiersChecker {
}
OperatorModifierChecker.INSTANCE.check(declaration, descriptor, trace, languageVersionSettings);
PublishedApiUsageChecker.INSTANCE.check(declaration, descriptor, trace);
OptionalExpectationTargetChecker.INSTANCE.check(declaration, descriptor, trace);
}
public void checkTypeParametersModifiers(@NotNull KtModifierListOwner modifierListOwner) {

View File

@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.UserDataProperty
import org.jetbrains.kotlin.resolve.calls.checkers.*
import org.jetbrains.kotlin.resolve.calls.components.SamConversionTransformer
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
import org.jetbrains.kotlin.resolve.checkers.*
import org.jetbrains.kotlin.resolve.lazy.DelegationFilter
@@ -62,6 +63,7 @@ abstract class TargetPlatform(val platformName: String) {
) {
override fun configureModuleComponents(container: StorageComponentContainer) {
container.useInstance(SyntheticScopes.Empty)
container.useInstance(SamConversionTransformer.Empty)
container.useInstance(TypeSpecificityComparator.NONE)
}
}
@@ -100,7 +102,8 @@ private val DEFAULT_CALL_CHECKERS = listOf(
)
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(
DeprecatedClassifierUsageChecker(), ApiVersionClassifierUsageChecker, MissingDependencyClassChecker.ClassifierUsage
DeprecatedClassifierUsageChecker(), ApiVersionClassifierUsageChecker, MissingDependencyClassChecker.ClassifierUsage,
OptionalExpectationUsageChecker()
)
private val DEFAULT_ANNOTATION_CHECKERS = listOf<AdditionalAnnotationChecker>(
ExperimentalMarkerDeclarationAnnotationChecker

View File

@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.platform.PlatformToKotlinClassMap
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.UserDataProperty
import org.jetbrains.kotlin.resolve.calls.checkers.*
import org.jetbrains.kotlin.resolve.calls.components.SamConversionTransformer
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
import org.jetbrains.kotlin.resolve.checkers.*
import org.jetbrains.kotlin.resolve.lazy.DelegationFilter
@@ -62,6 +63,7 @@ abstract class TargetPlatform(val platformName: String) {
) {
override fun configureModuleComponents(container: StorageComponentContainer) {
container.useInstance(SyntheticScopes.Empty)
container.useInstance(SamConversionTransformer.Empty)
container.useInstance(TypeSpecificityComparator.NONE)
}
}

View File

@@ -207,10 +207,14 @@ class KotlinToResolvedCallTransformer(
for (valueArgument in resolvedCall.call.valueArguments) {
val argumentMapping = resolvedCall.getArgumentMapping(valueArgument!!)
val (expectedType, callPosition) = when (argumentMapping) {
is ArgumentMatch -> Pair(
getEffectiveExpectedType(argumentMapping.valueParameter, valueArgument, context),
CallPosition.ValueArgumentPosition(resolvedCall, argumentMapping.valueParameter, valueArgument)
)
is ArgumentMatch -> {
val expectedType = resolvedCall.getExpectedTypeForSamConvertedArgument(valueArgument)
?: getEffectiveExpectedType(argumentMapping.valueParameter, valueArgument, context)
Pair(
expectedType,
CallPosition.ValueArgumentPosition(resolvedCall, argumentMapping.valueParameter, valueArgument)
)
}
else -> Pair(TypeUtils.NO_EXPECTED_TYPE, CallPosition.Unknown)
}
val newContext =
@@ -513,6 +517,8 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
private var extensionReceiver = resolvedCallAtom.extensionReceiverArgument?.receiver?.receiverValue
private var dispatchReceiver = resolvedCallAtom.dispatchReceiverArgument?.receiver?.receiverValue
private var smartCastDispatchReceiverType: KotlinType? = null
private var expedtedTypeForSamConvertedArgumentMap: MutableMap<ValueArgument, UnwrappedType>? = null
override val kotlinCall: KotlinCall get() = resolvedCallAtom.atom
@@ -601,6 +607,22 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
TypeApproximator().approximateToSuperType(substituted, TypeApproximatorConfiguration.CapturedTypesApproximation) ?: substituted
}
calculateExpedtedTypeForSamConvertedArgumentMap(substitutor)
}
fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
expedtedTypeForSamConvertedArgumentMap?.get(valueArgument)
private fun calculateExpedtedTypeForSamConvertedArgumentMap(substitutor: NewTypeSubstitutor?) {
if (resolvedCallAtom.argumentsWithConversion.isEmpty()) return
expedtedTypeForSamConvertedArgumentMap = hashMapOf()
for ((argument, description) in resolvedCallAtom.argumentsWithConversion) {
val typeWithFreshVariables = resolvedCallAtom.substitutor.safeSubstitute(description.convertedTypeByCandidateParameter)
val expectedType = substitutor?.safeSubstitute(typeWithFreshVariables) ?: typeWithFreshVariables
expedtedTypeForSamConvertedArgumentMap!![argument.psiCallArgument.valueArgument] = expectedType
}
}
init {

View File

@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
import org.jetbrains.kotlin.resolve.BindingContext
@@ -41,6 +42,8 @@ import org.jetbrains.kotlin.utils.ifEmpty
import java.io.File
object ExpectedActualDeclarationChecker : DeclarationChecker {
internal val OPTIONAL_EXPECTATION_FQ_NAME = FqName("kotlin.OptionalExpectation")
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) return
@@ -67,6 +70,8 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
val compatibility = ExpectedActualResolver.findActualForExpected(descriptor, platformModule) ?: return
if (compatibility.allStrongIncompatibilities() && isOptionalAnnotationClass(descriptor)) return
val shouldReportError =
compatibility.allStrongIncompatibilities() ||
Compatible !in compatibility && compatibility.values.flatMapTo(hashSetOf()) { it }.all { actual ->
@@ -89,6 +94,10 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
}
}
internal fun isOptionalAnnotationClass(descriptor: DeclarationDescriptor): Boolean {
return descriptor.annotations.hasAnnotation(OPTIONAL_EXPECTATION_FQ_NAME)
}
private fun ExpectActualTracker.reportExpectActual(expected: MemberDescriptor, actualMembers: Sequence<MemberDescriptor>) {
if (this is ExpectActualTracker.DoNothing) return

View File

@@ -265,18 +265,6 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
}
}
private fun PsiElement.isUsageAsAnnotationOrImport(): Boolean {
val parent = parent
if (parent is KtUserType) {
return parent.parent is KtTypeReference &&
parent.parent.parent is KtConstructorCalleeExpression &&
parent.parent.parent.parent is KtAnnotationEntry
}
return parent is KtDotQualifiedExpression && parent.parent is KtImportDirective
}
private fun PsiElement.isUsageAsQualifier(): Boolean {
if (this is KtSimpleNameExpression) {
val qualifier = getTopmostParentQualifiedExpressionForSelector() ?: this

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.resolve.checkers
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.MemberDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace
object OptionalExpectationTargetChecker {
fun check(
declaration: KtDeclaration,
descriptor: DeclarationDescriptor,
trace: BindingTrace
) {
if (descriptor is MemberDescriptor && descriptor.isExpect) return
for (entry in declaration.annotationEntries) {
val annotationDescriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
if (annotationDescriptor.fqName == ExpectedActualDeclarationChecker.OPTIONAL_EXPECTATION_FQ_NAME) {
trace.report(Errors.OPTIONAL_EXPECTATION_NOT_ON_EXPECTED.on(entry))
}
}
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.resolve.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
class OptionalExpectationUsageChecker : ClassifierUsageChecker {
override fun check(targetDescriptor: ClassifierDescriptor, element: PsiElement, context: ClassifierUsageCheckerContext) {
if (!ExpectedActualDeclarationChecker.isOptionalAnnotationClass(targetDescriptor)) return
if (!element.isUsageAsAnnotationOrImport()) {
context.trace.report(Errors.OPTIONAL_DECLARATION_OUTSIDE_OF_ANNOTATION_ENTRY.on(element))
}
}
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.resolve.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.psi.*
internal fun PsiElement.isUsageAsAnnotationOrImport(): Boolean {
val parent = parent
if (parent is KtUserType) {
return parent.parent is KtTypeReference &&
parent.parent.parent is KtConstructorCalleeExpression &&
parent.parent.parent.parent is KtAnnotationEntry
}
return parent is KtDotQualifiedExpression && parent.parent is KtImportDirective
}

View File

@@ -15,6 +15,7 @@ dependencies {
compile(project(":compiler:frontend.java"))
compile(project(":compiler:cli"))
compile(project(":kotlin-build-common"))
compile(project(":compiler:daemon-common"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep()) { includeJars("annotations") }

View File

@@ -29,6 +29,11 @@ data class BuildDifference(val ts: Long, val isIncremental: Boolean, val dirtyDa
data class BuildDiffsStorage(val buildDiffs: List<BuildDifference>) {
companion object {
fun readFromFile(file: File, reporter: ICReporter?): BuildDiffsStorage? {
val diffs = readDiffsFromFile(file, reporter)
return diffs?.let { BuildDiffsStorage(it) }
}
fun readDiffsFromFile(file: File, reporter: ICReporter?): MutableList<BuildDifference>? {
fun reportFail(reason: String) {
reporter?.report { "Could not read diff from file $file: $reason" }
}
@@ -48,7 +53,7 @@ data class BuildDiffsStorage(val buildDiffs: List<BuildDifference>) {
repeat(size) {
result.add(input.readBuildDifference())
}
return BuildDiffsStorage(result)
return result
}
}
catch (e: IOException) {

View File

@@ -23,5 +23,5 @@ internal sealed class ChangesEither {
val lookupSymbols: Collection<LookupSymbol> = emptyList(),
val fqNames: Collection<FqName> = emptyList()
) : ChangesEither()
internal class Unknown : ChangesEither()
internal class Unknown(val reason: String? = null) : ChangesEither()
}

View File

@@ -27,8 +27,6 @@ import org.jetbrains.kotlin.compilerRunner.toGeneratedFile
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
import org.jetbrains.kotlin.incremental.parsing.classesFqNames
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
@@ -43,8 +41,6 @@ abstract class IncrementalCompilerRunner<
cacheDirName: String,
protected val cacheVersions: List<CacheVersion>,
protected val reporter: ICReporter,
protected val artifactChangesProvider: ArtifactChangesProvider?,
protected val changesRegistry: ChangesRegistry?,
private val localStateDirs: Collection<File> = emptyList()
) {
@@ -307,16 +303,11 @@ abstract class IncrementalCompilerRunner<
open fun runWithNoDirtyKotlinSources(caches: CacheManager): Boolean = false
protected open fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) {
if (changesRegistry == null) return
if (compilationMode is CompilationMode.Incremental) {
changesRegistry.registerChanges(currentBuildInfo.startTS, dirtyData)
}
else {
assert(compilationMode is CompilationMode.Rebuild) { "Unexpected compilation mode: ${compilationMode::class.java}" }
changesRegistry.unknownChanges(currentBuildInfo.startTS)
}
protected open fun processChangesAfterBuild(
compilationMode: CompilationMode,
currentBuildInfo: BuildInfo,
dirtyData: DirtyData
) {
}
companion object {

View File

@@ -67,9 +67,7 @@ class IncrementalJsCompilerRunner(
workingDir,
"caches-js",
cacheVersions,
reporter,
artifactChangesProvider = null,
changesRegistry = null
reporter
) {
override fun isICEnabled(): Boolean =
IncrementalCompilation.isEnabled() && IncrementalCompilation.isEnabledForJs()

View File

@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.incremental
import com.intellij.lang.java.JavaLanguage
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiFileFactory
@@ -39,8 +38,9 @@ import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider
import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry
import org.jetbrains.kotlin.incremental.multiproject.EmptyModulesApiHistory
import org.jetbrains.kotlin.incremental.multiproject.ModulesApiHistory
import org.jetbrains.kotlin.incremental.util.Either
import org.jetbrains.kotlin.load.java.JavaClassesTracker
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
@@ -64,6 +64,7 @@ fun makeIncrementally(
val rootsWalk = sourceRoots.asSequence().flatMap { it.walk() }
val files = rootsWalk.filter(File::isFile)
val sourceFiles = files.filter { it.extension.toLowerCase() in allExtensions }.toList()
val buildHistoryFile = File(cachesDir, "build-history.bin")
withIC {
val compiler = IncrementalJvmCompilerRunner(
@@ -72,7 +73,9 @@ fun makeIncrementally(
versions, reporter,
// Use precise setting in case of non-Gradle build
usePreciseJavaTracking = true,
localStateDirs = emptyList()
localStateDirs = emptyList(),
buildHistoryFile = buildHistoryFile,
modulesApiHistory = EmptyModulesApiHistory
)
compiler.compile(sourceFiles, args, messageCollector, providedChangedFiles = null)
}
@@ -101,19 +104,15 @@ class IncrementalJvmCompilerRunner(
cacheVersions: List<CacheVersion>,
reporter: ICReporter,
private var kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null,
artifactChangesProvider: ArtifactChangesProvider? = null,
changesRegistry: ChangesRegistry? = null,
private val buildHistoryFile: File? = null,
private val friendBuildHistoryFile: File? = null,
private val usePreciseJavaTracking: Boolean,
localStateDirs: Collection<File>
private val buildHistoryFile: File,
localStateDirs: Collection<File>,
private val modulesApiHistory: ModulesApiHistory
) : IncrementalCompilerRunner<K2JVMCompilerArguments, IncrementalJvmCachesManager>(
workingDir,
"caches-jvm",
cacheVersions,
reporter,
artifactChangesProvider,
changesRegistry,
localStateDirs = localStateDirs
) {
override fun isICEnabled(): Boolean =
@@ -166,41 +165,18 @@ class IncrementalJvmCompilerRunner(
val lastBuildInfo = BuildInfo.read(lastBuildInfoFile) ?: return CompilationMode.Rebuild { "No information on previous build" }
reporter.report { "Last Kotlin Build info -- $lastBuildInfo" }
val changesFromFriend by lazy {
val myLastTS = lastBuildInfo.startTS
val storage = friendBuildHistoryFile?.let { BuildDiffsStorage.readFromFile(it, reporter) } ?: return@lazy ChangesEither.Unknown()
val classpathChanges = getClasspathChanges(args.classpathAsList, changedFiles, lastBuildInfo)
val (prevDiffs, newDiffs) = storage.buildDiffs.partition { it.ts < myLastTS }
if (prevDiffs.isEmpty()) return@lazy ChangesEither.Unknown()
val dirtyLookupSymbols = HashSet<LookupSymbol>()
val dirtyClassesFqNames = HashSet<FqName>()
for ((_, isIncremental, dirtyData) in newDiffs) {
if (!isIncremental) return@lazy ChangesEither.Unknown()
dirtyLookupSymbols.addAll(dirtyData.dirtyLookupSymbols)
dirtyClassesFqNames.addAll(dirtyData.dirtyClassesFqNames)
@Suppress("UNUSED_VARIABLE") // for sealed when
val unused = when (classpathChanges) {
is ChangesEither.Unknown -> return CompilationMode.Rebuild {
// todo: we can recompile all files incrementally (not cleaning caches), so rebuild won't propagate
"Could not get classpath's changes${classpathChanges.reason?.let { ": $it" }}"
}
is ChangesEither.Known -> {
markDirtyBy(classpathChanges.lookupSymbols)
markDirtyBy(classpathChanges.fqNames)
}
markDirtyBy(dirtyLookupSymbols)
markDirtyBy(dirtyClassesFqNames)
ChangesEither.Known(dirtyLookupSymbols, dirtyClassesFqNames)
}
val friendDirs = args.friendPaths?.map { File(it) } ?: emptyList()
for (file in changedFiles.removed.asSequence() + changedFiles.modified.asSequence()) {
if (!file.isClassFile()) continue
val isFriendClassFile = friendDirs.any { FileUtil.isAncestor(it, file, false) }
if (isFriendClassFile && changesFromFriend is ChangesEither.Known) continue
return CompilationMode.Rebuild { "Cannot get changes from modified or removed class file: ${reporter.pathsAsString(file)}" }
}
val classpathSet = args.classpathAsList.toHashSet()
val modifiedClasspathEntries = changedFiles.modified.filter { it in classpathSet }
val classpathChanges = getClasspathChanges(modifiedClasspathEntries, lastBuildInfo)
if (classpathChanges !is ChangesEither.Known) {
return CompilationMode.Rebuild { "could not get changes from modified classpath entries: ${reporter.pathsAsString(modifiedClasspathEntries)}" }
}
if (!usePreciseJavaTracking) {
@@ -221,8 +197,6 @@ class IncrementalJvmCompilerRunner(
val removedClassesChanges = getRemovedClassesChanges(caches, changedFiles)
markDirtyBy(androidLayoutChanges)
markDirtyBy(classpathChanges.lookupSymbols)
markDirtyBy(classpathChanges.fqNames)
markDirtyBy(removedClassesChanges.dirtyLookupSymbols)
markDirtyBy(removedClassesChanges.dirtyClassesFqNames)
@@ -285,33 +259,51 @@ class IncrementalJvmCompilerRunner(
}
private fun getClasspathChanges(
modifiedClasspath: List<File>,
lastBuildInfo: BuildInfo?
classpath: List<File>,
changedFiles: ChangedFiles.Known,
lastBuildInfo: BuildInfo
): ChangesEither {
if (modifiedClasspath.isEmpty()) {
reporter.report {"No classpath changes"}
return ChangesEither.Known()
val classpathSet = HashSet<File>()
for (file in classpath) {
when {
file.isFile -> classpathSet.add(file)
file.isDirectory -> file.walk().filterTo(classpathSet) { it.isFile }
}
}
val lastBuildTS = lastBuildInfo?.startTS
if (lastBuildTS == null) {
reporter.report {"Could not determine last build timestamp"}
return ChangesEither.Unknown()
}
val modifiedClasspath = changedFiles.modified.filterTo(HashSet()) { it in classpathSet }
val removedClasspath = changedFiles.removed.filterTo(HashSet()) { it in classpathSet }
// todo: removed classes could be processed normally
if (removedClasspath.isNotEmpty()) return ChangesEither.Unknown("Some files are removed from classpath $removedClasspath")
if (modifiedClasspath.isEmpty()) return ChangesEither.Known()
val lastBuildTS = lastBuildInfo.startTS
val symbols = HashSet<LookupSymbol>()
val fqNames = HashSet<FqName>()
for (file in modifiedClasspath) {
val diffs = artifactChangesProvider?.getChanges(file, lastBuildTS)
if (diffs == null) {
reporter.report {"Could not get changes for file: $file"}
return ChangesEither.Unknown()
val historyFilesEither = modulesApiHistory.historyFilesForChangedFiles(modifiedClasspath)
val historyFiles = when (historyFilesEither) {
is Either.Success<Set<File>> -> historyFilesEither.value
is Either.Error -> return ChangesEither.Unknown(historyFilesEither.reason)
}
for (historyFile in historyFiles) {
val allBuilds = BuildDiffsStorage.readDiffsFromFile(historyFile, reporter = reporter)
?: return ChangesEither.Unknown("Could not read diffs from $historyFile")
val (knownBuilds, newBuilds) = allBuilds.partition { it.ts <= lastBuildTS }
if (knownBuilds.isEmpty()) {
return ChangesEither.Unknown("No previously known builds for $historyFile")
}
diffs.forEach {
symbols.addAll(it.dirtyLookupSymbols)
fqNames.addAll(it.dirtyClassesFqNames)
for (buildDiff in newBuilds) {
if (!buildDiff.isIncremental) return ChangesEither.Unknown("Non-incremental build from dependency $historyFile")
val dirtyData = buildDiff.dirtyData
symbols.addAll(dirtyData.dirtyLookupSymbols)
fqNames.addAll(dirtyData.dirtyClassesFqNames)
}
}
@@ -400,16 +392,15 @@ class IncrementalJvmCompilerRunner(
override fun additionalDirtyLookupSymbols(): Iterable<LookupSymbol> =
javaFilesProcessor?.allChangedSymbols ?: emptyList()
override fun processChangesAfterBuild(compilationMode: CompilationMode, currentBuildInfo: BuildInfo, dirtyData: DirtyData) {
super.processChangesAfterBuild(compilationMode, currentBuildInfo, dirtyData)
if (buildHistoryFile == null) return
override fun processChangesAfterBuild(
compilationMode: CompilationMode,
currentBuildInfo: BuildInfo,
dirtyData: DirtyData
) {
val prevDiffs = BuildDiffsStorage.readFromFile(buildHistoryFile, reporter)?.buildDiffs ?: emptyList()
val newDiff = if (compilationMode is CompilationMode.Incremental) {
BuildDifference(currentBuildInfo.startTS, true, dirtyData)
}
else {
} else {
val emptyDirtyData = DirtyData()
BuildDifference(currentBuildInfo.startTS, false, emptyDirtyData)
}

View File

@@ -1,24 +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.incremental.multiproject
import org.jetbrains.kotlin.incremental.DirtyData
interface ChangesRegistry {
fun registerChanges(timestamp: Long, dirtyData: DirtyData)
fun unknownChanges(timestamp: Long)
}

View File

@@ -0,0 +1,186 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.multiproject
import org.jetbrains.kotlin.daemon.common.IncrementalModuleEntry
import org.jetbrains.kotlin.daemon.common.IncrementalModuleInfo
import org.jetbrains.kotlin.incremental.util.Either
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
import java.util.zip.ZipFile
interface ModulesApiHistory {
fun historyFilesForChangedFiles(changedFiles: Set<File>): Either<Set<File>>
}
object EmptyModulesApiHistory : ModulesApiHistory {
override fun historyFilesForChangedFiles(changedFiles: Set<File>): Either<Set<File>> =
Either.Error("Multi-module IC is not configured")
}
open class ModulesApiHistoryJvm(protected val modulesInfo: IncrementalModuleInfo) : ModulesApiHistory {
protected val projectRootPath: Path = Paths.get(modulesInfo.projectRoot.absolutePath)
private val dirToHistoryFileCache = HashMap<File, Set<File>>()
override fun historyFilesForChangedFiles(changedFiles: Set<File>): Either<Set<File>> {
val result = HashSet<File>()
val jarFiles = ArrayList<File>()
val classFiles = ArrayList<File>()
for (file in changedFiles) {
val extension = file.extension
when {
extension.equals("class", ignoreCase = true) -> {
classFiles.add(file)
}
extension.equals("jar", ignoreCase = true) -> {
jarFiles.add(file)
}
}
}
for (jar in jarFiles) {
val historyEither = getBuildHistoryFilesForJar(jar)
when (historyEither) {
is Either.Success<Set<File>> -> result.addAll(historyEither.value)
is Either.Error -> return historyEither
}
}
val classFileDirs = classFiles.groupBy { it.parentFile }
for ((dir, files) in classFileDirs) {
val historyEither = getBuildHistoryForDir(dir)
when (historyEither) {
is Either.Success<Set<File>> -> result.addAll(historyEither.value)
is Either.Error -> return historyEither
}
}
return Either.Success(result)
}
protected open fun getBuildHistoryForDir(file: File): Either<Set<File>> {
val history = dirToHistoryFileCache.getOrPut(file) {
val module = modulesInfo.dirToModule[file]
val parent = file.parentFile
when {
module != null ->
setOf(module.buildHistoryFile)
parent != null && projectRootPath.isParentOf(parent) -> {
val parentHistory = getBuildHistoryForDir(parent)
when (parentHistory) {
is Either.Success<Set<File>> -> parentHistory.value
is Either.Error -> return parentHistory
}
}
else ->
return Either.Error("Unable to get build history for $file")
}
}
return Either.Success(history)
}
protected open fun getBuildHistoryFilesForJar(jar: File): Either<Set<File>> {
val classListFile = modulesInfo.jarToClassListFile[jar] ?: return Either.Error("Unknown jar: $jar")
if (!classListFile.isFile) return Either.Error("Class list file does not exist $classListFile")
val classFiles = try {
classListFile.readText().split(File.pathSeparator).map(::File)
} catch (t: Throwable) {
return Either.Error("Could not read class list for $jar from $classListFile: $t")
}
val classFileDirs = classFiles.groupBy { it.parentFile }
val result = HashSet<File>()
for ((dir, files) in classFileDirs) {
val historyEither = getBuildHistoryForDir(dir)
when (historyEither) {
is Either.Success<Set<File>> -> result.addAll(historyEither.value)
is Either.Error -> return historyEither
}
}
return Either.Success(result)
}
}
class ModulesApiHistoryAndroid(modulesInfo: IncrementalModuleInfo) : ModulesApiHistoryJvm(modulesInfo) {
private val delegate = ModulesApiHistoryJvm(modulesInfo)
override fun historyFilesForChangedFiles(changedFiles: Set<File>): Either<Set<File>> {
val historyFromDelegate = delegate.historyFilesForChangedFiles(changedFiles)
if (historyFromDelegate is Either.Success<Set<File>>) return historyFromDelegate
return super.historyFilesForChangedFiles(changedFiles)
}
override fun getBuildHistoryFilesForJar(jar: File): Either<Set<File>> {
// Module detection is expensive, so we don't don it for jars outside of project dir
if (!projectRootPath.isParentOf(jar)) return Either.Error("Non-project jar is modified $jar")
val jarPath = Paths.get(jar.absolutePath)
return getHistoryForModuleNames(jarPath, getPossibleModuleNamesFromJar(jarPath))
}
override fun getBuildHistoryForDir(file: File): Either<Set<File>> {
if (!projectRootPath.isParentOf(file)) return Either.Error("Non-project file while looking for history $file")
// check both meta-inf and META-INF directories
val moduleNames =
getPossibleModuleNamesForDir(file.resolve("meta-inf")) + getPossibleModuleNamesForDir(file.resolve("META-INF"))
if (moduleNames.isEmpty()) {
return if (file.parentFile == null) {
Either.Error("Unable to find history for $file")
} else {
getBuildHistoryForDir(file.parentFile)
}
}
return getHistoryForModuleNames(file.toPath(), moduleNames)
}
private fun getPossibleModuleNamesFromJar(path: Path): Collection<String> {
val result = HashSet<String>()
try {
ZipFile(path.toFile()).use { zip ->
val entries = zip.entries()
while (entries.hasMoreElements()) {
val entry = entries.nextElement()
val name = entry.name
if (name.endsWith(".kotlin_module", ignoreCase = true)) {
result.add(File(name).nameWithoutExtension)
}
}
}
} catch (t: Throwable) {
return emptyList()
}
return result
}
private fun getPossibleModuleNamesForDir(path: File): List<String> {
if (!path.isDirectory) return listOf()
return path.listFiles().filter { it.name.endsWith(".kotlin_module", ignoreCase = true) }.map { it.nameWithoutExtension }
}
private fun getHistoryForModuleNames(path: Path, moduleNames: Iterable<String>): Either<Set<File>> {
val possibleModules =
moduleNames.flatMapTo(HashSet<IncrementalModuleEntry>()) { modulesInfo.nameToModules[it] ?: emptySet() }
val modules = possibleModules.filter { Paths.get(it.buildDir.absolutePath).isParentOf(path) }
if (modules.isEmpty()) return Either.Error("Unknown module for $path (candidates: ${possibleModules.joinToString()})")
val result = modules.mapTo(HashSet()) { it.buildHistoryFile }
return Either.Success(result)
}
}
private fun Path.isParentOf(path: Path) = path.startsWith(this)
private fun Path.isParentOf(file: File) = this.isParentOf(Paths.get(file.absolutePath))

View File

@@ -0,0 +1,11 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.util
sealed class Either<out T> {
class Success<T>(val value: T) : Either<T>()
class Error(val reason: String) : Either<Nothing>()
}

View File

@@ -0,0 +1,165 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.incremental.multiproject
import org.jetbrains.kotlin.daemon.common.IncrementalModuleEntry
import org.jetbrains.kotlin.daemon.common.IncrementalModuleInfo
import org.jetbrains.kotlin.incremental.util.Either
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder
import java.io.File
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
import kotlin.test.assertEquals
import kotlin.test.assertTrue
class ModulesApiHistoryAndroidTest {
@JvmField
@Rule
val tmpFolder = TemporaryFolder()
private lateinit var appRoot: File
private lateinit var appKotlinDestination: File
private lateinit var appHistory: File
private lateinit var libRoot: File
private lateinit var libKotlinDestination: File
private lateinit var libHistory: File
private lateinit var androidHistory: ModulesApiHistoryAndroid
@Before
fun setUp() {
val projectRoot = tmpFolder.newFolder()
appRoot = projectRoot.resolve("app")
appHistory = appRoot.resolve("build/tmp/kotlin/app_history.bin")
appKotlinDestination = appRoot.resolve("build/tmp/kotlin-classes").apply { mkdirs() }
val appEntry = IncrementalModuleEntry(":app", "app", appRoot.resolve("build"), appHistory)
appRoot.resolve("build/intermediates/classes/meta-inf/").apply {
mkdirs()
resolve("app.kotlin_module").createNewFile()
}
libRoot = projectRoot.resolve("lib")
libHistory = libRoot.resolve("lib/build/tmp/kotlin/lib_history.bin")
libKotlinDestination = libRoot.resolve("build/tmp/kotlin-classes").apply { mkdirs() }
val libEntry = IncrementalModuleEntry(":lib", "lib", libRoot.resolve("build"), libHistory)
libRoot.resolve("build/intermediates/classes/meta-inf/").apply {
mkdirs()
resolve("lib.kotlin_module").createNewFile()
}
val info = IncrementalModuleInfo(
projectRoot = projectRoot,
dirToModule = mapOf(appKotlinDestination to appEntry, libKotlinDestination to libEntry),
nameToModules = mapOf("app" to setOf(appEntry), "lib" to setOf(libEntry)),
jarToClassListFile = mapOf()
)
androidHistory = ModulesApiHistoryAndroid(info)
}
@Test
fun testClassChangeInAppTopLevel() {
val changed = appRoot.resolve("build/intermediates/classes/Changed.class").let {
it.mkdirs()
it
}
val changedFiles = androidHistory.historyFilesForChangedFiles(setOf(changed))
changedFiles as Either.Success<Set<File>>
assertEquals(setOf(appHistory), changedFiles.value)
}
@Test
fun testClassChangeInAppInPackage() {
val changed = appRoot.resolve("build/intermediates/classes/com/exampleChanged.class").let {
it.mkdirs()
it
}
val changedFiles = androidHistory.historyFilesForChangedFiles(setOf(changed))
changedFiles as Either.Success<Set<File>>
assertEquals(setOf(appHistory), changedFiles.value)
}
@Test
fun testClassMultipleChanges() {
val classesRoot = appRoot.resolve("build/intermediates/classes/com/example/")
classesRoot.mkdirs()
val changed = 1.until(10).map { classesRoot.resolve("MyClass_$it.class") }.toSet()
val changedFiles = androidHistory.historyFilesForChangedFiles(changed)
changedFiles as Either.Success<Set<File>>
assertEquals(setOf(appHistory), changedFiles.value)
}
@Test
fun testClassChangeInAppOutsideClasses() {
val changed = appRoot.resolve("build/Changed.class").let {
it.mkdirs()
it
}
val changedFiles = androidHistory.historyFilesForChangedFiles(setOf(changed))
assertTrue(changedFiles is Either.Error, "Fetching history should fail for file outside classes dir.")
}
@Test
fun testClassChangeInAppAndLib() {
val changedApp = appRoot.resolve("build/intermediates/classes/com/exampleChanged.class").let {
it.mkdirs()
it
}
val changedLib = libRoot.resolve("build/intermediates/classes/com/exampleChanged.class").let {
it.mkdirs()
it
}
val changedFiles = androidHistory.historyFilesForChangedFiles(setOf(changedApp, changedLib))
changedFiles as Either.Success<Set<File>>
assertEquals(setOf(appHistory, libHistory), changedFiles.value)
}
@Test
fun testJarChangeInApp() {
val jarFile = appRoot.resolve("build/intermediates/classes.jar")
jarFile.parentFile.mkdirs()
ZipOutputStream(jarFile.outputStream()).use {
it.putNextEntry(ZipEntry("meta-inf/app.kotlin_module"))
it.closeEntry()
}
val changedFiles = androidHistory.historyFilesForChangedFiles(setOf(jarFile))
changedFiles as Either.Success<Set<File>>
assertEquals(setOf(appHistory), changedFiles.value)
}
@Test
fun testJarChangesInAppAndLib() {
val appJar = appRoot.resolve("build/intermediates/classes.jar")
appJar.parentFile.mkdirs()
ZipOutputStream(appJar.outputStream()).use {
it.putNextEntry(ZipEntry("meta-inf/app.kotlin_module"))
it.closeEntry()
}
val libJar = libRoot.resolve("build/intermediates/classes.jar")
libJar.parentFile.mkdirs()
ZipOutputStream(libJar.outputStream()).use {
it.putNextEntry(ZipEntry("META-INF/lib.kotlin_module"))
it.closeEntry()
}
val changedFiles = androidHistory.historyFilesForChangedFiles(setOf(appJar, libJar))
changedFiles as Either.Success<Set<File>>
assertEquals(setOf(appHistory, libHistory), changedFiles.value)
}
}

View File

@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.codegen.OwnerKind
import org.jetbrains.kotlin.codegen.SourceInfo
import org.jetbrains.kotlin.codegen.inline.*
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation
@@ -54,9 +53,6 @@ class IrSourceCompilerForInline(
override val callElementText: String
get() = callElement.toString()
override val callableDescriptor: CallableDescriptor
get() = callElement.descriptor
override val callsiteFile: PsiFile?
get() = TODO("not implemented")

View File

@@ -26,6 +26,7 @@ import com.intellij.psi.*
import com.intellij.psi.impl.PsiSubstitutorImpl
import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.impl.source.PsiImmediateClassType
import com.intellij.psi.impl.source.tree.TreeUtil
import com.intellij.psi.scope.PsiScopeProcessor
import com.intellij.psi.search.SearchScope
import com.intellij.psi.stubs.IStubElementType
@@ -34,6 +35,7 @@ import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
import com.intellij.psi.util.PsiUtilCore
import com.intellij.util.IncorrectOperationException
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.annotations.NonNls
@@ -345,34 +347,23 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
return null
}
if (classOrObject is KtObjectDeclaration && classOrObject.isObjectLiteral()) {
if (classOrObject.containingFile.virtualFile == null) return null
return when {
classOrObject is KtObjectDeclaration && classOrObject.isObjectLiteral() ->
KtLightClassForAnonymousDeclaration(classOrObject)
return KtLightClassForAnonymousDeclaration(classOrObject)
classOrObject.isLocal ->
KtLightClassForLocalDeclaration(classOrObject)
else ->
KtLightClassImpl(classOrObject)
}
if (isEnumEntryWithoutBody(classOrObject)) {
return null
}
if (classOrObject.isLocal) {
if (classOrObject.containingFile.virtualFile == null) return null
return KtLightClassForLocalDeclaration(classOrObject)
}
return KtLightClassImpl(classOrObject)
}
private fun isEnumEntryWithoutBody(classOrObject: KtClassOrObject): Boolean {
if (classOrObject !is KtEnumEntry) {
return false
}
return classOrObject.getBody()?.declarations?.isEmpty() ?: true
}
fun getLightClassDataHolder(classOrObject: KtClassOrObject): LightClassDataHolder.ForClass {
if (classOrObject.shouldNotBeVisibleAsLightClass()) {
return InvalidLightClassDataHolder
}
return classOrObject.containingKtFile.script?.let { KtLightClassForScript.getLightClassCachedValue(it).value } ?:
getLightClassCachedValue(classOrObject).value
}
@@ -516,5 +507,44 @@ fun KtClassOrObject.defaultJavaAncestorQualifiedName(): String? {
}
}
fun KtClassOrObject.shouldNotBeVisibleAsLightClass() =
parentsWithSelf.filterIsInstance<KtClassOrObject>().any { it.hasExpectModifier() }
fun KtClassOrObject.shouldNotBeVisibleAsLightClass(): Boolean {
if (parentsWithSelf.filterIsInstance<KtClassOrObject>().any { it.hasExpectModifier() }) {
return true
}
if (isLocal) {
if (containingFile.virtualFile == null) return true
if (hasParseErrorsAround(this) || PsiUtilCore.hasErrorElementChild(this)) return true
}
if (isEnumEntryWithoutBody(this)) {
return true
}
return false
}
private fun isEnumEntryWithoutBody(classOrObject: KtClassOrObject): Boolean {
if (classOrObject !is KtEnumEntry) {
return false
}
return classOrObject.getBody()?.declarations?.isEmpty() ?: true
}
private fun hasParseErrorsAround(psi: PsiElement): Boolean {
val node = psi.node ?: return false
TreeUtil.nextLeaf(node)?.let { nextLeaf ->
if (nextLeaf.elementType == TokenType.ERROR_ELEMENT || nextLeaf.treePrev?.elementType == TokenType.ERROR_ELEMENT) {
return true
}
}
TreeUtil.prevLeaf(node)?.let { prevLeaf ->
if (prevLeaf.elementType == TokenType.ERROR_ELEMENT || prevLeaf.treeNext?.elementType == TokenType.ERROR_ELEMENT) {
return true
}
}
return false
}

View File

@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isPropertyParameter
import org.jetbrains.kotlin.resolve.AnnotationChecker
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.annotations.JVM_DEFAULT_FQ_NAME
import org.jetbrains.kotlin.resolve.source.getPsi
abstract class KtLightModifierList<out T : KtLightElement<KtModifierListOwner, PsiModifierListOwner>>(protected val owner: T)
@@ -138,9 +139,18 @@ private fun getAnnotationDescriptors(declaration: KtDeclaration, annotatedLightE
else -> descriptor
} ?: return emptyList()
return annotatedDescriptor.annotations.getAllAnnotations()
.filter { it.matches(annotatedLightElement) }
.map { it.annotation }
val annotations = annotatedDescriptor.annotations.getAllAnnotations()
.filter { it.matches(annotatedLightElement) }
.map { it.annotation }
if (descriptor is PropertyDescriptor) {
val jvmDefault = descriptor.annotations.findAnnotation(JVM_DEFAULT_FQ_NAME)
if (jvmDefault != null) {
return annotations + jvmDefault
}
}
return annotations
}
private fun hasAnnotationsInSource(declaration: KtDeclaration): Boolean {

View File

@@ -266,10 +266,14 @@ public class Preloader {
}
}
private static class PreloaderException extends RuntimeException {
public static class PreloaderException extends RuntimeException {
public PreloaderException(String message) {
super(message);
}
public PreloaderException(String message, Throwable cause) {
super(message, cause);
}
}
private static class Handler extends ClassHandler {

View File

@@ -99,7 +99,7 @@ abstract class KtCodeFragment(
override fun clone(): KtCodeFragment {
val clone = cloneImpl(calcTreeElement().clone() as FileElement) as KtCodeFragment
clone.isPhysical = false
clone.originalFile = this
clone.myOriginalFile = this
clone.imports = imports
clone.viewProvider =
SingleRootFileViewProvider(PsiManager.getInstance(_project), LightVirtualFile(name, KotlinFileType.INSTANCE, text), false)

View File

@@ -0,0 +1,203 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.psi.*
import com.intellij.psi.impl.PsiManagerEx
import com.intellij.psi.impl.source.tree.FileElement
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.tree.IElementType
import com.intellij.testFramework.LightVirtualFile
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
abstract class KtCodeFragment(
private val _project: Project,
name: String,
text: CharSequence,
imports: String?, // Should be separated by JetCodeFragment.IMPORT_SEPARATOR
elementType: IElementType,
private val context: PsiElement?
) : KtFile(
(PsiManager.getInstance(_project) as PsiManagerEx).fileManager.createFileViewProvider(
LightVirtualFile(
name,
KotlinFileType.INSTANCE,
text
), true
), false
), JavaCodeFragment {
private var viewProvider = super.getViewProvider() as SingleRootFileViewProvider
private var imports = LinkedHashSet<String>()
private val fakeContextForJavaFile: PsiElement? by lazy {
this.getCopyableUserData(FAKE_CONTEXT_FOR_JAVA_FILE)?.invoke()
}
init {
getViewProvider().forceCachedPsi(this)
init(TokenType.CODE_FRAGMENT, elementType)
if (context != null) {
initImports(imports)
}
}
override final fun init(elementType: IElementType, contentElementType: IElementType?) {
super.init(elementType, contentElementType)
}
private var resolveScope: GlobalSearchScope? = null
private var thisType: PsiType? = null
private var superType: PsiType? = null
private var exceptionHandler: JavaCodeFragment.ExceptionHandler? = null
private var isPhysical = true
abstract fun getContentElement(): KtElement?
override fun forceResolveScope(scope: GlobalSearchScope?) {
resolveScope = scope
}
override fun getForcedResolveScope() = resolveScope
override fun isPhysical() = isPhysical
override fun isValid() = true
override fun getContext(): PsiElement? {
if (fakeContextForJavaFile != null) return fakeContextForJavaFile
if (context !is KtElement) {
LOG.warn("CodeFragment with non-kotlin context should have fakeContextForJavaFile set: \noriginalContext = ${context?.getElementTextWithContext()}")
return null
}
return context
}
override fun getResolveScope() = context?.resolveScope ?: super.getResolveScope()
override fun clone(): KtCodeFragment {
val clone = cloneImpl(calcTreeElement().clone() as FileElement) as KtCodeFragment
clone.isPhysical = false
clone.myOriginalFile = this
clone.imports = imports
clone.viewProvider =
SingleRootFileViewProvider(PsiManager.getInstance(_project), LightVirtualFile(name, KotlinFileType.INSTANCE, text), false)
clone.viewProvider.forceCachedPsi(clone)
return clone
}
final override fun getViewProvider() = viewProvider
override fun getThisType() = thisType
override fun setThisType(psiType: PsiType?) {
thisType = psiType
}
override fun getSuperType() = superType
override fun setSuperType(superType: PsiType?) {
this.superType = superType
}
override fun importsToString(): String {
return imports.joinToString(IMPORT_SEPARATOR)
}
override fun addImportsFromString(imports: String?) {
if (imports == null || imports.isEmpty()) return
imports.split(IMPORT_SEPARATOR).forEach {
addImport(it)
}
// we need this code to force re-highlighting, otherwise it does not work by some reason
val tempElement = KtPsiFactory(project).createColon()
add(tempElement).delete()
}
fun addImport(import: String) {
val contextFile = getContextContainingFile()
if (contextFile != null) {
if (contextFile.importDirectives.find { it.text == import } == null) {
imports.add(import)
}
}
}
fun importsAsImportList(): KtImportList? {
if (!imports.isEmpty() && context != null) {
return KtPsiFactory(this).createAnalyzableFile("imports_for_codeFragment.kt", imports.joinToString("\n"), context).importList
}
return null
}
override val importDirectives: List<KtImportDirective>
get() = importsAsImportList()?.imports ?: emptyList()
override fun setVisibilityChecker(checker: JavaCodeFragment.VisibilityChecker?) {}
override fun getVisibilityChecker() = JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE
override fun setExceptionHandler(checker: JavaCodeFragment.ExceptionHandler?) {
exceptionHandler = checker
}
override fun getExceptionHandler() = exceptionHandler
override fun importClass(aClass: PsiClass): Boolean {
return true
}
fun getContextContainingFile(): KtFile? {
return getOriginalContext()?.containingKtFile
}
fun getOriginalContext(): KtElement? {
val contextElement = getContext() as? KtElement
val contextFile = contextElement?.containingKtFile
if (contextFile is KtCodeFragment) {
return contextFile.getOriginalContext()
}
return contextElement
}
private fun initImports(imports: String?) {
if (imports != null && !imports.isEmpty()) {
val importsWithPrefix = imports.split(IMPORT_SEPARATOR).map { it.takeIf { it.startsWith("import ") } ?: "import ${it.trim()}" }
importsWithPrefix.forEach {
addImport(it)
}
}
}
companion object {
val IMPORT_SEPARATOR: String = ","
val RUNTIME_TYPE_EVALUATOR: Key<Function1<KtExpression, KotlinType?>> = Key.create("RUNTIME_TYPE_EVALUATOR")
val FAKE_CONTEXT_FOR_JAVA_FILE: Key<Function0<KtElement>> = Key.create("FAKE_CONTEXT_FOR_JAVA_FILE")
private val LOG = Logger.getInstance(KtCodeFragment::class.java)
}
}

View File

@@ -36,9 +36,9 @@ object KotlinStubVersions {
// BuiltIn stub version should be increased if changes are made to builtIn stub building subsystem (org.jetbrains.kotlin.idea.decompiler.builtIns)
// Increasing this version will lead to reindexing of all builtIn files (see KotlinBuiltInFileType).
const val BUILTIN_STUB_VERSION = BINARY_STUB_VERSION + 1
const val BUILTIN_STUB_VERSION = BINARY_STUB_VERSION + 2
// 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 + 1
const val JS_STUB_VERSION = BINARY_STUB_VERSION + 2
}

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