Compare commits

...

942 Commits

Author SHA1 Message Date
Pavel V. Talanov
a3f51fabce Comments for review 2017-07-24 18:00:02 +03:00
Kirill Rakhman
4c7ddbe397 "Use destructuring declaration" should not be available for top-level and class properties (#1205)
Fixes #KT-19167
2017-07-24 14:33:46 +02:00
Dmitry Petrov
f558b4238c Use counter loop in intrinsic array constructors
#KT-19149 Fixed Target versions 1.1.5
2017-07-24 10:17:30 +03:00
Dmitry Petrov
c9d9a8220d Minor: use IntrinsicMethods.INTRINSICS_CLASS_NAME where appropriate 2017-07-24 10:15:27 +03:00
Dmitry Petrov
fda89e9c72 Add test for KT-19128
It looks like the problem was caused by incorrect merging of
StrictBasicValues and was fixed by commit
904c7f9c64.

 #KT-19128 Fixed
2017-07-24 10:15:27 +03:00
Dmitry Petrov
d0c8af5621 Keep track of second receiver type in CallReceiver
#KT-17725 Fixed Target versions 1.1.5
2017-07-24 10:15:27 +03:00
Dmitry Petrov
3f34a97880 Minor: extract CallReceiver to a top-level class, move code around 2017-07-24 10:15:27 +03:00
Simon Ogorodnik
f079ed949c KT-19015: Enable multiarg completion for non-first argument
#KT-19015 fixed
2017-07-24 00:00:11 +03:00
Ilya Gorbunov
ec5c15f190 test-dagger-maven-example: kotlin version comes as a parameter 2017-07-21 20:15:34 +03:00
Ilya Gorbunov
d8ea3ddcc8 Cleanup poms of projects migrated to gradle 2017-07-21 20:15:34 +03:00
Alexander Udalov
f69e96b240 Fix IAE at protoDifferenceUtils.kt on new metadata field
The class_local_variable/package_local_variable JVM extensions were
added in 616d575fb6

 #KT-19155 Fixed
2017-07-21 20:11:43 +03:00
Nikolay Krasko
b6bd3e15c5 Fix outdated highlighting for Kotlin injected fragments (KT-18842)
Do not use cached value for injection in non-dispatch threads and throw
PCE if value isn't ready. Otherwise outdated value may be stored in
highlighting.

 #KT-18842 Fixed
2017-07-21 19:57:21 +03:00
Alexander Udalov
7f8e7c66f5 Suppress FNFE in .kotlin_metadata index
Similarly to VirtualFileKotlinClass.create.

This could happen for example when some files are removed from
kotlin-stdlib-common
2017-07-21 19:03:15 +03:00
Alexander Udalov
ebdf5aa223 Discriminate header classes in favor of non-header type aliases
In the test case, the problem was that Foo.a's type was resolved to the
_class A_, which was written to metadata on JVM instead of the class
AImpl with typealias A as an abbreviation. This metadata was incorrect
because there's no class A from the JVM compiler's point of view; that's
why the error "cannot access class A" was reported

 #KT-19151 Fixed
2017-07-21 19:03:15 +03:00
Mikhail Glukhikh
6ee94dae6f Code cleanup: KotlinSafeDeleteProcessor 2017-07-21 18:59:13 +03:00
Mikhail Glukhikh
d05a525d8d Search for KtTypeAlias in safe delete processor
Related to KT-16046
2017-07-21 18:59:07 +03:00
Mikhail Glukhikh
dd0cf8219e Add type aliases into UnusedSymbolInspection / safe delete
So #KT-16046 Fixed
2017-07-21 18:59:01 +03:00
Mikhail Glukhikh
951e8cd91a Code cleanup: unnecessary local variable applied 2017-07-21 18:58:48 +03:00
Mikhail Glukhikh
202fb19cf6 If-then to safe access: more correct receiver calculation
So #KT-18928 Fixed
2017-07-21 18:58:33 +03:00
Mikhail Glukhikh
31bb1cc0f9 Invoke back setting "show inline dialog for local variables"
So #KT-19130 Fixed
2017-07-21 18:58:27 +03:00
Kirill Rakhman
a7084ceb9b Fix some type hints related issues (#1204)
* Type hints shouldn't appear for negative literals
Fixes #KT-18974

* Make type hints work for destructuring declarations
Fixes #KT-18444

* Hide type hints for generic constructor calls if type arguments are explicitly specified
Fixes #KT-19167
2017-07-21 16:31:46 +02:00
Nikolay Krasko
f4038f7109 Fix slow typing because of counting injected fragments (KT-18842)
- cache result of kotlin injection on modification tracker
- never count injection in dispatch thread, use cached result instead
- compute injection with write action priority, reuse cache if unfinished

 #KT-18842 Fixed
2017-07-21 15:41:06 +03:00
Nikolay Krasko
436b637282 Refactoring: show using ProcessCancelException in method name 2017-07-21 15:41:06 +03:00
Nikolay Krasko
fbe16f7b91 Refactoring: delete unused CachedValueProperty class 2017-07-21 15:41:06 +03:00
Mikhail Glukhikh
1cb6128f2f Minor: J2K test fix 2017-07-21 12:21:04 +03:00
Dmitry Petrov
bf3e896464 Update 'this' extension receiver when there's a smart cast
If 'this' (implicit or explicit) was used as an extension receiver,
and the corresponding call required a smart-cast,
this information was effectively lost in "old" resolution & inference,
but is required by "old" JVM BE to generate proper CHECKCASTs.
2017-07-21 08:58:52 +03:00
Dmitry Petrov
c9d54d7110 Generate proper error candidates for type aliases
#KT-17745 Fixed Target versions 1.1.5
2017-07-21 08:58:12 +03:00
Dmitry Petrov
b4d8337ca5 Ignore test for 'primitive Char == object' in JS (KT-19081) 2017-07-21 08:52:29 +03:00
Dmitry Petrov
709a7e201f Simplify code for specialized BranchedValues 2017-07-21 08:52:29 +03:00
Dmitry Petrov
e1a55e8dec Prefer compact bytecode for primitive/object comparisons with Boolean
'java.lang.Boolean#valueOf' doesn't allocate new objects
(it uses pre-allocated singletons for 'true' and 'false').
2017-07-21 08:52:29 +03:00
Dmitry Petrov
8e9c0294fe Do not box primitives for 'primitive == object'
NB user-defined 'equals' can violate contract for 'Object#equals', e.g.,
it can be asymmetric.
Thus we can't avoid boxing for 'object == primitive'.
2017-07-21 08:52:29 +03:00
Dmitry Petrov
fa42f202fa Avoid boxing on 'primitive == boxed' when possible
Similar to 'boxed == primitive' case, different bytecode due to
evaluation order.
2017-07-21 08:52:29 +03:00
Dmitry Petrov
e440de3494 Minor: GeneratePrimitiveVsObjectEqualityTestData 2017-07-21 08:52:29 +03:00
Dmitry Petrov
98ee83f4a3 Minor: move condition for boxed==primitive to corresponding isApplicable 2017-07-21 08:52:29 +03:00
Dmitry Petrov
4cba600268 Minor: some more evaluation order tests for 'boxed == primitive' 2017-07-21 08:52:29 +03:00
Dmitry Petrov
81609e4c6f Generate complex equality comparison only when RHS can have side effects
In "short" version, LHS is always evaluated before RHS,
and RHS may be not evaluated if LHS is null.
So, it makes sense to use "short" version in cases when RHS can't have
side effects (because of more compact bytecode and more opportunities
for code elimination).
2017-07-21 08:52:29 +03:00
Dmitry Petrov
8aacddb9f0 Avoid primitive boxing for 'boxed == primitive' if possible
This makes sense for non-floating-point primitive type
(boolean, char, byte, short, int, long):
floating-point types use specialized versions of 'areEqual'.
2017-07-21 08:52:29 +03:00
Dmitry Petrov
275c758da1 Cleanup and move code around in BranchedValue
- Cleanup inspections
- Move optimized boxed-vs-primitive comparisons to a separate file
2017-07-21 08:52:29 +03:00
Dmitry Petrov
051ac44759 Verify bytecode after mandatory transformations and after optimizations 2017-07-21 08:52:29 +03:00
Simon Ogorodnik
7ed1669050 KT-19011: Fix import optimizing when extension functional type is used
It should check is extension functional type imported from companion
is actually called on companion instance

 #KT-19011 fixed
2017-07-21 03:08:06 +03:00
Dimach
65e603c1ed KT-13552: Fix J2K to generate else block while converting switch
#KT-13552 fixed
2017-07-20 23:35:11 +03:00
Mikhail Glukhikh
44790eccaf Use "unnecessary variable" inspection in J2K
Unused variables are no more treated as unnecessary
Related to KT-15958
2017-07-20 17:48:27 +03:00
Mikhail Glukhikh
39f1ef390e Do not report "redundant Unit" for generic calls coerced to Unit
So #KT-18999 Fixed
2017-07-20 17:48:20 +03:00
Mikhail Glukhikh
c554bfa20d Move: RemoveSetterParameterTypeInspection to inspections package 2017-07-20 17:48:14 +03:00
Mikhail Glukhikh
e154e4cf75 Move: RedundantUnitReturnTypeInspection to inspections package 2017-07-20 17:48:07 +03:00
Simon Ogorodnik
8f78446bff Minor: Clarify code for KT-18786: Fix J2K to move properties to top 2017-07-20 16:04:07 +03:00
Dmitry Jemerov
9213c4a1ab EA-104855 - (1.1.4) NPE: KotlinCommonBlockKt.isFirstParameter 2017-07-20 12:50:12 +02:00
Dmitry Jemerov
fbcc519098 Fix tests affected by annotation wrapping changes 2017-07-20 12:32:48 +02:00
Alexander Udalov
5128b8a409 Add default implementation for Annotations.findAnnotation 2017-07-20 13:27:34 +03:00
Alexander Udalov
def3f73fdd Use AnnotationDescriptor.fqName instead of type
Also use the annotationClass extension property instead of
TypeUtils.getClassDescriptor(annotation.type)
2017-07-20 13:26:13 +03:00
Alexander Udalov
541b9dab52 Introduce optimized BuiltInAnnotationDescriptor for built-in annotations
It's built on a FQ name and avoids resolution of the annotation class
descriptor as much as possible
2017-07-20 13:26:13 +03:00
Alexander Udalov
f39106f75c Do not use parameter descriptors in AnnotationDescriptorImpl 2017-07-20 13:26:13 +03:00
Alexander Udalov
eb205f620c Do not use parameter descriptors in most annotation implementations
Except AnnotationDescriptorImpl, which is refactored in the subsequent
commit.

Note that we no longer check the presence of parameters with the
corresponding names in the annotation class in
LazyJavaAnnotationDescriptor, this is why test data changed
2017-07-20 13:25:39 +03:00
Alexander Udalov
cc7ed2ba54 Change map key type in AnnotationDescriptor.getAllValueArguments
Turns out, only the parameter's name is needed at all usages of this
method. Such a map is both easier to use (no need to call
ValueParameterDescriptor.getName) and easier to construct (no need to
resolve annotation class, its constructor, its parameters). In this
commit, only usages have changed but the implementations are still using
the old logic, this is going to be refactored in subsequent commits
2017-07-20 13:25:39 +03:00
Alexander Udalov
41ea0e8ef8 Introduce AnnotationDescriptor.fqName
Could be used instead of ".annotationClass.fqName" to avoid the unneeded
resolution of the annotation class descriptor
2017-07-20 13:25:38 +03:00
Alexander Udalov
1d64b61a8f J2K AnnotationDescriptor, refactor implementations 2017-07-20 13:25:38 +03:00
Alexander Udalov
7ec67505c5 Optimize Annotations.isEmpty in some implementations 2017-07-20 13:25:38 +03:00
Alexander Udalov
9ee4b39e1b Provide default implementation for Annotations.findExternalAnnotation 2017-07-20 13:25:38 +03:00
Alexander Udalov
5636318eb4 Optimize DeserializedAnnotations in terms of memory traffic
Do not wrap every annotation object into an AnnotationWithTarget
2017-07-20 13:25:38 +03:00
Alexander Udalov
21197b53aa Do not load annotations on value parameter if there are none
Also fix an error in the doc in descriptors.proto
2017-07-20 13:25:38 +03:00
Alexander Udalov
c197db9c69 Remove some unnecessary lazy computations in LazyJavaClassDescriptor 2017-07-20 13:25:38 +03:00
Mikhail Glukhikh
bdc44ff4cf Unnecessary variable: do not start inlining in write action
So #KT-19110 Fixed

(cherry picked from commit 6325fb1)
2017-07-20 12:39:52 +03:00
Ilya Chernikov
e38aaf3e07 Fix xmx setting for the daemon in tests 2017-07-20 10:54:05 +02:00
Ilya Chernikov
17a189a24b Improve logging and exception handling in the daemon 2017-07-20 10:54:05 +02:00
Denis Zharkov
904c7f9c64 Fix nullable variables spilling in coroutines
See the last comment in testData for clarification

 #KT-18983 Fixed
2017-07-20 10:53:32 +03:00
Denis Zharkov
90e894b171 Use known jvm binary class for package part if possible 2017-07-20 10:53:09 +03:00
Denis Zharkov
99a10d8d63 Minor. Rename compactIfPossible -> compact
As ArrayList can always be compacted
2017-07-20 10:53:09 +03:00
Denis Zharkov
f454858bbb Optimize memory footprint for case of empty annotations in types
It seems that most of the simple types don't have any annotations,
so for that case it's worth removing the field from SimpleTypeImpl

Also introduce a NotNullSimpleType being used when replacing nullability
2017-07-20 10:53:09 +03:00
Denis Zharkov
f8a12a0ec3 Optimize JavaTypeResolver by avoiding using some language features
It's quite a hot point and using local functions with default
parameters seem to affect negatively to overall performance
(at least some of compiler benchmark have shown it)
2017-07-20 10:53:09 +03:00
Denis Zharkov
d7cee95d95 Call compactIfPossible where it's possible in BinaryJava*
It helps to avoid retaining a lot of redundant empty SmartList's
instances
2017-07-20 10:53:09 +03:00
Denis Zharkov
e2ce285ec3 Reduce memory footprint after functions substitution
Do not recreate new instances if descriptors' parts remain
effectively the same
2017-07-20 10:53:09 +03:00
Denis Zharkov
4a73fbb70a Reduce memory footprint of TypeSubstitutor
Avoid creating new instances if types remain unchanged
2017-07-20 10:53:09 +03:00
Denis Zharkov
4385ce8828 Reduce memory footprint for basic case of flexible types
The case is when we have a simple type constructor
(not array nor collection) and type is not raw:
A<T1, >..A<T1>?

Actually these types are almost equal besides of nullability,
but we create and resolve two different simple types,
they have different arguments' lists, etc.

The idea is to add NullableSimpleType subclass with delegate
to another simple type

It should help a lot both with common cases and with corner ones:
flexibles types in spark for Function22 having exponential size
because of its flexibility

 #KT-14375 Fixed
 #KT-14323 Fixed
2017-07-20 10:53:09 +03:00
Denis Zharkov
59f2ba98a6 Avoid creating SimpleType instances for default type 2017-07-20 10:53:09 +03:00
Denis Zharkov
8576054788 Use SmartList instead of SmartSet for overridden descriptors
SmartSet was used because it was the only lightweight collection
available in core, but now there is org.jetbrains.kotlin.utils.SmartList
2017-07-20 10:53:09 +03:00
Denis Zharkov
729f20ed81 Reduce memory size retained by LookupTrackerImpl
By default SmartList is used there for storing values of a multimap,
so a lot of duplicated items is stored there (file names are being
duplicated).

Even although there is a separate interner for these values,
retained memory size has been reduced for 30M when compiling `idea`
module in Kotlin project
2017-07-20 10:53:09 +03:00
Denis Zharkov
c7e6f200da Use SmartList for storing annotations in binary classes
Looks like in the most cases there are <= 1 annotations
in real declarations
2017-07-20 10:53:09 +03:00
Simon Ogorodnik
36ab31f2f7 Minor: fix test after merge 2017-07-20 02:30:34 +03:00
Toshiaki Kameyama
fe599463ac KT-18978 Intention Move to class body generates incorrect code for vararg val/var (#1188)
Intention Move to class body generates incorrect code for vararg val/var #KT-18978 Fixed
2017-07-20 01:29:56 +03:00
Dimach
a59021a25e KT-18786: J2K should move all properties to top of class
#KT-18786 fixed
2017-07-20 01:15:15 +03:00
Simon Ogorodnik
ccfcfd8721 Add benchmark for local completion and improve benchmarking 2017-07-19 21:18:58 +03:00
Dmitry Jemerov
4df6db141c Advance source stub version which wasn't advanced in 5d87276cf
#KT-19113 Fixed
2017-07-19 18:52:29 +02:00
Dmitry Petrov
891799c853 Generate 'Deprecated' annotation on invisible companion object field
Design decision: if the field for a companion object should have
non-public visibility, generate it with @Deprecated annotation in
language version 1.2.

TODO: generate it with proper visibility in 1.3 and later.

KT-11567 Companion object INSTANCE field more visible than companion object class itself
2017-07-19 17:38:17 +03:00
Dmitry Jemerov
951392005b Add options for wrapping local variable and property annotations
#KT-14950 Fixed
2017-07-19 15:03:00 +02:00
Dmitry Jemerov
050ff03b07 Implement wrapping options for enum constants
#KT-14126 Fixed
2017-07-19 15:02:59 +02:00
Dmitry Jemerov
7555bb6c3c Support formatting of 'where' clauses
#KT-14083 Fixed
2017-07-19 15:02:58 +02:00
Dmitry Jemerov
325e950bfe Reformat expression body property accessors
#KT-17394 Fixed
2017-07-19 15:02:52 +02:00
Dmitry Jemerov
4db8639bf8 Consistent name for option controlling spaces around .. 2017-07-19 15:02:50 +02:00
Dmitry Jemerov
31840fa328 Fix GradleLanguageFeatureQuickFixTest on Windows 2017-07-19 13:56:00 +02:00
Toshiaki Kameyama
366b9d1d79 KT-12195 Quickfix @JvmStatic on main() method in an object (#1192)
* Quickfix @JvmStatic on main() method in an object #KT-12195 Fixed

* Fixed #KT-12195
2017-07-19 13:37:12 +02:00
Toshiaki Kameyama
a8da79a130 KT-12504 Intention to make open class with only private constructors sealed (#1193)
* Intention to make open class with only private constructors sealed #KT-12504 Fixed

* Fixed #KT-12504
2017-07-19 13:36:36 +02:00
Nikolay Krasko
dd2a87dbf7 Rewrite test class to make it work on Windows
Stop using dummy file and assert result with assertEqualsToFile().

Previous version didn't work on Windows because of `\r`.
2017-07-19 13:25:17 +03:00
Nikolay Krasko
4e76975a52 Force OOB in accessors for properties without explicit type (KT-19062)
#KT-19062 Fixed
2017-07-19 12:45:06 +03:00
Nikolay Krasko
bcbff98382 Check OOB stays the same for string in super type constructor call 2017-07-19 12:45:06 +03:00
Pavel V. Talanov
41276c950b Update CodegenTestCase after rebasing on latest changes 2017-07-19 12:29:27 +03:00
Pavel V. Talanov
5faad493b4 Catch and report exceptions from DependenciesResolver 2017-07-19 12:29:25 +03:00
Pavel V. Talanov
eb5be038fa ScriptDependenciesUpdater: compute script contents synchronously 2017-07-19 12:29:22 +03:00
Pavel V. Talanov
9eb8cec5cf ScriptDependenciesUpdater: set job to null after processing result
Fix inconsistency introduced after extracting ScriptDependenciesUpdater
2017-07-19 12:29:20 +03:00
Pavel V. Talanov
537b1689b7 DependenciesCache: remove ad-hoc ScriptDependencies comparison 2017-07-19 12:29:17 +03:00
Pavel V. Talanov
b1ac451959 Make sure template classpath is always among script dependencies 2017-07-19 12:29:15 +03:00
Pavel V. Talanov
f84cc7fb5b Offload legacy dependency resolver work to a separate thread pool
This is mainly to improve experience for kdsl users before gradle migrates to new API
2017-07-19 12:29:12 +03:00
Pavel V. Talanov
bc399444ab Fix creating DependenciesResolver with default arguments 2017-07-19 12:29:09 +03:00
Pavel V. Talanov
7aee51fd77 Refactor ScriptDependenciesUpdater: improve readability a bit 2017-07-19 12:29:07 +03:00
Pavel V. Talanov
c0e08c61ee Minor: extract ScriptContentLoader::getEnvironment 2017-07-19 12:29:04 +03:00
Pavel V. Talanov
42629d6f8d ScriptDependenciesUpdater: use Job explicitly instead of futures
Cancel jobs without interrupting
2017-07-19 12:29:02 +03:00
Pavel V. Talanov
999c3c5e76 Rename services related to script dependencies
KotlinScriptConfigurationManager -> ScriptDependenciesManager
KotlinScriptExternalImportsProvider -> ScriptDependenciesProvider
2017-07-19 12:28:59 +03:00
Pavel V. Talanov
96db16a988 ScriptDependenciesUpdater, minor: improve isLastSentRequestCheck 2017-07-19 12:28:56 +03:00
Pavel V. Talanov
aacb9a437a Rename: dependenciesClasspath -> templateClasspath
Clearer distinction from additionalResolverClasspath
2017-07-19 12:28:54 +03:00
Pavel V. Talanov
96d8f685e9 Refactor KotlinScriptConfigurationManager: extract parts
Introduce ScriptDependenciesUpdater, DependenciesCache and ScriptContentLoader
2017-07-19 12:28:51 +03:00
Pavel V. Talanov
1b42095dc1 Support @AcceptedAnnotations for different kinds of resolvers 2017-07-19 12:28:49 +03:00
Pavel V. Talanov
1c412b4068 AsyncDependenciesResolver: provide implementation for sync resolve 2017-07-19 12:28:46 +03:00
Pavel V. Talanov
008c27d547 Compiler build depends on kotlinx-coroutines-core 2017-07-19 12:28:43 +03:00
Pavel V. Talanov
ee70a64e1c Minor, template providers: don't create classloader for empty classpath 2017-07-19 12:28:41 +03:00
Pavel V. Talanov
beb28a1c7d Gradle Kotlin DSL uses compiler-embdeddable jar when loading resolver 2017-07-19 12:28:38 +03:00
Pavel V. Talanov
5c18ab750b GradleScriptTemplateProvider: avoid duplicating template loading code 2017-07-19 12:28:36 +03:00
Pavel V. Talanov
6c3ce7adc1 ScriptTemplatesProvider: refactor dependency loading
Change dependenciesClasspath is of type List<File>
Add additionalResolverClasspath
2017-07-19 12:28:33 +03:00
Pavel V. Talanov
a77cd0ab09 Catch errors when instantiating script templates
If we throw from this code IDE becomes unusable

 #KT-18945 Fixed
2017-07-19 12:28:31 +03:00
Pavel V. Talanov
8ac17400ae ScriptDependenciesFileAttribute: fix TODOs 2017-07-19 12:28:28 +03:00
Pavel V. Talanov
75220e145b Minor: suppress deprecation warning 2017-07-19 12:28:26 +03:00
Pavel V. Talanov
cf57e5a7a1 Script templates: search for parameterless constructor of resolver 2017-07-19 12:28:23 +03:00
Pavel V. Talanov
10e14103b6 Propagate reports from script dependency resolver
Compiler: show as compiler messages
IDE: annotate code in a separate highlighting pass
2017-07-19 12:28:20 +03:00
Pavel V. Talanov
96c2a589c0 Support legacy resolver interface 2017-07-19 12:28:18 +03:00
Pavel V. Talanov
65dba3615c Update project code to use new script.runtime APIs 2017-07-19 12:28:15 +03:00
Pavel V. Talanov
375b058a28 Add coroutines-jdk8 to project 2017-07-19 12:28:13 +03:00
Pavel V. Talanov
1012a24afc Refactor: move KotlinScriptExternalImportsProviderImpl to 'cli' module 2017-07-19 12:28:10 +03:00
Pavel V. Talanov
b6a7d831bf Script IDE API: remove <TF: Any> 2017-07-19 12:28:08 +03:00
Pavel V. Talanov
581176fa90 AbstractScriptConfigurationTest: adapt to changes in API 2017-07-19 12:28:05 +03:00
Pavel V. Talanov
788eaf8a18 Refactor getting dependencies for script files API
Deprecate KotlinScriptDefinition#getDependenciesFor
Expose dependencyResolver as a property
KotlinScriptExternalImportsProvider is the component clients should be asking for dependencies
2017-07-19 12:28:02 +03:00
Pavel V. Talanov
ff391628de KSCM: fix wrong update on null return from Template.getDependenciesFor 2017-07-19 12:28:00 +03:00
Pavel V. Talanov
1834721880 KSCM: persist script dependencies between idea launches 2017-07-19 12:27:55 +03:00
Pavel V. Talanov
930d502b12 KSCM: rework async requests 2017-07-19 12:27:53 +03:00
Pavel V. Talanov
3c511f3f40 KSCM: temporary workaround gradle returning results in unstable order 2017-07-19 12:27:50 +03:00
Pavel V. Talanov
fb0e0e3767 Introduce ScriptDependenciesFileAttribute to persist script dependencies 2017-07-19 12:27:48 +03:00
Pavel V. Talanov
a2aeda7b2c Support async script dependency updates for annotation based templates
Do not try to cache dependencies for every script on startup
Schedule cache updates upon request as opposed to updating them synchronously
2017-07-19 12:27:45 +03:00
Pavel V. Talanov
b7fc909821 Split compiler and ide specific parts of script dependency caching
Move all caching logic to ide specific KotlinScriptConfigurationManager
Clean up apis
Remove logging when updating caches
2017-07-19 12:27:43 +03:00
Anton Bannykh
e43a145614 fixup: updated EXPECTED_REACHABLE_NODES 2017-07-19 12:24:09 +03:00
Anton Bannykh
6ed7eaf546 JS tests: changes to kotlin.test + the way compiler tests are generated. 2017-07-19 12:24:09 +03:00
Alexey Sedunov
eda747c0bf Minor: Fix tests 2017-07-19 11:34:30 +03:00
Roman Elizarov
f2b5f37b22 Support inline suspend functions built with compiler version less than 1.1.4/1.2-M1
The error message is removed and is replaced with a code that adapts
inline suspend functions produced by the old compiler with the
suspension markers that new compiler expects.
2017-07-19 08:59:55 +03:00
Roman Elizarov
9f0810f723 Pull implementations up from AbstractCoroutineContextElemenet
Fixes KT-18671
2017-07-19 08:59:43 +03:00
Alexander Udalov
c9b14c5a45 Reduce classpath for class loader in CodegenTestCase
There's no point in adding JDK (mock or full) roots to it, as well as
stdlib/reflect/test (they are loaded by the parent class loader, created
in ForTestCompileRuntime)
2017-07-18 20:10:07 +03:00
Alexander Udalov
743278d456 Fix ReplInterpreter on Java 9 2017-07-18 20:10:05 +03:00
Alexander Udalov
aa53fa7e15 Fix execution of simple .kts scripts on Java 9 2017-07-18 20:10:05 +03:00
Alexander Udalov
bc2c958a2e Remove unused class GenericRepl 2017-07-18 20:10:05 +03:00
Alexander Udalov
36001ff931 Do not allow to access compiler internals in .kts scripts
Set parent class loader to null explicitly instead of the system class
loader
2017-07-18 20:10:05 +03:00
Alexander Udalov
d1603c4329 Minor, move deserializeToDescriptor to package kotlin.reflect.jvm.internal
To prevent binary-compatibility-validator from reporting it as a public
API; that happens because the signature is different after the
gradle-shadow-plugin is applied
2017-07-18 20:09:24 +03:00
Yan Zhulanow
00225b3de3 Use compiling evaluator only if there is non-inline lambda or a loop in the bytecode 2017-07-18 18:22:30 +03:00
Yan Zhulanow
a6925e0d0f Minor: Fixes after review 2017-07-18 18:22:29 +03:00
Yan Zhulanow
904b693571 Pass byte array more efficiently
Filling byte[] values is especially slow on Android (>3000ms to fill a byte[3000] on emulator).
2017-07-18 18:22:28 +03:00
Yan Zhulanow
069579fd79 Debugger: Disable code interpreting by default in evaluator
Provide the compiled bytecode to debugger instead of interpreting the expression by default.
This significantly increases evaluation speed in numerous cases, e.g. `(1..10000).map { it.toString() }.count()`.
Leave interpreter mode as a fallback.

Android does not provide decent in-memory class loading support.
Moreover, we need to run dex on the compiled classes, and it required significant time.
So for now compiling evaluator for Android is available only in Android O, and only if there're any local classes or non-inline lambdas (evaluator didn't work for them before so we may consider this change as an improvement).
2017-07-18 18:22:28 +03:00
Yan Zhulanow
4851a83a83 Android Extensions: put new functionality under the flag 2017-07-18 18:10:30 +03:00
Yan Zhulanow
77eafb9716 Kapt: Map kaptGenerateStubsKotlin task classpath properly, ensure the destination for compileKotlin isn't in it (KT-18799) 2017-07-18 18:10:29 +03:00
Yan Zhulanow
83f9835e00 Android Exensions: Add kotlin-android-extensions-runtime dependency automatically in Gradle plugin 2017-07-18 18:10:28 +03:00
Yan Zhulanow
b303fa9caa Android Extensions: Fixes after review 2017-07-18 18:10:27 +03:00
Yan Zhulanow
7b238e0b21 Android Extensions: Add SparseArray implementation for the View cache (KT-18250) 2017-07-18 18:10:26 +03:00
Yan Zhulanow
fbfd51e97e Minor: Group plugin modules 2017-07-18 18:10:25 +03:00
Yan Zhulanow
820f914d35 Remove obsolete kapt2 implementation 2017-07-18 18:10:24 +03:00
Yan Zhulanow
423a09e46a Android Extensions: Support LayoutContainer in code generation 2017-07-18 18:10:23 +03:00
Yan Zhulanow
a69f9729e0 Android Extensions: Use Activity and Fragment supertypes in INVOKE_VIRTUAL calls instead of the user implementation class names 2017-07-18 18:10:22 +03:00
Yan Zhulanow
d4b4bc71ee Android Extensions: Support @ContainerOptions in compiler plugin 2017-07-18 18:10:21 +03:00
Yan Zhulanow
6e1dd08fbb Android Extensions: Add runtime library with LayoutContainer and its options 2017-07-18 18:10:20 +03:00
Yan Zhulanow
1a1db5a6f1 Android Extensions: Support cache in custom Views 2017-07-18 18:10:19 +03:00
Yan Zhulanow
c9cd1a4d75 Minor: Android Extensions compiler plugin refactoring 2017-07-18 18:10:18 +03:00
Yan Zhulanow
0494862ce5 Minor: Move Android Extensions compiler plugin tests to some other package 2017-07-18 18:10:17 +03:00
Yan Zhulanow
303b246a49 Minor: Move AndroidExtensionsReportSubmitter to other KAE files 2017-07-18 18:10:16 +03:00
Yan Zhulanow
e037cafe18 Use descriptor modality in IDE inspections/intentions
This fixes KT-18160, KT-18194, KT-18195, KT-18197 ~
2017-07-18 18:10:15 +03:00
Yan Zhulanow
942fa7719a Android Extensions: Add synthetic property highlighting 2017-07-18 18:08:33 +03:00
Yan Zhulanow
f7786a42ab Android Extensions: Show warning on a dot-call of a reference which is missing in some configurations (KT-18012)
When more than one layout configuration is available, a particular resource (view or fragment) may be absent in some of them.
We should show a warning on such resource reference calls as the call may lead to NPE.
2017-07-18 18:08:32 +03:00
Yan Zhulanow
f4acf404ca Android Extensions: Support Android variants and library dependencies (KT-14086, KT-16934) 2017-07-18 18:08:31 +03:00
Yan Zhulanow
8e9a62d553 Kapt: Add gradle warnings for Android projects
1. When the old kapt (aka kapt1) is used
2. (for Android projects) When Kotlin plugin is applied but annotationProcessor (Java-only) dependencies are found
2017-07-18 18:08:29 +03:00
Toshiaki Kameyama
865f9d4c7e Wrong caption "Change to property access" for Quick Fix to convert class instantiation to object reference #KT-13870 Fixed (#1189) 2017-07-18 15:47:43 +02:00
Mikhail Glukhikh
987c7f5be8 Add "unnecessary local variable" inspection #KT-15958 Fixed 2017-07-18 16:37:47 +03:00
Dmitry Neverov
9d06a80519 Do not report "property can be private" on JvmField properties
So #KT-18970 Fixed
2017-07-18 15:48:10 +03:00
Nikolay Krasko
5281602381 Don't ignore filters in smart step over for inline calls 2017-07-18 14:39:55 +03:00
Nikolay Krasko
f664ffb06b Check correspondent call on end token for better step over (KT-18949)
#KT-18949 Fixed
2017-07-18 14:39:54 +03:00
Nikolay Krasko
d282f14eac Don't add double linenumber when return expression is absent (KT-18949)
#KT-18949 Fixed
2017-07-18 14:39:54 +03:00
Nikolay Krasko
a41c9d2476 Avoid state machine build for suspend function with single inline call
#KT-18949 Fixed
2017-07-18 14:39:54 +03:00
Nikolay Krasko
ce4f923ba0 Replace return with nop to avoid merging line instructions (KT-18949)
Dex ignores subsequent line numbers for same instructions and interprets
instruction after inline as if they were inlined. This makes debugger
behaves as if there's nowhere to stop on line with breakpoint.

This also makes stepping through inline function consistent with
non-inline analog. In both context debugger now stops on '}'.

 #KT-18949 Fixed
 #KT-17120 Fixed
2017-07-18 14:39:54 +03:00
Nikolay Krasko
fc685aa03f Refactoring: extract common part to function 2017-07-18 14:39:54 +03:00
Nikolay Krasko
179ec84684 Refactoring: mark getTopmostElementAtOffset() as not-null 2017-07-18 14:39:54 +03:00
Mikhail Glukhikh
c0e1b3ef2d CFG: fix label binding for last instruction of finally block
So #KT-18698 Fixed
2017-07-18 14:37:13 +03:00
Mikhail Glukhikh
ab0e734e7d PseudocodeLabel: add slightly better exception diagnostics 2017-07-18 14:36:42 +03:00
Mikhail Glukhikh
9a5b5393f5 Code cleanup: CFG (several inspections applied) 2017-07-18 14:36:18 +03:00
Mikhail Glukhikh
43f9035d07 Minor test fix 2017-07-18 13:51:27 +03:00
Toshiaki Kameyama
f8cf0f2ab9 Misleading quick fix message for an 'open' modifier on an interface member #KT-18738 Fixed 2017-07-18 18:59:22 +09:00
Alexey Sedunov
d2dbc47454 Create from Usage: Remove extra space before type parameters list
#KT-16352 Fixed
2017-07-17 16:09:57 +03:00
Alexey Sedunov
e98af7bfc1 Create Class from Usage: Use type parameter bounds as supertypes
#KT-15242 Fixed
2017-07-17 16:09:55 +03:00
Alexey Sedunov
95769dc9d3 Create from Usage: Make property lateinit where possible
#KT-17651 Fixed
2017-07-17 16:09:54 +03:00
Alexey Sedunov
e9bf1d2ab8 Create from Usage: Add test for KT-17537
#KT-17537 Fixed
2017-07-17 16:09:53 +03:00
Alexey Sedunov
0365d3a3d6 Create from Usage: Do not create type parameter by constuctor reference
#KT-17353 Fixed
2017-07-17 16:09:52 +03:00
Alexey Sedunov
2e76a76088 Control Flow: Fix CFG usage info for double-colon expressions
#KT-12551 Fixed
 #KT-17092 Fixed
2017-07-17 16:09:51 +03:00
Alexey Sedunov
216b28ec55 Implement Members: Do not generate 'header' keyword
#KT-18466 Fixed
2017-07-17 16:09:50 +03:00
Alexey Sedunov
26d6088c82 Create from Usage: Infer expected type for lambda body
#KT-18186 Fixed
2017-07-17 16:09:49 +03:00
Alexey Sedunov
b48feb257c Create from Usage: Create data class property from destructuring entry
#KT-18540 Fixed
2017-07-17 16:09:48 +03:00
Simon Ogorodnik
a212a1bf72 Put all internal actions under Tools | Kotlin | Internal group 2017-07-17 16:03:10 +03:00
Simon Ogorodnik
4cdc3fdde9 KT-14606: Never compute decompiled text in BasicLookupElementFactory
#KT-14606 fixed
2017-07-17 16:03:07 +03:00
Simon Ogorodnik
6036c95511 Prevent KotlinDecompiledFileViewProvider from reading vfile when possible 2017-07-17 16:03:04 +03:00
Simon Ogorodnik
bc5872dd8f Add completion benchmark to check completion speed 2017-07-17 16:03:02 +03:00
Nikolay Krasko
dfef1f4921 Add reference equality shortcut for equals() in light members 2017-07-17 14:50:59 +03:00
Nikolay Krasko
44ed903303 Implement equivalence of light members by origin when possible
Previous implementation worked through equality that used equality
of method stubs (see LightMemberOriginForCompiledMethod). But method
stubs for compiled element can be recreated when caches are outdated,
including weak reference cleaning (see ClsJavaStubByVirtualFileCache).

This could cause misbehave of find usages when java reference has an
outdated version of light element in resolution cache.
2017-07-17 14:50:59 +03:00
Toshiaki Kameyama
fda097fc3b Correct "before" sample in description for intention Convert to enum class #KT-18722 Fixed (#1196) 2017-07-17 13:03:15 +02:00
Dmitry Jemerov
6baa8614e6 Fix JS tests in AbstractConfigureKotlinTest 2017-07-17 12:09:11 +02:00
Dmitry Jemerov
2c2b64d44a AbstractConfigureKotlinTest: J2K 2017-07-17 12:09:10 +02:00
Dmitry Jemerov
4198a5c3ec AbstractConfigureKotlinTest: rename to .kt 2017-07-17 12:09:09 +02:00
Dmitry Jemerov
0e6c9a96c7 Specify library kind when configuring library in tests 2017-07-17 12:09:04 +02:00
Dmitry Jemerov
060b8e0025 ConfigLibraryUtil: J2K 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
921db30c90 ConfigLibraryUtil: rename to .kt 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
0fa09adf17 Provide library kind for common libraries; get rid of autodetection 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
c7e85ea28f Better encapsulate JS library detection 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
b8d453eec3 Set library kind when importing projects from Maven 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
608f5892f9 Set library kind when importing projects from Gradle 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
902fe1f5ce Implement explicit library kind for JS libraries, don't autodetect 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
1367e6f303 Get library versions directly, not through LibraryPresentationProvider 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
2d1ac69986 JSLibraryStdDescription: J2K 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
5f3366d60b JSLibraryStdDescription: J2K 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
c185730846 KotlinJsModuleConfigurator: J2K 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
ffb3e2fcbc KotlinJsModuleConfigurator: rename to .kt 2017-07-17 11:58:57 +02:00
Dmitry Jemerov
1f6788ac31 Fix CodeConformanceTest on Windows 2017-07-17 11:57:03 +02:00
Nikolay Krasko
b3e9dfcea9 Minor: fix weak warnings and formatting in KotlinReferencesSearcher.kt 2017-07-17 12:25:06 +03:00
Nikolay Krasko
d93e0adc4f Do not wrap to light elements if Kotlin search is requested (KT-19054)
#KT-19054 Fixed
2017-07-17 12:25:06 +03:00
Dmitry Petrov
8c7352e668 Generate constant "" for effectively empty string 2017-07-17 09:18:41 +03:00
Knize
389c7d03b7 KT-6676 Show enum ordinal in quickdoc (#1165)
KT-6676: Show enum ordinal in quickdoc

 #KT-6676 fixed
2017-07-14 22:28:16 +03:00
Simon Ogorodnik
cc8933c82b KT-17074: Make completion respect DslMarker's
#KT-17074 fixed
2017-07-14 21:06:43 +03:00
Alexander Udalov
3c04ca4397 Update KotlinVersion.CURRENT to 1.1.5 2017-07-14 21:03:06 +03:00
Alexander Udalov
2611c7de7e Restore anonymous classes for local delegate metadatas in inline functions
The problem is that now that the local delegated property metadata is in
the $$delegatedProperties array of the containing class, the access to
it from code calling an inline function with a local delegated property
is illegal.

Currently it seems to be a lot of work to support this rather rare case
properly (see the comment in ExpressionCodegen.getVariableMetadataValue)
so we postpone it and return the old behavior of using the anonymous
KProperty subclass for metadata
2017-07-14 15:13:12 +03:00
Alexander Udalov
616d575fb6 Support reflection for local delegated properties
#KT-15222 Fixed
2017-07-14 15:13:12 +03:00
Alexander Udalov
c444c4d10b Ignore $$delegatedProperties in light analysis mode tests
For tests with local delegated properties, this field is generated in
the full mode, but is not generated in the lite mode because local
variables are not analyzed properly in the lite mode
2017-07-14 15:04:05 +03:00
Alexander Udalov
db27a885f1 Rework property metadata generation for local delegated properties
Instead of generating an anonymous class for each delegated local
variable, store metadatas in the $$delegatedProperties array of the
containing class, as is done for member properties
2017-07-14 15:04:05 +03:00
Alexander Udalov
9344f7f42f Remove unused and obsolete code in JVM backend 2017-07-14 15:04:05 +03:00
Alexander Udalov
728de91140 Refactor generation of metadata for delegated properties
In CodegenAnnotatingVisitor, store all delegated properties whose
metadata should be generated in each class (identified by ASM Type).
Use the stored information later, both in the $$delegatedProperties
array generation and in the access to it from property's accessor
methods, instead of an heuristical indexOfDelegatedProperty()
2017-07-14 15:04:04 +03:00
Alexander Udalov
b97589b33e Remove CodegenBinding.LOCAL_VARIABLE_DELEGATE
Calculate this value at call sites explicitly instead
2017-07-14 15:04:04 +03:00
Alexander Udalov
66ea288be7 Minor, extract fakeDescriptorsForReferences.kt 2017-07-14 15:04:04 +03:00
Stanislav Erokhin
9e98c11114 [NI] Minor. Change return type substitute function to not null 2017-07-14 12:43:09 +03:00
Stanislav Erokhin
2602216039 [NI] Use NewTypeSubstitutor when create descriptor with fresh variables. 2017-07-14 12:43:09 +03:00
Stanislav Erokhin
652676dc71 [NI] Introduce transactions for constraint system.
This will be used for callable reference resolution.
2017-07-14 12:43:09 +03:00
Stanislav Erokhin
cb494c46d7 [NI] Add initial constraint to IncorporationConstraintPosition 2017-07-14 12:43:08 +03:00
Stanislav Erokhin
c767545d4c Minor. Remove unused CandidateWithBoundDispatchReceiver#copy 2017-07-14 12:43:08 +03:00
Stanislav Erokhin
ac06060260 [NI] Minor. Drop unused CommonSupertypeCalculator 2017-07-14 12:43:08 +03:00
Stanislav Erokhin
0404fbc092 [NI] Minor. Rename LambdaAnalyzer to KotlinResolutionCallbacks 2017-07-14 12:43:08 +03:00
Dmitry Petrov
178e3e2c98 [NI] Update argument types on call completion using nested calls resolution 2017-07-14 12:43:07 +03:00
Dmitry Petrov
4448637727 [NI] Support calling abstract class constructor in delegating call 2017-07-14 12:43:07 +03:00
Dmitry Petrov
549e8ba668 [NI] Use ALWAYS_SUITABLE_RECEIVER when no receiver is available
(as in "old" resolution & inference)

This fixes issues with Java static members access.
2017-07-14 12:43:07 +03:00
Dmitry Petrov
2bdeef7970 [NI] Postprocess lambda result expressions on call completion
Should update type to denotable, e.g.,
IntegerValueType(x) to proper numeric type.

TODO extract common code into some ValueArgumentPostprocessor
2017-07-14 12:43:07 +03:00
Dmitry Petrov
1d6ed4ef8e [NI] Update lambda result types.
When completing calls, update return types for functional descriptors
for lambdas using type inference results.

Add toString to some Call subclasses (for debugging purposes).
2017-07-14 12:43:06 +03:00
Dmitry Petrov
2bf252afe6 [NI] Introduce lambda result dependency edges
Given a lambda result type R_L with constraint R_L <: T,
for each constituent type variable V in T with variance matching
approximation direction for V, consider a dependency edge V -> R
(lambda-result-dependency).

E.g., given a constraint:
    R <: Out<V>
where V is approximated down (to sub-type).
After R is fixed, we obtain constraint
    Out<T> <: Out<V>
which is incorporated as
    T <: V
which is a relevant constraint for V.
2017-07-14 12:43:06 +03:00
Dmitry Petrov
13e8720ddc [NI] Keep track of fresh type variables created for particular call candidate
Otherwise we can't obtain inferred type arguments for the call,
which is required for reification.
2017-07-14 12:43:06 +03:00
Dmitry Petrov
eb7e9196b5 [NI] Fix some argument mapping problems
1. Value arguments for the resolved call are indexed with resulting
descriptor value parameters (which can be substituted).

2. Simple argument can be a single vararg element if the corresponding
value parameter is a vararg parameter.

3. Resulting descriptor should be approximated to super-type.
This doesn't affect type inference, but the JVM BE expects types with
proper classifiers.
2017-07-14 12:43:06 +03:00
Stanislav Erokhin
0c79949cf1 [NI] Implement NewTypeSubstitutor 2017-07-14 12:43:05 +03:00
Stanislav Erokhin
ff8a57dc26 [NI] Implement New CommonSuperTypeCalculation 2017-07-14 12:43:05 +03:00
Stanislav Erokhin
6aac67aa7e [NI] Approximate captured types when set them into variable.
Also do not store type with captured type inside possible types.
It is hack for now, but without it captured types can flow to
resolution and exception will be thrown.
2017-07-14 12:43:05 +03:00
Stanislav Erokhin
397103f9d0 [NI] Fix smart cast for expression with captured input type. 2017-07-14 12:43:05 +03:00
Stanislav Erokhin
73cc1fdd9c [NI] Resolve type variable to Nothing for TO_SUBTYPE direction. 2017-07-14 12:43:04 +03:00
Stanislav Erokhin
6e24b0f89d [NI] Approximate captured types when we resolve type variable TO_SUPER. 2017-07-14 12:43:04 +03:00
Stanislav Erokhin
53caa84db9 [NI] Add constrains even we try add constraint like TypeVariable <: CapturedType from subtyping.
If such captured type has lower type, then from TypeVariable <: lowerType => TypeVariable <: CapturedType.
2017-07-14 12:43:04 +03:00
Stanislav Erokhin
657c332a1f [NI] Do not run "or" branches for constraint subtyping.
We should never do that, because otherwise we can get unexpected result.
  Example for input constraint: C(in String) <: T.
  If we run usual subtyping algorithm, then we get 2 constraints:
  C(in String) <: T and T <: String.
  Of course such system has contradiction.
2017-07-14 12:43:04 +03:00
Stanislav Erokhin
0fadf0bf70 [NI] Approximate captured types before type variable fixation.
We prefer denotable types when we solve constraint system.
I.e. if for T we have not equality constraint with captured type we can approximate captured type to denotable type.
2017-07-14 12:43:03 +03:00
Stanislav Erokhin
b4bf534d29 [NI] Capture from supertypes of type parameter.
This works by accident in OI, so this should be supported by new inference.
2017-07-14 12:43:03 +03:00
Stanislav Erokhin
c4ddc7a3a6 [NI] Store stub resolved call to trace because some clients read this before all calls are completed.
This is bad idea, but this is how it works in old inference.
Now we just save old behaviour.
Future plan: fix checks where we get unfinished resolved calls.
2017-07-14 12:43:03 +03:00
Stanislav Erokhin
78f8d29a4c [NI] Fix find maximally specific for NI. 2017-07-14 12:43:03 +03:00
Dmitry Petrov
d67b51e91a [NI] Support wrong number of type arguments and integer constants.
- report WRONG_NUMBER_OF_TYPE_ARGUMENTS
- make integral types work again: IntegerValueType is represented as {Int & Byte & Short & Long} in the constraint system
2017-07-14 12:43:02 +03:00
Dmitry Petrov
f5c59b1343 [NI] Report special error message on constant expression type mismatch. 2017-07-14 12:43:02 +03:00
Dmitry Petrov
5afd3e72d6 [NI] Report diagnostic on abstract class instantiation. 2017-07-14 12:43:02 +03:00
Stanislav Erokhin
b012681a53 [NI] New inference -- initial commit. 2017-07-14 12:43:02 +03:00
Dmitry Petrov
036090be91 Support intersection type in TypeUtils.contains(...) 2017-07-14 12:43:01 +03:00
Stanislav Erokhin
e8501c7d54 Add method replaceType for ReceiverValue.
This method will used for capturing from expressions before call resolution.
2017-07-14 12:43:01 +03:00
Nikolay Krasko
1dcdb72a49 Process UastContext service absence (EA-100670) 2017-07-14 12:39:13 +03:00
Dmitry Jemerov
448dba3f78 License-related cleanup 2017-07-14 11:09:45 +02:00
Ilya Chernikov
84a812df19 Drop forced in-process compilation (as interface compatibility is resolved) 2017-07-13 15:45:34 +02:00
Dmitry Jemerov
9b37e76b14 Don't trigger update check when an in-memory file is modified
#KT-18954 Fixed
2017-07-13 12:50:15 +02:00
Mikhail Zarechenskiy
2d3ce89afc Use only completed arguments of special call 2017-07-13 12:26:03 +03:00
Dmitry Petrov
a687dea898 Introduce special IrDeclarationOrigin's for for-loop variables
FOR_LOOP_ITERATOR
 - temporary variable for for-loop iterator

FOR_LOOP_VARIABLE
 - `x` in `for (x in xs)`

FOR_LOOP_IMPLICIT_VARIABLE
 - temporary variable for for-loop with destructuring, e.g.:
   for ((x, y) in xys)
   =>
   for (tmp in xys) {
     val (x, y) = tmp
   }
2017-07-13 10:59:51 +03:00
Andrius Semionovas
1cab0d09ab KT-18979 Add val to proper place for 'Add val/var' intent 2017-07-13 01:20:24 +03:00
Alexander Udalov
f01de3a935 Minor, move lateinit tests into a subdirectory 2017-07-12 18:59:02 +03:00
Alexander Udalov
b2b492447f Maven plugin: initial support for Java 9 modules 2017-07-12 18:58:36 +03:00
Alexander Udalov
848edc14cb Maven plugin: fix warnings, update copyrights 2017-07-12 18:58:35 +03:00
Alexander Udalov
1d46070bd5 Minor, remove unneeded codegen test
This test is already present in compiler/testData/cli/jvm/
2017-07-12 18:58:35 +03:00
Mikhael Bogdanov
b2a7fb9534 Update ChangeLog.md for 1.1.4-EAP-11 2017-07-12 16:33:25 +02:00
Mikhael Bogdanov
b15cfeb0a0 Add 1.1.3-2 changes 2017-07-12 16:33:25 +02:00
Mikhael Bogdanov
ef003db020 Update ChangeLog.md for 1.1.3 2017-07-12 16:33:25 +02:00
baratynskiy
0b6ef5f291 Make idea-full exported in tests-common module because kapt3 tests use KotlinTestUtils.assertEqualsToFile which uses Editor defined in idea-full 2017-07-12 17:25:32 +03:00
baratynskiy
a288b8d318 Add jsr305.jar to intellij-core because guava-19.0 jar depends on Nullable defined in jsr305.jar 2017-07-12 17:25:32 +03:00
Anton Bannykh
0935ed41d4 JS: return exit code from the NodeJs kotlinc-js wrapper 2017-07-12 17:19:59 +03:00
Dmitry Petrov
da404de51e Add comment regarding testData generation to RangeValues.kt 2017-07-12 16:23:36 +03:00
Dmitry Petrov
2849e19af5 Add test for indices.reversed() 2017-07-12 15:56:29 +03:00
Dmitry Petrov
6a673a03e4 Generate test data for in-expression tests, fix bug with indices 2017-07-12 15:56:29 +03:00
Igor Chevdar
890c6a9983 Regenerated box tests 2017-07-12 15:12:34 +03:00
Igor Chevdar
fd380f7545 Split up test on map access onto two tests: stdlib & compiler box test 2017-07-12 15:12:33 +03:00
Mikhail Zarechenskiy
14890890b1 Minor, get rid of unchecked cast 2017-07-12 14:37:27 +03:00
Mikhail Zarechenskiy
ee173077c0 Simplify diagnostic when there are wrong number of type arguments
#KT-12767 Fixed
2017-07-12 14:37:27 +03:00
Mikhail Zarechenskiy
e82c909f75 Use more specific status to report diagnostics
#KT-12737 Fixed
2017-07-12 14:37:26 +03:00
Mikhail Zarechenskiy
178bb900b4 Introduce inapplicable wrong receiver status to improve diagnostics
#KT-10754 Fixed
2017-07-12 14:37:26 +03:00
Mikhail Zarechenskiy
79ee8f452c Add test for obsolete issue
#KT-12688 Obsolete
2017-07-12 14:37:26 +03:00
Toshiaki Kameyama
848f7423ee Do not report "can be private" on properties of private class
So #KT-18822 Fixed
2017-07-12 10:35:10 +03:00
Dmitry Petrov
f4d63158cc Take into account JvmName annotation when generating accessors
#KT-17444 Fixed Target versions 1.1.5
2017-07-12 09:37:16 +03:00
Dmitry Petrov
efb6756cbc Initialize property metadata array before class body generation
Initialization of companion object members (e.g., delegate properties
using provideDelegate convention) can depend on property metadata array,
which in turn can be initialized before other class members.

 #KT-18902 Fixed Target versions 1.1.5
2017-07-12 09:37:16 +03:00
Dmitry Petrov
8a9707c140 Generate proper initialization for possibly nullable SAM wrapper
#KT-18916 Fixed Target versions 1.1.5
2017-07-12 09:37:16 +03:00
Yan Zhulanow
b99007961f NoArg: Do not invoke initializers by default. Require "invokeInitializers" option to be set explicitly (KT-18667, KT-18668) 2017-07-12 00:17:24 +03:00
Yan Zhulanow
a983137978 Kapt: Handle parameter with Java names clashing with Java keywords properly (KT-18377) 2017-07-12 00:17:23 +03:00
Alexey Tsvetkov
e56e3d78c8 Use ANSI escape codes only with CLI tools
Before this change jansi was used by the compiler,
unless "kotlin.colors.enabled" is not set to false.
This caused multiple issues in different build systems,
where newer or older version of jansi could crash the JVM
since it uses native code.

The following short term solutions were discussed:
* Set "kotlin.colors.enabled" to false where jansi is not needed
(basically in any build system).
* Set "kotlin.colors.enabled" to true where jansi is needed,
and use it only when the system property is set to true.

Escaped codes are only needed in CLI tools (kotlinc, REPL),
so the second solution is preferred (less places to set the property).

     #KT-17031 fixed
     #KT-18874 fixed
     #KT-18927 fixed
2017-07-11 21:03:11 +03:00
Kirill Rakhman
cb19a86c44 Add "simplify if with constant" inspection #KT-17919 Fixed 2017-07-11 20:00:33 +03:00
Alexey Andreev
7634673213 Fix module re-importing when inlining functions in JS BE
When inliner reads function's body from other module, it performs
substitution _ -> moduleAlias. However, local alias can't be used
for this purpose, since call site can be in public inline function
itself, so the correct substitution would be -> _.$$imports$$.alias
2017-07-11 19:27:08 +03:00
Mikhail Glukhikh
cc4e55b829 Add groupPath/Name, change displayName for null checks -> safe call
Related to KT-14799
2017-07-11 19:25:38 +03:00
Dimach
7407083624 Add inspection to simplify successive null checks #KT-14799 Fixed 2017-07-11 18:47:26 +03:00
Ilya Chernikov
fc12f37105 Rolling back commits related to Unit -> Void? confersion in RMI interface
since it breaks the compatibility and doesn't actually help - the problem
with NoClassDef Unit is apparently elsewhere.
2017-07-11 15:06:38 +02:00
Ilya Chernikov
3da5ba4efe Switch to the newer gradle plugin, fix jansi problem, in-process compiling in gradle parts
Switching to in-process to avoid compilation warnings caused by introduced
daemon interface changes.
Switching to the gradle plugin 1.1.3 causes jansi incompatibility in
in-process compilation mode, so disabling jansi usage to avoid it.
2017-07-11 15:06:37 +02:00
Mikhail Glukhikh
0ca5c0fcc6 Refactoring (clone remove) of LiftAssignmentOutOfTryFix
Related to KT-18830
2017-07-11 15:28:45 +03:00
Toshiaki Kameyama
8cc9330e63 Introduce "Lift return out of try" intention #KT-18830 Fixed 2017-07-11 15:14:30 +03:00
Toshiaki Kameyama
8f9b680fc6 Support generic type parameters in 'Specify return type explicitly'
So #KT-18074 Fixed
2017-07-11 14:39:22 +03:00
Toshiaki Kameyama
0af3c6542d Correct "after" sample for intention "Convert to apply" #KT-18723 Fixed 2017-07-11 14:06:01 +03:00
Alexey Andreev
5a9adcca2d Improve performance of JS tests
* Do not read protos for descriptors of stdlib and kotlin-tests
  repeatedly
* Parse libraries lazily in inline, so that when no inline function
  exist in a test, we won't parse huge kotlin.js file
* Speed-up source map parser
2017-07-11 11:06:52 +03:00
Dmitry Petrov
83ec8aa918 typealias expansion fixes
- Exception on dynamic type in typealias argument expansion
 #KT-18858 Fixed Target versions 1.1.5
- Wrong report location for repeated annotations in typealias arguments
 #KT-18940 Fixed Target versions 1.1.5
- Don't drop type annotations for dynamic type
 #KT-18944 Fixed Target versions 1.1.5
2017-07-11 10:33:39 +03:00
Nikolay Krasko
a0f11f773b Better diagnostic for error configuration in debugger tests 2017-07-10 15:32:42 +03:00
Nikolay Krasko
68e0727894 Force space between { and first enum entry (KT-18863)
#KT-18863 Fixed
2017-07-10 15:32:42 +03:00
Nikolay Krasko
7f8d6b3008 Don't move line and /**/ comments during reformat (KT-18805)
#KT-18805 Fixed
2017-07-10 15:32:42 +03:00
Mikhail Glukhikh
ebdadf30d8 Get rid of redundant toMap() calls in DelegatingDataFlowInfo 2017-07-10 14:51:52 +03:00
Mikhail Glukhikh
8c9ace7d40 Get rid of Guava in DelegatingDataFlowInfo (except Multimap things) 2017-07-10 14:35:01 +03:00
Mikhail Glukhikh
564cc27a1d Get rid of Guava in CFA (except Multimap things) 2017-07-10 14:34:48 +03:00
Mikhail Glukhikh
dfe2c16bc7 More cleanup: lift return / assignment out 2017-07-10 12:59:58 +03:00
Alexander Udalov
9269de721e JPS: use module path instead of classpath for modular projects
No test added because it would involve running javac 9 and because tests
run JavaBuilder in the same process, this would require either a new
module in our project with dependency on JDK 9 (which would require
everyone to install JDK 9), or complex code that runs javac in another
process
2017-07-10 12:48:21 +03:00
Alexander Udalov
03a6488464 Use module path instead of class path for stdlib on Java 9
Also report the "named does not read unnamed" error, which was not
possible previously because we wouldn't be able to read anything from
kotlin-stdlib (because it was added to the unnamed module by default)
2017-07-10 12:48:21 +03:00
Alexander Udalov
c94b21edd5 Remove obsolete code about runtime versions conflict 2017-07-10 12:48:21 +03:00
Alexander Udalov
4128064f87 Move JavaModuleGraph from 'frontend.java' to 'cli' 2017-07-10 12:48:21 +03:00
Alexander Udalov
5b8e58fe36 Implement module accessibility checks differently in compiler and IDE
Essentially, the logic that was previously in
JvmModuleAccessibilityChecker.diagnosticFor, is moved into a new
abstract method JavaModuleResolver.checkAccessibility, which is
implemented differently in the compiler and in the IDE. In the compiler,
we use our JavaModuleInfo and JavaModuleGraph, as previously. In the
IDE, we use intellij's PsiJavaModule and JavaModuleGraphUtil.

This fixes strange behavior in IDE where some modules could be observed
in an invalid state. The cause of that was the JavaModuleGraph instance
caching modules in IdeJavaModuleResolver, which is a project component.

Moreover, this will allow to report an error "named module does not read
unnamed module" in the compiler, and avoid reporting it in the IDE (see
the comment in IdeJavaModuleResolver about that)
2017-07-10 12:48:21 +03:00
Alexey Andreev
7edb352aeb Copy stdlib-js source map during JPS build 2017-07-10 12:42:33 +03:00
Dmitry Petrov
0ce6bac7eb Generate proper 'compareTo' calls for non-primitive 'a in x .. y'
When we have some custom implementation of Comparable, it's important
that we compare values exactly as 'lowBound <= a && a <= highBound'.

Make sure that evaluation order and compareTo calls match for
optimized and non-optimized case.
2017-07-10 10:51:26 +03:00
Dmitry Petrov
dd5bb78178 Minor: don't use StringBuilder#setLength(0) - absent in JS 2017-07-10 10:51:26 +03:00
Dmitry Petrov
0962aec456 Minor: don't use java.lang.Integer in common test 2017-07-10 10:51:26 +03:00
Dmitry Petrov
aa7db727ba Fold I2L with ICONST_n when beneficial
ICONST_0; I2L -> LCONST_0
ICONST_1; I2L -> LCONST_1
2017-07-10 10:51:26 +03:00
Dmitry Petrov
ad80c3cd7f If at least one of the range bounds is "pure", order doesn't matter 2017-07-10 10:51:26 +03:00
Dmitry Petrov
22e12dc139 Minor: use method names in bytecode text tests 2017-07-10 10:51:26 +03:00
Dmitry Petrov
905a16e1df Maintain proper evaluation order for 'a in x .. y'
As of Kotlin 1.0 and 1.1, expression 'a in x .. y' is considered
equivalent to 'x.rangeTo(y).a', and should be evaluated in the following
order:
1. x
2. y
3. a
4. compare x with a
5. compare y with a (if needed)
2017-07-10 10:51:26 +03:00
Dmitry Petrov
fc3e9318d9 Handle DUPnXm instructions in PopBackwardPropagationTransformer 2017-07-10 10:51:26 +03:00
Dmitry Petrov
6a3ff5ca46 Add tests for intrinsified in/!in and mismatching range types 2017-07-10 10:51:26 +03:00
Dmitry Petrov
850e1b11fc Minor: test modification after review 2017-07-10 10:51:26 +03:00
Dmitry Petrov
64f880ba71 Add test for in/!in in a custom object range 2017-07-10 10:51:26 +03:00
Dmitry Petrov
9d1901fc7c Intrinsify some mismatching range/element combinations for in/in!
It's safe to upcast integer types to Long,
floating-point types to Double.
So we don't have to create a range instance for cases such as

fun testLongInInt(x: Long, a: Int, b: Int) =
    x in a .. b

which is equivalent to

fun testLongInInt(x: Long, a: Int, b: Int) =
    x in a.toLong() .. b.toLong()
2017-07-10 10:51:26 +03:00
Dmitry Petrov
d137b04b0a Pull up logic for ComparisonGenerator selection 2017-07-10 10:51:26 +03:00
Dmitry Petrov
ea95f31f99 Simplify some basic instructions using peephole optimization
DUP_X1; POP = SWAP

p1_a; p1_b; SWAP = p1_b; p1_a
where p1_a, p1_b are instructions without side effects pushing value of
size 1 on stack.
E.g.: ACONST_NULL; ALOAD 0; SWAP = ALOAD 0; ACONST_NULL

NOP; NOP = NOP
2017-07-10 10:51:26 +03:00
Dmitry Petrov
224848163d Use InContinuousRangeExpressionGenerator for primitive range intrinsics 2017-07-10 10:51:26 +03:00
Dmitry Petrov
c855b5c889 Extract SimpleBoundedValue class 2017-07-10 10:51:26 +03:00
Dmitry Petrov
a3409b46b0 Primitive number range literal as BoundedValue 2017-07-10 10:51:26 +03:00
Dmitry Petrov
b693b54a2c Fix DUPn_Xm handling in PopBackwardPropagationTransformer
DUPn_Xm instructions implicitly depend on elements directly under stack
top (which are not "copied", but still required). We can't analyze them
precisely now, and should skip methods containing these instructions.
Fortunately, we didn't generate these instructions under POP before,
but with new range check code generation and constant conditions
elimination such combination of instructions becomes possible.
2017-07-10 10:51:26 +03:00
Dmitry Petrov
4480a9bdfb Introduce BoundedValue as a generalization of (low..high) range
Provide BoundedValue-based implementation of InExpressionGenerator,
test it on range of comparable values.
Drop unneeded test (range of comparables is already tested by
ranges/contains/inComparableRanges.kt).
2017-07-10 10:51:26 +03:00
Dmitry Petrov
f4ea1a2f41 Minor: move RangeValue-related classes to proper packages 2017-07-10 10:51:26 +03:00
Dmitry Petrov
d19eb05382 Introduce AbstractForInProgressionLoopGenerator
AbstractForInProgressionLoopGenerator is a base class for
progression-based 'for' loop generators with progression step unknown
at compile time.
2017-07-10 10:51:26 +03:00
Dmitry Petrov
83ff1a2ef3 Minor: refactor ForInProgressionExpressionLoopGenerator initialization 2017-07-10 10:51:26 +03:00
Dmitry Petrov
6551fdc695 Add test for nullable primitive in range 2017-07-10 10:51:26 +03:00
Dmitry Petrov
db1dcc68ff Minor: cleanup in ExpressionCodegen 2017-07-10 10:51:26 +03:00
Dmitry Petrov
614d90d6ef Skip NOP instructions in fast pop backward propagation 2017-07-10 10:51:26 +03:00
Dmitry Petrov
36cbc0defd Ensure that {Collection, CharSequence}.indices intrinsic works with 'in' 2017-07-10 10:51:26 +03:00
Dmitry Petrov
ec99fa2142 Ensure that 'in/!in x until y' intrinsic works 2017-07-10 10:51:26 +03:00
Dmitry Petrov
05cad83c79 Fix tests for in/in! with primitive range literals
- ClosedFloatingPointRange<T>
- IntRange, etc
- extensions in kotlin.ranges for ranges of Byte/Int/Short
2017-07-10 10:51:26 +03:00
Dmitry Petrov
5decf65d6a Ensure that no range instance is created for 'x in array.indices' 2017-07-10 10:51:26 +03:00
Dmitry Petrov
4320b63922 Ensure that no boolean negation is generated for !in expression
#KT-18777 Fixed Target versions 1.1.4
2017-07-10 10:51:26 +03:00
Dmitry Petrov
b9c0ecf2b1 Ensure that ranges are not created for in-Comparable-range-literal
#KT-6247 Fixed Target versions 1.1.4
2017-07-10 10:51:26 +03:00
Dmitry Petrov
7175361c97 Ensure that BranchedValue for in/!in work well with boolean operations 2017-07-10 10:51:26 +03:00
Dmitry Petrov
a3cd4f415a Add test for comparison used for primitives and Comparable
There's a subtle difference in behavior between comparing
primitive Float/Double (comparison follows IEEE standard)
and boxed Float/Double (comparison is a total order).
Make sure this corner case is preserved.
2017-07-10 10:51:26 +03:00
Dmitry Petrov
fd402cb76c Provide intrinsic for in/in! expression with range of Comparable 2017-07-10 10:51:26 +03:00
Dmitry Petrov
bd2021411c Don't use intrinsic 'in' generator for non-intrinsified 'in' expressions 2017-07-10 10:51:26 +03:00
Dmitry Petrov
a7071ae7af Provide intrinsic generators for in/!in expression
TODO some tests should fail because range of comparables
(e.g., '"Alpha" .. "Omega"') is currently not implemented
2017-07-10 10:51:26 +03:00
Dmitry Petrov
e3320c53f5 Minor: AbstractForInRangeWithGivenBoundsLoopGenerator 2017-07-10 10:51:26 +03:00
Dmitry Petrov
e261b8edf8 Minor: extract high-level interface for ForLoopGenerator 2017-07-10 10:51:26 +03:00
Dmitry Petrov
c870eeac2e RangeCodegenUtil: convert to Kotlin + cleanup 2017-07-10 10:51:26 +03:00
Dmitry Petrov
304e4e8dce RangeCodegenUtil: .java -> .kt 2017-07-10 10:51:26 +03:00
Dmitry Petrov
6140f29818 Ranges: introduce RangeValue class
The overall idea is to unify intrinsics for 'for-in' loop generation
and for 'in'/'!in' expression generation.
2017-07-10 10:51:26 +03:00
Alexey Andreev
811da2e285 Compile stdlib-js with source map 2017-07-09 14:22:08 +03:00
Ilya Chernikov
25c731241b Fix parallel daemon start test reporting 2017-07-08 18:16:29 +02:00
Ilya Chernikov
21eed9ee78 Get rid of kotlin.Unit usage in RMI interfaces
attempt to fight mysterous "Cannot instantiate kotlin.Unit" exception.
2017-07-08 18:16:29 +02:00
Ilya Chernikov
06d27a9efa Fix failing tests on TC on Windows by falling back to standard launcher
...in one more case
Plus some minor test tweaks, diagnostics improvement and important comments
2017-07-08 18:16:28 +02:00
Ilya Chernikov
e4ed217a3b Add missing explicit serialVersionUID to the REPL API classes 2017-07-08 18:16:27 +02:00
Ilya Chernikov
8542e878f7 Refactor daemon periodic check and shutdown logic
Cleaner logic and logging, improved stability during shutdown, reduced
overhead of the periodic checks, and regular calls, should also eliminate
dying daemons scenario on parallel execution (another attempt to do it).
2017-07-08 18:16:26 +02:00
Ilya Chernikov
2c35675fd6 Refactor daemon parallel start test to improve diagnostics
also add daemon info to the RPC
and remove redundant daemon stopping calls, that should speed up
tests execution
2017-07-08 18:16:26 +02:00
Ilya Chernikov
e2d2c5ff42 Refactor daemon startup for better logging and cleaner code 2017-07-08 18:16:25 +02:00
Ilya Chernikov
2ec2a08753 Implement advanced gradle script template selection in the provider, improve diagnostics 2017-07-08 18:16:24 +02:00
Ilya Chernikov
ebcac3dd01 Use renamed Gradle Kotlin DSL template in the provider when available 2017-07-08 18:16:24 +02:00
Pavel V. Talanov
bf09d91e80 script.runtime: restore old apis and mark as deprecated
Needed for compatibility (i.e. with old gradle kdsl versions)
2017-07-08 15:10:46 +03:00
Pavel V. Talanov
20be924bbb script.runtime: update api
- Clean up some api inconsistencies
 - Provide experimental async resolver to allow cleaner async updates of dependencies
2017-07-08 15:10:45 +03:00
Alexander Udalov
127cd1295e Disable JSR-305 annotations by default, introduce CLI argument
No package annotations are going to be loaded, and
TypeQualifierDefault/TypeQualifierNickname are no longer recognized by
default. Use the CLI argument "-Xload-jsr305-annotations" to enable this
behavior back

 #KT-10942
2017-07-07 22:08:50 +03:00
Mikhail Glukhikh
522f67fda0 Severity is softened for some style issues 2017-07-07 18:15:38 +03:00
Mikhail Glukhikh
a960fa78cb Use expression body: add new line more accurately 2017-07-07 18:15:36 +03:00
Mikhail Glukhikh
b0fda5f451 Lift return out fix: do not suggest for labeled returns 2017-07-07 18:15:35 +03:00
Mikhail Glukhikh
41893736df Cleanup: make single KtExpression.isElseIf 2017-07-07 18:15:34 +03:00
Mikhail Glukhikh
a6f0b7c7a4 Preferred style inspections: WEAK WARNING -> INFO 2017-07-07 18:15:33 +03:00
Mikhail Glukhikh
1d2017b0fc Cleanup: apply "cascade if..." inspection (+ some others) 2017-07-07 18:15:32 +03:00
Mikhail Glukhikh
9c06739594 Cleanup: apply "lift out..." inspection (+ some others) 2017-07-07 18:15:30 +03:00
Mikhail Glukhikh
0c41ceea9d "Cascade if" inspection: do not suggest for one-line if 2017-07-07 18:15:28 +03:00
Mikhail Glukhikh
0fe9030eba "Cascade if" inspection: don't highlight for complex logical conditions
Related to KT-18615
2017-07-07 18:15:27 +03:00
Mikhail Glukhikh
8273eff1a1 Introduce "cascade if" inspection suggesting replacement with when
So #KT-18615 Fixed
2017-07-07 18:15:26 +03:00
Mikhail Glukhikh
1ddaee5b4a "Lift return / assignment": don't highlight if other returns available 2017-07-07 18:15:24 +03:00
Mikhail Glukhikh
691b733c55 "Lift return / assignment": do not suggest for else arguments 2017-07-07 18:15:22 +03:00
Mikhail Glukhikh
042990dda1 "Lift return / assignment": do not suggest for too long expressions 2017-07-07 18:15:21 +03:00
Mikhail Glukhikh
398f92dc6f Lift assignment out: do not suggest if other assignments available
So #KT-18709 Fixed
2017-07-07 18:15:20 +03:00
Mikhail Glukhikh
9c4dfa3343 Lift return out: do not suggest for lambda in return #KT-18711 Fixed 2017-07-07 18:15:18 +03:00
Mikhail Glukhikh
c0d10264bc Lift assignment out: do not highlight for exactly one assignment
Related to KT-14900
2017-07-07 18:15:17 +03:00
Mikhail Glukhikh
1010ecca8c Lift return out: do not report for zero returns
Also, do not highlight (but suggest fix) for exactly one return
Related to KT-14900
2017-07-07 18:15:16 +03:00
Mikhail Glukhikh
2deef48b84 Cleanup code: BranchedFoldingUtils 2017-07-07 18:15:15 +03:00
Mikhail Glukhikh
2d1abda9a1 Convert "lift return / assignment" intentions into a single inspection
Also includes minor test fix, related to KT-14900
2017-07-07 18:15:14 +03:00
Mikhail Glukhikh
8f33bd0768 Handle break / continue / throw in lift return / assignment intentions
So #KT-14900 Fixed
2017-07-07 18:15:09 +03:00
Mikhail Glukhikh
523cbc6723 Convert to expression body: insert new-line after = for long lines 2017-07-07 18:15:07 +03:00
Mikhail Glukhikh
d08b18f5f8 Introduce "use expression body" inspection #KT-16063 Fixed
Converted from the relevant intention
Reported cases: one-liners, whens
Also, more exact caret detection in local inspection tests
2017-07-07 18:15:06 +03:00
takahirom
fe9d3f16d3 KT-18501: Fix to find KDoc even if KDoc is in ModifierList 2017-07-07 18:12:19 +03:00
Dmitry Jemerov
4b92349031 Specify group for "Redundant 'Unit' return type" inspection 2017-07-07 16:53:42 +02:00
nd
33a93e5fc5 Inspection detecting redundant Unit return type (#1144) 2017-07-07 16:51:53 +02:00
Dmitry Jemerov
5f9a33564a Implement option for wrapping method annotations 2017-07-07 16:48:31 +02:00
Dmitry Jemerov
a379a814ba Implement option for wrapping class annotations 2017-07-07 16:48:31 +02:00
Dmitry Jemerov
6c62b60147 Implement option for wrapping parameter annotations 2017-07-07 16:48:31 +02:00
Dmitry Jemerov
be15ee3c03 Add "Wrap extends/implements list" option 2017-07-07 16:48:30 +02:00
Dmitry Jemerov
722cc521a9 Add "Blank lines before }" option
#KT-15504 Fixed
2017-07-07 16:48:30 +02:00
Dmitry Jemerov
5c8a90fe85 "Blank lines after class header" option supported 2017-07-07 16:48:30 +02:00
Dmitry Jemerov
6a96ade02c Options for blank lines between 'when' branches
#KT-18607 Fixed
2017-07-07 16:48:29 +02:00
Dmitry Jemerov
8fe2858c6a Option to use normal indent in chained calls
#KT-18605 Fixed
2017-07-07 16:48:29 +02:00
Simon Ogorodnik
d8bb0b1023 KT-16999: Fix duplicates in parameter info
Use ShadowedDeclarationFilter in Parameter Info
 #KT-16999 fixed
2017-07-07 17:40:32 +03:00
nd
58e5c497d0 Intention to replace add/addAll on a mutable collection with += (#1143) 2017-07-07 16:34:20 +02:00
nd
fae8efdc7f Handle unsafe implicit invoke on array access expression (#1151) 2017-07-07 16:29:11 +02:00
Dmitry Jemerov
8cc9195fae Merge remote-tracking branch 'origin/master' 2017-07-07 13:26:59 +02:00
Dmitry Jemerov
9dc4183a16 Fix tests affected by the inspection behavior change 2017-07-07 13:25:59 +02:00
Mikhail Zarechenskiy
039729908d Minor, remove field that never used 2017-07-07 14:20:03 +03:00
Mikhail Zarechenskiy
3fed4e6dc7 Improve diagnostic for unresolved reference when function expected
#KT-10657 Fixed
2017-07-07 14:20:02 +03:00
Mikhail Zarechenskiy
0ae45a2835 Add test for obsolete issue
#KT-6502 Obsolete
2017-07-07 14:20:01 +03:00
Mikhail Zarechenskiy
c853ac95ad Improve diagnostic message for annotations with @receiver
#KT-14647 Fixed
2017-07-07 14:19:59 +03:00
Mikhail Zarechenskiy
f5cd8c7e4d Relax name shadowing warning on parameter names
#KT-17611 Fixed
2017-07-07 14:19:57 +03:00
Mikhail Zarechenskiy
daa8521729 Avoid getting descriptors for collection literals from built-ins scope
#KT-18845 Fixed
2017-07-07 14:14:30 +03:00
Dmitry Jemerov
a12594fe27 Merge branch 'KT-18717' of https://github.com/nd/kotlin 2017-07-07 13:10:52 +02:00
Dmitry Jemerov
1de685949b Merge branch 'KT-18797' of https://github.com/nd/kotlin 2017-07-07 13:02:02 +02:00
Alexey Andreev
2f74fd6f90 Don't exit with error status when node.js tests fail 2017-07-07 11:57:32 +03:00
Vyacheslav Gerasimov
4cef8728d7 Add layout file name in completion for Android Extension properties
#KT-11051 Fixed
2017-07-07 03:24:19 +03:00
Vyacheslav Gerasimov
f59859842a Fix Android extensions import rename
#KT-17890 Fixed
2017-07-07 03:24:10 +03:00
Vyacheslav Gerasimov
ee53e81e8e Fix Android resource reference folding
Properly fold qualified expressions and handle nested references

 #KT-18429 Fixed
2017-07-07 03:24:03 +03:00
Vyacheslav Gerasimov
7c6ffff198 Refactor Kotlin Gradle configurator 2017-07-07 03:23:34 +03:00
Vyacheslav Gerasimov
9810c10f8b Implement Add Kotlin library quickfix for GSK 2017-07-07 03:23:26 +03:00
Vyacheslav Gerasimov
2ec1a4311a Implement Kotlin configurator for GSK
#KT-14965 Fixed
2017-07-07 03:23:17 +03:00
Vyacheslav Gerasimov
2116877991 J2K: rename KotlinAndroidGradleModuleConfigurator .java -> kt 2017-07-07 03:22:28 +03:00
Simon Ogorodnik
9f340b40c2 Minor: Add test to check inferred types shown correctly in parameter info
#KT-11858 Obsolete
2017-07-06 20:40:53 +03:00
Alexander Udalov
0f15413d47 Minor, do not output stack trace on invalid contents of build file 2017-07-06 17:03:25 +03:00
Alexander Udalov
55468735df Rename -module argument to -Xbuild-file
To prevent confusion with Java 9 module-related arguments

 #KT-18754 Fixed
2017-07-06 17:03:25 +03:00
Alexey Sedunov
6200d07808 Minor: Fix compilation 2017-07-06 14:42:24 +03:00
Alexander Udalov
0b399fe7bb Ignore testAutomaticModuleNames on older Java 9 builds 2017-07-06 13:01:16 +03:00
Alexander Udalov
158afdea2b Improve sorting of compiler messages in GroupingMessageCollector
Ensure that messages reported on a file but with no line information are
reported before diagnostics related to code. This fixes
Java9ModulesIntegrationTest.testSeveralModulesWithTheSameName on some
machines
2017-07-06 13:01:16 +03:00
Alexander Udalov
3808ecbd1e Minor, return a set in JavaModuleGraph.getAllDependencies
To prevent duplicate roots to be added
2017-07-06 13:01:15 +03:00
Alexander Udalov
ec6e4f2469 Minor, take List instead of Iterable in convertClasspathRoots
To emphasize that the order is important
2017-07-06 13:01:15 +03:00
Alexander Udalov
0f06140a3d Check 'Multi-Release' manifest attribute value for multi-release jars
See http://openjdk.java.net/jeps/238
2017-07-06 13:01:14 +03:00
Alexander Udalov
7ab018da7b Use ASM 6 API to read class files in IDE
Otherwise ASM throws exceptions trying to read module-info.class

 #KT-13072 Fixed
2017-07-06 13:01:13 +03:00
Alexander Udalov
51fb02b2d5 Report warning for several modules with same name on module path 2017-07-06 13:01:13 +03:00
Alexander Udalov
e8a8bdc58e Add test on cyclicly dependent Java 9 modules 2017-07-06 13:01:12 +03:00
Alexander Udalov
9199023952 Improve automatic module handling in module graph construction
Add all automatic modules to roots if at least one automatic module is
added, as per
http://cr.openjdk.java.net/~mr/jigsaw/spec/api/java/lang/module/package-summary.html
2017-07-06 13:01:12 +03:00
Alexander Udalov
c428505d4d Load automatic module names correctly
Load the Automatic-Module-Name manifest entry value if it's present (see
http://mail.openjdk.java.net/pipermail/jpms-spec-observers/2017-May/000877.html),
otherwise sanitize the name of the .jar file, throwing out all chars
except alphanumeric, duplicate dots and a version qualifier
2017-07-06 12:50:05 +03:00
Alexander Udalov
612e64d8e3 Load module-info.class from multi-release jars' META-INF/versions/ 2017-07-06 12:50:04 +03:00
Alexander Udalov
5b9ee88b52 Remove --add-opens options to workaround Java 9 visibility checks
These options are no longer needed because the problematic code in
intellij-core that was accessing these private APIs has been dealt with
in the 171 branch.

The remaining options in "Codegen Tests" run configurations are needed
because of reflection usage on JDK internals in KtUsefulTestCase
2017-07-06 12:50:04 +03:00
Alexander Udalov
40d4eeab4f Do not try to load jrt file system from JDK version < 9
The FileSystems.newFileSystem call failed if the compiler was being run
on Java 9 with -jdk-home $JDK_16
2017-07-06 12:50:03 +03:00
Alexander Udalov
0f4684da67 Fix codegen tests on JDK 9 with jdkKind = FULL_JDK 2017-07-06 11:58:03 +03:00
Alexey Andreev
4bd9866975 Remove unnecessary overriding methods, fix compilation 2017-07-06 10:34:05 +03:00
Alexey Andreev
ca63717124 Multiple fixes of JS source maps
- elvis expression with complex RHS
- destructuring declarations
- decomposition of `var` statement (for example, in case of
  inline destructuring functions)
- `is` LHS &&/|| inline fun RHS
- argument assignment to temporary var on inline call site
- assignment of `next()` result to temporary var in `for` expression
- rethrow statement in exception handler
2017-07-06 10:20:49 +03:00
Alexey Andreev
f873834529 Fix JS source maps for objects and enums 2017-07-06 10:20:49 +03:00
Alexey Andreev
d8fe7e55db Fix JS source maps for lambdas with captured variables 2017-07-06 10:20:48 +03:00
Alexey Andreev
ec2a5bf0ee Fix JS source map for char boxing and unboxing 2017-07-06 10:20:47 +03:00
Alexey Andreev
be7f3a787c Fix JS source maps for when expression 2017-07-06 10:20:46 +03:00
Alexey Andreev
d613124cb1 Generate JS source maps for temporary vars declarations and definitions 2017-07-06 10:20:46 +03:00
Alexey Andreev
64f335380f Provide more source map info about statements in JS tests 2017-07-06 10:20:45 +03:00
Alexey Andreev
fa95f78e78 Generate JS source map for if statement got from optional argument 2017-07-06 10:20:44 +03:00
Alexey Andreev
1e74325c52 Generated source map for JS function's closing curly bracket 2017-07-06 10:20:44 +03:00
Alexey Andreev
4e18ea2d04 Fix JS source map of decomposed conditional expression 2017-07-06 10:20:43 +03:00
Alexey Andreev
b5218915f8 Fix associativity of generated comma operator in JS BE 2017-07-06 10:20:42 +03:00
Alexey Andreev
2122f57f51 Don't merge locations in JS source map test cases
Don't merge locations of containing if/while/do..while/for
statements with locations of conditions
2017-07-06 10:20:42 +03:00
Alexey Andreev
dea73ebecf Refactor generator of JS source map
- refactor pipeline for generation of source map
- generate "empty" mappings for nodes that impossible
  to map to something reasonable
- generate more accurate locations in source maps for specific
  JS AST nodes
- for binary operation nodes parser now returns location
  of binary operator tokens instead of location of first operand
- change completely how source map remapper works
2017-07-06 10:20:41 +03:00
Nikolay Krasko
6a2f3d8065 Minor: remove let usage 2017-07-05 20:21:13 +03:00
Nikolay Krasko
72611d1337 Fix extract refactoring for android extensions declarations (KT-11048)
Allow any target declarations in marking references. Otherwise conflicts
for references resolved to xml are not considered broken.

This also fix evaluate for extension fields.

 #KT-11048 Fixed
2017-07-05 20:21:13 +03:00
Mikhail Glukhikh
a09b31b568 Classify all Kotlin inspections 2017-07-05 16:00:22 +03:00
Mikhael Bogdanov
2808e45b89 Enable test in js, native 2017-07-05 11:15:38 +02:00
Dmitry Neverov
4a0e70ad53 Report MemberVisibilityCanBePrivate on visibility modifier if present 2017-07-04 21:33:37 +02:00
Alexander Udalov
d97fa604e1 Write metadata for suspend function into anonymous coroutine classes
To render nice Kotlin types in toString() of continuation
2017-07-04 19:41:48 +03:00
Alexander Udalov
5a8546519a Do not fail on lambdas without metadata in toString() 2017-07-04 19:41:47 +03:00
Vladimir Koshelev
61e52f0bfe Improve a reported message if -jdk-home path does not exist.
Fix KT-18794
2017-07-04 19:40:42 +03:00
Alexey Sedunov
994b6d687c Find Usages: Use MethodReferencesSearch to find constructor usages 2017-07-04 19:37:55 +03:00
Alexey Sedunov
28c5978d81 Light Classes: Fix AIOOBE on KtParameter -> PsiParameter conversion
EA-88058 Fixed
2017-07-04 19:37:54 +03:00
Alexey Sedunov
d69caea725 Kotlin Facet: Ignore modules unprocessed by kotlin project resolver
This happens in AS on project opening, but we can't (re-)configure facet
in such case since relevant module data are not available

 #KT-18725 Fixed
2017-07-04 19:37:53 +03:00
Alexey Sedunov
ee200c87ea Kotlin Facet: Change module JDK according to jdkHome
It's possible when JDK with the same home path is already configured
2017-07-04 19:37:52 +03:00
Alexey Sedunov
2a53043fef Generate equals/hashCode(): Fix function body generation
#KT-18596 Fixed
2017-07-04 19:37:50 +03:00
Simon Ogorodnik
33c22b8251 KT-8208: Support static members completion when receiver not-imported
#KT-8208 fixed
2017-07-04 16:41:50 +03:00
Dmitry Petrov
16505daeea Fix 'equals' for NotNullBasicValue
NotNullBasicValues were merged incorrectly sometimes,
which caused problems with INSTANCEOF checks.

 #KT-18779 Fixed
2017-07-04 12:19:10 +03:00
Mikhael Bogdanov
8121c1d3c4 Update test to support js-backend 2017-07-04 10:12:42 +02:00
Dmitry Neverov
08afaca518 Don't propose making property private if it's used in inline function 2017-07-03 21:58:22 +02:00
Mikhael Bogdanov
8666b95dd2 Delete local variables on default mask expantion
#KT-18792 Fixed
2017-07-03 17:01:06 +02:00
Mikhael Bogdanov
01e2f8e32c Preventively allocate slots for additional default parameters
Otherwise they are corrupted by inline
2017-07-03 17:01:06 +02:00
Denis Zharkov
5453f3067c Load @NonNull(when=UNKNOWN) annotated type as a flexible one 2017-07-03 17:55:37 +03:00
Denis Zharkov
55b585f3d0 Replace JavaTypeAttributes interface with simple data class 2017-07-03 17:55:37 +03:00
Denis Zharkov
939bacc810 Minor. Drop unused parameters in LazyJavaScope 2017-07-03 17:55:37 +03:00
Denis Zharkov
e26c210d69 Support TypeQualifierDefault from JSR 305 for nullability qualifiers
#KT-10942 Fixed
2017-07-03 17:55:37 +03:00
Denis Zharkov
5141a88a53 Add TypeQualifier annotation to IDE test data
Othewise nullability is not processed correctly
2017-07-03 17:55:37 +03:00
Denis Zharkov
a95d3e601b Fix container for extension receiver types from Java
No tests are added since there are some already
(e.g. TypeEnhancement.testOverriddenExtensions)
2017-07-03 17:55:37 +03:00
Denis Zharkov
57b7b91444 Do not add container annotaions to type artificially
It was only used for type-related nullability/mutability
annotations and it was necessary to remove them
in the descriptor renderer (duplicating their fqnames there).
At the same time they're only needed for types enhancement
where they can be simply restored from type owners' descriptors

The testData changes are more or less correct: this kind of annotations
is bound both to types themselves and their use because of their targets
2017-07-03 17:55:37 +03:00
Denis Zharkov
f877c82029 Simplify computeIndexedQualifiersForOverride() declaration
Do not pass properties of the to its own methods
2017-07-03 17:55:37 +03:00
Denis Zharkov
8812844d43 Move type qualifiers calculation into SignatureParts
It helps not to pass signature parts content to them
2017-07-03 17:55:37 +03:00
Denis Zharkov
92f9194112 Support TypeQualifierNickname for nullability annotations
#KT-10942 In Progress
2017-07-03 17:55:37 +03:00
Denis Zharkov
f2a55d590c Move type qualifiers extraction to SignatureEnhancement
These methods will depend on other components soon
2017-07-03 17:55:37 +03:00
Denis Zharkov
b3caa1da34 Introduce SignatureEnhancement component
It will depend on the AnnotationTypeQualifierResolver later
2017-07-03 17:55:37 +03:00
Denis Zharkov
21d1d16e74 Drop RawBound class and relevant property from JavaTypeAttributes
The main motivation behind this change is code simplification:
raw bounds can be simply replaced with common flexible bounds
2017-07-03 17:55:37 +03:00
Denis Zharkov
cbe62f076d Drop JavaTypeAttributes::isMarkedNotNull property
The only cases this code runs are annotation parameters
and supertypes that are already not-nullable by default
2017-07-03 17:55:37 +03:00
Denis Zharkov
42b2534c46 Remove redundant check in WhenByPlatformEnumChecker
If a type is annotated as not null its upper bound is not nullable
in most cases besides override conflicts, but in the latter case
we should behave consistently with flexibility of this type
2017-07-03 17:55:37 +03:00
Denis Zharkov
fc9810182e Get rid of JavaTypeAttributes::allowFlexible property
It's only false now in case of annotation parameters
2017-07-03 17:55:37 +03:00
Denis Zharkov
507eccc4ec Replace another allowFlexible=false with isNotNullable
Having field initilized doesn't make it inflexible in a sense
of mutability
2017-07-03 17:55:37 +03:00
Denis Zharkov
a0268d23bb Get rid of trivial allowFlexible replacing
As the type is anyway replaced with not-nullable version
explicitly, the only thing that changes is what type is loaded
for String[][].class:
- before it would be Array<Array<String?>?>
- now it's Array<(out) Array<(out) String!>!>

It's both a minor change and new behaviour can be considered
as correct
2017-07-03 17:55:37 +03:00
Denis Zharkov
58442e7b8b Drop TypeUsage::MEMBER_SIGNATURE_CONTRAVARIANT
It's only used for value parameters, but they're always resolved
with flexible types now
2017-07-03 17:55:37 +03:00
Denis Zharkov
6cd6608281 Drop TypeUsage::MEMBER_SIGNATURE_COVARIANT
It's only used for choosing mutability of a collection class, but
using annotations while loading is redundant since there is
a separate phase of type enhancement where they're taken
into account (for flexible types)

For inflexible type it doesn't matter since they appear only in
special cases like annotation methods (where collection classes can't be met)
2017-07-03 17:55:37 +03:00
Denis Zharkov
5ca3459a0f Minor. Merge TypeUsage::MEMBER_SIGNATURE_INVARIANT and COMMON
Their usages are effectively the same
2017-07-03 17:55:37 +03:00
Denis Zharkov
69e70575f9 Drop some of the TypeUsage enum entries
The only sensible usage of them was in the `isNullable` method
But you can check that UPPER_BOUND/SUPERTYPE_ARGUMENT are always
flexible and TYPE_ARGUMENT is not only in case of annotation
methods/parameters
2017-07-03 17:55:37 +03:00
Denis Zharkov
5c8f2a8ae8 Add resolution for JSR 305 type qualifier nicknames
#KT-10942 In Progress
2017-07-03 17:55:37 +03:00
Denis Zharkov
79e14f88e4 Support package level annotations in Java
#KT-10942 In Progress
2017-07-03 17:55:37 +03:00
Denis Zharkov
b7ead75947 Minor. Move BinaryJavaModifierListOwner -> MapBasedJavaAnnotationOwner 2017-07-03 17:55:04 +03:00
Mikhail Glukhikh
2d1e1cb6ed Minor: !!-related quick-fixes refactoring 2017-07-03 15:18:10 +03:00
Dmitry Neverov
4f678fa85c Do not suggest !! on expression which is always null
Related to KT-14643
2017-07-03 15:14:11 +03:00
Dmitry Neverov
66bd9d63dd Do not suggest adding !! on null constant #KT-14643 Fixed 2017-07-03 15:13:46 +03:00
Dmitry Jemerov
84418738a7 Optimize library kind detection and make it interruptible 2017-07-03 12:02:50 +02:00
Mikhael Bogdanov
49252f6eec Properly process primitive receiver on inlining bound callable references
#KT-18728 Fixed
2017-07-03 10:51:51 +02:00
Ilya Gorbunov
fe17c4416e Fix a typo: retail -> retain
#KT-18526 Fixed
2017-07-01 17:05:17 +03:00
Ilya Gorbunov
a21dbf08a8 Reorder values and entries in MutableMap to match docs
Also change references to mutable collections in docs.

#KT-18670 Fixed
2017-07-01 17:05:17 +03:00
Stuart Kent
962958c403 Fix String capitalize/decapitalize sample references and sample names 2017-07-01 17:05:17 +03:00
Simon Ogorodnik
ab919886ae Fix rendering of local anonymous object types for quick doc
#KT-8893 fixed
2017-07-01 15:04:29 +03:00
Nikolay Krasko
25109671b1 Postpone counting light elements till all psi checks done 2017-07-01 03:05:38 +03:00
Nikolay Krasko
fe17d616b9 Don't process Java references twice when looking for kotlin overrides (KT-17751) 2017-07-01 03:05:37 +03:00
Nikolay Krasko
0cd8ee57b8 Don't run another method reference search for constructors (KT-17751)
Constructors can't be used as properties and have no overrides.
2017-07-01 03:05:37 +03:00
Alexander Udalov
37982e4bb1 Move SAM-related descriptor classes to module frontend.java
Also move SyntheticMemberDescriptor to module resolution
2017-06-30 21:02:18 +03:00
Alexander Udalov
9717745b83 Minor, remove implementation overridden in all subclasses 2017-06-30 21:02:18 +03:00
Alexander Udalov
778a6758a5 Do not add inner class names to functions in Java static scope
Previously it was needed for SAM adapters, but they can no longer be
found in this scope
2017-06-30 21:02:18 +03:00
Sergey Igushkin
c4e7f1aa97 Fix parsing Gradle version with zero
(cherry picked from commit 732972c)
2017-06-30 20:44:59 +03:00
Sergey Igushkin
40a8bbf24d Fix friend paths not configured correctly with separate classes dirs
(cherry picked from commit d5ee659)
2017-06-30 20:44:49 +03:00
Alexey Sedunov
9ba868a903 Minor: Fix test data 2017-06-30 13:53:09 +03:00
Valentin Kipyatkov
6df0c28119 Correction after code review 2017-06-30 11:21:16 +03:00
Valentin Kipyatkov
8fabb6945e Allow slice rewrite in trace when in IDE 2017-06-30 11:21:16 +03:00
Valentin Kipyatkov
61d9a6b9cd Use the same way to check for ProcessCanceledException everywhere 2017-06-30 11:21:16 +03:00
Valentin Kipyatkov
eb4f322c77 Do not store ProcessCanceledException as result for cached value 2017-06-30 11:21:15 +03:00
Valentin Kipyatkov
09dbb07fb8 Optimization to reuse BindingContext in completion 2017-06-30 11:21:15 +03:00
Sergey Igushkin
1174c7bdd9 Add sourcesJar and javadocJar to artifacts of gradle-tools projects.
(cherry picked from commit 450345b)
2017-06-29 20:59:36 +03:00
Sergey Igushkin
a4be282074 Add Gradle Plugin Portal publication to the buildscripts
Add option to disable signing (-PnoSign), to be used when publishing
pre-built artifacts

Add option to define specific version for publishing, to be used when
publishing test versions

(cherry picked from commit dcd55e9)
2017-06-29 20:59:36 +03:00
Dmitry Jemerov
4497874f31 Remove unnecessary saveAll() 2017-06-29 17:56:59 +02:00
Sergey Igushkin
d1bddb6250 Fix disabling IC not applied to kapgGenerateStubsKotlin tasks
Issue #KT-18647 Fixed

(cherry picked from commit ffb656a)
2017-06-29 18:44:00 +03:00
Sergey Igushkin
a9cad7f112 Add a test for project.buildDir lazy evaluation
(cherry picked from commit ab0f9cd)
2017-06-29 18:42:50 +03:00
Nikita Skvortsov
b2cdb0d63d evaluate and use buildDir as late as possible
(cherry picked from commit a2c7f80)

(cherry picked from commit 5643fa1)
2017-06-29 18:41:53 +03:00
Sergey Igushkin
351f810797 Add tests for separate classes dirs
(cherry picked from commit b07d79b)
2017-06-29 18:31:53 +03:00
Sergey Igushkin
700b162233 Implemented separate classes dirs support in the Gradle plugins.
Issue #KT-18495 Fixed
Issue #KT-18544 Fixed

(cherry picked from commit e25f0fd)
2017-06-29 18:31:23 +03:00
Sergey Igushkin
ae47c59dc9 Pass freeCompilerArgs unchanged to the compiler, without parsing them
with the compiler loaded along the Gradle plugin.

Issues: #KT-17618 Fixed

(cherry picked from commit 44f7428)
2017-06-29 18:27:18 +03:00
Alexey Sedunov
88968807b2 Generate equals/hashCode(): Swap class literals in comparison 2017-06-29 17:42:20 +03:00
Alexey Sedunov
e3e4c447fa Generate equals/hashCode(): Use class literals when possible
#KT-18683 Fixed
2017-06-29 17:42:18 +03:00
Alexey Sedunov
50a38df8b1 Remove Parentheses: Forbid on call inside a call without argument list
#KT-18699 Fixed
2017-06-29 17:42:17 +03:00
Alexey Sedunov
20969f161c Introduce Parameter: Fix NPE on invalid parameter name or type
EA-95189 Fixed
2017-06-29 17:42:16 +03:00
Alexey Sedunov
2e8b374ce8 Move: Use KtNamedDeclaration as referrer when reporting a conflict
EA-103817 Fixed
2017-06-29 17:42:15 +03:00
Alexey Sedunov
58addf72ff New File Action: Do not start under write action
EA-102468 Fixed
2017-06-29 17:42:14 +03:00
Alexey Sedunov
b1637df8df Misc: Format generated members under write action
EA-87901 Fixed
2017-06-29 17:42:13 +03:00
Alexey Sedunov
392370bb23 Extract Interface: Fix NPE
EA-90440 Fixed
2017-06-29 17:42:11 +03:00
Alexey Sedunov
dd0f8e98e8 Create Type Alias From Usage: Disable on PsiPackage
EA-92625 Fixed
2017-06-29 17:42:10 +03:00
Alexey Sedunov
6060a39494 Change Signature: Use correct index in getOriginalParameter()
#KT-18642 Fixed
 #KT-18606 Fixed
2017-06-29 17:42:09 +03:00
Nikolay Krasko
9122f58d5d Re-enable optimize on the fly activation when unused imports found
Remove deprecated usages
2017-06-29 16:56:15 +03:00
Nikolay Krasko
6a5d6854bb Refactoring: inline implementation into KotlinStdJSProjectDescriptor 2017-06-29 16:56:15 +03:00
Nikolay Krasko
df393e18fe Configure AbstractInspectionTest with project descriptors
Previous implements produced flaky tests when non-js tests were
executed after js.
2017-06-29 16:56:15 +03:00
Nikolay Krasko
be28c4a48f Remove unused configuration of runtime library
The project descriptor used in the test already has the configuration.
Also directive is not used in tests.
2017-06-29 16:56:15 +03:00
Mikhail Glukhikh
c8a9b5f67a Restrict range of "simplifiable call chain" inspection 2017-06-29 16:25:58 +03:00
Mikhail Glukhikh
840847e47c Code cleanup: several inspections applied 2017-06-29 16:25:57 +03:00
Mikhail Glukhikh
fdca96634e Add restrictions for "simplifiable call chain" inspection
Do not use on maps; do not suggest for lambdas with return inside
Related to KT-18274
2017-06-29 16:25:55 +03:00
Mikhail Glukhikh
2f0159a7ab Minor fix: useless call on collection type 2017-06-29 16:25:54 +03:00
Mikhail Glukhikh
36be1fdaef Introduce "simplifiable call chain on collection" inspection
Related to KT-12165
So #KT-18274 Fixed
So #KT-17198 Fixed
2017-06-29 16:25:52 +03:00
Mikhail Glukhikh
bdb9f00c75 Introduce "Useless call on collection type" inspection
Related to KT-12165
Supported functions: filterNotNull, filterIsInstance,
mapNotNull, mapNotNullTo, mapIndexedNotNull, mapIndexedNotNullTo

Also, "Useless cal on not-null" improved a bit
2017-06-29 16:25:50 +03:00
Mikhail Glukhikh
f80f41d254 Introduce "redundant explicit type" inspection #KT-18517 Fixed
Reported cases: constants, constructors, object references
2017-06-29 16:25:47 +03:00
Mikhail Glukhikh
0f4ae3b727 Introduce "Useless call on not-null type" inspection #KT-18386 Fixed
Supported functions: orEmpty(), isNullOrEmpty(), isNullOrBlank()
2017-06-29 16:25:45 +03:00
Alexander Udalov
8c21ff66a4 Always treat all sources as parts of the module being compiled
If a path to the module-info.java file is passed as an argument, we
should treat all other source files passed as arguments (either as
individual source files or inside a source directory) as members of that
module. Previously we treated other source files as members of the
unnamed module, and this resulted in incorrect errors when using a
member exported with a qualification from another named module, for
example

 #KT-18598 In Fixed
2017-06-29 15:59:57 +03:00
Alexander Udalov
5192f946c5 Fix depth-first search for Java 9 modules
To compute modules to be added to compilation roots in
JavaModuleGraph.getAllDependencies, we should look not only for
transitive requirements of root modules, but for transitive requirements
of _root modules' requirements_. The same logic applies to
JavaModuleGraph.reads. In other words, when looking for a path in the
module graph between two modules, the first edge's transitiveness
doesn't matter, but all other edges after the first must be transitive.

There was also a stupid bug in dfs in
JavaModuleGraph.getAllDependencies: we continued the DFS only if the
module _was not_ added to the "visited" set ("add" returns true if the
element was added successfully)

 #KT-18598 In Progress
2017-06-29 15:59:57 +03:00
Alexander Udalov
72f37a278c Do not add all modules from module path when compiling unnamed module
Note that javac reports a nice error in this case ("package foo is
declared in module lib, which is not in the module graph"), but we only
report "unresolved reference" because the corresponding modules are not
added to classpath roots. We should improve this in the future

 #KT-18598 In Progress
2017-06-29 15:59:57 +03:00
Alexander Udalov
f8346d21c2 Check type alias expansion for Java 9 module accessibility
#KT-18598 In Progress
2017-06-29 15:59:57 +03:00
Alexander Udalov
8768500844 Fix incorrect behavior and refactor JvmModuleAccessibilityChecker
Previously we assumed that a symbol is accessible if its containing
package is exported by module-info.java. Which was obviously wrong and
could lead to a situation where a symbol would be incorrectly accessible
if a usage module has a dependency on the symbol's module in IDEA
project terms, but does not require it in its module-info.java

 #KT-18598 In Progress
2017-06-29 15:59:57 +03:00
Alexander Udalov
2d3888c710 Do not add JDK .jar roots if the JDK is modular (9+)
Files like ant-javafx.jar, deploy.jar, java.jnlp.jar, javafx-swt.jar etc
should not be added to the classpath if JDK home points to a JDK 9
distribution
2017-06-29 15:59:57 +03:00
Alexander Udalov
9274d963aa Create KotlinCoreEnvironment a bit later in tests
Before this change, diagnostic tests with Java source files failed
because KotlinCoreEnvironment was being created in the test's setUp,
even before the test data file has been split into .java/.kt and the
resulting .java files have been copied to a temporary directory. In
KotlinCoreEnvironment's constructor, we now inspect all roots for
module-info files, which involves calling VirtualFile.getChildren on all
roots in the configuration. CoreLocalVirtualFile.getChildren is
cached on the first access, and so because the temporary directory with
.java files was empty at this point, the VirtualFile for that directory
returned empty array in getChildren later in the test, resulting in
unresolved reference errors.

This is fixed by creating the environment _after_ the .java files have
been copied to a temporary directory. Note that slow assertions for
flexible types are now enabled in KtUsefulTestCase instead of
KotlinTestWithEnvironmentManagement, because BaseDiagnosticsTest no
longer inherits from the latter
2017-06-29 15:59:56 +03:00
Alexander Udalov
03d83db660 Support -Xmodule-path and -Xadd-modules command line arguments
#KT-18598 In Progress
 #KT-18599 Fixed
2017-06-29 15:59:56 +03:00
Alexander Udalov
e32880d9a3 Implement Java 9 module visibility checks
In this commit, only IDE tests are added, because we look for module
declarations in the IDE across the whole project, whereas in the
compiler we should do this on the module path only and that requires
separate work (KT-18599) which is done in the following commits.

(The change in Cache.kt is needed so that
JvmModuleAccessibilityChecker.ClassifierUsage, which is an inner class,
would be injected properly.)

 #KT-18598 In Progress
 #KT-18599 In Progress
2017-06-29 15:59:56 +03:00
Alexander Udalov
2275068c94 Introduce JavaModule, refactor module graph construction
#KT-18598 In Progress
 #KT-18599 In Progress
2017-06-29 15:59:56 +03:00
Mikhael Bogdanov
4f914fafca Calculate default mask shift properly
#KT-18689 Fixed
2017-06-29 14:57:42 +02:00
Alexey Andreev
1fa7193901 Change variance of return type of Promise.all function
See KT-18624
2017-06-29 10:34:10 +03:00
Alexey Andreev
479148f7e0 Run JS DCE gradle task in a separate process 2017-06-29 10:32:30 +03:00
Alexey Andreev
cfbb9209a7 Add JS DCE gradle plugin 2017-06-29 10:32:30 +03:00
Nikolay Krasko
9eefbc2036 Perform 'all import resolve' once and protect it with lock (EA-79696)
Binding context and diagnostic structures are not thread-safe now and
need to be protected with the lock.

Fix flacky test testRemoveDuplicateImport

This also probably fixes some traces in EA-79696
2017-06-28 18:57:13 +03:00
Nikolay Krasko
9f873f869a Print all diagnostics if null diagnostic found (EA-79696)
Diagnostics collection shouldn't contain nulls, but may do so when there
were unprotected simultaneous writes from several threads.
2017-06-28 18:57:12 +03:00
Mikhail Glukhikh
6c274cecff Protect getSingleAbstractMethodOrNull from data binding deadlock
Now it cannot cause resolve re-entrance
Probably #KT-18687 Fixed
2017-06-28 16:40:27 +03:00
Dmitry Neverov
3e29f9ed5a Don't report as redundant 1st semicolon in enum without entries
So #KT-12524 Fixed
2017-06-28 15:30:40 +03:00
Toshiaki Kameyama
3a606d13f0 Extends range of change visibility intention #KT-14093 Fixed 2017-06-28 15:28:50 +03:00
Dmitry Neverov
44ce5f73f7 Apply De Morgan's laws to non-negated binary expressions
So #KT-18460 Fixed
2017-06-28 15:28:43 +03:00
Toshiaki Kameyama
af53a0ecd5 Add quick-fix "Replace with safe call & elvis" #KT-17815 Fixed 2017-06-28 15:28:35 +03:00
Toshiaki Kameyama
c2707bb81b Support cascade if / when in lift return / assignment intentions
So #KT-13458 Fixed
So #KT-13436 Fixed
2017-06-28 15:28:28 +03:00
Toshiaki Kameyama
ed04b4debd Add quick-fix for empty brackets after primary constructor
So #KT-18534 Fixed
2017-06-28 15:28:21 +03:00
Mikhael Bogdanov
69457ef3f1 Generate optimized hashCode for primitive type with jvmTarget 1.8+
#KT-7571 Fixed
2017-06-28 13:44:07 +02:00
Igor Chevdar
d7e4350d42 Ignored/fixed some tests for Kotlin/Native 2017-06-28 12:54:32 +03:00
Alexey Andreev
7b52300287 Remove unnecessary system property from JS tests launch configuration
Replace it with property that allows to disable DCE tests.
This is useful for temporary disabling DCE without examining source
code to find property name.
2017-06-28 10:48:02 +03:00
Alexey Andreev
4037112f28 Implement deepCopy in JsRegExpr 2017-06-28 10:48:01 +03:00
Alexey Andreev
64331ffa40 Avoid excessive copying in JsLabel
See KT-18331
2017-06-28 10:48:01 +03:00
Denis Zharkov
3dc4f8a2ff Do not write generics for $suspendImpl synthetic method
#KT-18252 Fixed
2017-06-28 10:25:08 +03:00
Yan Zhulanow
e7e0032cc8 Kapt3, minor, tests: Weaken regular expression for Metadata shrinking 2017-06-28 10:25:08 +03:00
Denis Zharkov
d88d1d6189 Do not use non-existing class for suspend markers
As they remain in inline functions now proguard emits
a warning about them, even though inline suspend functions
are effectively inline-only and these markers can't be
executed at runtime

 #KT-18702 Fixed
2017-06-28 10:24:53 +03:00
Denis Zharkov
cb95986c36 Report error on calls to obsolete inline suspend functions
They do not contain markers for suspend calls in them

See the changes introduced for fixing KT-16603
2017-06-28 10:24:27 +03:00
Zalim Bashorov
6441c9d913 Restore executable attributes for all files in kotlinc/bin after copying them 2017-06-27 21:57:59 +03:00
Zalim Bashorov
6cd678af06 Add the ability to provide custom tag when deploy to npm 2017-06-27 21:35:09 +03:00
Nikolay Krasko
d8d862fa68 Do not compute class names for inline usages during stepping (KT-18411)
This was lost in "Debugger: Fix AbstractPositionManagerTest"(622430a29)

ExtraSteppingFilter: do not compute classNames for inline (f28f7eaa3b)

 #KT-18411 Fixed
2017-06-27 17:39:17 +03:00
Mikhail Glukhikh
7d7ef18e99 Fix type in README 2017-06-27 17:10:27 +03:00
Alexey Andreev
f6964b18db Fix performance issue in JS inliner
See KT-18679
2017-06-27 15:10:21 +03:00
Alexander Udalov
f96ef96078 Check JDK_16 and JDK_18 existence in build.xml 2017-06-27 14:54:53 +03:00
Alexander Udalov
e42b151561 Support primitive array annotation arguments in ConstantValueFactory
This has no visible consequences at the moment, but will help once we
need to load such argument from some annotation in the compiler in the
future
2017-06-27 14:53:39 +03:00
Alexander Udalov
b67542533b Drop unused FunctionDescriptor.Configuration.setSource 2017-06-27 14:53:39 +03:00
Alexander Udalov
288c2b5dc9 Minor, remove some obsolete usages of ResolutionContext#replaceScope 2017-06-27 14:53:39 +03:00
Alexander Udalov
59b932a815 Optimize away unneeded FqName computation in KotlinBuiltIns
Before computing the FqName, check the simple class name first. This
code was responsible for about 20% of FqNameUnsafe instances created
during compilation of "core" modules
2017-06-27 14:53:39 +03:00
Alexander Udalov
0352bdbca5 Optimize and improve AbstractClassTypeConstructor.equals
Instead of computing and comparing FQ names, compare simple names of
classes and theirs containers. This code was responsible for creation of
about 10% of FqNameUnsafe instances during compilation of "core"
modules.

Also make the check more strict: previously, a class "c" declared in
package "a.b" would be considered equal to a class "c" declared in class
"b" in package "a". Because JVM type descriptors of such classes are
different, this behavior was suspicious and might have lead to error at
runtime. Now, we require the number of containing classes of the given
two classes also to be the same
2017-06-27 14:53:39 +03:00
Dmitry Petrov
d5e02f069a Fast version for POP backward propagation (without SourceInterpreter) 2017-06-27 14:28:42 +03:00
Dmitry Petrov
f1183d98a9 Fix complexity formula for SourceInterpreter
It is actually N^2 * F (VERY pessimistic case),
N = number of instructions
F = frame size
because frames contain sets of instructions.
2017-06-27 14:28:42 +03:00
Dmitry Petrov
a84c2a6f31 Improve string concatentation & string templates code generation
Reuse StringBuilder instances for nested subexpressions.
(NB StringBuilder instance for string template with a string
concatenation inside an expression entry, such as `"${"a" + "b"}"`,
will not be reused, although that doesn't seem to be a real-life issue).

 #KT-18558 Fixed Target versions 1.1.4
 #KT-13682 Fixed Target versions 1.1.4

Join adjacent strings literals, escaped strings, and constant values
(in a language version that supports const val inlining).
Use StringBuilder#append(char) for single-character constants
(e.g., " " in "$a $b").

 #KT-17280 Fixed Target versions 1.1.4
 #KT-15235 Fixed Target versions 1.1.4
2017-06-27 14:28:42 +03:00
Dmitry Petrov
ae71833a12 Use original descriptors for functions when generating stubs
Descriptors for builtin class members on JVM are substituted.
2017-06-27 13:00:10 +03:00
Dmitry Petrov
5e5a1bd686 Use java.lang.Object as a fall-back reference type
If for some reason during preliminary analysis in redundant null check
elimination we failed to determine a local variable type statically,
treat it as java.lang.Object.
This will disable some further optimizations using precise type
information (such as INSTANCEOF check elimination), but will not fail
with an exception anyway.
2017-06-27 12:56:34 +03:00
vitaly.khudobakhshov
d165ea9ea7 Add expression type string to the REPL API
PR-1131
2017-06-27 11:28:40 +02:00
Alexander Udalov
8783f7a94e Remove unneeded nullability annotations in CallableReference 2017-06-26 18:46:26 +03:00
Alexey Andreev
20842dcc44 Add module name as a prefix to declaration keys in JS translator
This is necessary due to different modules can have same
package declarations. When importing declarations from these
packages, we should distinguish from which module we are importing it.

See KT-18652
2017-06-26 18:16:00 +03:00
Alexey Andreev
3331be9cc8 Fix JS CLI test that fails in Windows 2017-06-26 18:15:30 +03:00
Alexey Andreev
adc04196b1 Support JS source map source embedding configuration in IDEA 2017-06-26 18:15:29 +03:00
Alexey Andreev
a0e1bde594 Allow to embed source files into JS source maps 2017-06-26 18:15:28 +03:00
Nikolay Krasko
73c37ecd25 Remove usage of HighlightingSession.getEditor()
It's going to be deleted in IDEA.
2017-06-26 17:39:39 +03:00
Alexander Udalov
0c8ca5f930 Extract some functions from test class into base class
To be used in other tests which will be subclasses of
AbstractKotlinCompilerIntegrationTest
2017-06-26 16:22:05 +03:00
Alexander Udalov
69efb81a12 Minor refactoring in JavaModuleInfo
Remove unused declarations
2017-06-26 16:22:05 +03:00
Alexander Udalov
fd0658e0f4 Minor, inline unneeded JvmDependenciesIndexFactory 2017-06-26 16:22:05 +03:00
Alexander Udalov
0e2e3b3e65 Cleanup KotlinCoreEnvironment and usages
Remove unused API, weaken declaration visibility, reformat
2017-06-26 16:22:05 +03:00
Alexander Udalov
999e4cda1d Compute module mappings eagerly in JvmPackagePartProvider, refactor
Previously we traversed all notLoadedRoots on each request for package
parts with the given package FQ name. Since notLoadedRoots might contain
a lot of roots (which never transition into "loadedModules" because e.g.
they are not Kotlin libraries, but just Java libraries or SDK roots with
the META-INF directory), this was potentially hurting performance. It
seems it's more optimal to compute everything eagerly once
JvmPackagePartProvider is constructed.

Another problem with the previous version of JvmPackagePartProvider was
that it did not support "updateable classpath" which is used by REPL and
kapt2, it only used the initial roots provided in the
CompilerConfiguration. In REPL specifically, we would thus fail to
resolve top-level callables from libraries which were dynamically added
to the execution classpath (via some kind of a @DependsOn annotation).
In the new code, JvmPackagePartProvider no longer depends on
CompilerConfiguration to avoid this sort of confusion, but rather relies
on the object that constructed it (KotlinCoreEnvironment in this case)
to provide the correct roots. This is also beneficial because the
computation of actual VirtualFile-based roots from the ones in the
CompilerConfiguration might get trickier with modular Java 9 roots
2017-06-26 16:22:05 +03:00
Alexander Udalov
a5a78b8f91 Minor refactoring in ClasspathRootsResolver.convertClasspathRoots
Package prefix only makes sense for JavaSourceRoot content roots
2017-06-26 16:22:05 +03:00
Alexander Udalov
2424431e16 Extract ClasspathRootsResolver out of KotlinCoreEnvironment 2017-06-26 16:22:04 +03:00
Alexander Udalov
6d48b1c3fb Minor, extract MessageUtil.virtualFileToPath 2017-06-26 16:22:04 +03:00
Alexander Udalov
8af923c5ff Refactor MockLibraryUtil and related tests
- separate compileLibraryToJar into two public functions, for JVM and JS
- allow to pass any extra options instead of just -Xallow-kotlin-package
- add a bunch of default arguments for the most common cases
2017-06-26 16:22:04 +03:00
Alexander Udalov
68df1d73e7 J2K MockLibraryUtil: prettify 2017-06-26 16:22:04 +03:00
Alexander Udalov
46a6dc6550 J2K MockLibraryUtil: convert 2017-06-26 16:22:04 +03:00
Alexander Udalov
884e85653f J2K MockLibraryUtil: rename .java -> .kt 2017-06-26 16:22:04 +03:00
Denis Zharkov
c8a2de0243 Allow custom expected result for fast class reading tests 2017-06-24 17:26:02 +03:00
Denis Zharkov
bc564af2fc Regenerate mockJDK using openJDK 7 2017-06-24 17:26:01 +03:00
Dmitry Jemerov
3158c71c29 Check that we have correct sources for mockjdk 2017-06-24 17:08:11 +03:00
Nikolay Krasko
87889904ee Allow only one invoke to be a target for smart step into (KT-18632)
It's difficult to distinguish such calls reliably in debug session

 #KT-18632 Fixed
2017-06-23 21:33:26 +03:00
Mikhail Glukhikh
247c0497b1 Visibility can be private: weaken level to INFO 2017-06-23 18:15:21 +03:00
Mikhail Glukhikh
c99db11ace Visibility can be private: do not perform too expensive search
Also, additional test for usage via accessor was added
So #KT-18617 Fixed
2017-06-23 18:15:20 +03:00
Zalim Bashorov
3358f0ab69 KJS: use korlinc-js runner written in js to make possible to run it on any OS
Restore executable attributes on kotlinc* bash scripts after copying them.
2017-06-23 15:14:35 +03:00
Nikolay Krasko
502ac80b89 Do not skip invoke call on parameters during smart step into (KT-18577)
#KT-18577 Fixed
2017-06-23 13:47:33 +03:00
Nikolay Krasko
e5ce91dc5b Show receiver for invoke calls in smart step into popup 2017-06-23 13:47:33 +03:00
Alexey Sedunov
9681f5ca42 Generate equals/hashCode(): Enable for classes without properties
Also:
- forbid for enum classes
- use javaClass.hashCode() instead of 0 if class has no properties

 #KT-18418 Fixed
2017-06-22 19:50:55 +03:00
Alexey Sedunov
895407f5e3 Rename: Do not silently rename all parameters in function hierarchy
#KT-18325 Fixed
2017-06-22 19:50:54 +03:00
Alexey Sedunov
31d21a14f2 Copy: Disable when selection doesn't contain Kotlin source files
#KT-18390 Fixed
2017-06-22 19:50:53 +03:00
Alexey Sedunov
423fb9dfb3 Move/Copy: Warn about usages of JDK when moving to non-JVM module
#KT-18135 Fixed
2017-06-22 19:50:52 +03:00
Alexey Sedunov
1d36c49537 Copy: Copy elements and process usages under the same write action
In some cases doing these operations in separate write actions
may lead to invalidation of copied elements

 #KT-18149 Fixed
2017-06-22 19:50:51 +03:00
Alexey Sedunov
6b18ff1d97 Copy/Move: Fix processing of calls used as callees
#KT-18241 Fixed
2017-06-22 19:50:50 +03:00
Mikhail Zarechenskiy
87a41293e8 Improve diagnostics on callable reference of unresolved class
#KT-10839 Fixed
2017-06-22 15:02:13 +03:00
Mikhail Zarechenskiy
0579604653 Do not propose to specify constructor invocation in diagnostics
#KT-17188 Fixed
2017-06-22 15:02:10 +03:00
Mikhail Zarechenskiy
0f350f5db8 Don't report error on member that overrides open member from final class
#KT-14598 Fixed
2017-06-22 15:02:09 +03:00
Mikhail Zarechenskiy
9847278699 Report error about invalid if as expression on the if keyword
#KT-14633 Fixed
2017-06-22 14:18:11 +03:00
Mikhail Zarechenskiy
e40c8fff05 Make resolution status name more precise 2017-06-22 13:50:01 +03:00
Mikhail Zarechenskiy
7a9e1b2b1d Improve diagnostic on overload resolution ambiguity
Report type mismatch on argument when a nullable argument is passed to non-null parameter.

 Note that this affects only functions with simple types without generics

 #KT-2007 Fixed
 #KT-9282 Fixed
2017-06-22 13:41:31 +03:00
Mikhail Zarechenskiy
16de991b07 Add test for obsolete issue
#KT-8262 Obsolete
2017-06-22 13:41:30 +03:00
Mikhail Zarechenskiy
4b3ffd9418 If all candidates are invisible then don't report ambiguity
#KT-10045 Fixed
2017-06-22 13:41:28 +03:00
Mikhail Zarechenskiy
cd1ae7f0f2 Add resolution status to report about unsuccessful smartcast
#KT-10248 Fixed
 #KT-11119 Fixed
2017-06-22 13:41:27 +03:00
Mikhail Zarechenskiy
0f4497256b Report about wrong number of type arguments instead of ambiguity
#KT-7975 Fixed
 #KT-1809 Fixed
2017-06-22 13:05:10 +03:00
Dmitry Jemerov
24f1bbfb46 Add code for configuring eap-1.2 bintray repo
#KT-18316 Fixed
2017-06-22 11:01:03 +02:00
Dmitry Petrov
2b3043bf9f Fix CFG problem for 'when' in Konan
If type of 'when' expression is 'Nothing', it should be kept that way
even if the expression itself is implicitly coerced to Unit.
2017-06-22 10:21:54 +03:00
Alexander Udalov
1f34dfabd5 Use kotlin.Lazy for script definition computation, add test for no definition 2017-06-22 10:19:06 +03:00
Ilya Chernikov
4178188e15 Fix name retrieval on exception reporting during analysis 2017-06-22 10:19:05 +03:00
Alexander Udalov
135f0a136e CLI: report error if the first argument for "-script" is not kts
#KT-3045 Fixed
2017-06-22 10:19:05 +03:00
Alexander Udalov
85d1bef351 Add reflection.jvm module sources to kotlin-reflect library
To be able to debug classes in kotlin-reflect via reflection.jvm's
sources when running tests
2017-06-22 00:08:38 +03:00
Alexander Udalov
a064b59a7d Do not put "Class-Path: kotlin-stdlib.jar" into kotlin-reflect manifest
Since the kotlin-reflect artifact might be used in environments where
the kotlin-stdlib artifact is named something else (e.g.
kotlin-stdlib-{version}.jar) and the file existence is verified by the
launcher

 #KT-16399 Fixed
2017-06-22 00:08:38 +03:00
Dmitry Jemerov
2407f8b9ac Add collection building methods to default blacklist
#KT-18030 Fixed
2017-06-21 19:09:23 +02:00
Dmitry Jemerov
16c8a092ca Correctly show parameter name hints for non-ambiguous overloads 2017-06-21 19:09:21 +02:00
Nikolay Krasko
ad6c84924b Copy bootstrap compiler to dist directory
Can by used in old branches where it's impossible to make dist properly
2017-06-21 17:51:51 +03:00
Nikolay Krasko
3ffd63a17c Attempt for fix flaky debugger tests - wait for the resume before exit 2017-06-21 17:49:03 +03:00
Alexander Udalov
233b63469a Fix IllegalAccessException on private annotation in reflection
#KT-14094 Fixed
2017-06-21 15:43:00 +03:00
Alexander Udalov
fb60f4ad8f Do not load annotations of each function in JvmBuiltInsSettings.isFunctionAvailable
This fixes the exception in the case described in KT-14094 because we no
longer try to load annotations on functions which cannot be annotated
with @PlatformDependent. (However, the underlying problem in KT-14094 is
not fixed by this, and is still reproducible on explicit call to
KCallable.annotations.)

 #KT-14094 In Progress
2017-06-21 15:43:00 +03:00
Alexander Udalov
6388c1885c Fix KCallable.call for protected members from base class
Class.getMethod does not return protected methods from super class, so
we invoke getDeclaredMethod on each super class manually instead

 #KT-18480 Fixed
2017-06-21 15:42:59 +03:00
Alexander Udalov
a25aa2fed8 Cleanup DefaultErrorMessagesJvm
Use static imports, use Kotlin stdlib API, use more precise renderers
2017-06-21 15:42:59 +03:00
Alexander Udalov
4e51448b66 Refactor and simplify functionTypes.kt and related code
Remove unused declarations, inline one-liners, optimize by using
KotlinBuiltIns.isUnderKotlinPackage
2017-06-21 15:42:58 +03:00
Alexander Udalov
5a25ba199a Micro optimization to avoid computing class FQ name when not necessary
KotlinBuiltIns.isConstructedFromGivenClass checks the simple name of the
class first, and only computes the full FQ name if it matches the last
segment of the expected FQ name
2017-06-21 15:42:57 +03:00
Alexander Udalov
aed5b934f8 Introduce KotlinBuiltIns.isUnderKotlinPackage
Semantics is the same as in the former
FunctionDescriptor.hasSubpackageOfKotlin, but it doesn't compute the FQ
name of the descriptor
2017-06-21 15:42:57 +03:00
Alexey Sedunov
7bc42f89d3 Configuration: Fix API version selection on language version change 2017-06-21 12:36:53 +03:00
Alexey Sedunov
3460a31e3a Kotlin Facet: Do not import dependency-based classpath from Gradle
JPS obtains it automatically via imported module dependencies

 #KT-18475 Fixed
2017-06-21 12:36:52 +03:00
Alexey Sedunov
f68689b5e4 Kotlin Facet: Do not import jdkHome from Gradle/Maven model
#KT-18151 Fixed
2017-06-21 12:36:51 +03:00
Alexey Sedunov
fe42586c6f Kotlin Facet: Fix NPE in Maven importer tests
#KT-18376 Fixed
2017-06-21 12:36:50 +03:00
Alexey Sedunov
0570592952 Kotlin Facet: Avoid rewriting platform version with project settings
#KT-18373 Fixed
2017-06-21 12:36:49 +03:00
Ilya Chernikov
2e823a4816 Fix compatibility with renamed Gradle Kotlin DSL 2017-06-21 11:35:21 +02:00
Mikhail Zarechenskiy
1e020644e1 Fix getting right bracket element for collection literal 2017-06-21 01:22:08 +03:00
Mikhail Zarechenskiy
837df66c19 Register reference contributor for collection literals
#KT-18551 Fixed
2017-06-21 00:16:28 +03:00
Alexey Andreev
78b238a05b Report warning when two .kt files get same paths in JS source map 2017-06-20 17:40:36 +03:00
Alexey Andreev
60dd475493 Don't expose sourceMapSourceRoots argument to Gradle (JS)
Exposing this property causes IDEA to treat it as a free
command line argument, which is undesirable.
Support source roots via setting command line arguments inside
JS gradle task.
2017-06-20 17:40:35 +03:00
Alexey Andreev
49b742ab3d Add new JS source map config options to Maven plugin 2017-06-20 17:40:35 +03:00
Alexey Andreev
cfd3b137d8 Add support for JS source map source roots to Gradle plugin 2017-06-20 17:40:34 +03:00
Alexey Andreev
62fb149f08 Add support for sourceMapPrefix option (JS) in IDEA 2017-06-20 17:40:34 +03:00
Alexey Andreev
1d6f01ee6c Add support for relative JS source map paths in JPS 2017-06-20 17:40:33 +03:00
Alexey Andreev
13ab63ae09 Generate relative paths in JS source maps
Also, add CLI options to manipulate prefixes of path

See KT-4078
2017-06-20 17:40:32 +03:00
Nikolay Krasko
44d3b8fb1a Ignore sub-queries for other operators with the same receiver (KT-18566)
ExpressionsOfTypeProcessor searches for all occurence of expression
with given type. It start from usages of the class, searches for sub-classes,
declarations that return those classes, usages of these declarations,
and so on.

During this search, find usages for all operators that return the
subject type is executed as sub-queries. Full search for such queries
can't give addition types. And it also shouldn't give additional scopes
for search, because same scopes should be located by operands. In other
words, if sub-query can spot the scope of usage starting from the same
type, the original query should also process same scope.

 #KT-18566 Fixed
2017-06-20 16:53:05 +03:00
Yan Zhulanow
0f3dff44ac Minor: Remove invalid Maven module reference 2017-06-20 15:23:15 +03:00
Alexander Udalov
31b2fffbe1 Avoid NPE at UtilKt.toJavaClass for unrecognized classes
Sadly, the case where this NPE would reproduce, remains unknown

 #KT-18494 Fixed
2017-06-20 14:39:48 +03:00
Alexander Udalov
8ef3531c48 Add kotlin.Any to KClass.superclasses if it's absent
#KT-18476 Fixed
2017-06-20 14:39:48 +03:00
Alexander Udalov
9471f33c38 Refactor getDefaultSupertype, drop obsolete diagnostic 2017-06-20 14:39:47 +03:00
Alexander Udalov
90f2ea87a6 Fix exception on callBy of callable with more than 32 parameters
The previous condition that checked if we'd skipped any optional
parameters didn't work when number of parameters > 32 because the number
of bit masks in that case was more than one

 #KT-18404 Fixed
2017-06-20 14:39:47 +03:00
Mikhael Bogdanov
62cd57b0d2 Make base test classes 'abstract' 2017-06-20 13:07:30 +02:00
Dmitry Petrov
786ac46fa6 Do not store nulls for captured variables going out of scope
These values can't be read after going out of scope.
JVM implementation can take care of such object references on its own.
Ref objects for captured variables are not different from any other
objects stored in local variables, so there's really no reason to
nullify these references explicitly.

 #KT-18478 Fixed Target versions 1.1.4
2017-06-20 13:31:36 +03:00
Dmitry Petrov
9356c1e0ef Skip PopBackwardPropagation for methods with large frames or no POPs
TODO get rid of SourceInterpreter here, it's quite expensive.
2017-06-20 13:31:36 +03:00
Dmitry Petrov
0a622e4440 Rewrite OtherOrigin overloads to prevent further silly problems
#KT-18413 Fixed Target versions 1.1.4
2017-06-20 13:31:36 +03:00
Mikhael Bogdanov
8ca82c8e99 Add missed common parts 2017-06-20 11:08:53 +02:00
Mikhael Bogdanov
956cc0dbfd Support IMPLICIT_INTEGER_COERCION 2017-06-20 11:01:10 +02:00
Mikhael Bogdanov
d888addba0 Add KCallableNamePropertyLowering 2017-06-20 11:00:38 +02:00
Mikhael Bogdanov
44b7f5a5be Add inline tests to IR 2017-06-20 10:26:38 +02:00
Mikhael Bogdanov
8ab705a14c Introduce IrInliner 2017-06-20 10:26:37 +02:00
Mikhael Bogdanov
9f736f2192 Extract PsiSourceCompiler 2017-06-20 10:26:36 +02:00
Mikhael Bogdanov
2507780e19 Extract PsiInlineCodegen 2017-06-20 10:26:35 +02:00
Mikhael Bogdanov
8dc1b8f95f Introduce BaseExpressionCodegen and SourceCompilerForInline,
switch CallGenerator and InlineCodegen to them

~base
2017-06-20 10:26:35 +02:00
Alexey Andreev
3ae214b97a Fix reified parameters with non-identifier names in JS
See KT-18169
2017-06-20 10:41:52 +03:00
Alexey Andreev
d3a5201ecc Intrinsify String?.plus in JS BE
See KT-8020
2017-06-20 10:40:21 +03:00
Ilya Gorbunov
7efb9ddd4e Early return if value is null
The change is required to fix compilation for IDEA 172, where getValue()
became explicitly nullable.
2017-06-20 02:58:40 +03:00
Zalim Bashorov
8b9fd44bbe Publish kotlin compiler artifacts to NPM 2017-06-19 22:52:01 +03:00
Zalim Bashorov
06cd02f769 Publish to NPM with dev tag by default 2017-06-19 22:52:00 +03:00
Yan Zhulanow
04c09bedeb SamWithReceiver, minor: Add missing module to Spring plugin classpath (fixes Spring tests) 2017-06-19 20:28:48 +03:00
Yan Zhulanow
d07fd52c43 SamWithReceiver: Add general-purpose plugin and Gradle/Maven integrations 2017-06-19 20:28:47 +03:00
Alexey Sedunov
db3172a750 Configuration: Inline createDefaultArguments() methods
It's a superficial fix: the bug is actually caused by
uninitialized companion instance reference in
Kotlin2JvmCompilerArgumentsHolder class

 #KT-18505 Fixed
2017-06-19 18:15:40 +03:00
Mikhail Zarechenskiy
2a4cac024b Add test for obsolete issue
#KT-13813 Obsolete
2017-06-19 17:36:10 +03:00
Mikhail Zarechenskiy
aeac2ea384 Fix 'add not-null asserted call' quick fix for operation in
#KT-18529 Fixed
2017-06-19 17:36:09 +03:00
Mikhail Zarechenskiy
b53a3b324f Fix 'infix call' diagnostic for in operation
#KT-8845 Fixed
2017-06-19 17:36:08 +03:00
Mikhail Zarechenskiy
d17f31c8b0 Refactoring: move several utils from js module to frontend 2017-06-19 17:36:07 +03:00
Mikhail Zarechenskiy
dbfea9b787 Fix TCE for invalid code with wrong callee expression
#KT-14927 Fixed
2017-06-19 17:36:06 +03:00
Sergey Igushkin
0032719ab9 (minor) Bump Android Gradle plugin version to 3.0.0-alpha4 in tests 2017-06-19 14:37:02 +03:00
Mike
7e01ac81ab Fixed Slack link (#1140)
http://kotlinslackin.herokuapp.com/ is down, replaced with http://slack.kotlinlang.org/
2017-06-19 08:33:13 +02:00
Mikhail Glukhikh
e8b0d47765 PlainTextPasteImportResolver: use relevant facade for Java classes
Fixes EA-75803 for this particular case
2017-06-16 17:17:38 +03:00
Vyacheslav Gerasimov
f51e3ab90c Fix Android extensions property usage highlighting
#KT-10736 Fixed
2017-06-16 17:13:34 +03:00
Mikhail Zarechenskiy
f8617f6676 Adapt collecting synthetic constructors in IDE for completion 2017-06-16 16:44:53 +03:00
Mikhail Zarechenskiy
011231f2ab Collect sam adapters for constructors in synthetic scope
Also place computation of synthetic constructors under one function
2017-06-16 16:44:52 +03:00
Mikhail Zarechenskiy
0adc8d9bfa Minor: remove val 2017-06-16 16:44:51 +03:00
Mikhail Glukhikh
e9e028f987 Minor: add getName() for three local quick fixes to fix 162 / AS23 2017-06-16 16:20:55 +03:00
Mikhail Glukhikh
4f8db14e5b Update changelog (1.1.3-eap-85)
(cherry picked from commit 61cb598)
2017-06-16 16:04:32 +03:00
Derek Alexander
1f5cc059f9 Fix compiler failure related NO_EXPECTED_TYPE
Changes to turn KT-16016 into a compiler diagnostic error rather than a
stack trace

#KT-16016 Fixed
2017-06-16 15:52:09 +03:00
Mikhail Glukhikh
ace3bfbbf9 Fix if -> ?: / ?. highlight type
if should be transformed, default level used (weak warning);
if should not be transformed, no highlighting (information) used.
2017-06-16 15:23:48 +03:00
Mikhail Glukhikh
9e85b0c2ba Has platform type inspection: do not enforce weak warning type
So #KT-17954 Fixed
2017-06-16 15:17:50 +03:00
Mikhail Glukhikh
c3f3392f0c Minor 2017-06-16 15:04:29 +03:00
fitermay
81f5a29526 Make overridden member open: invalidate cached state on PSI modification
Before, waiting for inspection rerun was necessary
Also rename: computeState --> computeInfo
Related to KT-17740
2017-06-16 15:04:22 +03:00
fitermay
289286c8cd Avoid mutating state and do not rely on side effects for proper function
So #KT-17740 Fixed
2017-06-16 15:04:16 +03:00
fitermay
0dced8d29c Do not suggest "Make overridden member open" for already open ones
So #KT-18148 Fixed
2017-06-16 15:04:10 +03:00
shiraji
cbccf932a7 Add inspection removing redundant spread operator for arrayOf call
So #KT-17920 Fixed
2017-06-16 15:04:04 +03:00
Mikhail Glukhikh
ce55d9e364 Fix of "Replace array of with array literal"
Do not apply if module does not support the relevant feature
Related to KT-17164
2017-06-16 15:03:58 +03:00
Toshiaki Kameyama
b9fb7cc3a5 Add quick fix to generate equals / hashcode in data class with arrays
So #KT-15893 Fixed
2017-06-16 15:03:52 +03:00
Dmitry Neverov
5df5a001a1 Support implicit receiver in if-then intentions #KT-16069 Fixed 2017-06-16 15:02:44 +03:00
Kirill Rakhman
13a2612e20 Add inspection for ranges with start > endInclusive #KT-18438 Fixed 2017-06-16 15:02:31 +03:00
shiraji
647558c98a Add inspection for potentially wrongly placed unary operators
So #KT-18236 Fixed
2017-06-16 15:02:24 +03:00
Alexey Sedunov
eaea160f0e Kotlin Facet: Fix detection of source set name by Gradle compile task
#KT-17492 Fixed
2017-06-15 17:26:40 +03:00
Alexey Sedunov
1544467725 Presentation: Fix NPE on star projection rendering
EA-100480 Fixed
2017-06-15 17:26:39 +03:00
shiraji
ab4eb1dd20 Add better quickfix for scope functions #KT-13676 Fixed 2017-06-15 15:01:42 +03:00
Mikhail Glukhikh
09d8c31433 Change highlight type of many inspections to GENERIC_ERROR_OR_WARNING
This way they will use highlight type depending on their level.
Otherwise highlight type is enforced and changing level in IDE
actually changes nothing.
2017-06-15 15:01:41 +03:00
Dimach
d369fa094a Add Boolean? == const to elvis conversion and vice versa #KT-15368 Fixed
Convert elvis to equality check implemented as inspection due
code style guide
2017-06-15 15:01:39 +03:00
Nikolay Krasko
6e9c0a0fda Move test logging processing in find usages to single place 2017-06-15 14:00:43 +03:00
Nikolay Krasko
60c8d5dcc0 Fix search usages for invoke() with vararg parameter (KT-18479)
#KT-18479 Fixed
2017-06-15 14:00:42 +03:00
Nikolay Krasko
018d4653e8 Fix search usages for invoke() extension operator (KT-18269)
#KT-18269 Fixed
2017-06-15 14:00:41 +03:00
Pavel V. Talanov
46512f34e4 Fix 'Find symbol' and 'Go to declaration' when jar is used in many libs
SourceNavigationHelper takes into account all the module infos
    that given virtual file is a part of

 #KT-15093 Fixed
2017-06-15 13:35:40 +03:00
Pavel V. Talanov
6eb4addb6e Test 'find symbol' when same jar is shared by libs(some without sources) 2017-06-15 13:35:40 +03:00
Pavel V. Talanov
8cfd6ffae0 Test navigation from source when same jar is in different libraries
One library can have sources attached and the other doesn't

 #KT-15093 In progress
2017-06-15 13:35:39 +03:00
Pavel V. Talanov
b12de14482 Refactor, extract some 'goto' related testing utils 2017-06-15 13:35:38 +03:00
Pavel V. Talanov
4356795324 Refactor, extract util in test code 2017-06-15 13:35:37 +03:00
Pavel V. Talanov
7949d3209b Minor, untangle Multi(Module)HighlightingTest hierarchy a bit 2017-06-15 13:35:36 +03:00
Nikolay Krasko
850568b8e9 Support "Force Step Over" action over suspended calls (KT-18453)
#KT-18453 Fixed
2017-06-15 13:29:28 +03:00
Nikolay Krasko
0e8e8ef546 Step over for suspended calls (KT-18453)
Debugger do the normal step over action and checks if function is
going to suspend. In this case the "run-to-cursor" breakpoint is
installed on function enter to intercept re-enter into function
after suspension.

 #KT-18453 In Progress
2017-06-15 13:29:27 +03:00
Nikolay Krasko
6d7ce6cec1 Prevent debugger to stop twice on breakpoints after suspension point
#KT-18453 In Progress
2017-06-15 13:29:26 +03:00
Nikolay Krasko
49baba017a Allow to stop in suspend funciton on enter and before suspended return
This commit is needed to implement "step over" action over suspended
call. Debugger have to understand when function is going to be
suspended and be able to set a breakpoint on function re-enter.

 #KT-18453 In Progress
2017-06-15 13:29:25 +03:00
Dmitry Jemerov
a2427c64a1 Reset library caches on file types change and dumb mode enter/exit
Ref: 50df476199
2017-06-14 18:08:52 +02:00
Mikhail Glukhikh
94dcadbec7 filterNotInSource: retains only files in contentScope
So #KT-18221 Fixed
2017-06-14 18:22:52 +03:00
Mikhail Glukhikh
81a1f26b1d Rename: findSyntheticFiles -> filterNotInSource 2017-06-14 18:22:46 +03:00
Mikhail Glukhikh
7734ec3bd5 Do not highlight semantics in files not under module content
Related to KT-18221
2017-06-14 18:22:40 +03:00
Mikhail Glukhikh
2a1c101350 Use NotUnderContentRootModuleInfo only from PsiElement.getModuleInfo()
This makes getModuleInfoByVirtualFile nullable
Fixes a variant of EA-75803 (from moveConflictUtils)
2017-06-14 18:22:24 +03:00
Dmitry Jemerov
0e2bdb8e66 Support CONFIGURE_LIBRARY directive in intention tests
Also restore tests for ConvertCamelCaseTestFunctionToSpaced
and apply fix for KT-18375
2017-06-14 16:17:01 +02:00
Dmitry Jemerov
4fa75256b7 Options for wrapping parentheseses in calls (KT-18113) 2017-06-14 14:37:30 +02:00
Dmitry Jemerov
72e8cd7e78 Consistent names for spacing options 2017-06-14 14:37:30 +02:00
Dmitry Jemerov
2e9a3e6d12 Option to use continuation indent in expression bodies (KT-9818) 2017-06-14 14:37:22 +02:00
Dmitry Jemerov
f4c75e61ad Option to use continuation indent in parameter lists 2017-06-14 14:33:52 +02:00
Dmitry Jemerov
a4916a3c00 NodeIndentStrategy: J2K and cleanup 2017-06-14 14:33:51 +02:00
Dmitry Jemerov
14edd7e357 NodeIndentStrategy: rename to .kt 2017-06-14 14:33:51 +02:00
Dmitry Jemerov
6c954d7e04 Refactor custom options registration for more type-safe API 2017-06-14 14:33:44 +02:00
Dmitry Jemerov
fc2a1fce8b Remove line break between ) and : if there's a line break before ) 2017-06-14 14:33:42 +02:00
Dmitry Jemerov
2ce430d608 Refactor spacing rules representation for easier debugging 2017-06-14 14:33:41 +02:00
Dmitry Jemerov
a0b5a3a8a2 Implement parenthesis wrapping options 2017-06-14 14:33:41 +02:00
Dmitry Jemerov
487d948ad3 KotlinLanguageCodeStyleSettingsProvider: J2K and cleanup 2017-06-14 14:33:40 +02:00
Dmitry Jemerov
1da3c7f577 KotlinLanguageCodeStyleSettingsProvider: rename to .kt 2017-06-14 14:18:59 +02:00
Dmitry Jemerov
f32dc9e84e Put lambda parameters on the same line as opening curly brace 2017-06-14 14:18:58 +02:00
Toshiaki Kameyama
af941bfdf5 KT-18158 Expand selection should select the comment after expression getter on the same line (#1122)
* Expand selection should select the comment after expression getter on the same line #KT-18158 Fixed

* Fixed expand selection behavior for the declaration with comment #KT-18158

* Remove redundant code #KT-18158
2017-06-14 12:28:56 +02:00
Dmitry Jemerov
b1f84676d1 Update tests according to new formatter behavior 2017-06-14 11:40:41 +02:00
Andrius Semionovas
8c6f93b899 Add tests for KEEP_LINE_BREAKS 2017-06-14 11:28:57 +02:00
Andrius Semionovas
839141e4f6 Stop formatting line breaks between keywords and parentheses 2017-06-14 11:28:57 +02:00
Andrius Semionovas
c6acc4c5be KT-16558 Add space before parentheses config 2017-06-14 11:28:57 +02:00
Mikhael Bogdanov
c4fc0f3808 Review fixes 2017-06-14 10:34:25 +02:00
Mikhael Bogdanov
724ac3cf59 Convert text util methods to extension properties 2017-06-14 10:34:24 +02:00
Mikhael Bogdanov
e96d2212da Workaround for LightClass generation problem KT-18419 2017-06-14 10:34:24 +02:00
Mikhael Bogdanov
c8d3553a31 Rename InlineCodegenUtil.kt to inlineCodegenUtils.kt 2017-06-14 10:34:23 +02:00
Mikhael Bogdanov
bbb2b36794 Merge InlineCodegeUtil and InlineCodegeUtils 2017-06-14 10:34:22 +02:00
Mikhael Bogdanov
172a9c7e1e Code clean after convertion 2017-06-14 10:34:21 +02:00
Mikhael Bogdanov
51d494a271 Convert InlineCodegenUtil to Kotlin 2017-06-14 10:34:21 +02:00
Mikhael Bogdanov
b7b3b3a19c Rename InlineCodegenUtil.java to InlineCodegenUtil.kt 2017-06-14 10:34:20 +02:00
Mikhael Bogdanov
63c4794c30 Clean code after convertion 2017-06-14 10:34:19 +02:00
Mikhael Bogdanov
e6dbe87ee2 Convert InlineCodegen to Kotlin 2017-06-14 10:34:18 +02:00
Mikhael Bogdanov
7ce980815c Rename InlineCodegen.java to InlineCodegen.kt 2017-06-14 10:34:18 +02:00
Dmitry Jemerov
52cfec5bc1 Add actions for toggling type hints to list of irrelevant actions
They are available in many tests and only starting with  the 172 branch,
 so we ignore them to reduce clutter and branch divergence.
2017-06-13 19:45:39 +02:00
Nikolay Krasko
b0c82aac6a Minor: remove warnings and reformat KotlinDebuggerTestCase.java 2017-06-13 19:14:50 +03:00
Nikolay Krasko
a4f6b17559 Invalidate debugger tests caches on dist compiler updates 2017-06-13 19:14:49 +03:00
Nikolay Krasko
6d22e06359 Move all test data for single test to one directory 2017-06-13 19:14:48 +03:00
Simon Ogorodnik
75e5dca735 KT-18051: Allow copy-pasting from IDEA java to kotlin conversion
#KT-18051 fixed
2017-06-13 15:32:21 +03:00
Simon Ogorodnik
fa3f87492c KT-12104: Fix smart completion for argument of implicit invoke
#KT-12104 fixed
2017-06-13 15:32:09 +03:00
Dmitry Jemerov
8077a71aec Show more correct type hints
- Don't show hints containing error type as type parameter
 - Do not expand type aliases
 - Show base type for types of anonymous objects

 #KT-18369 Fixed
 #KT-18341 Fixed
 #KT-18343 Fixed
2017-06-13 14:26:56 +02:00
Mikhail Glukhikh
c6578384fb Minor: remove unused functions 2017-06-13 15:18:16 +03:00
Mikhail Glukhikh
ada697c6b0 Highlighting visitor: make holder immutable 2017-06-13 15:18:10 +03:00
Mikhail Glukhikh
945859ae4d Remove non-actual suppress 2017-06-13 15:18:05 +03:00
Mikhail Glukhikh
d5e605d5cc Distinguish captured highlighting from local variable / parameter
So #KT-14271 Fixed
2017-06-13 15:17:59 +03:00
Mikhail Glukhikh
aa3589004e Highlighting visitor: refactoring
Do not call AnnotationHolder functions directly,
only via HighlightingVisitor
2017-06-13 15:17:53 +03:00
Mikhail Glukhikh
f225d8dea5 J2K: HighlightingVisitor, AfterAnalysisHighlightingVisitor 2017-06-13 15:17:48 +03:00
Mikhail Glukhikh
44e727b75c Redundant toString() in string template: highlight selector only
And not the receiver. So #KT-18253 Fixed
2017-06-13 15:17:42 +03:00
Toshiaki Kameyama
2afe8989df Make <modifier> intention handle sealed correctly #KT-18425 Fixed 2017-06-13 15:02:36 +03:00
Dmitry Jemerov
a6d80b78de Fix tests 2017-06-13 13:04:11 +02:00
Vasily Kirichenko
6829c5ef8f add a test 2017-06-13 13:04:10 +02:00
Vasily Kirichenko
0381018d00 add the check into CanBePrimaryConstructorPropertyInspection as well 2017-06-13 13:04:10 +02:00
Vasily Kirichenko
c0ee50a693 do not show "Move to constructor" intention for properties declared in interfaces 2017-06-13 13:04:09 +02:00
Dmitry Jemerov
b9cfb6b59b typo 2017-06-12 19:20:12 +02:00
Dmitry Jemerov
2d9bf73049 Sort plugins before uploading 2017-06-12 19:02:20 +02:00
Toshiaki Kameyama
ac03c91dcc Make <modifier> intention inserts modifier between annotation and class keywords #KT-14092 Fixed 2017-06-12 18:32:35 +02:00
Alexey Sedunov
79493985be Kotlin Facet: Fix facet existence check during Gradle import
EA-101476 Fixed
2017-06-12 16:37:41 +03:00
Simon Ogorodnik
a371bcb624 Fix flaky kdoc lexer test
Normalize line separators
2017-06-11 18:13:49 +03:00
Ilya Gorbunov
4798c029de Limit visibility of sublists, make them implement RandomAccess 2017-06-10 10:00:15 +03:00
Ilya Gorbunov
d7ad1f3950 Explicitly disable ArrayLiteralsInAnnotations feature in test which validates it's unsupported 2017-06-10 10:00:15 +03:00
Anton Bannykh
46d9d296ca JS: use '/' as separator on all platforms to prevent sourcemap parse errors 2017-06-09 20:32:22 +03:00
Alexey Sedunov
3b15285a0c Analyze Data Flow: Add usage context panels 2017-06-09 17:19:23 +03:00
Alexey Sedunov
ff5a52b445 Analyze Data Flow: Respect member hierarchies
#KT-11994 In Progress
2017-06-09 17:19:22 +03:00
Alexey Sedunov
49da81f681 Analyze Data Flow: Support val/var parameters
#KT-11994 In Progress
2017-06-09 17:19:20 +03:00
Alexey Sedunov
ea7d535ae7 Analyze Data Flow: Support properties with custom accessors
#KT-11994 In Progress
2017-06-09 17:19:20 +03:00
Alexey Sedunov
d61ddaccb6 Analyze Data Flow: Support callable references
#KT-11994 In Progress
2017-06-09 17:19:18 +03:00
Alexey Sedunov
3f411fc93b Analyze Data Flow: Support lambdas/anonymous functions
#KT-11994 In Progress
2017-06-09 17:19:18 +03:00
Alexey Sedunov
0f44dd6ab0 Analyze Data Flow: Support dereference processing
#KT-11994 In Progress
2017-06-09 17:19:16 +03:00
Alexey Sedunov
858b454138 Analyze Data Flow: Initial implementation
#KT-11994 In Progress
2017-06-09 17:19:15 +03:00
Dmitry Neverov
3f104833ba Handle multi-line spaces and leading asterisks more correctly 2017-06-09 17:14:28 +03:00
Sergey Igushkin
0453c4a7bf Fix Android SDK licenses not being accepted in Kapt3AndroidIT
(cherry picked from commit 8084ac6)
2017-06-09 16:38:09 +03:00
Mikhail Glukhikh
630af6a9c6 Correct 1.1-specific test to fix 1.2-M1 build 2017-06-09 13:10:37 +03:00
Valentin Kipyatkov
ca7a0da10f Fixed one more case of redundant type arguments 2017-06-08 23:26:39 +03:00
Valentin Kipyatkov
4b0cbc61d1 More correct 2017-06-08 23:26:38 +03:00
Valentin Kipyatkov
c08d862e9e More correct algorithm for redundant type arguments detection 2017-06-08 23:26:38 +03:00
Valentin Kipyatkov
cfa442a42a Move refactoring available on cut/paste declarations from an object to top-level 2017-06-08 23:26:12 +03:00
Dmitry Jemerov
b143b1be42 Revert tesdata changes to match changed code behavior 2017-06-08 19:48:12 +02:00
fitermay
4fab29b648 KT-18006 Don't cut off trailing new lines. Make behavior consistent with Java literal copy/paste 2017-06-08 19:48:12 +02:00
fitermay
a63d631435 KT-18006 Bring behavior of Kotlin literal copy/paste inline with Java's after IDEA-172984 2017-06-08 19:48:12 +02:00
Nikolay Krasko
ba34ed89d3 Allow to report exceptions in internal mode when updates are available 2017-06-08 17:21:13 +03:00
Toshiaki Kameyama
c149e956cc Replace explicit parameter isn't shown on destructuring declaration
So #KT-17026 Fixed
2017-06-08 16:32:54 +03:00
Alexey Sedunov
e5717d3e96 Copy: Enable file copy for mixed Java-Kotlin case
Also merge CopyKotlinFileHandler with CopyKotlinDeclarationsHandler
as it currently can't be invoked for such cases

 #KT-18200 Fixed
2017-06-08 14:37:37 +03:00
Alexey Sedunov
13212f06b4 Copy/Move: Fix processing of imported Java static members
#KT-18098 Fixed
2017-06-08 14:37:37 +03:00
Alexey Sedunov
a0629bfc58 Rename: Fix rename of import alias referring to object member
#KT-18096 Fixed
2017-06-08 14:37:35 +03:00
Alexey Sedunov
1ded171720 Rename: Disable member inplace when variable inplace is available 2017-06-08 14:37:34 +03:00
Alexey Sedunov
69c315443a Rename: Disable label rename outside of reference range
#KT-17128 Fixed
2017-06-08 14:37:34 +03:00
Alexey Sedunov
566e701131 Rename: Disable Java member rename by reference to import alias
#KT-18076 Fixed
2017-06-08 14:37:32 +03:00
Alexey Sedunov
9c11c42ec2 Rename: Fix inplace refactoring for declarations with backticked names
#KT-15859 Fixed
2017-06-08 14:37:31 +03:00
Alexey Sedunov
2f88b6ef9b Copy: Rename only self-usages of the copied class
#KT-18034 Fixed
2017-06-08 14:37:30 +03:00
Alexey Andreev
4252d9786b Fix translation of interface with non-abstract methods in JS BE
Fix additional case of generic interfaces in KT-18187
2017-06-08 13:51:18 +03:00
Alexander Udalov
09e4775a10 REPL: display configuration-related messages after start
Previously these messages (e.g. non-existing jar path in classpath,
invalid language version, etc.) were shown after the user exited from
the REPL
2017-06-08 12:28:07 +03:00
Alexander Udalov
cbb6269391 REPL: do not report warnings when there are errors
#KT-18349 Fixed
2017-06-08 12:28:06 +03:00
Alexander Udalov
ed922deb93 REPL: do not output additional newline after compiler and runtime errors 2017-06-08 12:28:05 +03:00
Alexander Udalov
bd9dd90649 REPL: print newline before exit
No tests added because the only way to test this seems to be to launch a
new process and send "Ctrl+D" into it, which seems cumbersome for such
small change
2017-06-08 12:28:04 +03:00
Alexander Udalov
6f22baa0f6 REPL: improve "are all errors at EOF" detection
Also ignore whitespaces and comments that appear after the last error in
a REPL line

 #KT-15172 Fixed
2017-06-08 12:26:54 +03:00
Dmitry Jemerov
2326b5faf3 Update testdata according to behavior changes 2017-06-08 10:43:19 +02:00
Toshiaki Kameyama
d90cc6f4cf Intention Make private and friends should respect modifier order #KT-17823 Fixed 2017-06-08 10:41:07 +02:00
Mikhael Bogdanov
5dfe77b7c3 Fix array element processing 2017-06-08 09:23:50 +02:00
Mikhael Bogdanov
5bba5b2fb7 Bind annotation methods via primary constructor 2017-06-08 09:23:45 +02:00
Mikhael Bogdanov
514d25bdd4 Fix FAKE_OVERRIDE processing 2017-06-08 09:23:39 +02:00
imknown J. Kimu
317e24ce69 Fix Git CLI typo. (#1119)
No soft-wrapped words.
2017-06-08 08:28:06 +02:00
Simon Ogorodnik
a6e153312c Prevent early deleting of not-null assertions
Before val to var conversion applied, smart-cast can cause
dropping not-null assertion, which will be required when val will
become var
2017-06-07 21:21:37 +03:00
Simon Ogorodnik
e41c027c9a Add IDEA data-flow analysis to guess nullability
Add "if return..." folding to "return if"
2017-06-07 21:21:36 +03:00
Simon Ogorodnik
1f26353de4 Add measureTimeMillisWithResult function to addToStdlib 2017-06-07 21:21:34 +03:00
Simon Ogorodnik
682a278cb8 Fix deleting of semicolon when it required to mark statement empty
#KT-18142 fixed
#KT-18141 fixed
2017-06-07 21:08:08 +03:00
Dmitry Jemerov
558203e2bb Rename "Remove no constructor" to "Remove constructor call"; fix test 2017-06-07 19:49:45 +02:00
Toshiaki Kameyama
bb5681fdb5 Add quick-fix for NO_CONSTRUCTOR error #KT-17842 Fixed 2017-06-07 19:47:36 +02:00
Ilya Zorin
862631b2ec Handle spaces around dot in type references and before type argument list 2017-06-07 19:43:14 +02:00
Andrius Semionovas
4acb95acb5 Fix KT-16725; Remove spaces between array indices 2017-06-07 19:39:55 +02:00
Zoltan Polgar
46ce9a6946 JS: Avoid declaration skeleton body generation in case of external class or object 2017-06-07 19:22:24 +02:00
Alexander Udalov
15e392bbd1 Fix compilation on Windows
JDK_16 environment variable may have spaces in it ("C:\Program
Files\..."), so it should be passed as a separate argument explicitly to
the kotlinc ant task
2017-06-07 16:26:09 +03:00
Alexander Udalov
c851e9d206 CLI: use JDK 1.6 to compile the "kotlin" launcher script
"kotlin" is used to run programs compiled by "kotlinc" which supports
emitting JVM bytecode 1.6, so it should also be runnable on JDK 1.6
2017-06-07 14:57:44 +03:00
Alexander Udalov
96bd8cb3c2 Minor, move PluginCliParser and PluginURLClassLoader to subpackage 2017-06-07 14:56:58 +03:00
Alexander Udalov
534e8a5c50 Do not pack useless files into the compiler jar
Do not pack META-INF/services to compiler-quick from out directories
because they're packed from sources anyway in the pack-compiler target.
Also do not pack the "META-INF/jb/$$size$$" and "META-INF/LICENSE" files
found in some IntelliJ libraries. Licenses are not required in binaries,
and previously only the first of them was packed anyway
2017-06-07 14:41:13 +03:00
Alexander Udalov
a614419b43 Fix KotlinJpsBuildTest.testHelp on Windows 2017-06-07 14:17:35 +03:00
Alexander Udalov
4844d720cc Remove dependency of module 'java-model-wrappers' on 'annotation-processing'
This breaks the circular dependency between them
2017-06-07 14:06:01 +03:00
Nikolay Krasko
0e693c39a3 Don't remove else block if it participate in other expression (KT-18309)
#KT-18309 Fixed
2017-06-07 13:49:34 +03:00
Dmitry Jemerov
5c993ce83f Fix Slack link 2017-06-07 11:58:00 +02:00
Pavel V. Talanov
2b153d5c10 Improve search for facade light class by kotlin file
LightClassUtil#getWrappingClass works for clashing facade fq names

 #KT-17855 Fixed
2017-06-07 11:19:23 +03:00
Mikhail Glukhikh
417b430033 Test reproducing KT-17855 2017-06-07 11:19:23 +03:00
Alexey Andreev
59240a4bd9 Report errors in JS source maps as compiler warnings 2017-06-07 11:13:55 +03:00
Alexey Andreev
bf21cfd6e0 Use source map remapper in JS inliner 2017-06-07 11:13:55 +03:00
Alexey Andreev
9c4ec902b0 Fix test broken by changes in JS source maps 2017-06-07 11:13:54 +03:00
Alexey Andreev
e43cc65702 Fix location reported by JS parser in case of long lines 2017-06-07 11:13:54 +03:00
Alexey Andreev
1dae687e7d Fix support of - and + prefix operators in JS parser
Treat number literal that represents minimum integer as integer node in
JS AST.

Treat +<number_literal> JS AST as unary node (+) containing single
number literal
2017-06-07 11:13:53 +03:00
Alexey Andreev
590954e9a8 Add processor that removes location from ambiguous JS AST nodes
There are cases when it's impossible to distinguish which JS node
owns location denoted by source map. Consider example:

a + b

Both root JsBinaryNode and its arg1 point to the same start location.
Out translator provides full information, though parser can't
produce the same AST. The second AST will miss some of the locations
available on the first one. This processor gets AST node produced
by translator and removes locations from there so that both ASTs
become equal.
2017-06-07 11:13:53 +03:00
Alexey Andreev
c5bf76578a Add test infrastructure for JS source map parser and generator 2017-06-07 11:13:52 +03:00
Alexey Andreev
ca738a9536 Prevent JS source map builder from inserting overlapping mappings
Check if newly inserted mapping is in the same position within
JS line and in this case omit the mapping
2017-06-07 11:13:51 +03:00
Alexey Andreev
174068c462 Add JS source map parser and remapper
JS source map remapper takes parsed source maps
together with JS AST with correct JS positioning information
and converts the latter into Kotlin positioning information
2017-06-07 11:13:51 +03:00
Alexey Andreev
e784d1846e Fix warning in BasicBoxTest (JS) 2017-06-07 11:13:50 +03:00
Alexey Andreev
93ec81d2eb Add source information to parsed JS AST 2017-06-07 11:13:50 +03:00
Alexey Andreev
1d1da326be Refactor JS parser 2017-06-07 11:13:49 +03:00
Alexey Andreev
3a3720db8d Reformat JS parser for conformance with project's style settings 2017-06-07 11:13:49 +03:00
Alexey Andreev
41ad637bad Fix warnings in JS parser 2017-06-07 11:13:48 +03:00
Alexey Andreev
9d186cfc66 Fix JS source maps for temporary variables 2017-06-07 11:13:47 +03:00
Alexey Andreev
27a44f3282 Fix JS source maps for complex enum entry 2017-06-07 11:13:47 +03:00
Alexey Andreev
b70c52e41f Fix JS source maps for optional arguments
Also, when function has expression body, use expression instead
of function declaration to mark return statement.
2017-06-07 11:13:46 +03:00
Alexey Andreev
6f0e4c4deb Fix JS source maps for data class synthetic methods 2017-06-07 11:13:46 +03:00
Alexey Andreev
5bc6c07f9e Fix JS source maps for companion objects of enum 2017-06-07 11:13:45 +03:00
Alexey Andreev
c9545f291a Fix JS source maps for properties without initializer 2017-06-07 11:13:44 +03:00
Vyacheslav Gerasimov
fdf098d65c Add gutter icon with navigation to related files for Android components 2017-06-06 20:47:30 +03:00
Vyacheslav Gerasimov
3f03b05bd3 Fix Android gutterIcon test, use findGuttersAtCaret method 2017-06-06 20:47:21 +03:00
Vyacheslav Gerasimov
643e3587cc Kotlin UAST should visit property delegate expression
#KT-15164 Fixed
2017-06-06 20:47:01 +03:00
Vyacheslav Gerasimov
15bfd4439a Fix AddTargetVersionCheckQuickFix, generate else branch with TODO
when surrounded statement used as expression

#KT-17786 Fixed
#KT-17788 Fixed
2017-06-06 20:46:53 +03:00
Vyacheslav Gerasimov
33c3ba815f Fix Android SuppressLint and Api quickfixes: proper annotation placing
#KT-17783 Fixed
 #KT-17787 Fixed
2017-06-06 20:46:40 +03:00
Alexander Udalov
e6001f57fa Remove dependency of module 'backend' on 'backend.jvm' and 'ir.tree'
This breaks the circular dependency between 'backend' and 'backend.jvm'
2017-06-06 19:55:06 +03:00
Alexander Udalov
cf04157ec8 Ignore gradle build directories in the root module 2017-06-06 19:52:43 +03:00
Alexander Udalov
5e6db3d4a6 Fix broken source and class roots of project libraries 2017-06-06 19:52:42 +03:00
Alexander Udalov
fb520e3040 Maven: do not set JVM target to null
After a236400, it's expected that the value of jvmTarget should not be
null. Otherwise ArgumentUtils.convertArgumentsToStringList fails with
NPE
2017-06-06 19:52:04 +03:00
Alexander Udalov
a802e7fb71 CLI: fix non-XML rendering of argument parse error, simplify code
If the compiler is invoked through JPS, an instance of
XmlMessageRenderer is used and the output should be a valid XML.
Previously, we reported the argument parse error (and the note to try
"-help") before calling messageRenderer.renderPreamble, which resulted
in invalid XML. The same was happening for the usage printed on "-help".
Both of these problems are fixed

 #KT-14848 Fixed
2017-06-06 19:52:04 +03:00
Alexander Udalov
a67382fdec Daemon: do not exit with internal error on invalid arguments
Invalid compiler arguments should lead to a compilation error, not
internal error. This has been fixed by splitting the
"parseArguments(...)" call (which does parsing + validation) in
CompileServiceImpl into two calls of parseCommandLineArguments +
validateArguments, and returning with a compilation error if the latter
did not succeed

 #KT-16057 Fixed
 #KT-14848 In Progress
2017-06-06 19:52:02 +03:00
Sergey Igushkin
2cad64881d (minor) Improve exception message in case no Android plugin was found 2017-06-06 17:21:20 +03:00
Sergey Igushkin
21b88995ab Add tests for the introduced fixes
Add a test for applying kotlin-android plugin with com.android.feature

Add a test for Databinding (not passing yet with 3.0.0+, until
3.0.0-alpha4 is released, which contains the fix from the Android side).

Add missing test project android-databinding.

Refactor and improve the tests

* Remove redundant files from test project 'android-databinding'
* Refactoring and minor improvements in the tests
2017-06-06 17:21:20 +03:00
Sergey Igushkin
483218e491 Fix for the Databinding issue where the kapt task started to early, not
letting the Databinding pre-process the project.
2017-06-06 17:21:20 +03:00
Sergey Igushkin
f053d79994 Add support for com.android.feature plugin. 2017-06-06 17:21:20 +03:00
Pavel V. Talanov
bdf76f23c4 Jvm Codegen: do not throw on malformed delegation to a type parameter
Fix exception on light class building

See KT-15931
2017-06-06 17:11:19 +03:00
Pavel V. Talanov
19db4304bd Use clsDelegate to calculate hasModifierProperty("final") for light psi
AllOpen plugin can make some changes and we don't have the tools to make
    correct decision based on psi

 #KT-17857 Fixed
2017-06-06 17:11:18 +03:00
Pavel V. Talanov
f3f2379e5a KtLightMemberModifierList:hasExplicitModifier("default") returns false
#KT-18070 Fixed
2017-06-06 17:11:17 +03:00
Mikhail Glukhikh
f54267eab4 Revert 'configureSilently' removal 2017-06-06 16:14:50 +03:00
Nikolay Krasko
0980446836 Fix running Android tests locally on windows 2017-06-06 14:56:22 +03:00
Nikolay Krasko
45958e630d Refactoring: move method 2017-06-06 14:56:21 +03:00
Nikolay Krasko
cb4c840d3b Remote old tasks for fetching continuous branches 2017-06-06 14:56:21 +03:00
Alexander Udalov
6a4c1b138f Remove dependency of module 'cli' on 'builtins-serializer'
This breaks the circular dependency between them
2017-06-06 14:29:27 +03:00
Alexander Udalov
7febd846e8 Export 'intellij-core' in module 'frontend'
Remove intellij-core from dependencies of modules which already depend
on frontend or any module that exports frontend (such as frontend.java)
2017-06-06 14:29:26 +03:00
Alexander Udalov
2ed027219c Remove dependency of module 'frontend' on 'plugin-api'
This breaks the circular dependency between them
2017-06-06 14:29:25 +03:00
Alexander Udalov
cc2f607be3 Remove dependency of module 'frontend.java' on 'javac-wrapper'
This breaks the circular dependency between them
2017-06-06 14:29:24 +03:00
Alexander Udalov
1df13e0bc9 Move TopDownAnalyzerFacadeForJVM to module 'cli'
It's only used in the command line compiler and in tests
2017-06-06 14:29:23 +03:00
Alexander Udalov
f6c263b54d Remove dependency of module 'javac-wrapper' on 'cli' and 'cli-common'
This breaks the circular dependency between them
2017-06-06 14:29:22 +03:00
Alexander Udalov
1273ac9647 Remove dependency of module 'descriptors' on 'deserialization' 2017-06-06 14:29:21 +03:00
Alexander Udalov
751ff48301 Extract logic of builtins package fragment provider creation
This allows to drop the compile dependency of module 'descriptors' on
'deserialization', breaking the circular dependency between them
2017-06-06 14:29:20 +03:00
Alexander Udalov
1728b77b2c Minor, refactor createBuiltInsPackageFragmentProvider 2017-06-06 14:29:19 +03:00
Alexander Udalov
cbaa676c3d Move some declarations between 'descriptors' and 'deserialization'
- Move the following from 'deserialization' to 'descriptors':
  NotFoundClasses.kt
  AdditionalClassPartsProvider.kt
  ClassDescriptorFactory.kt
  PlatformDependentDeclarationFilter.kt
  findClassInModule.kt
- Move the following form 'descriptors' to 'deserialization':
  BuiltInSerializerProtocol.kt
  builtInsPackageFragmentProvider.kt
- Extract a marker interface from BuiltInsPackageFragment and move its
  implementation to 'deserialization'
- Change the type of parameters in PlatformDependentDeclarationFilter
  and AdditionalClassPartsProvider to ClassDescriptor

This will help in getting rid of the circular dependency of
'descriptors' <-> 'deserialization'
2017-06-06 14:29:18 +03:00
Alexander Udalov
a4931568ba Relocate service definition files for kotlin-reflect
See
http://imperceptiblethoughts.com/shadow/#merging_service_descriptor_files

 #KT-16810 Fixed
2017-06-06 14:29:17 +03:00
Alexander Udalov
2b878f863c CLI: report error if kotlinc is invoked on Java 6 or 7
#KT-17297 Fixed
2017-06-06 14:17:28 +03:00
Alexander Udalov
ea9194e1fb CLI: compile preloader against JDK 1.6
To be able to detect the Java runtime version at startup to report an
error if it's < 1.8
2017-06-06 14:17:27 +03:00
Alexander Udalov
a236400785 CLI: drop CommonCompilerArguments.createDefaultInstance
Move the corresponding default value initializers to the field
declarations
2017-06-06 14:17:26 +03:00
Alexander Udalov
26e3d2cf5d Use TopLevelDeclarations analysis mode in REPL
#KT-12564 Fixed
2017-06-06 14:00:45 +03:00
Alexey Andreev
b6d12fe7f3 Fix bug in re-importing modules from inline declarations in JS
Fix another case in KT-18201
2017-06-06 13:36:19 +03:00
Alexey Andreev
67f9474e2e Update changelog for 1.1.3 2017-06-06 11:40:36 +03:00
Dmitry Petrov
fd1866b838 Do not check argumentMapping.isError()
Argument matching status can be considered an "error" in resolve,
even though it is not a compilation error and doesn't prevent code
from being generated.
Actually, we should only check if the argument matching status is
ArgumentMatch.

 #KT-18294 Fixed
2017-06-06 10:19:18 +03:00
Dmitry Neverov
e2aa3518df Property accessor isn't recursive when called on another object
So #KT-18120 Fixed
2017-06-05 19:42:44 +03:00
Mikhail Glukhikh
ecfc2236a6 Fix script properties kind in modifier checker #KT-18234 Fixed 2017-06-05 17:22:11 +03:00
Mikhail Glukhikh
29f25ebeb9 Fix of JUnitMembersSearcherTest.testJunit3 2017-06-05 16:57:10 +03:00
5959 changed files with 98866 additions and 30913 deletions

View File

@@ -72,6 +72,7 @@
</element>
<element id="archive" name="android-extensions-compiler.jar">
<element id="module-output" name="android-extensions-compiler" />
<element id="module-output" name="android-extensions-runtime" />
</element>
<element id="archive" name="android-lint.jar">
<element id="module-output" name="uast-kotlin" />
@@ -105,6 +106,7 @@
<element id="library" level="project" name="uast-java" />
<element id="library" level="project" name="kotlinx-coroutines-core" />
<element id="library" level="project" name="javaslang" />
<element id="library" level="project" name="kotlinx-coroutines-jdk8" />
</element>
<element id="directory" name="kotlinc">
<element id="dir-copy" path="$PROJECT_DIR$/dist/kotlinc" />

9
.idea/libraries/android_layoutlib.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="android-layoutlib">
<CLASSES>
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/android/lib/layoutlib.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -6,7 +6,6 @@
<CLASSES>
<root url="file://$PROJECT_DIR$/ideaSDK/plugins/android/lib" />
<root url="file://$PROJECT_DIR$/ideaSDK/plugins/android/lib/jps" />
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/android-common.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>

View File

@@ -3,7 +3,6 @@
<CLASSES>
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/coverage/lib/coverage.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/coverage/lib/jacocoant.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/coverage/lib/coverage-agent.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>

View File

@@ -18,12 +18,14 @@
<root url="jar://$PROJECT_DIR$/ideaSDK/core/util.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/core/xpp3-1.1.4-min.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/core/xstream-1.4.8.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/jsr305.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/guava-19.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
<root url="jar://$PROJECT_DIR$/dependencies/asm-src.zip!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/jsr305.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -9,17 +9,6 @@
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/antLayout/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/jps-builders/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/jps-builders/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/jps-launcher/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-api/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-impl/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-impl/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-serialization/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/model-serialization/testSrc" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/plugin-system/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/jps/standalone-builder/src" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/jps" recursive="false" />
</library>

9
.idea/libraries/json_org.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="json-org">
<CLASSES>
<root url="jar://$PROJECT_DIR$/dependencies/json-org.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

View File

@@ -4,6 +4,9 @@
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
<SOURCES>
<root url="file://$PROJECT_DIR$/core/reflection.jvm/src" />
<root url="file://$PROJECT_DIR$/core/descriptors.runtime/src" />
</SOURCES>
</library>
</component>

View File

@@ -1,13 +1,13 @@
<component name="libraryTable">
<library name="kotlin-test">
<CLASSES>
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-test.jar!/"/>
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-test.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/shared/src/main/kotlin" />
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/shared/src/main/kotlin.jvm" />
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/junit/src/main/kotlin" />
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/common/src/main/kotlin" />
<root url="file://$PROJECT_DIR$/libraries/kotlin.test/jvm/src/main/kotlin" />
</SOURCES>
</library>
</component>

View File

@@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="kotlinx-coroutines-jdk8">
<CLASSES>
<root url="jar://$PROJECT_DIR$/dependencies/kotlinx-coroutines-jdk8.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/kotlinx-coroutines-jdk8-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -7,11 +7,6 @@
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/trove4j.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/src/trove4j_src.jar!/core/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/src/trove4j_src.jar!/generated/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/src/trove4j_src.jar!/test/src" />
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/src/trove4j_src.jar!/util/src" />
</SOURCES>
<SOURCES />
</library>
</component>

13
.idea/modules.xml generated
View File

@@ -9,11 +9,11 @@
<module fileurl="file://$PROJECT_DIR$/plugins/android-extensions/android-extensions-compiler/android-extensions-compiler.iml" filepath="$PROJECT_DIR$/plugins/android-extensions/android-extensions-compiler/android-extensions-compiler.iml" group="plugins/android-extensions" />
<module fileurl="file://$PROJECT_DIR$/plugins/android-extensions/android-extensions-idea/android-extensions-idea.iml" filepath="$PROJECT_DIR$/plugins/android-extensions/android-extensions-idea/android-extensions-idea.iml" group="plugins/android-extensions" />
<module fileurl="file://$PROJECT_DIR$/plugins/android-extensions/android-extensions-jps/android-extensions-jps.iml" filepath="$PROJECT_DIR$/plugins/android-extensions/android-extensions-jps/android-extensions-jps.iml" group="plugins/android-extensions" />
<module fileurl="file://$PROJECT_DIR$/plugins/android-extensions/android-extensions-runtime/android-extensions-runtime.iml" filepath="$PROJECT_DIR$/plugins/android-extensions/android-extensions-runtime/android-extensions-runtime.iml" group="plugins/android-extensions" />
<module fileurl="file://$PROJECT_DIR$/android-studio/android-studio.iml" filepath="$PROJECT_DIR$/android-studio/android-studio.iml" group="ide" />
<module fileurl="file://$PROJECT_DIR$/compiler/android-tests/android-tests.iml" filepath="$PROJECT_DIR$/compiler/android-tests/android-tests.iml" group="compiler" />
<module fileurl="file://$PROJECT_DIR$/plugins/annotation-based-compiler-plugins-ide-support/annotation-based-compiler-plugins-ide-support.iml" filepath="$PROJECT_DIR$/plugins/annotation-based-compiler-plugins-ide-support/annotation-based-compiler-plugins-ide-support.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/annotation-collector/annotation-collector.iml" filepath="$PROJECT_DIR$/plugins/annotation-collector/annotation-collector.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/plugins/annotation-processing/annotation-processing.iml" filepath="$PROJECT_DIR$/plugins/annotation-processing/annotation-processing.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/ant/ant.iml" filepath="$PROJECT_DIR$/ant/ant.iml" />
<module fileurl="file://$PROJECT_DIR$/compiler/backend/backend.iml" filepath="$PROJECT_DIR$/compiler/backend/backend.iml" group="compiler/java" />
<module fileurl="file://$PROJECT_DIR$/compiler/backend-common/backend-common.iml" filepath="$PROJECT_DIR$/compiler/backend-common/backend-common.iml" group="compiler" />
@@ -63,7 +63,6 @@
<module fileurl="file://$PROJECT_DIR$/compiler/ir/ir.psi2ir/ir.psi2ir.iml" filepath="$PROJECT_DIR$/compiler/ir/ir.psi2ir/ir.psi2ir.iml" group="compiler/ir" />
<module fileurl="file://$PROJECT_DIR$/compiler/ir/ir.tree/ir.tree.iml" filepath="$PROJECT_DIR$/compiler/ir/ir.tree/ir.tree.iml" group="compiler/ir" />
<module fileurl="file://$PROJECT_DIR$/j2k/j2k.iml" filepath="$PROJECT_DIR$/j2k/j2k.iml" group="j2k" />
<module fileurl="file://$PROJECT_DIR$/plugins/java-model-wrappers/java-model-wrappers.iml" filepath="$PROJECT_DIR$/plugins/java-model-wrappers/java-model-wrappers.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/compiler/javac-wrapper/javac-wrapper.iml" filepath="$PROJECT_DIR$/compiler/javac-wrapper/javac-wrapper.iml" group="compiler" />
<module fileurl="file://$PROJECT_DIR$/jps-plugin/jps-plugin.iml" filepath="$PROJECT_DIR$/jps-plugin/jps-plugin.iml" group="ide/jps" />
<module fileurl="file://$PROJECT_DIR$/jps-plugin/jps-tests/jps-tests.iml" filepath="$PROJECT_DIR$/jps-plugin/jps-tests/jps-tests.iml" group="ide/jps" />
@@ -76,14 +75,14 @@
<module fileurl="file://$PROJECT_DIR$/js/js.tests/js.tests.iml" filepath="$PROJECT_DIR$/js/js.tests/js.tests.iml" group="compiler/js" />
<module fileurl="file://$PROJECT_DIR$/js/js.translator/js.translator.iml" filepath="$PROJECT_DIR$/js/js.translator/js.translator.iml" group="compiler/js" />
<module fileurl="file://$PROJECT_DIR$/jps-plugin/kannotator-jps-plugin-test/kannotator-jps-plugin-test.iml" filepath="$PROJECT_DIR$/jps-plugin/kannotator-jps-plugin-test/kannotator-jps-plugin-test.iml" group="ide/jps" />
<module fileurl="file://$PROJECT_DIR$/plugins/kapt3/kapt3.iml" filepath="$PROJECT_DIR$/plugins/kapt3/kapt3.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/kapt3/kapt3.iml" filepath="$PROJECT_DIR$/plugins/kapt3/kapt3.iml" group="plugins" />
<module fileurl="file://$PROJECT_DIR$/idea/kotlin-gradle-tooling/kotlin-gradle-tooling.iml" filepath="$PROJECT_DIR$/idea/kotlin-gradle-tooling/kotlin-gradle-tooling.iml" />
<module fileurl="file://$PROJECT_DIR$/compiler/light-classes/light-classes.iml" filepath="$PROJECT_DIR$/compiler/light-classes/light-classes.iml" group="compiler/java" />
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-api/lint-api.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-api/lint-api.iml" group="plugins/lint" />
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-checks/lint-checks.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-checks/lint-checks.iml" group="plugins/lint" />
<module fileurl="file://$PROJECT_DIR$/plugins/lint/lint-idea/lint-idea.iml" filepath="$PROJECT_DIR$/plugins/lint/lint-idea/lint-idea.iml" group="plugins/lint" />
<module fileurl="file://$PROJECT_DIR$/plugins/noarg/noarg-cli/noarg-cli.iml" filepath="$PROJECT_DIR$/plugins/noarg/noarg-cli/noarg-cli.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/noarg/noarg-ide/noarg-ide.iml" filepath="$PROJECT_DIR$/plugins/noarg/noarg-ide/noarg-ide.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/noarg/noarg-cli/noarg-cli.iml" filepath="$PROJECT_DIR$/plugins/noarg/noarg-cli/noarg-cli.iml" group="plugins/noarg" />
<module fileurl="file://$PROJECT_DIR$/plugins/noarg/noarg-ide/noarg-ide.iml" filepath="$PROJECT_DIR$/plugins/noarg/noarg-ide/noarg-ide.iml" group="plugins/noarg" />
<module fileurl="file://$PROJECT_DIR$/non-compiler-tests/non-compiler-tests.iml" filepath="$PROJECT_DIR$/non-compiler-tests/non-compiler-tests.iml" />
<module fileurl="file://$PROJECT_DIR$/compiler/plugin-api/plugin-api.iml" filepath="$PROJECT_DIR$/compiler/plugin-api/plugin-api.iml" group="compiler" />
<module fileurl="file://$PROJECT_DIR$/plugins/plugins-tests/plugins-tests.iml" filepath="$PROJECT_DIR$/plugins/plugins-tests/plugins-tests.iml" group="plugins" />
@@ -91,8 +90,8 @@
<module fileurl="file://$PROJECT_DIR$/core/reflection.jvm/reflection.jvm.iml" filepath="$PROJECT_DIR$/core/reflection.jvm/reflection.jvm.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/compiler/resolution/resolution.iml" filepath="$PROJECT_DIR$/compiler/resolution/resolution.iml" group="compiler" />
<module fileurl="file://$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" filepath="$PROJECT_DIR$/core/runtime.jvm/runtime.jvm.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-cli/sam-with-receiver-cli.iml" filepath="$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-cli/sam-with-receiver-cli.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-ide/sam-with-receiver-ide.iml" filepath="$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-ide/sam-with-receiver-ide.iml" />
<module fileurl="file://$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-cli/sam-with-receiver-cli.iml" filepath="$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-cli/sam-with-receiver-cli.iml" group="plugins/sam-with-receiver" />
<module fileurl="file://$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-ide/sam-with-receiver-ide.iml" filepath="$PROJECT_DIR$/plugins/sam-with-receiver/sam-with-receiver-ide/sam-with-receiver-ide.iml" group="plugins/sam-with-receiver" />
<module fileurl="file://$PROJECT_DIR$/core/script.runtime/script.runtime.iml" filepath="$PROJECT_DIR$/core/script.runtime/script.runtime.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/compiler/serialization/serialization.iml" filepath="$PROJECT_DIR$/compiler/serialization/serialization.iml" group="compiler" />
<module fileurl="file://$PROJECT_DIR$/plugins/source-sections/source-sections-compiler/source-sections-compiler.iml" filepath="$PROJECT_DIR$/plugins/source-sections/source-sections-compiler/source-sections-compiler.iml" group="plugins" />

View File

@@ -13,7 +13,7 @@
<option name="MAIN_CLASS_NAME" value="org.jetbrains.kotlin.codegen.CodegenJdkCommonTestSuite" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-Dkotlin.test.default.jvm.target=1.6 -ea -XX:+HeapDumpOnOutOfMemoryError -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.desktop/javax.swing=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED" />
<option name="VM_PARAMETERS" value="-Dkotlin.test.default.jvm.target=1.6 -ea -XX:+HeapDumpOnOutOfMemoryError -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true --add-opens java.desktop/javax.swing=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />

View File

@@ -13,7 +13,7 @@
<option name="MAIN_CLASS_NAME" value="org.jetbrains.kotlin.codegen.CodegenJdkCommonTestSuite" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-Dkotlin.test.default.jvm.target=1.8 -ea -XX:+HeapDumpOnOutOfMemoryError -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.desktop/javax.swing=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED" />
<option name="VM_PARAMETERS" value="-Dkotlin.test.default.jvm.target=1.8 -ea -XX:+HeapDumpOnOutOfMemoryError -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true --add-opens java.desktop/javax.swing=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />

View File

@@ -13,7 +13,7 @@
<option name="MAIN_CLASS_NAME" value="org.jetbrains.kotlin.codegen.CodegenJdkCommonTestSuite" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="class" />
<option name="VM_PARAMETERS" value="-Dkotlin.test.default.jvm.target=1.8 -Dkotlin.test.substitute.bytecode.1.8.to.1.9=true -ea -XX:+HeapDumpOnOutOfMemoryError -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.desktop/javax.swing=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.util.concurrent.atomic=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED" />
<option name="VM_PARAMETERS" value="-Dkotlin.test.default.jvm.target=1.8 -Dkotlin.test.substitute.bytecode.1.8.to.1.9=true -ea -XX:+HeapDumpOnOutOfMemoryError -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true --add-opens java.desktop/javax.swing=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />

View File

@@ -8,7 +8,7 @@
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx1250m -XX:+UseCodeCacheFlushing -Djna.nosys=true -Dkotlin.js.generateThreshold=true" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx1250m -XX:+UseCodeCacheFlushing -Djna.nosys=true -Dkotlin.js.skipMinificationTest=false" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />

View File

@@ -3,9 +3,400 @@
<!-- Find: ([^\`/\[])(KT-\d+) -->
<!-- Replace: $1[`$2`](https://youtrack.jetbrains.com/issue/$2) -->
## 1.1.3
## 1.1.4-EAP-11
### Android
- [`KT-11048`](https://youtrack.jetbrains.com/issue/KT-11048) Android Extensions: cannot evaluate expression containing generated properties
- [`KT-11051`](https://youtrack.jetbrains.com/issue/KT-11051) Android Extensions: completion of generated properties is unclear for ambiguous ids
- [`KT-14912`](https://youtrack.jetbrains.com/issue/KT-14912) Lint: "Code contains STOPSHIP marker" ignores suppress annotation
- [`KT-15164`](https://youtrack.jetbrains.com/issue/KT-15164) Kotlin Lint: problems in delegate expression are not reported
- [`KT-17783`](https://youtrack.jetbrains.com/issue/KT-17783) Kotlin Lint: quick fixes to add inapplicable @RequiresApi and @SuppressLint make code incompilable
- [`KT-17786`](https://youtrack.jetbrains.com/issue/KT-17786) Kotlin Lint: "Surround with if()" quick fix is not suggested for single expression `get()`
- [`KT-17787`](https://youtrack.jetbrains.com/issue/KT-17787) Kotlin Lint: "Add @TargetApi" quick fix is not suggested for top level property accessor
- [`KT-17788`](https://youtrack.jetbrains.com/issue/KT-17788) Kotlin Lint: "Surround with if()" quick fix corrupts code in case of destructuring declaration
- [`KT-17890`](https://youtrack.jetbrains.com/issue/KT-17890) [kotlin-android-extensions] Renaming layout file does not rename import
### Compiler
#### New Features
- [`KT-10942`](https://youtrack.jetbrains.com/issue/KT-10942) Support meta-annotations from JSR 305 for nullability qualifiers
- [`KT-14187`](https://youtrack.jetbrains.com/issue/KT-14187) Redundant "is" check is not detected
- [`KT-16603`](https://youtrack.jetbrains.com/issue/KT-16603) Support `inline suspend` function
- [`KT-17585`](https://youtrack.jetbrains.com/issue/KT-17585) Generate state machine for named functions in their bodies
#### Performance Improvements
- [`KT-3098`](https://youtrack.jetbrains.com/issue/KT-3098) Generate efficient comparisons
- [`KT-6247`](https://youtrack.jetbrains.com/issue/KT-6247) Optimization for 'in' and '..'
- [`KT-7571`](https://youtrack.jetbrains.com/issue/KT-7571) Don't box Double instance to call hashCode on Java 8
- [`KT-9900`](https://youtrack.jetbrains.com/issue/KT-9900) Optimize range operations for 'until' extension from stdlib
- [`KT-11959`](https://youtrack.jetbrains.com/issue/KT-11959) Unnceessary boxing/unboxing due to Comparable.compareTo
- [`KT-12158`](https://youtrack.jetbrains.com/issue/KT-12158) Optimize away boxing when comparing nullable primitive type value to primitive value
- [`KT-13682`](https://youtrack.jetbrains.com/issue/KT-13682) Reuse StringBuilder for concatenation and string interpolation
- [`KT-15235`](https://youtrack.jetbrains.com/issue/KT-15235) Escaped characters in template strings are generating inefficient implementations
- [`KT-17280`](https://youtrack.jetbrains.com/issue/KT-17280) Inline constant expressions in string templates
- [`KT-17903`](https://youtrack.jetbrains.com/issue/KT-17903) Generate 'for-in-indices' as a precondition loop
- [`KT-18157`](https://youtrack.jetbrains.com/issue/KT-18157) Optimize out trivial INSTANCEOF checks
- [`KT-18162`](https://youtrack.jetbrains.com/issue/KT-18162) Do not check nullability assertions twice for effectively same value
- [`KT-18164`](https://youtrack.jetbrains.com/issue/KT-18164) Do not check nullability for values that have been already checked with !!
- [`KT-18478`](https://youtrack.jetbrains.com/issue/KT-18478) Unnecessary nullification of bound variables
- [`KT-18558`](https://youtrack.jetbrains.com/issue/KT-18558) Flatten nested string concatenation
- [`KT-18777`](https://youtrack.jetbrains.com/issue/KT-18777) Unnecessary boolean negation generated for 'if (expr !in range)'
#### Fixes
- [`KT-1809`](https://youtrack.jetbrains.com/issue/KT-1809) Confusing diagnostics when wrong number of type arguments are specified and there are several callee candiates
- [`KT-2007`](https://youtrack.jetbrains.com/issue/KT-2007) Improve diagnostics when + in not resolved on a pair of nullable ints
- [`KT-5066`](https://youtrack.jetbrains.com/issue/KT-5066) Bad diagnostic message for ABSTRACT_MEMBER_NOT_IMPLEMENTED for (companion) object
- [`KT-5511`](https://youtrack.jetbrains.com/issue/KT-5511) Inconsistent handling of inner enum
- [`KT-7773`](https://youtrack.jetbrains.com/issue/KT-7773) Disallow to explicitly extend Enum<E> class
- [`KT-7975`](https://youtrack.jetbrains.com/issue/KT-7975) Unclear error message when redundant type arguments supplied
- [`KT-8340`](https://youtrack.jetbrains.com/issue/KT-8340) vararg in a property setter must be an error
- [`KT-8612`](https://youtrack.jetbrains.com/issue/KT-8612) Incorrect error message for var extension property without getter or setter
- [`KT-8829`](https://youtrack.jetbrains.com/issue/KT-8829) Type parameter of a class is not resolved in the constructor parameter's default value
- [`KT-8845`](https://youtrack.jetbrains.com/issue/KT-8845) Bogus diagnostic on infix operation "in"
- [`KT-9282`](https://youtrack.jetbrains.com/issue/KT-9282) Improve diagnostic on overload resolution ambiguity when a nullable argument is passed to non-null parameter
- [`KT-10045`](https://youtrack.jetbrains.com/issue/KT-10045) Not specific enough compiler error message in case of trying to call overloaded private methods
- [`KT-10164`](https://youtrack.jetbrains.com/issue/KT-10164) Incorrect error message for external inline method
- [`KT-10248`](https://youtrack.jetbrains.com/issue/KT-10248) Smart casts: Misleading error on overloaded function call
- [`KT-10657`](https://youtrack.jetbrains.com/issue/KT-10657) Confusing diagnostic when trying to invoke value as a function
- [`KT-10839`](https://youtrack.jetbrains.com/issue/KT-10839) Weird diagnostics on callable reference of unresolved class
- [`KT-11119`](https://youtrack.jetbrains.com/issue/KT-11119) Confusing error message when overloaded method is called on nullable receiver
- [`KT-12408`](https://youtrack.jetbrains.com/issue/KT-12408) Generic information lost for override values
- [`KT-13749`](https://youtrack.jetbrains.com/issue/KT-13749) Error highlighting range for no 'override' modifier is bigger than needed
- [`KT-14598`](https://youtrack.jetbrains.com/issue/KT-14598) Do not report "member is final and cannot be overridden" when overriding something from final class
- [`KT-14633`](https://youtrack.jetbrains.com/issue/KT-14633) "If must have both main and else branches" diagnostic range is too high
- [`KT-14647`](https://youtrack.jetbrains.com/issue/KT-14647) Confusing error message "'@receiver:' annotations could be applied only to extension function or extension property declarations"
- [`KT-14927`](https://youtrack.jetbrains.com/issue/KT-14927) TCE in QualifiedExpressionResolver
- [`KT-15243`](https://youtrack.jetbrains.com/issue/KT-15243) Report deprecation on usages of type alias expanded to a deprecated class
- [`KT-15804`](https://youtrack.jetbrains.com/issue/KT-15804) Prohibit having duplicate parameter names in functional types
- [`KT-15810`](https://youtrack.jetbrains.com/issue/KT-15810) destructuring declarations don't work in scripts on the top level
- [`KT-15931`](https://youtrack.jetbrains.com/issue/KT-15931) IllegalStateException: ClassDescriptor of superType should not be null: T by a
- [`KT-16016`](https://youtrack.jetbrains.com/issue/KT-16016) Compiler failure with NO_EXPECTED_TYPE
- [`KT-16448`](https://youtrack.jetbrains.com/issue/KT-16448) Inline suspend functions with inlined suspend invocations are miscompiled (VerifyError, ClassNotFound)
- [`KT-16576`](https://youtrack.jetbrains.com/issue/KT-16576) Wrong code generated with skynet benchmark
- [`KT-17007`](https://youtrack.jetbrains.com/issue/KT-17007) Kotlin is not optimizing away unreachable code based on const vals
- [`KT-17188`](https://youtrack.jetbrains.com/issue/KT-17188) Do not propose to specify constructor invocation for classes without an accessible constructor
- [`KT-17611`](https://youtrack.jetbrains.com/issue/KT-17611) Unnecessary "Name shadowed" warning on parameter of local function or local class member
- [`KT-17692`](https://youtrack.jetbrains.com/issue/KT-17692) NPE in compiler when calling KClass.java on function result of type Unit
- [`KT-17820`](https://youtrack.jetbrains.com/issue/KT-17820) False "useless cast" when target type is flexible
- [`KT-17972`](https://youtrack.jetbrains.com/issue/KT-17972) Anonymous class generated from lambda captures its outer and tries to set nonexistent this$0 field.
- [`KT-18029`](https://youtrack.jetbrains.com/issue/KT-18029) typealias not working in .kts files
- [`KT-18085`](https://youtrack.jetbrains.com/issue/KT-18085) Compilation Error:Kotlin: [Internal Error] kotlin.TypeCastException: null cannot be cast to non-null type com.intellij.psi.PsiElement
- [`KT-18115`](https://youtrack.jetbrains.com/issue/KT-18115) Generic inherited classes in different packages with coroutine causes java.lang.VerifyError: Bad local variable type
- [`KT-18189`](https://youtrack.jetbrains.com/issue/KT-18189) Incorrect generic signature generated for implementation methods overriding special built-ins
- [`KT-18234`](https://youtrack.jetbrains.com/issue/KT-18234) Top-level variables in script aren't local variables
- [`KT-18413`](https://youtrack.jetbrains.com/issue/KT-18413) Strange compiler error - probably incremental compiler
- [`KT-18486`](https://youtrack.jetbrains.com/issue/KT-18486) Superfluos generation of suspend function state-machine because of inner suspension of different coroutine
- [`KT-18598`](https://youtrack.jetbrains.com/issue/KT-18598) Report error on access to declarations from non-exported packages and from inaccessible modules on Java 9
- [`KT-18702`](https://youtrack.jetbrains.com/issue/KT-18702) Proguard warning with Kotlin 1.2-M1
- [`KT-18728`](https://youtrack.jetbrains.com/issue/KT-18728) Integer method reference application fails with CompilationException: Back-end (JVM) Internal error
- [`KT-18845`](https://youtrack.jetbrains.com/issue/KT-18845) Exception on building gradle project with collection literals
### IDE
#### New Features
- [`KT-2638`](https://youtrack.jetbrains.com/issue/KT-2638) Inline property (with accessors) refactoring
- [`KT-7107`](https://youtrack.jetbrains.com/issue/KT-7107) Rename refactoring for labels
- [`KT-9818`](https://youtrack.jetbrains.com/issue/KT-9818) Code style for method expression bodies
- [`KT-14965`](https://youtrack.jetbrains.com/issue/KT-14965) "Configure Kotlin in project" should support build.gradle.kts
- [`KT-15504`](https://youtrack.jetbrains.com/issue/KT-15504) Add code style options to limit number of blank lines
- [`KT-16558`](https://youtrack.jetbrains.com/issue/KT-16558) Code Style: Add Options for "Spaces Before Parentheses"
- [`KT-18113`](https://youtrack.jetbrains.com/issue/KT-18113) Add new line options to code style for method parameters
- [`KT-18605`](https://youtrack.jetbrains.com/issue/KT-18605) Option to not use continuation indent in chained calls
- [`KT-18607`](https://youtrack.jetbrains.com/issue/KT-18607) Options to put blank lines between 'when' branches
#### Performance Improvements
- [`KT-17751`](https://youtrack.jetbrains.com/issue/KT-17751) Kotlin slows down java inspections big time
#### Fixes
- [`KT-6610`](https://youtrack.jetbrains.com/issue/KT-6610) Language injection doesn't work with String Interpolation
- [`KT-8893`](https://youtrack.jetbrains.com/issue/KT-8893) Quick documentation shows type for top-level object-type elements, but "no name provided" for local ones
- [`KT-9359`](https://youtrack.jetbrains.com/issue/KT-9359) "Accidental override" error message does not mention class (type) names
- [`KT-10736`](https://youtrack.jetbrains.com/issue/KT-10736) Highlighting usages doesn't work for synthetic properties created by the Android Extensions
- [`KT-11980`](https://youtrack.jetbrains.com/issue/KT-11980) Spring: Generate Constructor, Setter Dependency in XML for Kotlin class: IOE at LightElement.add()
- [`KT-12123`](https://youtrack.jetbrains.com/issue/KT-12123) Formatter: always indent after newline in variable initialization
- [`KT-12910`](https://youtrack.jetbrains.com/issue/KT-12910) spring: create init-method/destroy-method from usage results in IOE
- [`KT-13072`](https://youtrack.jetbrains.com/issue/KT-13072) Kotlin struggles to index JDK 9 classes
- [`KT-13099`](https://youtrack.jetbrains.com/issue/KT-13099) formatting in angle brackets ignored and not fixed
- [`KT-14271`](https://youtrack.jetbrains.com/issue/KT-14271) Value captured in closure doesn't always get highlighted
- [`KT-14974`](https://youtrack.jetbrains.com/issue/KT-14974) "Find Usages" hangs in ExpressionsOfTypeProcessor
- [`KT-15270`](https://youtrack.jetbrains.com/issue/KT-15270) Quickfix to migrate from @native***
- [`KT-16725`](https://youtrack.jetbrains.com/issue/KT-16725) Formatter does not fix spaces before square brackets
- [`KT-16999`](https://youtrack.jetbrains.com/issue/KT-16999) "Parameter info" shows duplicates on toString
- [`KT-17357`](https://youtrack.jetbrains.com/issue/KT-17357) BuiltIns for module build with project LV settings, not with facet module settings
- [`KT-17759`](https://youtrack.jetbrains.com/issue/KT-17759) Breakpoints not working in JS
- [`KT-17849`](https://youtrack.jetbrains.com/issue/KT-17849) Automatically insert trimMargin() or trimIndent() on enter in multi-line strings
- [`KT-17855`](https://youtrack.jetbrains.com/issue/KT-17855) Main function is shown as unused
- [`KT-17894`](https://youtrack.jetbrains.com/issue/KT-17894) String `trimIndent` support inserts wrong indent in some cases
- [`KT-17942`](https://youtrack.jetbrains.com/issue/KT-17942) Enter in multiline string with injection doesn't add a proper indent
- [`KT-18006`](https://youtrack.jetbrains.com/issue/KT-18006) Copying part of string literal with escape sequences converts this sequences to special characters
- [`KT-18030`](https://youtrack.jetbrains.com/issue/KT-18030) Parameters hints: `kotlin.arrayOf(elements)` should be on the blacklist by default
- [`KT-18059`](https://youtrack.jetbrains.com/issue/KT-18059) Kotlin Lint: False positive error "requires api level 24" for interface method with body
- [`KT-18149`](https://youtrack.jetbrains.com/issue/KT-18149) PIEAE "Element class CompositeElement of type REFERENCE_EXPRESSION (class KtNameReferenceExpressionElementType)" at PsiInvalidElementAccessException.createByNode()
- [`KT-18151`](https://youtrack.jetbrains.com/issue/KT-18151) Do not import jdkHome from Gradle/Maven model
- [`KT-18158`](https://youtrack.jetbrains.com/issue/KT-18158) Expand selection should select the comment after expression getter on the same line
- [`KT-18221`](https://youtrack.jetbrains.com/issue/KT-18221) AE at org.jetbrains.kotlin.analyzer.ResolverForProjectImpl.descriptorForModule
- [`KT-18269`](https://youtrack.jetbrains.com/issue/KT-18269) Find Usages fails to find operator-style usages of `invoke()` defined as extension
- [`KT-18298`](https://youtrack.jetbrains.com/issue/KT-18298) spring: strange menu at "Navige to the spring bean" gutter
- [`KT-18309`](https://youtrack.jetbrains.com/issue/KT-18309) Join lines breaks code
- [`KT-18373`](https://youtrack.jetbrains.com/issue/KT-18373) Facet: can't change target platform between JVM versions
- [`KT-18376`](https://youtrack.jetbrains.com/issue/KT-18376) Maven import fails with NPE at ArgumentUtils.convertArgumentsToStringList() if `jvmTarget` setting is absent
- [`KT-18418`](https://youtrack.jetbrains.com/issue/KT-18418) Generate equals and hashCode should be available for classes without properties
- [`KT-18429`](https://youtrack.jetbrains.com/issue/KT-18429) Android strings resources folding false positives
- [`KT-18475`](https://youtrack.jetbrains.com/issue/KT-18475) Gradle/IntelliJ sync can result in IntelliJ modules getting gradle artifacts added to the classpath, breaking compilation
- [`KT-18479`](https://youtrack.jetbrains.com/issue/KT-18479) Can't find usages of invoke operator with vararg parameter
- [`KT-18566`](https://youtrack.jetbrains.com/issue/KT-18566) Long find usages for operators when there are several operators for the same type
- [`KT-18596`](https://youtrack.jetbrains.com/issue/KT-18596) "Generate hashCode" produces poorly formatted code
- [`KT-18725`](https://youtrack.jetbrains.com/issue/KT-18725) Android: `kotlin-language` facet disappears on reopening the project
### IDE. Completion
- [`KT-8208`](https://youtrack.jetbrains.com/issue/KT-8208) Support static member completion with not-imported-yet classes
- [`KT-12104`](https://youtrack.jetbrains.com/issue/KT-12104) Smart completion does not work with "invoke" when receiver is expression
- [`KT-18443`](https://youtrack.jetbrains.com/issue/KT-18443) IntelliJ not handling default constructor argument from companion object well
### IDE. Debugger
- [`KT-18453`](https://youtrack.jetbrains.com/issue/KT-18453) Support 'Step over' and 'Force step over' action for suspended calls
- [`KT-18577`](https://youtrack.jetbrains.com/issue/KT-18577) Debug: Smart Step Into does not enter functions passed as variable or parameter: "Method invoke() has not been called"
- [`KT-18632`](https://youtrack.jetbrains.com/issue/KT-18632) Debug: Smart Step Into does not enter functions passed as variable or parameter when signature of lambda and parameter doesn't match
### IDE. Inspections and Intentions
#### New Features
- [`KT-12119`](https://youtrack.jetbrains.com/issue/KT-12119) Intention to replace .addAll() on a mutable collection with +=
- [`KT-13436`](https://youtrack.jetbrains.com/issue/KT-13436) Replace 'when' with return: handle case when all branches jump out (return Nothing)
- [`KT-13458`](https://youtrack.jetbrains.com/issue/KT-13458) Cascade "replace with return" for if/when expressions
- [`KT-13676`](https://youtrack.jetbrains.com/issue/KT-13676) Add better quickfix for 'let' and 'error 'only not null or asserted calls are allowed'
- [`KT-14648`](https://youtrack.jetbrains.com/issue/KT-14648) Add quickfix for @receiver annotation being applied to extension member instead of extension type
- [`KT-14900`](https://youtrack.jetbrains.com/issue/KT-14900) "Lift return out of when/if" should work with control flow expressions
- [`KT-15257`](https://youtrack.jetbrains.com/issue/KT-15257) JS: quickfix to migrate from @native to external
- [`KT-15368`](https://youtrack.jetbrains.com/issue/KT-15368) Add intention to convert Boolean? == true to ?: false and vice versa
- [`KT-15893`](https://youtrack.jetbrains.com/issue/KT-15893) "Array property in data class" inspection could have a quick fix to generate `equals()` and `hashcode()`
- [`KT-16063`](https://youtrack.jetbrains.com/issue/KT-16063) Inspection to suggest converting block body to expression body
- [`KT-17198`](https://youtrack.jetbrains.com/issue/KT-17198) Inspection to replace filter calls followed by functions with a predicate variant
- [`KT-17580`](https://youtrack.jetbrains.com/issue/KT-17580) Add remaning branches intention should be available for sealed classes
- [`KT-17583`](https://youtrack.jetbrains.com/issue/KT-17583) Support "Declaration access can be weaker" inspection for kotlin properties
- [`KT-17815`](https://youtrack.jetbrains.com/issue/KT-17815) Quick-fix "Replace with safe call & elvis"
- [`KT-17842`](https://youtrack.jetbrains.com/issue/KT-17842) Add quick-fix for NO_CONSTRUCTOR error
- [`KT-17895`](https://youtrack.jetbrains.com/issue/KT-17895) Inspection to replace 'a .. b-1' with 'a until b'
- [`KT-17920`](https://youtrack.jetbrains.com/issue/KT-17920) Add intention/inspection removing redundant spread operator for arrayOf call
- [`KT-17970`](https://youtrack.jetbrains.com/issue/KT-17970) Intention actions to format parameter/argument list placing each on separate line
- [`KT-18236`](https://youtrack.jetbrains.com/issue/KT-18236) Add inspection for potentially wrongly placed unary operators
- [`KT-18274`](https://youtrack.jetbrains.com/issue/KT-18274) Add inspection to replace map+joinTo with joinTo(transform)
- [`KT-18386`](https://youtrack.jetbrains.com/issue/KT-18386) Inspection to detect safe calls of orEmpty()
- [`KT-18438`](https://youtrack.jetbrains.com/issue/KT-18438) Add inspection for empty ranges with start > endInclusive
- [`KT-18460`](https://youtrack.jetbrains.com/issue/KT-18460) Add intentions to apply De Morgan's laws to conditions
- [`KT-18516`](https://youtrack.jetbrains.com/issue/KT-18516) Add inspection to detect & remove redundant Unit
- [`KT-18517`](https://youtrack.jetbrains.com/issue/KT-18517) Provide "Remove explicit type" inspection for some obvious cases
- [`KT-18534`](https://youtrack.jetbrains.com/issue/KT-18534) Quick-fix to add empty brackets after primary constructor
- [`KT-18615`](https://youtrack.jetbrains.com/issue/KT-18615) Inspection to replace if with three or more options with when
- [`KT-18749`](https://youtrack.jetbrains.com/issue/KT-18749) Inspection for useless operations on collection with not-null elements
#### Fixes
- [`KT-11906`](https://youtrack.jetbrains.com/issue/KT-11906) Spring: "Create getter / setter" quick fixes cause IOE at LightElement.add()
- [`KT-12524`](https://youtrack.jetbrains.com/issue/KT-12524) Wrong "redundant semicolon" for semicolon inside an enum class before the companion object declaration
- [`KT-14092`](https://youtrack.jetbrains.com/issue/KT-14092) "Make <modifier>" intention inserts modifier between annotation and class keywords
- [`KT-14093`](https://youtrack.jetbrains.com/issue/KT-14093) "Make <modifier>" intention available only on modifier when declaration already have a visibility modifier
- [`KT-14643`](https://youtrack.jetbrains.com/issue/KT-14643) "Add non-null asserted call" quickfix should not be offered on literal null constants
- [`KT-16069`](https://youtrack.jetbrains.com/issue/KT-16069) "Simplify if statement" doesn't work in specific case
- [`KT-17026`](https://youtrack.jetbrains.com/issue/KT-17026) "Replace explicit parameter" should not be shown on destructuring declaration
- [`KT-17537`](https://youtrack.jetbrains.com/issue/KT-17537) Create from Usage should suggest Boolean return type if function is used in if condition
- [`KT-17623`](https://youtrack.jetbrains.com/issue/KT-17623) "Remove explicit type arguments" is too conservative sometimes
- [`KT-17726`](https://youtrack.jetbrains.com/issue/KT-17726) Nullability quick-fixes operate incorrectly with implicit nullable receiver
- [`KT-17740`](https://youtrack.jetbrains.com/issue/KT-17740) CME at MakeOverriddenMemberOpenFix.getText()
- [`KT-17823`](https://youtrack.jetbrains.com/issue/KT-17823) Intention "Make private" and friends should respect modifier order
- [`KT-17917`](https://youtrack.jetbrains.com/issue/KT-17917) Superfluos suggestion to add replaceWith for DeprecationLevel.HIDDEN
- [`KT-17954`](https://youtrack.jetbrains.com/issue/KT-17954) Setting error severity on "Kotlin | Function or property has platform type" does not show up as error in IDE
- [`KT-17996`](https://youtrack.jetbrains.com/issue/KT-17996) Android Studio Default Constructor Command Removes Custom Setter
- [`KT-18033`](https://youtrack.jetbrains.com/issue/KT-18033) Do not suggest to cast expression to non-nullable type when it's the same as !!
- [`KT-18035`](https://youtrack.jetbrains.com/issue/KT-18035) Quickfix for "CanBePrimaryConstructorProperty" does not work correctly with vararg constructor properties
- [`KT-18044`](https://youtrack.jetbrains.com/issue/KT-18044) "Move to class body" intention: better placement in the body
- [`KT-18120`](https://youtrack.jetbrains.com/issue/KT-18120) Recursive property accessor gives false positives
- [`KT-18148`](https://youtrack.jetbrains.com/issue/KT-18148) Incorrect, not working quickfix - final and can't be overridden
- [`KT-18253`](https://youtrack.jetbrains.com/issue/KT-18253) Wrong location of "Redundant 'toString()' call in string template" quickfix
- [`KT-18347`](https://youtrack.jetbrains.com/issue/KT-18347) Nullability quickfixes are not helpful when using invoke operator
- [`KT-18375`](https://youtrack.jetbrains.com/issue/KT-18375) Backticked function name is suggested to be renamed to the same name
- [`KT-18385`](https://youtrack.jetbrains.com/issue/KT-18385) Spring: Generate Dependency causes Throwable "AWT events are not allowed inside write action"
- [`KT-18407`](https://youtrack.jetbrains.com/issue/KT-18407) "Move property to constructor" action should not appear on properties declared in interfaces
- [`KT-18425`](https://youtrack.jetbrains.com/issue/KT-18425) Make <modifier> intention inserts modifier at wrong position for sealed class
- [`KT-18529`](https://youtrack.jetbrains.com/issue/KT-18529) Add '!!' quick fix applies to wrong expression on operation 'in'
- [`KT-18642`](https://youtrack.jetbrains.com/issue/KT-18642) Remove unused parameter intention transfers default value to another parameter
- [`KT-18683`](https://youtrack.jetbrains.com/issue/KT-18683) Wrong 'equals' is generated for Kotlin JS project
- [`KT-18709`](https://youtrack.jetbrains.com/issue/KT-18709) "Lift assignment out of if" changes semantics
- [`KT-18711`](https://youtrack.jetbrains.com/issue/KT-18711) "Lift return out of when" changes semantics for functional type
- [`KT-18717`](https://youtrack.jetbrains.com/issue/KT-18717) Report MemberVisibilityCanBePrivate on visibility modifier if present
### IDE. Refactorings
#### New Features
- [`KT-4379`](https://youtrack.jetbrains.com/issue/KT-4379) Support renaming import alias
- [`KT-8180`](https://youtrack.jetbrains.com/issue/KT-8180) Copy Class
- [`KT-17547`](https://youtrack.jetbrains.com/issue/KT-17547) Refactor / Move: Problems Detected / Conflicts in View: only referencing file is mentioned
#### Fixes
- [`KT-9054`](https://youtrack.jetbrains.com/issue/KT-9054) Copy / pasting a Kotlin file should bring up the Copy Class dialog
- [`KT-13437`](https://youtrack.jetbrains.com/issue/KT-13437) Change signature replaces return type with Unit when it's not requested
- [`KT-15859`](https://youtrack.jetbrains.com/issue/KT-15859) Renaming variables or functions with backticks removes the backticks
- [`KT-17062`](https://youtrack.jetbrains.com/issue/KT-17062) Field/property inline refactoring works incorrectly with Kotlin & Java usages
- [`KT-17128`](https://youtrack.jetbrains.com/issue/KT-17128) Refactor / Rename in the last position of label name throws Throwable "PsiElement(IDENTIFIER) by com.intellij.refactoring.rename.inplace.MemberInplaceRenamer" at InplaceRefactoring.buildTemplateAndStart()
- [`KT-17489`](https://youtrack.jetbrains.com/issue/KT-17489) Refactor / Inline Property: cannot inline val with the following plusAssign
- [`KT-17571`](https://youtrack.jetbrains.com/issue/KT-17571) Refactor / Move warns about using private/internal class from Java, but this is not related to the move
- [`KT-17622`](https://youtrack.jetbrains.com/issue/KT-17622) Refactor / Inline Function loses type arguments
- [`KT-18034`](https://youtrack.jetbrains.com/issue/KT-18034) Copy Class refactoring replaces all usages of the class with the new one!
- [`KT-18076`](https://youtrack.jetbrains.com/issue/KT-18076) Refactor / Rename on alias of Java class suggests to select between refactoring handlers
- [`KT-18096`](https://youtrack.jetbrains.com/issue/KT-18096) Refactor / Rename on import alias usage of a class member element tries to rename the element itself
- [`KT-18098`](https://youtrack.jetbrains.com/issue/KT-18098) Refactor / Copy can't generate proper import if original code uses import alias of java member
- [`KT-18135`](https://youtrack.jetbrains.com/issue/KT-18135) Refactor: no Problems Detected for Copy/Move source using platform type to another platform's module
- [`KT-18200`](https://youtrack.jetbrains.com/issue/KT-18200) Refactor / Copy is enabled for Java source selected with Kotlin file, but not for Java source selected with Kotlin class
- [`KT-18241`](https://youtrack.jetbrains.com/issue/KT-18241) Refactor / Copy (and Move) fails for chain of lambdas and invoke()'s with IllegalStateException: "No selector for PARENTHESIZED" at KtSimpleNameReference.changeQualifiedName()
- [`KT-18325`](https://youtrack.jetbrains.com/issue/KT-18325) Renaming a parameter name in one implementation silently rename it in all implementations
- [`KT-18390`](https://youtrack.jetbrains.com/issue/KT-18390) Refactor / Copy called for Java class opens only Copy File dialog
- [`KT-18699`](https://youtrack.jetbrains.com/issue/KT-18699) Refactor / Copy, Move loses necessary parentheses
### JavaScript
#### Performance Improvements
- [`KT-18331`](https://youtrack.jetbrains.com/issue/KT-18331) JS: compilation performance degrades fast when inlined nested labels are used
#### Fixes
- [`KT-4078`](https://youtrack.jetbrains.com/issue/KT-4078) JS sourcemaps should contain relative path. The relative base & prefix should be set from project/module preferences
- [`KT-8020`](https://youtrack.jetbrains.com/issue/KT-8020) JS: String? plus operator crashes on runtime
- [`KT-13919`](https://youtrack.jetbrains.com/issue/KT-13919) JS: Source map weirdness
- [`KT-15456`](https://youtrack.jetbrains.com/issue/KT-15456) JS: inlining doesn't work for array constructor with size and lambda
- [`KT-16984`](https://youtrack.jetbrains.com/issue/KT-16984) KotlinJS - 1 > 2 > false causes unhandled javascript exception
- [`KT-17285`](https://youtrack.jetbrains.com/issue/KT-17285) JS: wrong result when call function with default parameter overridden by delegation by function from another interface
- [`KT-17445`](https://youtrack.jetbrains.com/issue/KT-17445) JS: minifier for Kotlin JS apps
- [`KT-17476`](https://youtrack.jetbrains.com/issue/KT-17476) JS: Some symbols in identifiers compile, but are not legal
- [`KT-17871`](https://youtrack.jetbrains.com/issue/KT-17871) JS: spread vararg call doesn't work on functions imported with @JsModule
- [`KT-18027`](https://youtrack.jetbrains.com/issue/KT-18027) JS: Illegal symbols are possible in backticked labels, but cause crash in runtime and malformed js code
- [`KT-18032`](https://youtrack.jetbrains.com/issue/KT-18032) JS: Illegal symbols are possible in backticked package names, but cause crash in runtime and malformed js code
- [`KT-18169`](https://youtrack.jetbrains.com/issue/KT-18169) JS: reified generic backticked type name containing non-identifier symbols causes malformed JS and runtime crash
- [`KT-18187`](https://youtrack.jetbrains.com/issue/KT-18187) JS backend does not copy non-abstract method of interface to implementing class in some cases
- [`KT-18201`](https://youtrack.jetbrains.com/issue/KT-18201) JS backend generates wrong code for inline function which calls non-inline function from another module
- [`KT-18652`](https://youtrack.jetbrains.com/issue/KT-18652) JS: Objects from same package but from different libraries are incorrectly accessed
### Libraries
- [`KT-18526`](https://youtrack.jetbrains.com/issue/KT-18526) Small typo in documentation for kotlin-stdlib / kotlin.collections / retainAll
- [`KT-18624`](https://youtrack.jetbrains.com/issue/KT-18624) JS: Bad return type for Promise.all
- [`KT-18670`](https://youtrack.jetbrains.com/issue/KT-18670) Incorrect documentation of MutableMap.values
### Reflection
- [`KT-14094`](https://youtrack.jetbrains.com/issue/KT-14094) IllegalAccessException when try to get members annotated by private annotation with parameter
- [`KT-16399`](https://youtrack.jetbrains.com/issue/KT-16399) Embedded Tomcat fails to load Class-Path: kotlin-runtime.jar from kotlin-reflect-1.0.6.jar
- [`KT-16810`](https://youtrack.jetbrains.com/issue/KT-16810) Do not include incorrect ExternalOverridabilityCondition service file into kotlin-reflect.jar
- [`KT-18404`](https://youtrack.jetbrains.com/issue/KT-18404) “KotlinReflectionInternalError: This callable does not support a default call” when function or constructor has more than 32 parameters
- [`KT-18476`](https://youtrack.jetbrains.com/issue/KT-18476) KClass<*>.superclasses does not contain Any::class
- [`KT-18480`](https://youtrack.jetbrains.com/issue/KT-18480) Kotlin Reflection unable to call getter of protected read-only val with custom getter from parent class
### Tools
- [`KT-18062`](https://youtrack.jetbrains.com/issue/KT-18062) SamWithReceiver compiler plugin not used by IntelliJ for .kt files
- [`KT-18874`](https://youtrack.jetbrains.com/issue/KT-18874) Crash during compilation after switching to 1.1.3-release-IJ2017.2-2
### Tools. CLI
- [`KT-17297`](https://youtrack.jetbrains.com/issue/KT-17297) Report error when CLI compiler is not being run under Java 8+
- [`KT-18599`](https://youtrack.jetbrains.com/issue/KT-18599) Support -Xmodule-path and -Xadd-modules arguments for modular compilation on Java 9
- [`KT-18794`](https://youtrack.jetbrains.com/issue/KT-18794) kotlinc-jvm prints an irrelevant error message when a JVM Home directory does not exist
- [`KT-3045`](https://youtrack.jetbrains.com/issue/KT-3045) Report error instead of failing with exception on "kotlinc -script foo.kt"
- [`KT-18754`](https://youtrack.jetbrains.com/issue/KT-18754) Rename CLI argument "-module" to "-Xbuild-file"
- [`KT-18927`](https://youtrack.jetbrains.com/issue/KT-18927) run kotlin app crashes eclipse
### Tools. Gradle
- [`KT-10537`](https://youtrack.jetbrains.com/issue/KT-10537) Gradle plugin doesn't pick up changed project.buildDir
- [`KT-17031`](https://youtrack.jetbrains.com/issue/KT-17031) JVM crash on in-process compilation in Gradle with debug
- [`KT-17618`](https://youtrack.jetbrains.com/issue/KT-17618) Pass freeCompilerArgs to compiler unchanged
### Tools. J2K
- [`KT-10762`](https://youtrack.jetbrains.com/issue/KT-10762) J2K removes empty lines from Doc-comments
- [`KT-13146`](https://youtrack.jetbrains.com/issue/KT-13146) J2K goes into infinite loop with anonymous inner class that references itself
- [`KT-15761`](https://youtrack.jetbrains.com/issue/KT-15761) Converting Java to Kotlin corrupts string which includes escaped backslash
- [`KT-16133`](https://youtrack.jetbrains.com/issue/KT-16133) Converting switch statement inserts dead code (possibly as a false positive for fall-through)
- [`KT-16142`](https://youtrack.jetbrains.com/issue/KT-16142) Kotlin Konverter produces empty line in Kdoc
- [`KT-18038`](https://youtrack.jetbrains.com/issue/KT-18038) Java to Kotlin converter messes up empty lines while converting from JavaDoc to KDoc
- [`KT-18051`](https://youtrack.jetbrains.com/issue/KT-18051) Doesn't work the auto-convert Java to Kotlin in Android Studio 3.0
- [`KT-18141`](https://youtrack.jetbrains.com/issue/KT-18141) J2K changes semantic when while does not have a body
- [`KT-18142`](https://youtrack.jetbrains.com/issue/KT-18142) J2K changes semantics when `if` does not have a body
- [`KT-18512`](https://youtrack.jetbrains.com/issue/KT-18512) J2K Incorrect null parameter conversion
### Tools. JPS
- [`KT-14848`](https://youtrack.jetbrains.com/issue/KT-14848) JPS: invalid compiler argument causes exception (see also EA-92062)
- [`KT-16057`](https://youtrack.jetbrains.com/issue/KT-16057) Provide better error message when the same compiler argument is set twice
### Tools. Maven
- [`KT-18224`](https://youtrack.jetbrains.com/issue/KT-18224) Maven compilation with JDK 9 fails with InaccessibleObjectException
### Tools. REPL
- [`KT-5620`](https://youtrack.jetbrains.com/issue/KT-5620) REPL: Support destructuring declarations
- [`KT-12564`](https://youtrack.jetbrains.com/issue/KT-12564) Kotlin REPL Doesn't Perform Many Checks
- [`KT-15172`](https://youtrack.jetbrains.com/issue/KT-15172) REPL: function declarations that contain empty lines throw error
- [`KT-18181`](https://youtrack.jetbrains.com/issue/KT-18181) REPL: support non-headless execution for Swing code
- [`KT-18349`](https://youtrack.jetbrains.com/issue/KT-18349) REPL: do not show warnings when there are errors
## 1.1.3-2
#### Fixes
- Noarg compiler plugin reverted to 1.1.2 behavior: by default, it will not run any initialization code
from the generated default constructor. If you want to run initializers, you need to enable
the corresponding option as described in the documentation.
Note that if a @noarg class has initializers that depend on constructor parameters, you will get incorrect
compiler behavior, so you shouldn't enable this option if you have such classes in your project.
This resolves [`KT-18667`](https://youtrack.jetbrains.com/issue/KT-18667) and [`KT-18668`](https://youtrack.jetbrains.com/issue/KT-18668).
- [`KT-18689`](https://youtrack.jetbrains.com/issue/KT-18689) Incorrect bytecode generated when passing a bound member reference to an inline function with default argument values
- [`KT-18377`](https://youtrack.jetbrains.com/issue/KT-18377) Syntax error while generating kapt stubs
- [`KT-18411`](https://youtrack.jetbrains.com/issue/KT-18411) Slow debugger step-in into inlined function
- [`KT-18687`](https://youtrack.jetbrains.com/issue/KT-18687) Deadlock in resolve with Kotlin 1.1.3
- [`KT-18726`](https://youtrack.jetbrains.com/issue/KT-18726) Frequent UI hangs in 2017.2 EAPs
## 1.1.3
### Android
#### New Features
- [`KT-12049`](https://youtrack.jetbrains.com/issue/KT-12049) Kotlin Lint: "Missing Parcelable CREATOR field" could suggest "Add implementation" quick fix
- [`KT-16712`](https://youtrack.jetbrains.com/issue/KT-16712) Show warning in IDEA when using Java 1.8 api in Android
- [`KT-16843`](https://youtrack.jetbrains.com/issue/KT-16843) Android: provide gutter icons for resources like colors and drawables
- [`KT-17389`](https://youtrack.jetbrains.com/issue/KT-17389) Implement Intention "Add Activity / BroadcastReceiver / Service to manifest"
- [`KT-17465`](https://youtrack.jetbrains.com/issue/KT-17465) Add intentions Add/Remove/Redo parcelable implementation
#### Fixes
- [`KT-14970`](https://youtrack.jetbrains.com/issue/KT-14970) ClassCastException: butterknife.lint.LintRegistry cannot be cast to com.android.tools.klint.client.api.IssueRegistry
- [`KT-17287`](https://youtrack.jetbrains.com/issue/KT-17287) Configure kotlin in Android Studio: don't show menu Choose Configurator with single choice
- [`KT-17288`](https://youtrack.jetbrains.com/issue/KT-17288) Android Studio: please remove menu item Configure Kotlin (JavaScript) in Project
- [`KT-17289`](https://youtrack.jetbrains.com/issue/KT-17289) Android Studio: Hide "Configure Kotlin" balloon if Kotlin is configured from a kt file banner
- [`KT-17291`](https://youtrack.jetbrains.com/issue/KT-17291) Android Studio 2.4: Cannot get property 'metaClass' on null object error after Kotlin configuring
- [`KT-17610`](https://youtrack.jetbrains.com/issue/KT-17610) "Unknown reference: kotlinx"
### Compiler
#### New Features
- [`KT-11167`](https://youtrack.jetbrains.com/issue/KT-11167) Support compilation against JRE 9
- [`KT-17497`](https://youtrack.jetbrains.com/issue/KT-17497) Warn about redundant else branch in exhaustive when
#### Performance Improvements
- [`KT-7931`](https://youtrack.jetbrains.com/issue/KT-7931) Optimize iteration over strings/charsequences on JVM
- [`KT-10848`](https://youtrack.jetbrains.com/issue/KT-10848) Optimize substitution of inline function with default parameters
- [`KT-12497`](https://youtrack.jetbrains.com/issue/KT-12497) Optimize inlined bytecode for functions with default parameters
- [`KT-17342`](https://youtrack.jetbrains.com/issue/KT-17342) Optimize control-flow for case of many variables
- [`KT-17562`](https://youtrack.jetbrains.com/issue/KT-17562) Optimize KtFile::isScript
#### Fixes
- [`KT-4960`](https://youtrack.jetbrains.com/issue/KT-4960) Redeclaration is not reported for type parameters of interfaces
- [`KT-5160`](https://youtrack.jetbrains.com/issue/KT-5160) No warning when a lambda parameter hides a variable
- [`KT-5246`](https://youtrack.jetbrains.com/issue/KT-5246) is check fails on cyclic type parameter bounds
@@ -13,158 +404,236 @@
- [`KT-7645`](https://youtrack.jetbrains.com/issue/KT-7645) Prohibit default value for `catch`-block parameter
- [`KT-7724`](https://youtrack.jetbrains.com/issue/KT-7724) Can never import private member
- [`KT-7796`](https://youtrack.jetbrains.com/issue/KT-7796) Wrong scope for default parameter value resolution
- [`KT-7931`](https://youtrack.jetbrains.com/issue/KT-7931) Optimize iteration over strings/charsequences on JVM
- [`KT-7984`](https://youtrack.jetbrains.com/issue/KT-7984) Unexpected "Unresolved reference" in a default value expression in a local function
- [`KT-7985`](https://youtrack.jetbrains.com/issue/KT-7985) Unexpected "Unresolved reference to a type parameter" in a default value expression in a local function
- [`KT-8320`](https://youtrack.jetbrains.com/issue/KT-8320) It should not be possible to catch a type parameter type
- [`KT-8877`](https://youtrack.jetbrains.com/issue/KT-8877) Automatic labeling doesn't work for infix calls
- [`KT-9251`](https://youtrack.jetbrains.com/issue/KT-9251) Qualified this does not work with labeled function literals
- [`KT-9370`](https://youtrack.jetbrains.com/issue/KT-9370) not possible to pass an argument that starts with "-" to a script using kotlinc
- [`KT-9551`](https://youtrack.jetbrains.com/issue/KT-9551) False warning "No cast needed"
- [`KT-9645`](https://youtrack.jetbrains.com/issue/KT-9645) Incorrect inspection: No cast Needed
- [`KT-9986`](https://youtrack.jetbrains.com/issue/KT-9986) 'null as T' should be unchecked cast
- [`KT-10397`](https://youtrack.jetbrains.com/issue/KT-10397) java.lang.reflect.GenericSignatureFormatError when generic inner class is mentioned in function signature
- [`KT-10848`](https://youtrack.jetbrains.com/issue/KT-10848) Optimize substitution of inline function with default parameters
- [`KT-11167`](https://youtrack.jetbrains.com/issue/KT-11167) Support compilation against JRE 9
- [`KT-11474`](https://youtrack.jetbrains.com/issue/KT-11474) ISE: Requested A, got foo.A in JavaClassFinderImpl on Java file with package not matching directory
- [`KT-11622`](https://youtrack.jetbrains.com/issue/KT-11622) False "No cast needed" when ambiguous call because of smart cast
- [`KT-12049`](https://youtrack.jetbrains.com/issue/KT-12049) Kotlin Lint: "Missing Parcelable CREATOR field" could suggest "Add implementation" quick fix
- [`KT-12245`](https://youtrack.jetbrains.com/issue/KT-12245) Code with annotation that has an unresolved identifier as a parameter compiles successfully
- [`KT-12269`](https://youtrack.jetbrains.com/issue/KT-12269) False "Non-null type is checked for instance of nullable type"
- [`KT-12497`](https://youtrack.jetbrains.com/issue/KT-12497) Optimize inlined bytecode for functions with default parameters
- [`KT-12683`](https://youtrack.jetbrains.com/issue/KT-12683) A problem with `is` operator and non-reified type-parameters
- [`KT-12690`](https://youtrack.jetbrains.com/issue/KT-12690) USELESS_CAST compiler warning may break code when fix is applied
- [`KT-13348`](https://youtrack.jetbrains.com/issue/KT-13348) Report useless cast on safe cast from nullable type to the same not null type
- [`KT-13597`](https://youtrack.jetbrains.com/issue/KT-13597) No check for accessing final field in local object in constructor
- [`KT-13997`](https://youtrack.jetbrains.com/issue/KT-13997) Incorrect "Property must be initialized or be abstract" error for property with external accessors
- [`KT-14381`](https://youtrack.jetbrains.com/issue/KT-14381) Possible val reassignment not detected inside init block
- [`KT-14564`](https://youtrack.jetbrains.com/issue/KT-14564) java.lang.VerifyError: Bad local variable type
- [`KT-14801`](https://youtrack.jetbrains.com/issue/KT-14801) Invoke error message if nested class has the same name as a function from base class
- [`KT-14977`](https://youtrack.jetbrains.com/issue/KT-14977) IDE doesn't warn about checking null value of variable that cannot be null
- [`KT-15050`](https://youtrack.jetbrains.com/issue/KT-15050) Random build failures using maven 3 (multi-thread) + bamboo
- [`KT-15085`](https://youtrack.jetbrains.com/issue/KT-15085) Label and function naming conflict is resolved in unintuitive way
- [`KT-15161`](https://youtrack.jetbrains.com/issue/KT-15161) False warning "no cast needed" for array creation
- [`KT-15480`](https://youtrack.jetbrains.com/issue/KT-15480) Cannot destruct a list when "if" has an "else" branch
- [`KT-15495`](https://youtrack.jetbrains.com/issue/KT-15495) Internal typealiases in the same module are inaccessible on incremental compilation
- [`KT-15566`](https://youtrack.jetbrains.com/issue/KT-15566) Object member imported in file scope used in delegation expression in object declaration should be a compiler error
- [`KT-16283`](https://youtrack.jetbrains.com/issue/KT-16283) Maven compiler plugin warns, "Source root doesn't exist"
- [`KT-16016`](https://youtrack.jetbrains.com/issue/KT-16016) Compiler failure with NO_EXPECTED_TYPE
- [`KT-16426`](https://youtrack.jetbrains.com/issue/KT-16426) Return statement resolved to function instead of property getter
- [`KT-16712`](https://youtrack.jetbrains.com/issue/KT-16712) Show warning in IDEA when using Java 1.8 api in Android
- [`KT-16743`](https://youtrack.jetbrains.com/issue/KT-16743) Update configuration options in Kotlin Maven plugin
- [`KT-16754`](https://youtrack.jetbrains.com/issue/KT-16754) J2K: Apply quick-fixes from EDT thread only
- [`KT-16762`](https://youtrack.jetbrains.com/issue/KT-16762) Maven: JS compiler option main is missing
- [`KT-16813`](https://youtrack.jetbrains.com/issue/KT-16813) Anonymous objects returned from private-in-file members should behave as for private class members
- [`KT-16816`](https://youtrack.jetbrains.com/issue/KT-16816) Java To Kotlin bug: if + chained assignment doesn't include brackets
- [`KT-16843`](https://youtrack.jetbrains.com/issue/KT-16843) Android: provide gutter icons for resources like colors and drawables
- [`KT-16986`](https://youtrack.jetbrains.com/issue/KT-16986) header symbols referring types from standard library are not matched with their implementations in IDE
- [`KT-17093`](https://youtrack.jetbrains.com/issue/KT-17093) Import from maven: please provide a special tag for coroutine option
- [`KT-17100`](https://youtrack.jetbrains.com/issue/KT-17100) "kotlin" launcher script: do not add current working directory to classpath if explicit "-classpath" is specified
- [`KT-17112`](https://youtrack.jetbrains.com/issue/KT-17112) IncompatibleClassChangeError on invoking Kotlin compiler daemon on JDK 9
- [`KT-17140`](https://youtrack.jetbrains.com/issue/KT-17140) Warning "classpath entry points to a file that is not a jar file" could just be disabled
- [`KT-16864`](https://youtrack.jetbrains.com/issue/KT-16864) Local delegate + ad-hoc object leads to CCE
- [`KT-17144`](https://youtrack.jetbrains.com/issue/KT-17144) Breakpoint inside `when`
- [`KT-17149`](https://youtrack.jetbrains.com/issue/KT-17149) Incorrect warning "Kotlin: This operation has led to an overflow"
- [`KT-17245`](https://youtrack.jetbrains.com/issue/KT-17245) Kapt: Javac compiler arguments can't be specified in Gradle
- [`KT-17264`](https://youtrack.jetbrains.com/issue/KT-17264) Change the format of advanced CLI arguments ("-X...") to require value after "=", not a whitespace
- [`KT-17287`](https://youtrack.jetbrains.com/issue/KT-17287) Configure kotlin in Android Studio: don't show menu Choose Configurator with single choice
- [`KT-17288`](https://youtrack.jetbrains.com/issue/KT-17288) Android Studio: please remove menu item Configure Kotlin (JavaScript) in Project
- [`KT-17289`](https://youtrack.jetbrains.com/issue/KT-17289) Android Studio: Hide "Configure Kotlin" balloon if Kotlin is configured from a kt file banner
- [`KT-17291`](https://youtrack.jetbrains.com/issue/KT-17291) Android Studio 2.4: Cannot get property 'metaClass' on null object error after Kotlin configuring
- [`KT-17156`](https://youtrack.jetbrains.com/issue/KT-17156) No re-parse after lambda was converted to block
- [`KT-17318`](https://youtrack.jetbrains.com/issue/KT-17318) Typo in DSL Marker message `cant`
- [`KT-17342`](https://youtrack.jetbrains.com/issue/KT-17342) Optimize control-flow for case of many variables
- [`KT-17384`](https://youtrack.jetbrains.com/issue/KT-17384) break/continue expression in inlined function parameter argument causes compilation exception
- [`KT-17387`](https://youtrack.jetbrains.com/issue/KT-17387) When compiling in the IDE, progress tracker says "configuring the compilation environment" when it clearly isn't
- [`KT-17389`](https://youtrack.jetbrains.com/issue/KT-17389) Implement Intention "Add Activity / BroadcastReceiver / Service to manifest"
- [`KT-17418`](https://youtrack.jetbrains.com/issue/KT-17418) "The following options were not recognized by any processor: '[kapt.kotlin.generated]'" warning from Javac shouldn't be shown even if no processor supports the generated annotation
- [`KT-17448`](https://youtrack.jetbrains.com/issue/KT-17448) Regression: Sample Resolve
- [`KT-17456`](https://youtrack.jetbrains.com/issue/KT-17456) kapt3: NoClassDefFound com/sun/tools/javac/util/Context
- [`KT-17465`](https://youtrack.jetbrains.com/issue/KT-17465) Add intentions Add/Remove/Redo parcelable implementation
- [`KT-17457`](https://youtrack.jetbrains.com/issue/KT-17457) Suspend + LongRange couldn't transform method node issue in Kotlin 1.1.1
- [`KT-17479`](https://youtrack.jetbrains.com/issue/KT-17479) val reassign is allowed via explicit this receiver
- [`KT-17560`](https://youtrack.jetbrains.com/issue/KT-17560) Overload resolution ambiguity on semi-valid class-files generated by Scala
- [`KT-17562`](https://youtrack.jetbrains.com/issue/KT-17562) Optimize KtFile::isScript
- [`KT-17572`](https://youtrack.jetbrains.com/issue/KT-17572) try-catch expression in inlined function parameter argument causes compilation exception
- [`KT-17573`](https://youtrack.jetbrains.com/issue/KT-17573) try-finally expression in inlined function parameter argument fails with VerifyError
- [`KT-17588`](https://youtrack.jetbrains.com/issue/KT-17588) Compiler error while optimizer tries to get rid of captured variable
- [`KT-17590`](https://youtrack.jetbrains.com/issue/KT-17590) conditional return in inline function parameter argument causes compilation exception
- [`KT-17591`](https://youtrack.jetbrains.com/issue/KT-17591) non-conditional return in inline function parameter argument causes compilation exception
- [`KT-17613`](https://youtrack.jetbrains.com/issue/KT-17613) 'this' expression referring to deprecated class instance is highlighted as deprecated in IDE
- [`KT-18358`](https://youtrack.jetbrains.com/issue/KT-18358) Keep smart pointers instead of PSI elements in JavaElementImpl and its descendants
### IDE
#### New Features
- [`KT-7810`](https://youtrack.jetbrains.com/issue/KT-7810) Separate icon for abstract class
- [`KT-8370`](https://youtrack.jetbrains.com/issue/KT-8370) "Can't move to original file" should not be an error
- [`KT-8930`](https://youtrack.jetbrains.com/issue/KT-8930) Refactor / Move preivew: moved element is shown as reference, and its file as subject
- [`KT-9158`](https://youtrack.jetbrains.com/issue/KT-9158) Refactor / Move preview mentions the package statement of moved class as a usage
- [`KT-10577`](https://youtrack.jetbrains.com/issue/KT-10577) Refactor / Move Kotlin + Java files adds wrong import in very specific case
- [`KT-10981`](https://youtrack.jetbrains.com/issue/KT-10981) Quickfix for INAPPLICABLE_JVM_FIELD to replace with 'const' when possible
- [`KT-11250`](https://youtrack.jetbrains.com/issue/KT-11250) Auto-completion for convention function names in 'operator fun' definitions
- [`KT-12293`](https://youtrack.jetbrains.com/issue/KT-12293) Autocompletion should propose `lateinit var` in addition to `lateinit`
- [`KT-8617`](https://youtrack.jetbrains.com/issue/KT-8617) Recognize TODO method usages and highlight them same as TODO-comment
- [`KT-12629`](https://youtrack.jetbrains.com/issue/KT-12629) Add rainbow/semantic-highlighting for local variables
- [`KT-13192`](https://youtrack.jetbrains.com/issue/KT-13192) Refactor / Move: to another class: "To" field code completion suggests facade and Java classes
- [`KT-13466`](https://youtrack.jetbrains.com/issue/KT-13466) Refactor / Move: class to upper level: the package statement is not updated
- [`KT-13524`](https://youtrack.jetbrains.com/issue/KT-13524) Completing the keyword 'constructor' before a primary constructor wrongly inserts parentheses
- [`KT-13673`](https://youtrack.jetbrains.com/issue/KT-13673) Add 'companion { ... }' code completion opsion
- [`KT-14046`](https://youtrack.jetbrains.com/issue/KT-14046) Add intention to add inline keyword if a function has parameter with noinline and/or crossinline modifier
- [`KT-14109`](https://youtrack.jetbrains.com/issue/KT-14109) support parameter hints in idea plugin
- [`KT-14435`](https://youtrack.jetbrains.com/issue/KT-14435) "Use destructuring declaration" should be available as intention even without usages
- [`KT-14601`](https://youtrack.jetbrains.com/issue/KT-14601) Formatter inserts unnecessary indent before 'else'
- [`KT-14665`](https://youtrack.jetbrains.com/issue/KT-14665) No completion for "else" keyword
- [`KT-14974`](https://youtrack.jetbrains.com/issue/KT-14974) "Find Usages" hangs in ExpressionsOfTypeProcessor
- [`KT-15273`](https://youtrack.jetbrains.com/issue/KT-15273) Kotlin IDE plugin adds `import java.lang.String` with "Optimize Imports", making project broken
- [`KT-15519`](https://youtrack.jetbrains.com/issue/KT-15519) KDoc comments for data class values get removed by Change Signature
- [`KT-15543`](https://youtrack.jetbrains.com/issue/KT-15543) "Convert receiver to parameter" refactoring breaks code
- [`KT-15603`](https://youtrack.jetbrains.com/issue/KT-15603) Annoying completion when making a primary constructor private
- [`KT-15660`](https://youtrack.jetbrains.com/issue/KT-15660) Quick-fix "Create header interface implementation" chooses wrong source root
- [`KT-15680`](https://youtrack.jetbrains.com/issue/KT-15680) Implementations gutter icon for header interface shows duplicates
- [`KT-15854`](https://youtrack.jetbrains.com/issue/KT-15854) Debugger not able to evaluate internal member functions
- [`KT-15903`](https://youtrack.jetbrains.com/issue/KT-15903) QuickFix to add/remove suspend in hierarchies
- [`KT-16025`](https://youtrack.jetbrains.com/issue/KT-16025) Step into suspend functions stops at the function end
- [`KT-16136`](https://youtrack.jetbrains.com/issue/KT-16136) Wrong type parameter variance suggested if type parameter is used in nested anonymous object
- [`KT-16161`](https://youtrack.jetbrains.com/issue/KT-16161) Completion of 'onEach' inserts unneeded angular brackets
- [`KT-16339`](https://youtrack.jetbrains.com/issue/KT-16339) Incorrect warning: 'protected' visibility is effectively 'private' in a final class
- [`KT-16392`](https://youtrack.jetbrains.com/issue/KT-16392) Gradle/Maven java module: Add framework support/ Kotlin (Java or JavaScript) adds nothing
- [`KT-16645`](https://youtrack.jetbrains.com/issue/KT-16645) Support inlay type hints for implicitly typed vals, properties, and functions
- [`KT-17807`](https://youtrack.jetbrains.com/issue/KT-17807) Add Smart Enter processor for object expessions
#### Performance Improvements
- [`KT-16995`](https://youtrack.jetbrains.com/issue/KT-16995) Typing during in-place refactorings is impossibly laggy
- [`KT-17331`](https://youtrack.jetbrains.com/issue/KT-17331) Frequent long editor freezes
- [`KT-17383`](https://youtrack.jetbrains.com/issue/KT-17383) Slow editing in Kotlin files If breadcrumbs are enabled in module with many dependencies
- [`KT-17495`](https://youtrack.jetbrains.com/issue/KT-17495) Much time spent in LibraryDependenciesCache.getLibrariesAndSdksUsedWith
#### Fixes
- [`KT-7848`](https://youtrack.jetbrains.com/issue/KT-7848) When you paste text into a string literal special symbols should be escaped
- [`KT-7954`](https://youtrack.jetbrains.com/issue/KT-7954) 'Go to symbol' doesn't show containing declaration for local symbols
- [`KT-9091`](https://youtrack.jetbrains.com/issue/KT-9091) Sometimes backticks of the method name with spaces are highlighted with rose background
- [`KT-10577`](https://youtrack.jetbrains.com/issue/KT-10577) Refactor / Move Kotlin + Java files adds wrong import in very specific case
- [`KT-12856`](https://youtrack.jetbrains.com/issue/KT-12856) Import fold region is not updated to include imports added while editing file
- [`KT-14161`](https://youtrack.jetbrains.com/issue/KT-14161) Navigate to symbol doesn't see local named functions
- [`KT-14601`](https://youtrack.jetbrains.com/issue/KT-14601) Formatter inserts unnecessary indent before 'else'
- [`KT-14639`](https://youtrack.jetbrains.com/issue/KT-14639) Incorrect name of code style setting: Align in columns 'case' branches
- [`KT-15029`](https://youtrack.jetbrains.com/issue/KT-15029) "Go to symbol" action doesn't find properties declared in primary constructors
- [`KT-15255`](https://youtrack.jetbrains.com/issue/KT-15255) Move cursor to a better place when creating a new Kotlin file
- [`KT-15273`](https://youtrack.jetbrains.com/issue/KT-15273) Kotlin IDE plugin adds `import java.lang.String` with "Optimize Imports", making project broken
- [`KT-16159`](https://youtrack.jetbrains.com/issue/KT-16159) Wrong "Constructor call" highlighting if operator is called on newly created object
- [`KT-16392`](https://youtrack.jetbrains.com/issue/KT-16392) Gradle/Maven java module: Add framework support/ Kotlin (Java or JavaScript) adds nothing
- [`KT-16423`](https://youtrack.jetbrains.com/issue/KT-16423) Show expression type doesn't work when selecting from the middle of expression with "Expand Selection"
- [`KT-16635`](https://youtrack.jetbrains.com/issue/KT-16635) Do not show kotlin-specific live templates macros for all context types
- [`KT-16755`](https://youtrack.jetbrains.com/issue/KT-16755) No "Is sublassed by" icon for sealed class
- [`KT-16775`](https://youtrack.jetbrains.com/issue/KT-16775) Rewrite at slice CLASS key: OBJECT_DECLARATION while writing code in IDE
- [`KT-16786`](https://youtrack.jetbrains.com/issue/KT-16786) Intention to add "open" modifier to a non-private method or property in an open class
- [`KT-16838`](https://youtrack.jetbrains.com/issue/KT-16838) Navigate from header to impl shows all overloads
- [`KT-16850`](https://youtrack.jetbrains.com/issue/KT-16850) UI freeze for several seconds during inserting selected completion variant
- [`KT-16803`](https://youtrack.jetbrains.com/issue/KT-16803) Suspending iteration is not marked in the gutter by IDEA as suspending invocation
- [`KT-17037`](https://youtrack.jetbrains.com/issue/KT-17037) Editor suggests to import `EmptyCoroutineContext.plus` for any unresolved `+`
- [`KT-17046`](https://youtrack.jetbrains.com/issue/KT-17046) Kotlin facet, Compiler plugins: last line is shown empty when not selected
- [`KT-17053`](https://youtrack.jetbrains.com/issue/KT-17053) Inspection to detect use of callable reference as a lambda body
- [`KT-17088`](https://youtrack.jetbrains.com/issue/KT-17088) Settings: Kotlin Compiler: "Destination directory" should be enabled if "Copy library runtime files" is on on the dialog opening
- [`KT-17094`](https://youtrack.jetbrains.com/issue/KT-17094) Kotlin facet, additional command line parameters dialog: please provide a title
- [`KT-17138`](https://youtrack.jetbrains.com/issue/KT-17138) Configure Kotlin in Project: Choose Configurator popup: names could be unified
- [`KT-17145`](https://youtrack.jetbrains.com/issue/KT-17145) Kotlin facet: IllegalArgumentException on attempt to show settings common for several javascript kotlin facets with different moduleKind
- [`KT-17191`](https://youtrack.jetbrains.com/issue/KT-17191) Intention to name anonymous (_) parameter
- [`KT-17211`](https://youtrack.jetbrains.com/issue/KT-17211) Refactor / Move several files: superfluous FQN is inserted into reference to same file's element
- [`KT-17213`](https://youtrack.jetbrains.com/issue/KT-17213) Refactor / Inline Function: parameters of lambda as call argument turn incompilable
- [`KT-17223`](https://youtrack.jetbrains.com/issue/KT-17223) Absolute path to Kotlin compiler plugin in IML
- [`KT-17234`](https://youtrack.jetbrains.com/issue/KT-17234) Refactor / Inline on library property is rejected after GUI freeze for a while
- [`KT-17272`](https://youtrack.jetbrains.com/issue/KT-17272) Refactor / Inline Function: unused String literal in parameters is kept (while unsed Int is not)
- [`KT-17273`](https://youtrack.jetbrains.com/issue/KT-17273) Refactor / Inline Function: PIEAE: "Element: class org.jetbrains.kotlin.psi.KtCallExpression because: different providers" at PsiUtilCore.ensureValid()
- [`KT-17293`](https://youtrack.jetbrains.com/issue/KT-17293) Project Structure dialog is opened too slow for a project with a lot of empty gradle modules
- [`KT-17296`](https://youtrack.jetbrains.com/issue/KT-17296) Refactor / Inline Function: UOE at ExpressionReplacementPerformer.findOrCreateBlockToInsertStatement() for call of multi-statement function in declaration
- [`KT-17330`](https://youtrack.jetbrains.com/issue/KT-17330) Inline kotlin function causes an infinite loop
- [`KT-17331`](https://youtrack.jetbrains.com/issue/KT-17331) Frequent long editor freezes
- [`KT-17333`](https://youtrack.jetbrains.com/issue/KT-17333) KotlinChangeInfo retains 132MB of the heap
- [`KT-17372`](https://youtrack.jetbrains.com/issue/KT-17372) Specify explicit lambda signature handles anonymous parameters incorrectly
- [`KT-17383`](https://youtrack.jetbrains.com/issue/KT-17383) Slow editing in Kotlin files If breadcrumbs are enabled in module with many dependencies
- [`KT-17395`](https://youtrack.jetbrains.com/issue/KT-17395) Refactor / Inline Function: arguments passed to lambda turns code to incompilable
- [`KT-17400`](https://youtrack.jetbrains.com/issue/KT-17400) Navigate to impl: implementations are duplicated
- [`KT-17404`](https://youtrack.jetbrains.com/issue/KT-17404) Editor: attempt to pass type parameter as reified argument causes AE "Classifier descriptor of a type should be of type ClassDescriptor" at DescriptorUtils.getClassDescriptorForTypeConstructor()
- [`KT-17408`](https://youtrack.jetbrains.com/issue/KT-17408) "Convert to secondary constructor" intention is available for annotation parameters
- [`KT-17472`](https://youtrack.jetbrains.com/issue/KT-17472) Refactor / Move: another class: Java class could be reported explicitly
- [`KT-17304`](https://youtrack.jetbrains.com/issue/KT-17304) IDEA shows wrong type for expressions
- [`KT-17439`](https://youtrack.jetbrains.com/issue/KT-17439) Kotlin: 'autoscroll from source' doesn't work in Structure view
- [`KT-17448`](https://youtrack.jetbrains.com/issue/KT-17448) Regression: Sample Resolve
- [`KT-17482`](https://youtrack.jetbrains.com/issue/KT-17482) Set jvmTarget to 1.8 by default when configuring a project with JDK 1.8
- [`KT-17495`](https://youtrack.jetbrains.com/issue/KT-17495) Much time spent in LibraryDependenciesCache.getLibrariesAndSdksUsedWith
- [`KT-17496`](https://youtrack.jetbrains.com/issue/KT-17496) Refactor / Move: calls to moved extension function type properties are updated (incorrectly)
- [`KT-17503`](https://youtrack.jetbrains.com/issue/KT-17503) Intention "To raw string literal" should handle string concatenations
- [`KT-17515`](https://youtrack.jetbrains.com/issue/KT-17515) Refactor / Move inner class to another class, Move companion object: disabled in editor, but available in Move dialog
- [`KT-17492`](https://youtrack.jetbrains.com/issue/KT-17492) -jvm-target is ignored by IntelliJ
- [`KT-17505`](https://youtrack.jetbrains.com/issue/KT-17505) LazyLightClassMemberMatchingError from collection implementation
- [`KT-17517`](https://youtrack.jetbrains.com/issue/KT-17517) Compiler options specified as properties are not handled by Maven importer
- [`KT-17520`](https://youtrack.jetbrains.com/issue/KT-17520) Quickfix to update language/API version should work for Maven projects
- [`KT-17521`](https://youtrack.jetbrains.com/issue/KT-17521) Quickfix to enable coroutines should work for Maven projects
- [`KT-17525`](https://youtrack.jetbrains.com/issue/KT-17525) IDE: KNPE at KotlinAddImportActionKt.createSingleImportActionForConstructor() on invalid reference to inner class constructor
- [`KT-17578`](https://youtrack.jetbrains.com/issue/KT-17578) Throwable: "Reported element PsiIdentifier:AnnotationConfiguration is not from the file 'PsiFile:InSource.kt' the inspection 'ImplicitSubclassInspection'"
- [`KT-17638`](https://youtrack.jetbrains.com/issue/KT-17638) ISE in KotlinElementDescriptionProvider.renderShort
- [`KT-17698`](https://youtrack.jetbrains.com/issue/KT-17698) Unknown library format - prevents IDEA from configuring Kotlin JS
- [`KT-17714`](https://youtrack.jetbrains.com/issue/KT-17714) UAST inspection on non-physical element
- [`KT-17722`](https://youtrack.jetbrains.com/issue/KT-17722) IntelliJ plugin uses wrong JVM target when Kotlin Facet is not configured
- [`KT-17770`](https://youtrack.jetbrains.com/issue/KT-17770) Kotlin IntelliJ plugin fails to re-index Gradle script classpath after change to the `plugins` block
- [`KT-17777`](https://youtrack.jetbrains.com/issue/KT-17777) Logger$EmptyThrowable: "Facet Kotlin (app) [kotlin-language] not found" at FacetModelImpl.removeFacet()
- [`KT-17810`](https://youtrack.jetbrains.com/issue/KT-17810) Exception from unused import inspection leads to code analysis hangs
- [`KT-17821`](https://youtrack.jetbrains.com/issue/KT-17821) In Kotlin's plugin KotlinJsMetadataVersionIndex loads file with VfsUtilCore.loadText
- [`KT-17840`](https://youtrack.jetbrains.com/issue/KT-17840) Show expression type on `this` shows bogus disambiguation
- [`KT-17845`](https://youtrack.jetbrains.com/issue/KT-17845) Searching for usages of override property in primary constructor doesn't suggest base property search
- [`KT-17847`](https://youtrack.jetbrains.com/issue/KT-17847) Kotlin facet: strange warning if API version = 1.2
- [`KT-17857`](https://youtrack.jetbrains.com/issue/KT-17857) Java should see classes affected by "allopen" plugin as open
- [`KT-17861`](https://youtrack.jetbrains.com/issue/KT-17861) Setting 'kotlin.experimental.coroutines "enable"' doesn't work for Android projects
- [`KT-17875`](https://youtrack.jetbrains.com/issue/KT-17875) New Project/Module with Kotlin: on attempt to use libraries from plugin IDE suggests to rewrite them
- [`KT-17876`](https://youtrack.jetbrains.com/issue/KT-17876) New Project/Module with Kotlin: with "Copy to" option only part of jars are copied
- [`KT-17899`](https://youtrack.jetbrains.com/issue/KT-17899) Navigate to symbol: vararg signatures are indistinguishable from non-vararg ones
- [`KT-18070`](https://youtrack.jetbrains.com/issue/KT-18070) KtLightModifierList.hasExplicitModifier("default") is true for interface method with body
### IDE. Completion
#### New Features
- [`KT-11250`](https://youtrack.jetbrains.com/issue/KT-11250) Auto-completion for convention function names in 'operator fun' definitions
- [`KT-12293`](https://youtrack.jetbrains.com/issue/KT-12293) Autocompletion should propose `lateinit var` in addition to `lateinit`
- [`KT-13673`](https://youtrack.jetbrains.com/issue/KT-13673) Add 'companion { ... }' code completion opsion
#### Performance Improvements
- [`KT-10978`](https://youtrack.jetbrains.com/issue/KT-10978) Kotlin + JOOQ + Intellij performance is unusable
- [`KT-16715`](https://youtrack.jetbrains.com/issue/KT-16715) Typing is very slow since 1.1
- [`KT-16850`](https://youtrack.jetbrains.com/issue/KT-16850) UI freeze for several seconds during inserting selected completion variant
#### Fixes
- [`KT-13524`](https://youtrack.jetbrains.com/issue/KT-13524) Completing the keyword 'constructor' before a primary constructor wrongly inserts parentheses
- [`KT-14665`](https://youtrack.jetbrains.com/issue/KT-14665) No completion for "else" keyword
- [`KT-15603`](https://youtrack.jetbrains.com/issue/KT-15603) Annoying completion when making a primary constructor private
- [`KT-16161`](https://youtrack.jetbrains.com/issue/KT-16161) Completion of 'onEach' inserts unneeded angular brackets
- [`KT-16856`](https://youtrack.jetbrains.com/issue/KT-16856) Code completion optimization
### IDE. Debugger
- [`KT-15823`](https://youtrack.jetbrains.com/issue/KT-15823) Breakpoints not work inside crossinline from init of object passed into collection
- [`KT-15854`](https://youtrack.jetbrains.com/issue/KT-15854) Debugger not able to evaluate internal member functions
- [`KT-16025`](https://youtrack.jetbrains.com/issue/KT-16025) Step into suspend functions stops at the function end
- [`KT-17295`](https://youtrack.jetbrains.com/issue/KT-17295) Can't stop in kotlin.concurrent.timer lambda parameter
### IDE. Inspections and Intentions
#### New Features
- [`KT-10981`](https://youtrack.jetbrains.com/issue/KT-10981) Quickfix for INAPPLICABLE_JVM_FIELD to replace with 'const' when possible
- [`KT-14046`](https://youtrack.jetbrains.com/issue/KT-14046) Add intention to add inline keyword if a function has parameter with noinline and/or crossinline modifier
- [`KT-14137`](https://youtrack.jetbrains.com/issue/KT-14137) Add intention to convert top level val with object expression to object
- [`KT-15903`](https://youtrack.jetbrains.com/issue/KT-15903) QuickFix to add/remove suspend in hierarchies
- [`KT-16786`](https://youtrack.jetbrains.com/issue/KT-16786) Intention to add "open" modifier to a non-private method or property in an open class
- [`KT-16851`](https://youtrack.jetbrains.com/issue/KT-16851) Quickfix adding qualifier `@call` to unallowed 'return' in closures
- [`KT-17053`](https://youtrack.jetbrains.com/issue/KT-17053) Inspection to detect use of callable reference as a lambda body
- [`KT-17054`](https://youtrack.jetbrains.com/issue/KT-17054) Intention/ inspection to convert 'if' with 'is' check to 'as?' with safe call
- [`KT-17191`](https://youtrack.jetbrains.com/issue/KT-17191) Intention to name anonymous (_) parameter
- [`KT-17221`](https://youtrack.jetbrains.com/issue/KT-17221) Inspection for recursive calls in property accessors
- [`KT-17520`](https://youtrack.jetbrains.com/issue/KT-17520) Quickfix to update language/API version should work for Maven projects
- [`KT-17650`](https://youtrack.jetbrains.com/issue/KT-17650) Add quickfix inserting 'lateinit' modifier for not-initialized property
- [`KT-17660`](https://youtrack.jetbrains.com/issue/KT-17660) Inspection: data class copy without named argument(s)
#### Fixes
- [`KT-10211`](https://youtrack.jetbrains.com/issue/KT-10211) "Replace infix call with ordinary call" appears both as a quickfix and as an intention in the pop-up
- [`KT-11003`](https://youtrack.jetbrains.com/issue/KT-11003) Invalid quickfix in companion object for open properties
- [`KT-12805`](https://youtrack.jetbrains.com/issue/KT-12805) False positive redundant semicolon after while without block expression
- [`KT-14335`](https://youtrack.jetbrains.com/issue/KT-14335) Unexpected range of "convert lambda to reference" intention
- [`KT-14435`](https://youtrack.jetbrains.com/issue/KT-14435) "Use destructuring declaration" should be available as intention even without usages
- [`KT-14443`](https://youtrack.jetbrains.com/issue/KT-14443) IDEA intention suggest to make a method in an interface final
- [`KT-14820`](https://youtrack.jetbrains.com/issue/KT-14820) Convert function to property shouldn't insert explicit type if it was inferred previously
- [`KT-15076`](https://youtrack.jetbrains.com/issue/KT-15076) Replace if with elvis inspection should not be reported in some complex cases
- [`KT-15543`](https://youtrack.jetbrains.com/issue/KT-15543) "Convert receiver to parameter" refactoring breaks code
- [`KT-15942`](https://youtrack.jetbrains.com/issue/KT-15942) "Convert to secondary constructor" intention is available for data class
- [`KT-16136`](https://youtrack.jetbrains.com/issue/KT-16136) Wrong type parameter variance suggested if type parameter is used in nested anonymous object
- [`KT-16339`](https://youtrack.jetbrains.com/issue/KT-16339) Incorrect warning: 'protected' visibility is effectively 'private' in a final class
- [`KT-16577`](https://youtrack.jetbrains.com/issue/KT-16577) "Redundant semicolon" is not reported for semicolon after package statement in file with no imports
- [`KT-17079`](https://youtrack.jetbrains.com/issue/KT-17079) Kotlin: Bad conversion of double comparison to range check if bounds have mixed types
- [`KT-17372`](https://youtrack.jetbrains.com/issue/KT-17372) Specify explicit lambda signature handles anonymous parameters incorrectly
- [`KT-17404`](https://youtrack.jetbrains.com/issue/KT-17404) Editor: attempt to pass type parameter as reified argument causes AE "Classifier descriptor of a type should be of type ClassDescriptor" at DescriptorUtils.getClassDescriptorForTypeConstructor()
- [`KT-17408`](https://youtrack.jetbrains.com/issue/KT-17408) "Convert to secondary constructor" intention is available for annotation parameters
- [`KT-17503`](https://youtrack.jetbrains.com/issue/KT-17503) Intention "To raw string literal" should handle string concatenations
- [`KT-17599`](https://youtrack.jetbrains.com/issue/KT-17599) "Make primary constructor internal" intention is available for annotation class
- [`KT-17600`](https://youtrack.jetbrains.com/issue/KT-17600) "Make primary constructor private" intention is available for annotation class
- [`KT-17707`](https://youtrack.jetbrains.com/issue/KT-17707) "Final declaration can't be overridden at runtime" inspection reports Kotlin classes non final due to compiler plugin
- [`KT-17708`](https://youtrack.jetbrains.com/issue/KT-17708) "Move to class body" intention is available for annotation parameters
- [`KT-17762`](https://youtrack.jetbrains.com/issue/KT-17762) 'Convert to range' intention generates inequivalent code for doubles
### IDE. Refactorings
#### Performance Improvements
- [`KT-17234`](https://youtrack.jetbrains.com/issue/KT-17234) Refactor / Inline on library property is rejected after GUI freeze for a while
- [`KT-17333`](https://youtrack.jetbrains.com/issue/KT-17333) KotlinChangeInfo retains 132MB of the heap
#### Fixes
- [`KT-8370`](https://youtrack.jetbrains.com/issue/KT-8370) "Can't move to original file" should not be an error
- [`KT-8930`](https://youtrack.jetbrains.com/issue/KT-8930) Refactor / Move preivew: moved element is shown as reference, and its file as subject
- [`KT-9158`](https://youtrack.jetbrains.com/issue/KT-9158) Refactor / Move preview mentions the package statement of moved class as a usage
- [`KT-13192`](https://youtrack.jetbrains.com/issue/KT-13192) Refactor / Move: to another class: "To" field code completion suggests facade and Java classes
- [`KT-13466`](https://youtrack.jetbrains.com/issue/KT-13466) Refactor / Move: class to upper level: the package statement is not updated
- [`KT-15519`](https://youtrack.jetbrains.com/issue/KT-15519) KDoc comments for data class values get removed by Change Signature
- [`KT-17211`](https://youtrack.jetbrains.com/issue/KT-17211) Refactor / Move several files: superfluous FQN is inserted into reference to same file's element
- [`KT-17213`](https://youtrack.jetbrains.com/issue/KT-17213) Refactor / Inline Function: parameters of lambda as call argument turn incompilable
- [`KT-17272`](https://youtrack.jetbrains.com/issue/KT-17272) Refactor / Inline Function: unused String literal in parameters is kept (while unsed Int is not)
- [`KT-17273`](https://youtrack.jetbrains.com/issue/KT-17273) Refactor / Inline Function: PIEAE: "Element: class org.jetbrains.kotlin.psi.KtCallExpression because: different providers" at PsiUtilCore.ensureValid()
- [`KT-17296`](https://youtrack.jetbrains.com/issue/KT-17296) Refactor / Inline Function: UOE at ExpressionReplacementPerformer.findOrCreateBlockToInsertStatement() for call of multi-statement function in declaration
- [`KT-17330`](https://youtrack.jetbrains.com/issue/KT-17330) Inline kotlin function causes an infinite loop
- [`KT-17395`](https://youtrack.jetbrains.com/issue/KT-17395) Refactor / Inline Function: arguments passed to lambda turns code to incompilable
- [`KT-17496`](https://youtrack.jetbrains.com/issue/KT-17496) Refactor / Move: calls to moved extension function type properties are updated (incorrectly)
- [`KT-17515`](https://youtrack.jetbrains.com/issue/KT-17515) Refactor / Move inner class to another class, Move companion object: disabled in editor, but available in Move dialog
- [`KT-17526`](https://youtrack.jetbrains.com/issue/KT-17526) Refactor / Move: reference to companion member gets superfluous companion name in certain cases
- [`KT-17538`](https://youtrack.jetbrains.com/issue/KT-17538) Refactor / Move: moving file with import alias removes alias usage from code
- [`KT-17545`](https://youtrack.jetbrains.com/issue/KT-17545) Refactor / Move: false Problems Detected on moving class using parent's protected class, object
- [`KT-17599`](https://youtrack.jetbrains.com/issue/KT-17599) "Make primary constructor internal" intention is available for annotation class
- [`KT-17600`](https://youtrack.jetbrains.com/issue/KT-17600) "Make primary constructor private" intention is available for annotation class
- [`KT-18018`](https://youtrack.jetbrains.com/issue/KT-18018) F5 (for Copy) does not work for Kotlin files anymore
- [`KT-18205`](https://youtrack.jetbrains.com/issue/KT-18205) Moving multiple classes causes imports to be converted to fully qualified class names
### Infrastructure
- [`KT-14988`](https://youtrack.jetbrains.com/issue/KT-14988) Support running the Kotlin compiler on Java 9
- [`KT-17112`](https://youtrack.jetbrains.com/issue/KT-17112) IncompatibleClassChangeError on invoking Kotlin compiler daemon on JDK 9
### JavaScript
#### Fixes
### JS
- [`KT-12926`](https://youtrack.jetbrains.com/issue/KT-12926) JS: use # instead of @ when linking to sourcemap from generated code
- [`KT-13577`](https://youtrack.jetbrains.com/issue/KT-13577) Double.hashCode is zero for big numbers
- [`KT-15135`](https://youtrack.jetbrains.com/issue/KT-15135) JS: support friend modules
- [`KT-15484`](https://youtrack.jetbrains.com/issue/KT-15484) JS: (node): println with object /number argument leads to "TypeError: Invalid data, chunk must be a string or buffer, not object/number"
- [`KT-16658`](https://youtrack.jetbrains.com/issue/KT-16658) JS: Suspend function with default param value in interface
- [`KT-16717`](https://youtrack.jetbrains.com/issue/KT-16717) KotlinJs - copy() on data class doesn't work with when there is a secondary constructor
@@ -176,14 +645,87 @@
- [`KT-17281`](https://youtrack.jetbrains.com/issue/KT-17281) JS: wrong code generated for a recursive call in suspend function
- [`KT-17446`](https://youtrack.jetbrains.com/issue/KT-17446) JS: incorrect code generated for call to `suspendCoroutineOrReturn` when the same function calls another suspend function
- [`KT-17540`](https://youtrack.jetbrains.com/issue/KT-17540) Incorrect inlining optimization of `also`/`apply` function
### Reflection
- [`KT-14988`](https://youtrack.jetbrains.com/issue/KT-14988) Support running the Kotlin compiler on Java 9
- [`KT-17055`](https://youtrack.jetbrains.com/issue/KT-17055) NPE in hashCode and equals of kotlin.jvm.internal.FunctionReference (on local functions)
- [`KT-17594`](https://youtrack.jetbrains.com/issue/KT-17594) Cache the result of val Class<T>.kotlin: KClass<T>
- [`KT-17700`](https://youtrack.jetbrains.com/issue/KT-17700) Wrong code generated for 'str += (nullableChar ?: break)'
- [`KT-17966`](https://youtrack.jetbrains.com/issue/KT-17966) JS: Char literal inside of string template
### Libraries
- [`KT-17453`](https://youtrack.jetbrains.com/issue/KT-17453) Array iterators throw IndexOutOfBoundsException instead of NoSuchElementException
- [`KT-17635`](https://youtrack.jetbrains.com/issue/KT-17635) Document String#toIntOfNull may throw an exception
- [`KT-17686`](https://youtrack.jetbrains.com/issue/KT-17686) takeLast(n) incorrectly performs drop(n) for Lists without random access
- [`KT-17704`](https://youtrack.jetbrains.com/issue/KT-17704) Update JavaDoc for ReentrantReadWriteLock.write to put more stress on the fact that to upgrade to write lock, read lock is first released.
- [`KT-17853`](https://youtrack.jetbrains.com/issue/KT-17853) JS: Confusing parameter names in 'Math.atan2`
- [`KT-18092`](https://youtrack.jetbrains.com/issue/KT-18092) Issue using kotlin-reflect with proguard: missing annotations Mutable and ReadOnly
- [`KT-18210`](https://youtrack.jetbrains.com/issue/KT-18210) JS String::match(regex) should have nullable return type
### Reflection
- [`KT-17055`](https://youtrack.jetbrains.com/issue/KT-17055) NPE in hashCode and equals of kotlin.jvm.internal.FunctionReference (on local functions)
- [`KT-17594`](https://youtrack.jetbrains.com/issue/KT-17594) Cache the result of val Class<T>.kotlin: KClass<T>
- [`KT-18494`](https://youtrack.jetbrains.com/issue/KT-18494) KNPE from Kotlin reflection (sometimes) in UtilKt.toJavaClass
### Tools
- [`KT-16692`](https://youtrack.jetbrains.com/issue/KT-16692) No-Arg-Constructor plugin should generate code to initialize delegates
### Tools. CLI
- [`KT-17696`](https://youtrack.jetbrains.com/issue/KT-17696) Allow kotlinc to take friend modules as .jar files
- [`KT-17697`](https://youtrack.jetbrains.com/issue/KT-17697) Allow kotlinc to take .java files as arguments
- [`KT-9370`](https://youtrack.jetbrains.com/issue/KT-9370) not possible to pass an argument that starts with "-" to a script using kotlinc
- [`KT-17100`](https://youtrack.jetbrains.com/issue/KT-17100) "kotlin" launcher script: do not add current working directory to classpath if explicit "-classpath" is specified
- [`KT-17140`](https://youtrack.jetbrains.com/issue/KT-17140) Warning "classpath entry points to a file that is not a jar file" could just be disabled
- [`KT-17264`](https://youtrack.jetbrains.com/issue/KT-17264) Change the format of advanced CLI arguments ("-X...") to require value after "=", not a whitespace
- [`KT-18180`](https://youtrack.jetbrains.com/issue/KT-18180) Modules not exported by java.se are not readable when compiling against JRE 9
### Tools. Gradle
- [`KT-15151`](https://youtrack.jetbrains.com/issue/KT-15151) Kapt3: Support incremental compilation of Java stubs
- [`KT-16298`](https://youtrack.jetbrains.com/issue/KT-16298) Gradle: IOException "Parent file doesn't exist:/.../artifact-difference.tab.len" on non-incremental clean after incremental build
- [`KT-17681`](https://youtrack.jetbrains.com/issue/KT-17681) Support the new API of Android Gradle plugin (2.4.0+)
- [`KT-17936`](https://youtrack.jetbrains.com/issue/KT-17936) Circular dependency between gradle tasks dataBindingExportBuildInfoDebug and compileDebugKotlin
- [`KT-17960`](https://youtrack.jetbrains.com/issue/KT-17960) Improve test of memory leak with Gradle daemon
- [`KT-18047`](https://youtrack.jetbrains.com/issue/KT-18047) Gradle kotlin options should use unset value as default for languageVersion and apiVersion
### Tools. J2K
- [`KT-16754`](https://youtrack.jetbrains.com/issue/KT-16754) J2K: Apply quick-fixes from EDT thread only
- [`KT-16816`](https://youtrack.jetbrains.com/issue/KT-16816) Java To Kotlin bug: if + chained assignment doesn't include brackets
- [`KT-17230`](https://youtrack.jetbrains.com/issue/KT-17230) J2K Deadlock
- [`KT-17712`](https://youtrack.jetbrains.com/issue/KT-17712) Exception in J2K during InlineCodegen convertion: com.intellij.psi.impl.source.JavaDummyHolder cannot be cast to com.intellij.psi.PsiJavaFile
### Tools. JPS
- [`KT-16568`](https://youtrack.jetbrains.com/issue/KT-16568) modulesWhoseInternalsAreVisible in ModuleDependencies are not filled in for JS projects
- [`KT-17387`](https://youtrack.jetbrains.com/issue/KT-17387) When compiling in the IDE, progress tracker says "configuring the compilation environment" when it clearly isn't
- [`KT-17665`](https://youtrack.jetbrains.com/issue/KT-17665) JPS: Kotlin: The '-d' option with a directory destination is ignored because '-module' is specified
- [`KT-17801`](https://youtrack.jetbrains.com/issue/KT-17801) Unresolved supertypes from JRE on JDK 9 in JPS
### Tools. Maven
- [`KT-17093`](https://youtrack.jetbrains.com/issue/KT-17093) Import from maven: please provide a special tag for coroutine option
- [`KT-10028`](https://youtrack.jetbrains.com/issue/KT-10028) Support parallel builds in maven
- [`KT-15050`](https://youtrack.jetbrains.com/issue/KT-15050) Random build failures using maven 3 (multi-thread) + bamboo
- [`KT-15318`](https://youtrack.jetbrains.com/issue/KT-15318) Intermitent Kotlin compilation errors
- [`KT-16283`](https://youtrack.jetbrains.com/issue/KT-16283) Maven compiler plugin warns, "Source root doesn't exist"
- [`KT-16743`](https://youtrack.jetbrains.com/issue/KT-16743) Update configuration options in Kotlin Maven plugin
- [`KT-16762`](https://youtrack.jetbrains.com/issue/KT-16762) Maven: JS compiler option main is missing
### Tools. REPL
- [`KT-5822`](https://youtrack.jetbrains.com/issue/KT-5822) Exception on package directive in REPL
- [`KT-10060`](https://youtrack.jetbrains.com/issue/KT-10060) REPL: Cannot execute more than 255 lines
- [`KT-17365`](https://youtrack.jetbrains.com/issue/KT-17365) REPL crash when referencing a variable whose definition threw an exception
### Tools. kapt
- [`KT-17245`](https://youtrack.jetbrains.com/issue/KT-17245) Kapt: Javac compiler arguments can't be specified in Gradle
- [`KT-17418`](https://youtrack.jetbrains.com/issue/KT-17418) "The following options were not recognized by any processor: '[kapt.kotlin.generated]'" warning from Javac shouldn't be shown even if no processor supports the generated annotation
- [`KT-17456`](https://youtrack.jetbrains.com/issue/KT-17456) kapt3: NoClassDefFound com/sun/tools/javac/util/Context
- [`KT-17567`](https://youtrack.jetbrains.com/issue/KT-17567) Kapt (1.1.2-eap-77) generates invalid Java stub for internal class
- [`KT-17620`](https://youtrack.jetbrains.com/issue/KT-17620) Kapt3 IC: avoid running AP when API is not changed
- [`KT-17959`](https://youtrack.jetbrains.com/issue/KT-17959) Kapt3 doesn't preserve method parameter names for abstract methods
- [`KT-17999`](https://youtrack.jetbrains.com/issue/KT-17999) Cannot use KAPT3 1.1.2-4 in Android Studio java libs (null TypeCastException to WrappedVariantData<*> on Gradle Sync)
## 1.1.2

View File

@@ -16,8 +16,8 @@
<excludeFolder url="file://$MODULE_DIR$/libraries/.idea" />
<excludeFolder url="file://$MODULE_DIR$/libraries/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/examples/annotation-processor-example/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/examples/browser-example/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/examples/browser-example-with-library/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/examples/browser-example/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/examples/js-example/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/examples/kotlin-gradle-subplugin-example/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/examples/kotlin-java-example/target" />
@@ -26,6 +26,8 @@
<excludeFolder url="file://$MODULE_DIR$/libraries/examples/kotlin-jsr223-local-example/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/common/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/js/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/js/it/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/js/it/node_modules" />
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/junit/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/kotlin.test/jvm/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/stdlib/build" />
@@ -36,20 +38,25 @@
<excludeFolder url="file://$MODULE_DIR$/libraries/stdlib/js/node_modules" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/.idea" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/binary-compatibility-validator/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/gradle-tools/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/idl2k/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-allopen/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-allopen/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-android-extensions/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-annotation-processing/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-annotation-processing-maven/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-annotation-processing/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-build-common-test/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-compiler/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-compiler-client-embeddable/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-compiler-client-embeddable-test/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-compiler-client-embeddable/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-compiler-embeddable/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-compiler-runner/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-compiler/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-daemon-client/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-gradle-plugin-api/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-gradle-plugin-api/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-gradle-plugin-integration-tests/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-gradle-plugin-integration-tests/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-gradle-plugin/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-gradle-plugin/local-repo" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-gradle-plugin/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-maven-allopen/target" />
@@ -58,6 +65,7 @@
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-maven-plugin-test/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-maven-plugin/local-repo" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-maven-plugin/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-noarg/build" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-noarg/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-osgi-bundle/target" />
<excludeFolder url="file://$MODULE_DIR$/libraries/tools/kotlin-reflect/build" />
@@ -75,4 +83,4 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
</module>

View File

@@ -1,4 +1,4 @@
<a href="https://kotlinslackin.herokuapp.com"><img src="https://kotlinslackin.herokuapp.com/badge.svg" height="20"></a>
<a href="http://slack.kotlinlang.org/"><img src="http://slack.kotlinlang.org/badge.svg" height="20"></a>
[![TeamCity (simple build status)](https://img.shields.io/teamcity/http/teamcity.jetbrains.com/s/bt345.svg)](https://teamcity.jetbrains.com/viewType.html?buildTypeId=bt345&branch_Kotlin=%3Cdefault%3E&tab=buildTypeStatusDiv)
[![Maven Central](https://img.shields.io/maven-central/v/org.jetbrains.kotlin/kotlin-maven-plugin.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.jetbrains.kotlin%22)
[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0)
@@ -15,7 +15,7 @@ Welcome to [Kotlin](https://kotlinlang.org/)! Some handy links:
* [Forum](https://discuss.kotlinlang.org/)
* [Kotlin Blog](https://blog.jetbrains.com/kotlin/)
* [Follow Kotlin on Twitter](https://twitter.com/kotlin)
* [Public Slack channel](https://kotlinslackin.herokuapp.com/)
* [Public Slack channel](http://slack.kotlinlang.org/)
* [TeamCity CI build](https://teamcity.jetbrains.com/project.html?tab=projectOverview&projectId=Kotlin)
## Editing Kotlin
@@ -168,12 +168,15 @@ The best way to submit a patch is to [fork the project on github](https://help.g
[pull request](https://help.github.com/articles/creating-a-pull-request/) via [github](https://github.com).
If you create your own fork, it might help to enable rebase by default
when you pull by executing `git config --global pull.rebase
true`. This will avoid your local repo having too many merge commits
when you pull by executing
``` bash
git config --global pull.rebase true
```
This will avoid your local repo having too many merge commits
which will help keep your pull request simple and easy to apply.
## Commit comments
If you include in your comment this text (where KT-1234 is the Issue ID in the [Issue Tracker](https://youtrack.jetbrains.com/issues/KT), the issue will get automatically marked as fixed.
If you include in your comment this text (where KT-1234 is the Issue ID in the [Issue Tracker](https://youtrack.jetbrains.com/issues/KT)), the issue will get automatically marked as fixed.
#KT-1234 Fixed

View File

@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.compilerRunner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.cli.common.arguments.Argument;
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments;
import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments;
import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt;
import org.jetbrains.kotlin.utils.StringsKt;
@@ -32,7 +32,7 @@ public class ArgumentUtils {
private ArgumentUtils() {}
@NotNull
public static List<String> convertArgumentsToStringList(@NotNull CommonCompilerArguments arguments)
public static List<String> convertArgumentsToStringList(@NotNull CommonToolArguments arguments)
throws InstantiationException, IllegalAccessException {
List<String> result = new ArrayList<>();
convertArgumentsToStringList(arguments, arguments.getClass().newInstance(), arguments.getClass(), result);
@@ -41,8 +41,8 @@ public class ArgumentUtils {
}
private static void convertArgumentsToStringList(
@NotNull CommonCompilerArguments arguments,
@NotNull CommonCompilerArguments defaultArguments,
@NotNull CommonToolArguments arguments,
@NotNull CommonToolArguments defaultArguments,
@NotNull Class<?> clazz,
@NotNull List<String> result
) throws IllegalAccessException, InstantiationException {
@@ -61,7 +61,7 @@ public class ArgumentUtils {
continue;
}
if (Objects.equals(value, defaultValue)) continue;
if (value == null || Objects.equals(value, defaultValue)) continue;
Class<?> fieldType = field.getType();

View File

@@ -27,7 +27,7 @@ interface ICReporter {
fun reportCompileIteration(sourceFiles: Collection<File>, exitCode: ExitCode) {}
fun pathsAsString(files: Iterable<File>): String =
files.map { it.canonicalPath }.joinToString()
files.joinToString { it.canonicalPath }
fun pathsAsString(vararg files: File): String =
pathsAsString(files.toList())

View File

@@ -197,7 +197,7 @@ open class LookupStorage(private val targetDataDir: File) : BasicMapsOwner() {
}
class LookupTrackerImpl(private val delegate: LookupTracker) : LookupTracker {
val lookups = MultiMap<LookupSymbol, String>()
val lookups = MultiMap.createSet<LookupSymbol, String>()
val pathInterner = StringInterner()
private val interner = StringInterner()

View File

@@ -56,6 +56,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) return false
}
if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) return false
for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) return false
}
return true
}
enum class ProtoBufPackageKind {
@@ -64,7 +70,8 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
TYPE_ALIAS_LIST,
TYPE_TABLE,
SINCE_KOTLIN_INFO_TABLE,
PACKAGE_MODULE_NAME
PACKAGE_MODULE_NAME,
PACKAGE_LOCAL_VARIABLE_LIST
}
fun difference(old: ProtoBuf.Package, new: ProtoBuf.Package): EnumSet<ProtoBufPackageKind> {
@@ -91,6 +98,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkStringEquals(old.getExtension(JvmProtoBuf.packageModuleName), new.getExtension(JvmProtoBuf.packageModuleName))) result.add(ProtoBufPackageKind.PACKAGE_MODULE_NAME)
}
if (old.getExtensionCount(JvmProtoBuf.packageLocalVariable) != new.getExtensionCount(JvmProtoBuf.packageLocalVariable)) result.add(ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST)
for(i in 0..old.getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
if (!checkEquals(old.getExtension(JvmProtoBuf.packageLocalVariable, i), new.getExtension(JvmProtoBuf.packageLocalVariable, i))) result.add(ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST)
}
return result
}
@@ -147,6 +160,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) return false
}
if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) return false
for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) return false
}
return true
}
enum class ProtoBufClassKind {
@@ -166,7 +185,8 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
TYPE_TABLE,
SINCE_KOTLIN_INFO,
SINCE_KOTLIN_INFO_TABLE,
CLASS_MODULE_NAME
CLASS_MODULE_NAME,
CLASS_LOCAL_VARIABLE_LIST
}
fun difference(old: ProtoBuf.Class, new: ProtoBuf.Class): EnumSet<ProtoBufClassKind> {
@@ -224,6 +244,12 @@ open class ProtoCompareGenerated(val oldNameResolver: NameResolver, val newNameR
if (!checkStringEquals(old.getExtension(JvmProtoBuf.classModuleName), new.getExtension(JvmProtoBuf.classModuleName))) result.add(ProtoBufClassKind.CLASS_MODULE_NAME)
}
if (old.getExtensionCount(JvmProtoBuf.classLocalVariable) != new.getExtensionCount(JvmProtoBuf.classLocalVariable)) result.add(ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST)
for(i in 0..old.getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
if (!checkEquals(old.getExtension(JvmProtoBuf.classLocalVariable, i), new.getExtension(JvmProtoBuf.classLocalVariable, i))) result.add(ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST)
}
return result
}
@@ -1053,6 +1079,10 @@ fun ProtoBuf.Package.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int)
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.packageModuleName))
}
for(i in 0..getExtensionCount(JvmProtoBuf.packageLocalVariable) - 1) {
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.packageLocalVariable, i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}
@@ -1125,6 +1155,10 @@ fun ProtoBuf.Class.hashCode(stringIndexes: (Int) -> Int, fqNameIndexes: (Int) ->
hashCode = 31 * hashCode + stringIndexes(getExtension(JvmProtoBuf.classModuleName))
}
for(i in 0..getExtensionCount(JvmProtoBuf.classLocalVariable) - 1) {
hashCode = 31 * hashCode + getExtension(JvmProtoBuf.classLocalVariable, i).hashCode(stringIndexes, fqNameIndexes)
}
return hashCode
}

View File

@@ -41,9 +41,7 @@ import java.util.*
fun Iterable<File>.javaSourceRoots(roots: Iterable<File>): Iterable<File> =
filter(File::isJavaFile)
.map { findSrcDirRoot(it, roots) }
.filterNotNull()
filter(File::isJavaFile).mapNotNull { findSrcDirRoot(it, roots) }
fun makeModuleFile(name: String, isTest: Boolean, outputDir: File, sourcesToCompile: Iterable<File>, javaSourceRoots: Iterable<File>, classpath: Iterable<File>, friendDirs: Iterable<File>): File {
val builder = KotlinModuleXmlBuilder()
@@ -166,7 +164,7 @@ fun<Target> OutputItemsCollectorImpl.generatedFiles(
return outputs.map { outputItem ->
val target =
outputItem.sourceFiles.firstOrNull()?.let { sourceToTarget[it] } ?:
targets.filter { getOutputDir(it)?.let { outputItem.outputFile.startsWith(it) } ?: false }.singleOrNull() ?:
targets.singleOrNull { getOutputDir(it)?.let { outputItem.outputFile.startsWith(it) } ?: false } ?:
representativeTarget
when (outputItem.outputFile.extension) {

View File

@@ -186,7 +186,8 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
}
for (kind in diff) {
when (kind!!) {
@Suppress("UNUSED_VARIABLE") // To make this 'when' exhaustive
val unused: Any = when (kind!!) {
ProtoBufClassKind.COMPANION_OBJECT_NAME -> {
if (oldProto.hasCompanionObjectName()) oldProto.companionObjectName.oldToNames()
if (newProto.hasCompanionObjectName()) newProto.companionObjectName.newToNames()
@@ -203,10 +204,7 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
}
ProtoBufClassKind.CONSTRUCTOR_LIST -> {
val differentNonPrivateConstructors = calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getConstructorList)
if (differentNonPrivateConstructors.isNotEmpty()) {
isClassAffected = true
}
isClassAffected = isClassAffected || differentNonPrivateConstructors.isNotEmpty()
}
ProtoBufClassKind.FUNCTION_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Class::getFunctionList))
@@ -238,6 +236,9 @@ private class DifferenceCalculatorForClass(oldData: ProtoMapValue, newData: Prot
ProtoBufClassKind.CLASS_MODULE_NAME -> {
// TODO
}
ProtoBufClassKind.CLASS_LOCAL_VARIABLE_LIST -> {
// Not affected, local variables are not accessible outside of a file
}
}
}
@@ -267,7 +268,8 @@ private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newDa
}
for (kind in diff) {
when (kind!!) {
@Suppress("UNUSED_VARIABLE") // To make this 'when' exhaustive
val unused: Any = when (kind!!) {
ProtoBufPackageKind.FUNCTION_LIST ->
names.addAll(calcDifferenceForNonPrivateMembers(ProtoBuf.Package::getFunctionList))
ProtoBufPackageKind.PROPERTY_LIST ->
@@ -279,7 +281,9 @@ private class DifferenceCalculatorForPackageFacade(oldData: ProtoMapValue, newDa
ProtoBufPackageKind.PACKAGE_MODULE_NAME -> {
// TODO
}
else -> throw IllegalArgumentException("Unsupported kind: $kind")
ProtoBufPackageKind.PACKAGE_LOCAL_VARIABLE_LIST -> {
// Not affected, local variables are not accessible outside of a file
}
}
}

View File

@@ -42,5 +42,5 @@ open class BasicMapsOwner {
maps.forEach { it.flush(memoryCachesOnly) }
}
@TestOnly fun dump(): String = maps.map { it.dump() }.joinToString("\n\n")
@TestOnly fun dump(): String = maps.joinToString("\n\n") { it.dump() }
}

View File

@@ -22202,8 +22202,8 @@ public final class DebugProtoBuf {
* <code>optional int32 flags = 1 [default = 0];</code>
*
* <pre>
*declaresDefault
*hasAnnotations
*declaresDefault
*isCrossinline
*isNoinline
* </pre>
@@ -22213,8 +22213,8 @@ public final class DebugProtoBuf {
* <code>optional int32 flags = 1 [default = 0];</code>
*
* <pre>
*declaresDefault
*hasAnnotations
*declaresDefault
*isCrossinline
*isNoinline
* </pre>
@@ -22419,8 +22419,8 @@ public final class DebugProtoBuf {
* <code>optional int32 flags = 1 [default = 0];</code>
*
* <pre>
*declaresDefault
*hasAnnotations
*declaresDefault
*isCrossinline
*isNoinline
* </pre>
@@ -22432,8 +22432,8 @@ public final class DebugProtoBuf {
* <code>optional int32 flags = 1 [default = 0];</code>
*
* <pre>
*declaresDefault
*hasAnnotations
*declaresDefault
*isCrossinline
*isNoinline
* </pre>
@@ -22913,8 +22913,8 @@ public final class DebugProtoBuf {
* <code>optional int32 flags = 1 [default = 0];</code>
*
* <pre>
*declaresDefault
*hasAnnotations
*declaresDefault
*isCrossinline
*isNoinline
* </pre>
@@ -22926,8 +22926,8 @@ public final class DebugProtoBuf {
* <code>optional int32 flags = 1 [default = 0];</code>
*
* <pre>
*declaresDefault
*hasAnnotations
*declaresDefault
*isCrossinline
*isNoinline
* </pre>
@@ -22939,8 +22939,8 @@ public final class DebugProtoBuf {
* <code>optional int32 flags = 1 [default = 0];</code>
*
* <pre>
*declaresDefault
*hasAnnotations
*declaresDefault
*isCrossinline
*isNoinline
* </pre>
@@ -22955,8 +22955,8 @@ public final class DebugProtoBuf {
* <code>optional int32 flags = 1 [default = 0];</code>
*
* <pre>
*declaresDefault
*hasAnnotations
*declaresDefault
*isCrossinline
*isNoinline
* </pre>

View File

@@ -14,7 +14,9 @@ public final class DebugJvmProtoBuf {
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.isRaw);
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.typeParameterAnnotation);
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.classModuleName);
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.classLocalVariable);
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.packageModuleName);
registry.add(org.jetbrains.kotlin.serialization.jvm.DebugJvmProtoBuf.packageLocalVariable);
}
public interface StringTableTypesOrBuilder extends
// @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.serialization.jvm.StringTableTypes)
@@ -4586,6 +4588,17 @@ public final class DebugJvmProtoBuf {
.newFileScopedGeneratedExtension(
java.lang.Integer.class,
null);
public static final int CLASS_LOCAL_VARIABLE_FIELD_NUMBER = 102;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Class { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
org.jetbrains.kotlin.serialization.DebugProtoBuf.Class,
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Property>> classLocalVariable = org.jetbrains.kotlin.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.class,
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.getDefaultInstance());
public static final int PACKAGE_MODULE_NAME_FIELD_NUMBER = 101;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
@@ -4597,6 +4610,17 @@ public final class DebugJvmProtoBuf {
.newFileScopedGeneratedExtension(
java.lang.Integer.class,
null);
public static final int PACKAGE_LOCAL_VARIABLE_FIELD_NUMBER = 102;
/**
* <code>extend .org.jetbrains.kotlin.serialization.Package { ... }</code>
*/
public static final
org.jetbrains.kotlin.protobuf.GeneratedMessage.GeneratedExtension<
org.jetbrains.kotlin.serialization.DebugProtoBuf.Package,
java.util.List<org.jetbrains.kotlin.serialization.DebugProtoBuf.Property>> packageLocalVariable = org.jetbrains.kotlin.protobuf.GeneratedMessage
.newFileScopedGeneratedExtension(
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.class,
org.jetbrains.kotlin.serialization.DebugProtoBuf.Property.getDefaultInstance());
private static final org.jetbrains.kotlin.protobuf.Descriptors.Descriptor
internal_static_org_jetbrains_kotlin_serialization_jvm_StringTableTypes_descriptor;
private static
@@ -4678,9 +4702,15 @@ public final class DebugJvmProtoBuf {
"g.jetbrains.kotlin.serialization.Annotat" +
"ion:J\n\021class_module_name\022).org.jetbrains" +
".kotlin.serialization.Class\030e \001(\005B\004\230\265\030\001:" +
"N\n\023package_module_name\022+.org.jetbrains.k" +
"otlin.serialization.Package\030e \001(\005B\004\230\265\030\001B" +
"\022B\020DebugJvmProtoBuf"
"u\n\024class_local_variable\022).org.jetbrains." +
"kotlin.serialization.Class\030f \003(\0132,.org.j" +
"etbrains.kotlin.serialization.Property:N",
"\n\023package_module_name\022+.org.jetbrains.ko" +
"tlin.serialization.Package\030e \001(\005B\004\230\265\030\001:y" +
"\n\026package_local_variable\022+.org.jetbrains" +
".kotlin.serialization.Package\030f \003(\0132,.or" +
"g.jetbrains.kotlin.serialization.Propert" +
"yB\022B\020DebugJvmProtoBuf"
};
org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
new org.jetbrains.kotlin.protobuf.Descriptors.FileDescriptor. InternalDescriptorAssigner() {
@@ -4733,7 +4763,9 @@ public final class DebugJvmProtoBuf {
isRaw.internalInit(descriptor.getExtensions().get(4));
typeParameterAnnotation.internalInit(descriptor.getExtensions().get(5));
classModuleName.internalInit(descriptor.getExtensions().get(6));
packageModuleName.internalInit(descriptor.getExtensions().get(7));
classLocalVariable.internalInit(descriptor.getExtensions().get(7));
packageModuleName.internalInit(descriptor.getExtensions().get(8));
packageLocalVariable.internalInit(descriptor.getExtensions().get(9));
org.jetbrains.kotlin.protobuf.ExtensionRegistry registry =
org.jetbrains.kotlin.protobuf.ExtensionRegistry.newInstance();
registry.add(org.jetbrains.kotlin.serialization.DebugExtOptionsProtoBuf.stringIdInTable);

View File

@@ -26,7 +26,6 @@
<property name="tools.jar" value="${env.JDK_18}/lib/tools.jar"/>
<property name="java.target" value="1.8"/>
<property name="java.target.1.6" value="1.6"/>
<condition property="bootstrap.or.local.build" value="true" else="false">
<or>
@@ -65,6 +64,8 @@
<fileset dir="${dependencies}" includes="jansi.jar"/>
<fileset dir="${dependencies}" includes="jline.jar"/>
<fileset dir="${dependencies}" includes="javaslang-2.0.6.jar"/>
<fileset dir="${dependencies}" includes="json-org.jar"/>
<fileset dir="${dependencies}" includes="kotlinx-coroutines-core.jar"/>
<fileset dir="${basedir}/ideaSDK/jps" includes="jps-model.jar"/>
</path>
@@ -154,6 +155,7 @@
<include name="js.parser/**"/>
<include name="js.serializer/**"/>
<include name="js.dce/**"/>
<exclude name="**/META-INF/services/**"/>
</patternset>
<path id="compilerSources.path">
@@ -181,6 +183,9 @@
<target name="init">
<mkdir dir="${kotlin-home}"/>
<mkdir dir="${kotlin-home}/lib"/>
<fail unless="env.JDK_16" message="JDK_16 environment variable is not set."/>
<fail unless="env.JDK_18" message="JDK_18 environment variable is not set."/>
</target>
<target name="prepare-dist">
@@ -229,6 +234,15 @@
</copy>
</target>
<target name="copy-bootstrap-to-dist"
depends="clean"
description="Use bootstrap compiler instead of building one from sources">
<mkdir dir="${kotlin-home}"/>
<copy todir="${kotlin-home}">
<fileset dir="${bootstrap.compiler.home}"/>
</copy>
</target>
<target name="compiler-sources">
<jar jarfile="${output}/kotlin-compiler-sources.jar">
<!-- TODO How to convert it from pathset or dirset ? -->
@@ -283,7 +297,7 @@
<target name="preloader">
<cleandir dir="${output}/classes/preloader"/>
<javac destdir="${output}/classes/preloader" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false"
source="${java.target}" target="${java.target}">
source="1.6" target="1.6">
<src location="${basedir}/compiler/preloader/src"/>
</javac>
@@ -304,6 +318,9 @@
<cleandir dir="${output}/classes/runner"/>
<kotlinc output="${output}/classes/runner">
<src location="${basedir}/compiler/cli/cli-runner/src"/>
<compilerarg line="-jvm-target 1.6"/>
<compilerarg value="-jdk-home"/>
<compilerarg value="${env.JDK_16}"/>
</kotlinc>
<local name="runtime.jar"/>
@@ -354,6 +371,7 @@
<fileset dir="${output}/builtins">
<include name="kotlin/**"/>
</fileset>
<fileset dir="${basedir}/core/deserialization/src" includes="META-INF/services/**"/>
<fileset dir="${basedir}/core/descriptor.loader.java/src" includes="META-INF/services/**"/>
<fileset dir="${basedir}/compiler/frontend.java/src" includes="META-INF/services/**"/>
<fileset dir="${basedir}/compiler/backend/src" includes="META-INF/services/**"/>
@@ -371,20 +389,22 @@
<zipfileset src="${basedir}/ideaSDK/core/asm-all.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/guava-19.0.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/intellij-core.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/jdom.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/jdom.jar" excludes="META-INF/jb/** META-INF/LICENSE"/>
<zipfileset src="${basedir}/ideaSDK/core/jna.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/log4j.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/log4j.jar" excludes="META-INF/jb/** META-INF/LICENSE"/>
<zipfileset src="${basedir}/ideaSDK/core/picocontainer.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/snappy-in-java-0.5.1.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/trove4j.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/xpp3-1.1.4-min.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/xstream-1.4.8.jar"/>
<zipfileset src="${idea.sdk}/lib/jna-platform.jar"/>
<zipfileset src="${idea.sdk}/lib/oromatcher.jar"/>
<zipfileset src="${idea.sdk}/lib/oromatcher.jar" excludes="META-INF/jb/** META-INF/LICENSE"/>
<zipfileset src="${idea.sdk}/jps/jps-model.jar"/>
<zipfileset src="${dependencies}/jline.jar"/>
<zipfileset src="${dependencies}/javaslang-2.0.6.jar"/>
<zipfileset src="${dependencies}/json-org.jar"/>
<zipfileset src="${protobuf.jar}"/>
<zipfileset src="${dependencies}/kotlinx-coroutines-core.jar"/>
<manifest>
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
@@ -395,9 +415,6 @@
<attribute name="Class-Path" value="${compiler.manifest.class.path}"/>
<attribute name="Main-Class" value="org.jetbrains.kotlin.cli.jvm.K2JVMCompiler"/>
<!-- This is needed if the compiler is run on Java 9 via "java -jar kotlin-compiler.jar" -->
<attribute name="Add-Opens" value="java.base/java.lang java.base/java.util java.base/java.util.concurrent.atomic java.base/jdk.internal.misc"/>
</manifest>
</jar>
</sequential>
@@ -638,9 +655,11 @@
<skip pattern="kotlin/Metadata"/>
<src>
<pathelement path="plugins/android-extensions/android-extensions-compiler/src"/>
<pathelement path="plugins/android-extensions/android-extensions-runtime/src"/>
</src>
<classpath>
<pathelement path="${idea.sdk}/core/intellij-core.jar"/>
<pathelement path="${idea.sdk}/plugins/android/lib/layoutlib.jar"/>
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
</classpath>
</javac2>
@@ -859,7 +878,7 @@
</java>
<javac2 srcdir="${toString:src.dirset}" destdir="@{output}" debug="true" debuglevel="lines,vars,source"
includeAntRuntime="false" source="${java.target.1.6}" target="${java.target.1.6}">
includeAntRuntime="false" source="1.6" target="1.6">
<skip pattern="kotlin/Metadata"/>
<classpath>
<path refid="classpath.path"/>

View File

@@ -7,7 +7,6 @@
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="intellij-core" level="project" />
<orderEntry type="module" module-name="frontend" />
<orderEntry type="module" module-name="util" />
</component>

View File

@@ -158,7 +158,7 @@ object CodegenUtil {
@JvmStatic
fun constructFakeFunctionCall(project: Project, referencedFunction: FunctionDescriptor): KtCallExpression {
val fakeFunctionCall = StringBuilder("callableReferenceFakeCall(")
fakeFunctionCall.append(referencedFunction.valueParameters.map { "p${it.index}" }.joinToString(", "))
fakeFunctionCall.append(referencedFunction.valueParameters.joinToString(", ") { "p${it.index}" })
fakeFunctionCall.append(")")
return KtPsiFactory(project, markGenerated = false).createExpression(fakeFunctionCall.toString()) as KtCallExpression
}

View File

@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.resolve.BindingContextUtils
* TODO: data class with zero components gets no toString/equals/hashCode methods. This is inconsistent and should be
* changed here with the platform backends adopted.
*/
abstract class DataClassMethodGenerator(private val declaration: KtClassOrObject, private val bindingContext: BindingContext) {
abstract class DataClassMethodGenerator(protected val declaration: KtClassOrObject, private val bindingContext: BindingContext) {
protected val classDescriptor: ClassDescriptor = BindingContextUtils.getNotNull(bindingContext, BindingContext.CLASS, declaration)
fun generate() {

View File

@@ -9,11 +9,8 @@
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="frontend" />
<orderEntry type="module" module-name="frontend.java" />
<orderEntry type="library" scope="PROVIDED" name="intellij-core" level="project" />
<orderEntry type="module" module-name="serialization" />
<orderEntry type="module" module-name="backend-common" exported="" />
<orderEntry type="module" module-name="util" />
<orderEntry type="module" module-name="backend.jvm" />
<orderEntry type="module" module-name="ir.tree" />
</component>
</module>

View File

@@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.inline.FileMapping;
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.kotlin.codegen.inline.SMAPBuilder;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
@@ -29,6 +28,8 @@ import org.jetbrains.org.objectweb.asm.*;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
public abstract class AbstractClassBuilder implements ClassBuilder {
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.ASM5) {};
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.ASM5) {};
@@ -105,7 +106,7 @@ public abstract class AbstractClassBuilder implements ClassBuilder {
@Override
public void done() {
if (!fileMappings.isEmpty() && InlineCodegenUtil.GENERATE_SMAP) {
if (!fileMappings.isEmpty() && GENERATE_SMAP) {
FileMapping origin = fileMappings.get(0);
assert sourceName == null || origin.getName().equals(sourceName) : "Error " + origin.getName() + " != " + sourceName;
getVisitor().visitSource(origin.getName(), new SMAPBuilder(origin.getName(), origin.getPath(), fileMappings).build());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.codegen;
import kotlin.collections.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.annotation.WrappedAnnotated;
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.annotations.*;
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.AnnotationChecker;
import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
@@ -291,32 +293,27 @@ public abstract class AnnotationCodegen {
@Nullable
private String genAnnotation(@NotNull AnnotationDescriptor annotationDescriptor) {
ClassifierDescriptor classifierDescriptor = getAnnotationClass(annotationDescriptor);
assert classifierDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor;
RetentionPolicy rp = getRetentionPolicy(classifierDescriptor);
ClassDescriptor classDescriptor = getAnnotationClass(annotationDescriptor);
assert classDescriptor != null : "Annotation descriptor has no class: " + annotationDescriptor;
RetentionPolicy rp = getRetentionPolicy(classDescriptor);
if (rp == RetentionPolicy.SOURCE && !typeMapper.getClassBuilderMode().generateSourceRetentionAnnotations) {
return null;
}
String descriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor();
innerClassConsumer.addInnerClassInfoFromAnnotation(classDescriptor);
if (classifierDescriptor instanceof ClassDescriptor) {
innerClassConsumer.addInnerClassInfoFromAnnotation(((ClassDescriptor) classifierDescriptor));
}
AnnotationVisitor annotationVisitor = visitAnnotation(descriptor, rp == RetentionPolicy.RUNTIME);
String asmTypeDescriptor = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor();
AnnotationVisitor annotationVisitor = visitAnnotation(asmTypeDescriptor, rp == RetentionPolicy.RUNTIME);
genAnnotationArguments(annotationDescriptor, annotationVisitor);
annotationVisitor.visitEnd();
return descriptor;
return asmTypeDescriptor;
}
private void genAnnotationArguments(AnnotationDescriptor annotationDescriptor, AnnotationVisitor annotationVisitor) {
for (Map.Entry<ValueParameterDescriptor, ConstantValue<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
ValueParameterDescriptor descriptor = entry.getKey();
String name = descriptor.getName().asString();
genCompileTimeValue(name, entry.getValue(), annotationVisitor);
for (Map.Entry<Name, ConstantValue<?>> entry : annotationDescriptor.getAllValueArguments().entrySet()) {
genCompileTimeValue(entry.getKey().asString(), entry.getValue(), annotationVisitor);
}
}
@@ -475,16 +472,13 @@ public abstract class AnnotationCodegen {
}
AnnotationDescriptor retentionAnnotation = descriptor.getAnnotations().findAnnotation(new FqName(Retention.class.getName()));
if (retentionAnnotation != null) {
Collection<ConstantValue<?>> valueArguments = retentionAnnotation.getAllValueArguments().values();
if (!valueArguments.isEmpty()) {
ConstantValue<?> compileTimeConstant = valueArguments.iterator().next();
if (compileTimeConstant instanceof EnumValue) {
ClassDescriptor enumEntry = ((EnumValue) compileTimeConstant).getValue();
KotlinType classObjectType = DescriptorUtilsKt.getClassValueType(enumEntry);
if (classObjectType != null) {
if ("java/lang/annotation/RetentionPolicy".equals(typeMapper.mapType(classObjectType).getInternalName())) {
return RetentionPolicy.valueOf(enumEntry.getName().asString());
}
ConstantValue<?> compileTimeConstant = CollectionsKt.firstOrNull(retentionAnnotation.getAllValueArguments().values());
if (compileTimeConstant instanceof EnumValue) {
ClassDescriptor enumEntry = ((EnumValue) compileTimeConstant).getValue();
KotlinType classObjectType = DescriptorUtilsKt.getClassValueType(enumEntry);
if (classObjectType != null) {
if ("java/lang/annotation/RetentionPolicy".equals(typeMapper.mapType(classObjectType).getInternalName())) {
return RetentionPolicy.valueOf(enumEntry.getName().asString());
}
}
}

View File

@@ -27,15 +27,18 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.intrinsics.HashCode;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.kotlin.codegen.serialization.JvmStringTable;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.JvmTarget;
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JavaVisibilities;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.protobuf.MessageLite;
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
@@ -137,10 +140,18 @@ public class AsmUtil {
return primitiveTypeByBoxedType.get(boxedType);
}
public static boolean isBoxedTypeOf(@NotNull Type boxedType, @NotNull Type unboxedType) {
return unboxPrimitiveTypeOrNull(boxedType) == unboxedType;
}
public static boolean isIntPrimitive(Type type) {
return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE;
}
public static boolean isIntOrLongPrimitive(Type type) {
return isIntPrimitive(type) || type == Type.LONG_TYPE;
}
public static boolean isNumberPrimitiveOrBoolean(Type type) {
return isNumberPrimitive(type) || type.getSort() == Type.BOOLEAN;
}
@@ -512,7 +523,7 @@ public class AsmUtil {
});
}
static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type) {
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) {
@@ -525,16 +536,6 @@ public class AsmUtil {
else if (type.getSort() == Type.OBJECT) {
iv.invokevirtual("java/lang/Object", "hashCode", "()I", false);
}
else if (type.getSort() == Type.LONG) {
genLongHashCode(mv, iv);
}
else if (type.getSort() == Type.DOUBLE) {
iv.invokestatic("java/lang/Double", "doubleToLongBits", "(D)J", false);
genLongHashCode(mv, iv);
}
else if (type.getSort() == Type.FLOAT) {
iv.invokestatic("java/lang/Float", "floatToIntBits", "(F)I", false);
}
else if (type.getSort() == Type.BOOLEAN) {
Label end = new Label();
iv.dup();
@@ -543,8 +544,24 @@ public class AsmUtil {
iv.iconst(1);
iv.mark(end);
}
else { // byte short char int
// do nothing
else {
if (JvmTarget.JVM_1_6 == jvmTarget) {
if (type.getSort() == Type.LONG) {
genLongHashCode(mv, iv);
}
else if (type.getSort() == Type.DOUBLE) {
iv.invokestatic("java/lang/Double", "doubleToLongBits", "(D)J", false);
genLongHashCode(mv, iv);
}
else if (type.getSort() == Type.FLOAT) {
iv.invokestatic("java/lang/Float", "floatToIntBits", "(F)I", false);
}
else { // byte short char int
// do nothing
}
} else {
HashCode.Companion.invokeHashCode(iv, type);
}
}
}
@@ -700,7 +717,7 @@ public class AsmUtil {
if (innerType.getSort() == Type.OBJECT || innerType.getSort() == Type.ARRAY) {
v.dup();
v.visitLdcInsn(runtimeAssertionInfo.getMessage());
v.invokestatic("kotlin/jvm/internal/Intrinsics", "checkExpressionValueIsNotNull",
v.invokestatic(IntrinsicMethods.INTRINSICS_CLASS_NAME, "checkExpressionValueIsNotNull",
"(Ljava/lang/Object;Ljava/lang/String;)V", false);
}
StackValue.coerce(innerType, type, v);
@@ -790,6 +807,16 @@ public class AsmUtil {
}
}
public static void pop2(@NotNull MethodVisitor v, @NotNull Type type) {
if (type.getSize() == 2) {
v.visitInsn(Opcodes.POP2);
v.visitInsn(Opcodes.POP2);
}
else {
v.visitInsn(Opcodes.POP2);
}
}
public static void dup(@NotNull InstructionAdapter v, @NotNull Type type) {
dup(v, type.getSize());
}
@@ -806,6 +833,22 @@ public class AsmUtil {
}
}
public static void dupx(@NotNull InstructionAdapter v, @NotNull Type type) {
dupx(v, type.getSize());
}
private static void dupx(@NotNull InstructionAdapter v, int size) {
if (size == 2) {
v.dup2X2();
}
else if (size == 1) {
v.dupX1();
}
else {
throw new UnsupportedOperationException();
}
}
public static void dup(@NotNull InstructionAdapter v, @NotNull Type topOfStack, @NotNull Type afterTop) {
if (topOfStack.getSize() == 0 && afterTop.getSize() == 0) {
return;
@@ -861,6 +904,11 @@ public class AsmUtil {
return Type.getObjectType(internalNameByFqNameWithoutInnerClasses(fqName));
}
@NotNull
public static Type asmTypeByClassId(@NotNull ClassId classId) {
return Type.getObjectType(classId.asString().replace('.', '$'));
}
@NotNull
public static String internalNameByFqNameWithoutInnerClasses(@NotNull FqName fqName) {
return JvmClassName.byFqNameWithoutInnerClasses(fqName).getInternalName();

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.inline.NameGenerator
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
interface BaseExpressionCodegen {
val frameMap: FrameMap
val visitor: InstructionAdapter
val inlineNameGenerator: NameGenerator
val lastLineNumber: Int
fun consumeReifiedOperationMarker(typeParameterDescriptor: TypeParameterDescriptor)
fun propagateChildReifiedTypeParametersUsages(reifiedTypeParametersUsages: ReifiedTypeParametersUsages)
fun pushClosureOnStack(
classDescriptor: ClassDescriptor,
putThis: Boolean,
callGenerator: CallGenerator,
functionReferenceReceiver: StackValue?
)
fun markLineNumberAfterInlineIfNeeded()
}

View File

@@ -0,0 +1,308 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen
import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
abstract class NumberLikeCompare(
left: StackValue,
right: StackValue,
operandType: Type,
private val opToken: IElementType
) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) {
override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int =
NumberCompare.patchOpcode(opcode, v, opToken, operandType)
}
abstract class SafeCallFusedWithPrimitiveEqualityBase(
opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue
) : NumberLikeCompare(left, right, operandType, opToken) {
private val trueIfEqual = opToken == KtTokens.EQEQ || opToken == KtTokens.EQEQEQ
protected abstract fun cleanupOnNullReceiver(v: InstructionAdapter)
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
val endLabel = Label()
arg1.put(operandType, v)
arg2!!.put(operandType, v)
v.visitJumpInsn(patchOpcode(if (jumpIfFalse) opcode else negatedOperations[opcode]!!, v), jumpLabel)
v.goTo(endLabel)
cleanupOnNullReceiver(v)
if (jumpIfFalse == trueIfEqual) {
v.goTo(jumpLabel)
}
v.mark(endLabel)
}
override fun putSelector(type: Type, v: InstructionAdapter) {
val falseLabel = Label()
val endLabel = Label()
arg1.put(operandType, v)
arg2!!.put(operandType, v)
v.visitJumpInsn(patchOpcode(opcode, v), falseLabel)
if (!trueIfEqual) {
val trueLabel = Label()
v.goTo(trueLabel)
cleanupOnNullReceiver(v)
v.mark(trueLabel)
}
v.iconst(1)
v.goTo(endLabel)
if (trueIfEqual) {
cleanupOnNullReceiver(v)
}
v.mark(falseLabel)
v.iconst(0)
v.mark(endLabel)
coerceTo(type, v)
}
}
class SafeCallToPrimitiveEquality(
opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue,
private val safeReceiverType: Type,
private val safeReceiverIsNull: Label
) : SafeCallFusedWithPrimitiveEqualityBase(opToken, operandType, left, right) {
override fun cleanupOnNullReceiver(v: InstructionAdapter) {
v.mark(safeReceiverIsNull)
AsmUtil.pop(v, safeReceiverType)
}
}
class PrimitiveToSafeCallEquality(
opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue,
private val safeReceiverType: Type,
private val safeReceiverIsNull: Label
) : SafeCallFusedWithPrimitiveEqualityBase(opToken, operandType, left, right) {
override fun cleanupOnNullReceiver(v: InstructionAdapter) {
v.mark(safeReceiverIsNull)
AsmUtil.pop(v, safeReceiverType)
AsmUtil.pop(v, arg1.type)
}
}
class BoxedToPrimitiveEquality private constructor(
leftBoxed: StackValue,
rightPrimitive: StackValue,
primitiveType: Type,
private val frameMap: FrameMap
) : NumberLikeCompare(leftBoxed, rightPrimitive, primitiveType, KtTokens.EQEQ) {
private val boxedType = arg1.type
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
if (arg2!!.canHaveSideEffects()) {
val tmp = frameMap.enterTemp(operandType)
doJump(
v, jumpLabel, jumpIfFalse,
{
arg1.put(boxedType, v)
arg2.put(operandType, v)
v.store(tmp, operandType)
},
{ v.load(tmp, operandType) }
)
frameMap.leaveTemp(operandType)
}
else {
doJump(
v, jumpLabel, jumpIfFalse,
{ arg1.put(boxedType, v) },
{ arg2.put(operandType, v) }
)
}
}
private inline fun doJump(
v: InstructionAdapter,
jumpLabel: Label,
jumpIfFalse: Boolean,
putArg1: () -> Unit,
putArg2: () -> Unit
) {
val notNullLabel = Label()
val endLabel = Label()
putArg1()
AsmUtil.dup(v, boxedType)
v.ifnonnull(notNullLabel)
AsmUtil.pop(v, boxedType)
if (jumpIfFalse) v.goTo(jumpLabel) else v.goTo(endLabel)
v.mark(notNullLabel)
coerce(boxedType, operandType, v)
putArg2()
v.visitJumpInsn(patchOpcode(if (jumpIfFalse) opcode else negatedOperations[opcode]!!, v), jumpLabel)
v.mark(endLabel)
}
companion object {
@JvmStatic
fun create(
opToken: IElementType,
left: StackValue,
leftType: Type,
right: StackValue,
rightType: Type,
frameMap: FrameMap
): BranchedValue =
if (!isApplicable(opToken, leftType, rightType))
throw IllegalArgumentException("Not applicable for $opToken, $leftType, $rightType")
else when (opToken) {
KtTokens.EQEQ -> BoxedToPrimitiveEquality(left, right, rightType, frameMap)
KtTokens.EXCLEQ -> Invert(BoxedToPrimitiveEquality(left, right, rightType, frameMap))
else -> throw AssertionError("Unexpected opToken: $opToken")
}
@JvmStatic
fun isApplicable(opToken: IElementType, leftType: Type, rightType: Type) =
(opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) &&
AsmUtil.isIntOrLongPrimitive(rightType) &&
AsmUtil.isBoxedTypeOf(leftType, rightType)
}
}
abstract class PrimitiveToSomethingEquality
protected constructor(
leftPrimitive: StackValue,
right: StackValue,
primitiveType: Type
) : NumberLikeCompare(leftPrimitive, right, primitiveType, KtTokens.EQEQ) {
protected val primitiveType = leftPrimitive.type
protected val rightType = right.type
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
val notNullLabel = Label()
val endLabel = Label()
arg1.put(primitiveType, v)
arg2!!.put(rightType, v)
AsmUtil.dup(v, rightType)
jumpIfCanCompareTopWithPrimitive(v, notNullLabel)
AsmUtil.pop(v, rightType)
AsmUtil.pop(v, primitiveType)
if (jumpIfFalse) v.goTo(jumpLabel) else v.goTo(endLabel)
v.mark(notNullLabel)
coerceRightToPrimitive(v)
v.visitJumpInsn(patchOpcode(if (jumpIfFalse) opcode else negatedOperations[opcode]!!, v), jumpLabel)
v.mark(endLabel)
}
protected abstract fun jumpIfCanCompareTopWithPrimitive(v: InstructionAdapter, label: Label)
protected abstract fun coerceRightToPrimitive(v: InstructionAdapter)
}
class PrimitiveToBoxedEquality private constructor(
leftPrimitive: StackValue,
rightBoxed: StackValue,
primitiveType: Type
) : PrimitiveToSomethingEquality(leftPrimitive, rightBoxed, primitiveType) {
private val boxedType = rightBoxed.type
override fun jumpIfCanCompareTopWithPrimitive(v: InstructionAdapter, label: Label) {
v.ifnonnull(label)
}
override fun coerceRightToPrimitive(v: InstructionAdapter) {
coerce(boxedType, primitiveType, v)
}
companion object {
@JvmStatic
fun create(opToken: IElementType, left: StackValue, leftType: Type, right: StackValue, rightType: Type): BranchedValue =
if (!isApplicable(opToken, leftType, rightType))
throw IllegalArgumentException("Not applicable for $opToken, $leftType, $rightType")
else when (opToken) {
KtTokens.EQEQ -> PrimitiveToBoxedEquality(left, right, leftType)
KtTokens.EXCLEQ -> Invert(PrimitiveToBoxedEquality(left, right, leftType))
else -> throw AssertionError("Unexpected opToken: $opToken")
}
@JvmStatic
fun isApplicable(opToken: IElementType, leftType: Type, rightType: Type) =
(opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) &&
AsmUtil.isIntOrLongPrimitive(leftType) &&
AsmUtil.isBoxedTypeOf(rightType, leftType)
}
}
class PrimitiveToObjectEquality private constructor(
leftPrimitive: StackValue,
rightObject: StackValue,
primitiveType: Type
) : PrimitiveToSomethingEquality(leftPrimitive, rightObject, primitiveType) {
private val boxedType = AsmUtil.boxType(primitiveType)
override fun jumpIfCanCompareTopWithPrimitive(v: InstructionAdapter, label: Label) {
v.instanceOf(boxedType)
v.ifne(label)
}
override fun coerceRightToPrimitive(v: InstructionAdapter) {
coerce(rightType, boxedType, v)
coerce(boxedType, primitiveType, v)
}
companion object {
@JvmStatic
fun create(opToken: IElementType, left: StackValue, leftType: Type, right: StackValue, rightType: Type): BranchedValue =
if (!isApplicable(opToken, leftType, rightType))
throw IllegalArgumentException("Not applicable for $opToken, $leftType, $rightType")
else when (opToken) {
KtTokens.EQEQ -> PrimitiveToObjectEquality(left, right, leftType)
KtTokens.EXCLEQ -> Invert(PrimitiveToObjectEquality(left, right, leftType))
else -> throw AssertionError("Unexpected opToken: $opToken")
}
@JvmStatic
fun isApplicable(opToken: IElementType, leftType: Type, rightType: Type) =
(opToken == KtTokens.EQEQ || opToken == KtTokens.EXCLEQ) &&
AsmUtil.isIntOrLongPrimitive(leftType) &&
rightType.sort == Type.OBJECT
}
}

View File

@@ -54,9 +54,7 @@ open class BranchedValue(
condJump(jumpLabel, v, jumpIfFalse)
}
protected open fun patchOpcode(opcode: Int, v: InstructionAdapter): Int {
return opcode
}
protected open fun patchOpcode(opcode: Int, v: InstructionAdapter): Int = opcode
companion object {
val negatedOperations = hashMapOf<Int, Int>()
@@ -120,13 +118,9 @@ open class BranchedValue(
negatedOperations.put(negatedOp, op)
}
fun booleanConstant(value: Boolean): BranchedValue {
return if (value) TRUE else FALSE
}
fun booleanConstant(value: Boolean): BranchedValue = if (value) TRUE else FALSE
fun createInvertValue(argument: StackValue): StackValue {
return Invert(condJump(argument))
}
fun createInvertValue(argument: StackValue): StackValue = Invert(condJump(argument))
fun condJump(condition: StackValue, label: Label, jumpIfFalse: Boolean, iv: InstructionAdapter) {
condJump(condition).condJump(label, iv, jumpIfFalse)
@@ -136,14 +130,11 @@ open class BranchedValue(
condJump(condition).loopJump(label, iv, jumpIfFalse)
}
fun condJump(condition: StackValue): CondJump {
return CondJump(if (condition is BranchedValue) {
condition
}
else {
BranchedValue(condition, null, Type.BOOLEAN_TYPE, IFEQ)
}, IFEQ)
}
fun condJump(condition: StackValue): CondJump =
CondJump(
condition as? BranchedValue ?: BranchedValue(condition, null, Type.BOOLEAN_TYPE, IFEQ),
IFEQ
)
fun cmp(opToken: IElementType, operandType: Type, left: StackValue, right: StackValue): StackValue =
if (operandType.sort == Type.OBJECT)
@@ -203,7 +194,7 @@ class CondJump(val condition: BranchedValue, op: Int) : BranchedValue(condition,
}
class NumberCompare(
val opToken: IElementType,
private val opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue
@@ -213,17 +204,15 @@ class NumberCompare(
patchOpcode(opcode, v, opToken, operandType)
companion object {
fun getNumberCompareOpcode(opToken: IElementType): Int {
return when (opToken) {
KtTokens.EQEQ, KtTokens.EQEQEQ -> IFNE
KtTokens.EXCLEQ, KtTokens.EXCLEQEQEQ -> IFEQ
KtTokens.GT -> IFLE
KtTokens.GTEQ -> IFLT
KtTokens.LT -> IFGE
KtTokens.LTEQ -> IFGT
else -> {
throw UnsupportedOperationException("Don't know how to generate this condJump: " + opToken)
}
fun getNumberCompareOpcode(opToken: IElementType): Int = when (opToken) {
KtTokens.EQEQ, KtTokens.EQEQEQ -> IFNE
KtTokens.EXCLEQ, KtTokens.EXCLEQEQEQ -> IFEQ
KtTokens.GT -> IFLE
KtTokens.GTEQ -> IFLT
KtTokens.LT -> IFGE
KtTokens.LTEQ -> IFGT
else -> {
throw UnsupportedOperationException("Don't know how to generate this condJump: " + opToken)
}
}
@@ -258,100 +247,11 @@ class ObjectCompare(
) : BranchedValue(left, right, operandType, ObjectCompare.getObjectCompareOpcode(opToken)) {
companion object {
fun getObjectCompareOpcode(opToken: IElementType): Int {
return when (opToken) {
KtTokens.EQEQEQ -> IF_ACMPNE
KtTokens.EXCLEQEQEQ -> IF_ACMPEQ
else -> throw UnsupportedOperationException("don't know how to generate this condjump")
}
fun getObjectCompareOpcode(opToken: IElementType): Int = when (opToken) {
KtTokens.EQEQEQ -> IF_ACMPNE
KtTokens.EXCLEQEQEQ -> IF_ACMPEQ
else -> throw UnsupportedOperationException("don't know how to generate this condjump")
}
}
}
abstract class SafeCallFusedWithPrimitiveEqualityBase(
val opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue
) : BranchedValue(left, right, operandType, NumberCompare.getNumberCompareOpcode(opToken)) {
private val trueIfEqual = opToken == KtTokens.EQEQ || opToken == KtTokens.EQEQEQ
protected abstract fun cleanupOnNullReceiver(v: InstructionAdapter)
override fun patchOpcode(opcode: Int, v: InstructionAdapter): Int =
NumberCompare.patchOpcode(opcode, v, opToken, operandType)
override fun condJump(jumpLabel: Label, v: InstructionAdapter, jumpIfFalse: Boolean) {
val endLabel = Label()
arg1.put(operandType, v)
arg2!!.put(operandType, v)
v.visitJumpInsn(patchOpcode(if (jumpIfFalse) opcode else negatedOperations[opcode]!!, v), jumpLabel)
v.goTo(endLabel)
cleanupOnNullReceiver(v)
if (jumpIfFalse == trueIfEqual) {
v.goTo(jumpLabel)
}
v.mark(endLabel)
}
override fun putSelector(type: Type, v: InstructionAdapter) {
val falseLabel = Label()
val endLabel = Label()
arg1.put(operandType, v)
arg2!!.put(operandType, v)
v.visitJumpInsn(patchOpcode(opcode, v), falseLabel)
if (!trueIfEqual) {
val trueLabel = Label()
v.goTo(trueLabel)
cleanupOnNullReceiver(v)
v.mark(trueLabel)
}
v.iconst(1)
v.goTo(endLabel)
if (trueIfEqual) {
cleanupOnNullReceiver(v)
}
v.mark(falseLabel)
v.iconst(0)
v.mark(endLabel)
coerceTo(type, v)
}
}
class SafeCallToPrimitiveEquality(
opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue,
val safeReceiverType: Type,
val safeReceiverIsNull: Label
) : SafeCallFusedWithPrimitiveEqualityBase(opToken, operandType, left, right) {
override fun cleanupOnNullReceiver(v: InstructionAdapter) {
v.mark(safeReceiverIsNull)
AsmUtil.pop(v, safeReceiverType)
}
}
class PrimitiveToSafeCallEquality(
opToken: IElementType,
operandType: Type,
left: StackValue,
right: StackValue,
val safeReceiverType: Type,
val safeReceiverIsNull: Label
) : SafeCallFusedWithPrimitiveEqualityBase(opToken, operandType, left, right) {
override fun cleanupOnNullReceiver(v: InstructionAdapter) {
v.mark(safeReceiverIsNull)
AsmUtil.pop(v, safeReceiverType)
AsmUtil.pop(v, arg1.type)
}
}

View File

@@ -31,9 +31,9 @@ enum class ValueKind {
DEFAULT_LAMBDA_CAPTURED_PARAMETER
}
abstract class CallGenerator {
interface CallGenerator {
internal class DefaultCallGenerator(private val codegen: ExpressionCodegen) : CallGenerator() {
class DefaultCallGenerator(private val codegen: ExpressionCodegen) : CallGenerator {
override fun genCallInner(
callableMethod: Callable,
@@ -106,9 +106,9 @@ abstract class CallGenerator {
genCallInner(callableMethod, resolvedCall, callDefault, codegen)
}
abstract fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen)
fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen)
abstract fun genValueAndPut(
fun genValueAndPut(
valueParameterDescriptor: ValueParameterDescriptor,
argumentExpression: KtExpression,
parameterType: Type,
@@ -120,20 +120,20 @@ abstract class CallGenerator {
putValueIfNeeded(parameterType, value, ValueKind.GENERAL)
}
abstract fun putValueIfNeeded(
fun putValueIfNeeded(
parameterType: Type,
value: StackValue,
kind: ValueKind = ValueKind.GENERAL,
parameterIndex: Int = -1)
abstract fun putCapturedValueOnStack(
fun putCapturedValueOnStack(
stackValue: StackValue,
valueType: Type, paramIndex: Int)
abstract fun processAndPutHiddenParameters(justProcess: Boolean)
fun processAndPutHiddenParameters(justProcess: Boolean)
/*should be called if justProcess = true in processAndPutHiddenParameters*/
abstract fun putHiddenParamsIntoLocals()
fun putHiddenParamsIntoLocals()
abstract fun reorderArgumentsIfNeeded(actualArgsWithDeclIndex: List<ArgumentAndDeclIndex>, valueParameterTypes: List<Type>)
fun reorderArgumentsIfNeeded(actualArgsWithDeclIndex: List<ArgumentAndDeclIndex>, valueParameterTypes: List<Type>)
}

View File

@@ -0,0 +1,168 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
public class CallReceiver extends StackValue {
private final StackValue dispatchReceiver;
private final StackValue extensionReceiver;
private final Type secondReceiverType;
private CallReceiver(
@NotNull StackValue dispatchReceiver,
@NotNull StackValue extensionReceiver,
@NotNull Type type,
@Nullable Type secondReceiverType
) {
super(type, dispatchReceiver.canHaveSideEffects() || extensionReceiver.canHaveSideEffects());
this.dispatchReceiver = dispatchReceiver;
this.extensionReceiver = extensionReceiver;
this.secondReceiverType = secondReceiverType;
}
public StackValue withoutReceiverArgument() {
return new CallReceiver(dispatchReceiver, none(), type, secondReceiverType);
}
public static StackValue generateCallReceiver(
@NotNull ResolvedCall<?> resolvedCall,
@NotNull ExpressionCodegen codegen,
@Nullable Callable callableMethod,
@Nullable ReceiverParameterDescriptor dispatchReceiverParameter,
@NotNull StackValue dispatchReceiver,
@Nullable ReceiverParameterDescriptor extensionReceiverParameter,
@NotNull StackValue extensionReceiver
) {
KotlinTypeMapper typeMapper = codegen.typeMapper;
GenerationState state = codegen.getState();
Type type;
Type secondReceiverType = null;
if (extensionReceiverParameter != null) {
type = calcExtensionReceiverType(resolvedCall, extensionReceiverParameter, typeMapper, callableMethod, state);
if (dispatchReceiverParameter != null) {
secondReceiverType = calcDispatchReceiverType(resolvedCall, dispatchReceiverParameter, typeMapper, callableMethod);
}
}
else if (dispatchReceiverParameter != null) {
type = calcDispatchReceiverType(resolvedCall, dispatchReceiverParameter, typeMapper, callableMethod);
}
else if (isLocalFunCall(callableMethod)) {
type = callableMethod.getGenerateCalleeType();
}
else {
type = Type.VOID_TYPE;
}
assert type != null : "Could not map receiver type for " + resolvedCall;
return new CallReceiver(dispatchReceiver, extensionReceiver, type, secondReceiverType);
}
private static Type calcDispatchReceiverType(
@NotNull ResolvedCall<?> resolvedCall,
@Nullable ReceiverParameterDescriptor dispatchReceiver,
@NotNull KotlinTypeMapper typeMapper,
@Nullable Callable callableMethod
) {
if (dispatchReceiver == null) return null;
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
if (CodegenUtilKt.isJvmStaticInObjectOrClass(descriptor)) {
return Type.VOID_TYPE;
}
if (callableMethod != null) {
return callableMethod.getDispatchReceiverType();
}
// Extract the receiver from the resolved call, workarounding the fact that ResolvedCall#dispatchReceiver doesn't have
// all the needed information, for example there's no way to find out whether or not a smart cast was applied to the receiver.
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container instanceof ClassDescriptor) {
return typeMapper.mapClass((ClassDescriptor) container);
}
return typeMapper.mapType(dispatchReceiver);
}
private static Type calcExtensionReceiverType(
@NotNull ResolvedCall<?> resolvedCall,
@Nullable ReceiverParameterDescriptor extensionReceiver,
@NotNull KotlinTypeMapper typeMapper,
@Nullable Callable callableMethod,
@NotNull GenerationState state
) {
if (extensionReceiver == null) return null;
CallableDescriptor descriptor = resolvedCall.getCandidateDescriptor();
if (descriptor instanceof PropertyDescriptor &&
// hackaround: boxing changes behaviour of T.javaClass intrinsic
state.getIntrinsics().getIntrinsic((PropertyDescriptor) descriptor) != JavaClassProperty.INSTANCE
) {
ReceiverParameterDescriptor receiverCandidate = descriptor.getExtensionReceiverParameter();
assert receiverCandidate != null;
return typeMapper.mapType(receiverCandidate.getType());
}
return callableMethod != null ? callableMethod.getExtensionReceiverType() : typeMapper.mapType(extensionReceiver.getType());
}
@Override
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
StackValue currentExtensionReceiver = extensionReceiver;
boolean hasExtensionReceiver = extensionReceiver != none();
if (extensionReceiver instanceof SafeCall) {
currentExtensionReceiver.put(currentExtensionReceiver.type, v);
currentExtensionReceiver = StackValue.onStack(currentExtensionReceiver.type);
}
Type dispatchReceiverType = secondReceiverType != null ? secondReceiverType :
hasExtensionReceiver ? dispatchReceiver.type :
type;
dispatchReceiver.put(dispatchReceiverType, v);
currentExtensionReceiver
.moveToTopOfStack(hasExtensionReceiver ? type : currentExtensionReceiver.type, v, dispatchReceiverType.getSize());
}
@Override
public void dup(@NotNull InstructionAdapter v, boolean withReceiver) {
AsmUtil.dup(v, extensionReceiver.type, dispatchReceiver.type);
}
@NotNull
public StackValue getDispatchReceiver() {
return dispatchReceiver;
}
@NotNull
public StackValue getExtensionReceiver() {
return extensionReceiver;
}
}

View File

@@ -24,16 +24,17 @@ import kotlin.collections.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.context.ClosureContext;
import org.jetbrains.kotlin.codegen.context.EnclosedValueDescriptor;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.load.java.JvmAbi;
@@ -60,6 +61,7 @@ import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConst;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.CLOSURE;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtils2Kt.initDefaultSourceMappingIfNeeded;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
@@ -158,7 +160,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
superInterfaceAsmTypes
);
InlineCodegenUtil.initDefaultSourceMappingIfNeeded(context, this, state);
initDefaultSourceMappingIfNeeded(context, this, state);
v.visitSource(element.getContainingFile().getName(), null);
}
@@ -229,9 +231,10 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
@Override
protected void generateKotlinMetadataAnnotation() {
FunctionDescriptor frontendFunDescriptor = CodegenUtilKt.unwrapFrontendVersion(funDescriptor);
FunctionDescriptor freeLambdaDescriptor = createFreeLambdaDescriptor(frontendFunDescriptor);
Method method = v.getSerializationBindings().get(METHOD_FOR_FUNCTION, frontendFunDescriptor);
assert method != null : "No method for " + frontendFunDescriptor;
FunctionDescriptor freeLambdaDescriptor = FakeDescriptorsForReferencesKt.createFreeFakeLambdaDescriptor(frontendFunDescriptor);
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, freeLambdaDescriptor, method);
DescriptorSerializer serializer =
@@ -245,30 +248,6 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
});
}
/**
* Given a function descriptor, creates another function descriptor with type parameters copied from outer context(s).
* This is needed because once we're serializing this to a proto, there's no place to store information about external type parameters.
*/
@NotNull
private static FunctionDescriptor createFreeLambdaDescriptor(@NotNull FunctionDescriptor descriptor) {
FunctionDescriptor.CopyBuilder<? extends FunctionDescriptor> builder = descriptor.newCopyBuilder();
List<TypeParameterDescriptor> typeParameters = new ArrayList<>(0);
builder.setTypeParameters(typeParameters);
DeclarationDescriptor container = descriptor.getContainingDeclaration();
while (container != null) {
if (container instanceof ClassDescriptor) {
typeParameters.addAll(((ClassDescriptor) container).getDeclaredTypeParameters());
}
else if (container instanceof CallableDescriptor && !(container instanceof ConstructorDescriptor)) {
typeParameters.addAll(((CallableDescriptor) container).getTypeParameters());
}
container = container.getContainingDeclaration();
}
return typeParameters.isEmpty() ? descriptor : builder.build();
}
@Override
protected void done() {
writeOuterClassAndEnclosingMethod();
@@ -381,13 +360,30 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
@NotNull GenerationState state
) {
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container instanceof ClassDescriptor) {
// TODO: getDefaultType() here is wrong and won't work for arrays
putJavaLangClassInstance(iv, state.getTypeMapper().mapType(((ClassDescriptor) container).getDefaultType()));
wrapJavaClassIntoKClass(iv);
}
else if (container instanceof PackageFragmentDescriptor) {
iv.aconst(state.getTypeMapper().mapOwner(descriptor));
}
else if (descriptor instanceof VariableDescriptorWithAccessors) {
iv.aconst(state.getBindingContext().get(
CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, ((VariableDescriptorWithAccessors) descriptor)
));
}
else {
iv.aconst(null);
return;
}
boolean isContainerPackage =
descriptor instanceof LocalVariableDescriptor
? DescriptorUtils.getParentOfType(descriptor, ClassDescriptor.class) == null
: container instanceof PackageFragmentDescriptor;
if (isContainerPackage) {
// Note that this name is not used in reflection. There should be the name of the referenced declaration's module instead,
// but there's no nice API to obtain that name here yet
// TODO: write the referenced declaration's module name and use it in reflection
@@ -396,7 +392,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
Type.getMethodDescriptor(K_DECLARATION_CONTAINER_TYPE, getType(Class.class), getType(String.class)), false);
}
else {
iv.aconst(null);
wrapJavaClassIntoKClass(iv);
}
}

View File

@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import java.util.*
class DefaultCallArgs(val size: Int) {
@@ -32,7 +31,7 @@ class DefaultCallArgs(val size: Int) {
bits.set(index)
}
private fun toInts(): List<Int> {
fun toInts(): List<Int> {
if (bits.isEmpty || size == 0) {
return emptyList()
}
@@ -64,17 +63,4 @@ class DefaultCallArgs(val size: Int) {
}
return toInts.isNotEmpty()
}
fun generateOnStackIfNeeded(iv: InstructionAdapter, isConstructor: Boolean): Boolean {
val toInts = toInts()
if (!toInts.isEmpty()) {
for (mask in toInts) {
iv.iconst(mask)
}
val parameterType = if (isConstructor) AsmTypes.DEFAULT_CONSTRUCTOR_MARKER else AsmTypes.OBJECT_TYPE
iv.aconst(null)
}
return toInts.isNotEmpty()
}
}

View File

@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOriginFromPure
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
@@ -136,7 +137,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
(if (functionDescriptor.modality == Modality.FINAL && functionDescriptor !is ConstructorDescriptor) Opcodes.ACC_FINAL else 0) or
(if (remainingParameters.lastOrNull()?.varargElementType != null) Opcodes.ACC_VARARGS else 0)
val signature = typeMapper.mapSignatureWithCustomParameters(functionDescriptor, contextKind, remainingParameters, false)
val mv = classBuilder.newMethod(OtherOrigin(methodElement, functionDescriptor), flags,
val mv = classBuilder.newMethod(OtherOriginFromPure(methodElement, functionDescriptor), flags,
signature.asmMethod.name,
signature.asmMethod.descriptor,
signature.genericsSignature,

View File

@@ -39,11 +39,12 @@ import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenForLambda;
import org.jetbrains.kotlin.codegen.coroutines.CoroutineCodegenUtilKt;
import org.jetbrains.kotlin.codegen.coroutines.ResolvedCallWithRealDescriptor;
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
import org.jetbrains.kotlin.codegen.forLoop.AbstractForLoopGenerator;
import org.jetbrains.kotlin.codegen.forLoop.ForLoopGeneratorsKt;
import org.jetbrains.kotlin.codegen.inline.*;
import org.jetbrains.kotlin.codegen.intrinsics.*;
import org.jetbrains.kotlin.codegen.pseudoInsns.PseudoInsnsKt;
import org.jetbrains.kotlin.codegen.range.RangeValue;
import org.jetbrains.kotlin.codegen.range.RangeValuesKt;
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
@@ -59,7 +60,7 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor;
import org.jetbrains.kotlin.load.kotlin.TypeSignatureMappingKt;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
@@ -74,8 +75,7 @@ import org.jetbrains.kotlin.resolve.calls.model.*;
import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject;
import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt;
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluatorKt;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
@@ -105,9 +105,11 @@ import java.util.*;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isInt;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.extractReificationArgument;
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.unwrapInitialSignatureDescriptor;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.addInlineMarker;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.*;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.isVarCapturedInClosure;
@@ -118,7 +120,7 @@ import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFun
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> implements LocalLookup {
public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> implements LocalLookup, BaseExpressionCodegen {
private final GenerationState state;
final KotlinTypeMapper typeMapper;
private final BindingContext bindingContext;
@@ -598,7 +600,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
private void generateFor(@NotNull KtForExpression forExpression) {
generateForLoop(ForLoopGeneratorsKt.getForLoopGenerator(this, forExpression));
KtExpression range = forExpression.getLoopRange();
assert range != null : "No loop range in for expression";
RangeValue rangeValue = RangeValuesKt.createRangeValueForExpression(this, range);
generateForLoop(rangeValue.createForLoopGenerator(this, forExpression));
}
@NotNull
@@ -622,7 +627,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return context.getContextKind();
}
private void generateForLoop(AbstractForLoopGenerator generator) {
private void generateForLoop(ForLoopGenerator generator) {
Label loopExit = new Label();
Label loopEntry = new Label();
Label continueLabel = new Label();
@@ -824,14 +829,76 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@Override
public StackValue visitStringTemplateExpression(@NotNull KtStringTemplateExpression expression, StackValue receiver) {
StringBuilder constantValue = new StringBuilder("");
KtStringTemplateEntry[] entries = expression.getEntries();
List<StringTemplateEntry> entries = preprocessStringTemplate(expression);
if (entries.length == 1 && entries[0] instanceof KtStringTemplateEntryWithExpression) {
KtExpression expr = entries[0].getExpression();
return genToString(gen(expr), expressionType(expr));
Type type = expressionType(expression);
if (entries.size() == 0) {
return StackValue.constant("", type);
}
else if (entries.size() == 1) {
StringTemplateEntry entry = entries.get(0);
if (entry instanceof StringTemplateEntry.Expression) {
KtExpression expr = ((StringTemplateEntry.Expression) entry).expression;
return genToString(gen(expr), type);
}
else {
return StackValue.constant(((StringTemplateEntry.Constant) entry).value, type);
}
}
else {
return StackValue.operation(type, v -> {
genStringBuilderConstructor(v);
invokeAppendForEntries(v, entries);
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
return Unit.INSTANCE;
});
}
}
private void invokeAppendForEntries(InstructionAdapter v, List<StringTemplateEntry> entries) {
for (StringTemplateEntry entry : entries) {
if (entry instanceof StringTemplateEntry.Expression) {
invokeAppend(v, ((StringTemplateEntry.Expression) entry).expression);
}
else {
String value = ((StringTemplateEntry.Constant) entry).value;
if (value.length() == 1) {
v.iconst(value.charAt(0));
genInvokeAppendMethod(v, Type.CHAR_TYPE);
}
else {
v.aconst(value);
genInvokeAppendMethod(v, JAVA_STRING_TYPE);
}
}
}
}
private static abstract class StringTemplateEntry {
static class Constant extends StringTemplateEntry {
final String value;
Constant(String value) {
this.value = value;
}
}
static class Expression extends StringTemplateEntry {
final KtExpression expression;
Expression(KtExpression expression) {
this.expression = expression;
}
}
}
private @NotNull List<StringTemplateEntry> preprocessStringTemplate(@NotNull KtStringTemplateExpression expression) {
KtStringTemplateEntry[] entries = expression.getEntries();
List<StringTemplateEntry> result = new ArrayList<>(entries.length);
StringBuilder constantValue = new StringBuilder("");
for (KtStringTemplateEntry entry : entries) {
if (entry instanceof KtLiteralStringTemplateEntry) {
constantValue.append(entry.getText());
@@ -839,36 +906,46 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
else if (entry instanceof KtEscapeStringTemplateEntry) {
constantValue.append(((KtEscapeStringTemplateEntry) entry).getUnescapedValue());
}
else if (entry instanceof KtStringTemplateEntryWithExpression) {
KtExpression entryExpression = entry.getExpression();
if (entryExpression == null) throw new AssertionError("No expression in " + entry);
ConstantValue<?> compileTimeConstant =
getPrimitiveOrStringCompileTimeConstant(entryExpression, bindingContext, state.getShouldInlineConstVals());
if (compileTimeConstant != null && isConstantValueInlinableInStringTemplate(compileTimeConstant)) {
constantValue.append(String.valueOf(compileTimeConstant.getValue()));
}
else {
result.add(new StringTemplateEntry.Constant(constantValue.toString()));
constantValue.setLength(0);
result.add(new StringTemplateEntry.Expression(entryExpression));
}
}
else {
constantValue = null;
break;
throw new AssertionError("Unexpected string template entry: " + entry);
}
}
if (constantValue != null) {
Type type = expressionType(expression);
return StackValue.constant(constantValue.toString(), type);
}
else {
return StackValue.operation(JAVA_STRING_TYPE, v -> {
genStringBuilderConstructor(v);
for (KtStringTemplateEntry entry : entries) {
if (entry instanceof KtStringTemplateEntryWithExpression) {
invokeAppend(entry.getExpression());
}
else {
String text = entry instanceof KtEscapeStringTemplateEntry
? ((KtEscapeStringTemplateEntry) entry).getUnescapedValue()
: entry.getText();
v.aconst(text);
genInvokeAppendMethod(v, JAVA_STRING_TYPE);
}
}
v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;", false);
return Unit.INSTANCE;
});
String leftoverConstantValue = constantValue.toString();
if (leftoverConstantValue.length() > 0) {
result.add(new StringTemplateEntry.Constant(leftoverConstantValue));
}
return result;
}
private static boolean isConstantValueInlinableInStringTemplate(@NotNull ConstantValue<?> constant) {
return constant instanceof StringValue ||
constant instanceof BooleanValue ||
constant instanceof DoubleValue ||
constant instanceof FloatValue ||
constant instanceof IntegerValueConstant ||
constant instanceof NullValue;
}
@Override
public StackValue visitBlockExpression(@NotNull KtBlockExpression expression, StackValue receiver) {
return generateBlock(expression, false);
@@ -1294,10 +1371,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
int index = myFrameMap.leave(variableDescriptor);
if (isSharedVarType(type)) {
v.aconst(null);
v.store(index, OBJECT_TYPE);
}
v.visitLocalVariable(variableDescriptor.getName().asString(), type.getDescriptor(), null, scopeStart, blockEnd, index);
return null;
});
@@ -1352,6 +1425,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
//we should generate additional linenumber info after inline call only if it used as argument
@Override
public void markLineNumberAfterInlineIfNeeded() {
if (!shouldMarkLineNumbers) {
//if it used as general argument
@@ -1366,6 +1440,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
@Override
public int getLastLineNumber() {
return myLastLineNumber;
}
@@ -1414,14 +1489,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
Label finallyStart = new Label();
v.mark(finallyStart);
finallyBlockStackElement.addGapLabel(finallyStart);
if (InlineCodegenUtil.isFinallyMarkerRequired(context)) {
InlineCodegenUtil.generateFinallyMarker(v, finallyDepth, true);
if (isFinallyMarkerRequired(context)) {
generateFinallyMarker(v, finallyDepth, true);
}
//noinspection ConstantConditions
gen(jetTryExpression.getFinallyBlock().getFinalExpression(), Type.VOID_TYPE);
if (InlineCodegenUtil.isFinallyMarkerRequired(context)) {
InlineCodegenUtil.generateFinallyMarker(v, finallyDepth, false);
if (isFinallyMarkerRequired(context)) {
generateFinallyMarker(v, finallyDepth, false);
}
}
@@ -1464,7 +1539,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
generateFinallyBlocksIfNeeded(returnType, afterReturnLabel);
if (isNonLocalReturn) {
InlineCodegenUtil.generateGlobalReturnFlag(v, nonLocalReturn.labelName);
generateGlobalReturnFlag(v, nonLocalReturn.labelName);
v.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
}
else {
@@ -1502,7 +1577,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
FunctionDescriptor containingFunction =
BindingContextUtils.getContainingFunctionSkipFunctionLiterals(descriptor, true).getFirst();
//FIRST_FUN_LABEL to prevent clashing with existing labels
return new NonLocalReturnInfo(typeMapper.mapReturnType(containingFunction), InlineCodegenUtil.FIRST_FUN_LABEL);
return new NonLocalReturnInfo(typeMapper.mapReturnType(containingFunction), FIRST_FUN_LABEL);
} else {
//local
return null;
@@ -1538,11 +1613,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
// If it does not end with return we should return something
// because if we don't there can be VerifyError (specific cases with Nothing-typed expressions)
if (!endsWithReturn(expr)) {
markLineNumber(expr, true);
if (isLambdaVoidBody(expr, typeForExpression)) {
markLineNumber((KtFunctionLiteral) expr.getParent(), true);
}
else {
markLineNumber(expr, true);
}
if (typeForExpression.getSort() == Type.VOID) {
StackValue.none().put(returnType, v);
@@ -1706,31 +1782,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return lookupCapturedValueInConstructorParameters(descriptor);
}
return lookupValuaAndLocalVariableMetadata(descriptor, StackValue.LOCAL_0, state, false, context, this);
}
@Nullable
static StackValue lookupValuaAndLocalVariableMetadata(
@NotNull DeclarationDescriptor descriptor,
@NotNull StackValue prefix,
@NotNull GenerationState state,
boolean ignoreNoOuter,
@NotNull CodegenContext context,
@Nullable ExpressionCodegen codegen
) {
StackValue value = context.lookupInContext(descriptor, prefix, state, ignoreNoOuter);
if(!isDelegatedLocalVariable(descriptor) || value == null) {
return value;
StackValue value = context.lookupInContext(descriptor, StackValue.LOCAL_0, state, false);
if (isDelegatedLocalVariable(descriptor) && value != null) {
VariableDescriptor metadata = getDelegatedLocalVariableMetadata((VariableDescriptor) descriptor, bindingContext);
StackValue metadataValue = context.lookupInContext(metadata, StackValue.LOCAL_0, state, false);
assert metadataValue != null : "Metadata stack value should be non-null for local delegated property: " + descriptor;
return delegatedVariableValue(value, metadataValue, (VariableDescriptorWithAccessors) descriptor, typeMapper);
}
VariableDescriptor metadata = getDelegatedLocalVariableMetadata((VariableDescriptor) descriptor, state.getBindingContext());
StackValue metadataValue = context.lookupInContext(metadata, prefix, state, ignoreNoOuter);
assert metadataValue != null : "Metadata stack value should be non-null for local delegated property";
//required for ImplementationBodyCodegen.lookupConstructorExpressionsInClosureIfPresent
if (codegen == null) return null;
return codegen.delegatedVariableValue(value, metadataValue, (VariableDescriptorWithAccessors) descriptor,
state.getTypeMapper());
return value;
}
@Nullable
@@ -1741,7 +1801,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
int parameterOffsetInConstructor = context.closure.getCapturedParameterOffsetInConstructor(descriptor);
// when captured parameter is singleton
// see compiler/testData/codegen/box/objects/objectInLocalAnonymousObject.kt (fun local() captured in A)
if (parameterOffsetInConstructor == -1) return adjustVariableValue(parentResult , descriptor);
if (parameterOffsetInConstructor == -1) return adjustVariableValue(parentResult, descriptor);
assert parentResult instanceof StackValue.Field || parentResult instanceof StackValue.FieldForSharedVar
: "Part of closure should be either Field or FieldForSharedVar";
@@ -1978,32 +2038,27 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return genClosure((KtNamedFunction) expression, samType);
}
Type asmType =
state.getSamWrapperClasses().getSamWrapperClass(samType, expression.getContainingKtFile(), this);
Type asmType = state.getSamWrapperClasses().getSamWrapperClass(samType, expression.getContainingKtFile(), this);
return StackValue.operation(asmType, v -> {
v.anew(asmType);
v.dup();
Label afterAll = new Label();
Type functionType = typeMapper.mapType(samType.getKotlinFunctionType());
expression.accept(visitor, StackValue.none()).put(functionType, v);
Label ifNonNull = new Label();
Label afterAll = new Label();
v.dup();
v.ifnonnull(ifNonNull);
v.ifnull(afterAll);
// if null: pop function value and wrapper objects, put null
v.pop();
v.pop2();
v.aconst(null);
v.goTo(afterAll);
v.mark(ifNonNull);
int tmp = myFrameMap.enterTemp(functionType);
v.store(tmp, functionType);
v.anew(asmType);
v.dup();
v.load(tmp, functionType);
v.invokespecial(asmType.getInternalName(), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, functionType), false);
myFrameMap.leaveTemp(functionType);
v.mark(afterAll);
return null;
});
}
@@ -2172,19 +2227,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
if (isSuspendCall) {
v.invokestatic(
CoroutineCodegenUtilKt.COROUTINE_MARKER_OWNER,
CoroutineCodegenUtilKt.BEFORE_SUSPENSION_POINT_MARKER_NAME,
"()V", false
);
addSuspendMarker(v, true);
}
callGenerator.genCall(callableMethod, resolvedCall, defaultMaskWasGenerated, this);
if (isSuspendCall) {
v.invokestatic(
CoroutineCodegenUtilKt.COROUTINE_MARKER_OWNER,
CoroutineCodegenUtilKt.AFTER_SUSPENSION_POINT_MARKER_NAME, "()V", false);
addSuspendMarker(v, false);
addInlineMarker(v, false);
}
@@ -2233,12 +2282,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
// But the problem is that we should leave the receiver itself on the stack, so we store it in a temporary variable.
if (isSuspendCall && isSafeCallOrOnStack) {
boolean bothReceivers =
receiver instanceof StackValue.CallReceiver
&& ((StackValue.CallReceiver) receiver).getDispatchReceiver().type.getSort() != Type.VOID
&& ((StackValue.CallReceiver) receiver).getExtensionReceiver().type.getSort() != Type.VOID;
receiver instanceof CallReceiver
&& ((CallReceiver) receiver).getDispatchReceiver().type.getSort() != Type.VOID
&& ((CallReceiver) receiver).getExtensionReceiver().type.getSort() != Type.VOID;
Type firstReceiverType =
bothReceivers
? ((StackValue.CallReceiver) receiver).getDispatchReceiver().type
? ((CallReceiver) receiver).getDispatchReceiver().type
: receiver.type;
Type secondReceiverType = bothReceivers ? receiver.type : null;
@@ -2286,19 +2335,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
FunctionDescriptor original =
unwrapInitialSignatureDescriptor(DescriptorUtils.unwrapFakeOverride((FunctionDescriptor) descriptor.getOriginal()));
if (isDefaultCompilation) {
return new InlineCodegenForDefaultBody(original, this, state);
return new InlineCodegenForDefaultBody(original, this, state, new PsiSourceCompilerForInline(this, callElement));
}
else {
return new InlineCodegen(this, state, original, callElement, typeParameterMappings);
return new PsiInlineCodegen(this, state, original, typeParameterMappings, new PsiSourceCompilerForInline(this, callElement));
}
}
@NotNull
private static FunctionDescriptor unwrapInitialSignatureDescriptor(@NotNull FunctionDescriptor function) {
if (function.getInitialSignatureDescriptor() != null) return function.getInitialSignatureDescriptor();
return function;
}
@NotNull
protected CallGenerator getOrCreateCallGeneratorForDefaultImplBody(@NotNull FunctionDescriptor descriptor, @Nullable KtNamedFunction function) {
return getOrCreateCallGenerator(descriptor, function, null, true);
@@ -2368,22 +2411,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return typeArgumentsMap;
}
@Nullable
private static Pair<TypeParameterDescriptor, ReificationArgument> extractReificationArgument(@NotNull KotlinType type) {
int arrayDepth = 0;
boolean isNullable = type.isMarkedNullable();
while (KotlinBuiltIns.isArray(type)) {
arrayDepth++;
type = type.getArguments().get(0).getType();
}
TypeParameterDescriptor parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type);
if (parameterDescriptor == null) return null;
return new Pair<>(parameterDescriptor, new ReificationArgument(parameterDescriptor.getName().asString(), isNullable, arrayDepth));
}
@NotNull
public StackValue generateReceiverValue(@Nullable ReceiverValue receiverValue, boolean isSuper) {
if (receiverValue instanceof ImplicitClassReceiver) {
@@ -2828,76 +2855,9 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
private StackValue generateIn(StackValue leftValue, KtExpression rangeExpression, KtSimpleNameExpression operationReference) {
KtExpression deparenthesized = KtPsiUtil.deparenthesize(rangeExpression);
assert deparenthesized != null : "For with empty range expression";
boolean isInverted = operationReference.getReferencedNameElementType() == KtTokens.NOT_IN;
return StackValue.operation(Type.BOOLEAN_TYPE, v -> {
if (RangeCodegenUtil.isPrimitiveRangeSpecializationOfType(leftValue.type, deparenthesized, bindingContext) ||
RangeCodegenUtil.isPrimitiveRangeToExtension(operationReference, bindingContext)) {
generateInPrimitiveRange(leftValue, (KtBinaryExpression) deparenthesized, isInverted);
}
else {
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt
.getResolvedCallWithAssert(operationReference, bindingContext);
StackValue result = invokeFunction(resolvedCall.getCall(), resolvedCall, StackValue.none());
result.put(result.type, v);
if (isInverted) {
genInvertBoolean(v);
}
}
return null;
});
}
/*
* Translates x in a..b to a <= x && x <= b
* and x !in a..b to a > x || x > b for any primitive type
*/
private void generateInPrimitiveRange(StackValue argument, KtBinaryExpression rangeExpression, boolean isInverted) {
Type rangeType = argument.type;
int localVarIndex = myFrameMap.enterTemp(rangeType);
// Load left bound
gen(rangeExpression.getLeft(), rangeType);
// Load x into local variable to avoid StackValue#put side-effects
argument.put(rangeType, v);
v.store(localVarIndex, rangeType);
v.load(localVarIndex, rangeType);
// If (x < left) goto L1
Label l1 = new Label();
emitGreaterThan(rangeType, l1);
// If (x > right) goto L1
v.load(localVarIndex, rangeType);
gen(rangeExpression.getRight(), rangeType);
emitGreaterThan(rangeType, l1);
Label l2 = new Label();
v.iconst(isInverted ? 0 : 1);
v.goTo(l2);
v.mark(l1);
v.iconst(isInverted ? 1 : 0);
v.mark(l2);
myFrameMap.leaveTemp(rangeType);
}
private void emitGreaterThan(Type type, Label label) {
if (AsmUtil.isIntPrimitive(type)) {
v.ificmpgt(label);
}
else if (type == Type.LONG_TYPE) {
v.lcmp();
v.ifgt(label);
}
// '>' != 'compareTo' for NaN and +/- 0.0
else if (type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE) {
v.cmpg(type);
v.ifgt(label);
}
else {
throw new UnsupportedOperationException("Unexpected type: " + type);
}
RangeValue rangeValue = RangeValuesKt.createRangeValueForExpression(this, deparenthesized);
return rangeValue.createInExpressionGenerator(this, operationReference).generate(leftValue);
}
private StackValue generateBooleanAnd(KtBinaryExpression expression) {
@@ -2935,6 +2895,20 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return genCmpPrimitiveToSafeCall(left, leftType, (KtSafeQualifiedExpression) right, opToken);
}
if (BoxedToPrimitiveEquality.isApplicable(opToken, leftType, rightType)) {
return BoxedToPrimitiveEquality.create(opToken, genLazy(left, leftType), leftType, genLazy(right, rightType), rightType,
myFrameMap);
}
if (PrimitiveToBoxedEquality.isApplicable(opToken, leftType, rightType)) {
return PrimitiveToBoxedEquality.create(opToken, genLazy(left, leftType), leftType, genLazy(right, rightType), rightType);
}
if (PrimitiveToObjectEquality.isApplicable(opToken, leftType, rightType)) {
return PrimitiveToObjectEquality.create(opToken, genLazy(left, leftType), leftType, genLazy(right, rightType), rightType);
}
if (isPrimitive(leftType) != isPrimitive(rightType)) {
leftType = boxType(leftType);
rightType = boxType(rightType);
@@ -3272,22 +3246,31 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
public void invokeAppend(KtExpression expr) {
public void invokeAppend(InstructionAdapter v, KtExpression expr) {
expr = KtPsiUtil.safeDeparenthesize(expr);
ConstantValue<?> compileTimeConstant = getPrimitiveOrStringCompileTimeConstant(expr, bindingContext, state.getShouldInlineConstVals());
if (compileTimeConstant == null && expr instanceof KtBinaryExpression) {
KtBinaryExpression binaryExpression = (KtBinaryExpression) expr;
if (binaryExpression.getOperationToken() == KtTokens.PLUS) {
KtExpression left = binaryExpression.getLeft();
KtExpression right = binaryExpression.getRight();
Type leftType = expressionType(left);
if (compileTimeConstant == null) {
if (expr instanceof KtBinaryExpression) {
KtBinaryExpression binaryExpression = (KtBinaryExpression) expr;
if (binaryExpression.getOperationToken() == KtTokens.PLUS) {
KtExpression left = binaryExpression.getLeft();
KtExpression right = binaryExpression.getRight();
Type leftType = expressionType(left);
if (leftType.equals(JAVA_STRING_TYPE)) {
invokeAppend(left);
invokeAppend(right);
return;
if (leftType.equals(JAVA_STRING_TYPE)) {
invokeAppend(v, left);
invokeAppend(v, right);
return;
}
}
}
else if (expr instanceof KtStringTemplateExpression) {
List<StringTemplateEntry> entries = preprocessStringTemplate((KtStringTemplateExpression) expr);
invokeAppendForEntries(v, entries);
return;
}
}
Type exprType = expressionType(expr);
@@ -3517,7 +3500,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
@NotNull
private StackValue getVariableMetadataValue(VariableDescriptor variableDescriptor) {
private StackValue getVariableMetadataValue(@NotNull VariableDescriptorWithAccessors variableDescriptor) {
StackValue value = findLocalOrCapturedValue(getDelegatedLocalVariableMetadata(variableDescriptor, bindingContext));
assert value != null : "Can't find stack value for local delegated variable metadata: " + variableDescriptor;
return value;
@@ -3563,14 +3546,13 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
StackValue metadataValue = getVariableMetadataValue(variableDescriptor);
initializePropertyMetadata((KtProperty) variableDeclaration, variableDescriptor, metadataValue);
ResolvedCall<FunctionDescriptor> provideDelegateResolvedCall = bindingContext.get(PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor);
if (provideDelegateResolvedCall != null) {
resultType = generateProvideDelegateCallForLocalVariable(initializer, metadataValue, provideDelegateResolvedCall);
ResolvedCall<FunctionDescriptor> provideDelegateCall = bindingContext.get(PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor);
if (provideDelegateCall != null) {
resultType = generateProvideDelegateCallForLocalVariable(initializer, metadataValue, provideDelegateCall);
}
}
storeTo.storeSelector(resultType, v);
}
@NotNull
@@ -3617,10 +3599,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
@NotNull LocalVariableDescriptor variableDescriptor,
@NotNull StackValue metadataVar
) {
// TODO: do not generate anonymous classes for local delegated properties in inline functions
// We can use the $$delegatedProperties array as in non-inline functions and upon inlining, detect elements at what indices
// of that array are used in the inline function body, load the corresponding initializing bytecode from <clinit> of the
// container class (where the PropertyReferenceNImpl instance is created), copy and adapt it at the call site
//noinspection ConstantConditions
StackValue value = generatePropertyReference(variable.getDelegate(), variableDescriptor, variableDescriptor, null, null);
value.put(K_PROPERTY0_TYPE, v);
metadataVar.storeSelector(K_PROPERTY0_TYPE, v);
StackValue value = context.getFunctionDescriptor().isInline()
? generatePropertyReference(variable.getDelegate(), variableDescriptor, variableDescriptor, null, null)
: PropertyCodegen.getDelegatedPropertyMetadata(variableDescriptor, bindingContext);
value.put(K_PROPERTY_TYPE, v);
metadataVar.storeSelector(K_PROPERTY_TYPE, v);
}
@NotNull
@@ -4060,19 +4048,17 @@ The "returned" value of try expression with no finally is either the last expres
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind
) {
putReifiedOperationMarkerIfTypeIsReifiedParameter(type, operationKind, v);
putReifiedOperationMarkerIfTypeIsReifiedParameter(type, operationKind, v, this);
}
public void putReifiedOperationMarkerIfTypeIsReifiedParameter(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v
public static void putReifiedOperationMarkerIfTypeIsReifiedParameter(
@NotNull KotlinType type, @NotNull ReifiedTypeInliner.OperationKind operationKind, @NotNull InstructionAdapter v,
@NotNull BaseExpressionCodegen codegen
) {
Pair<TypeParameterDescriptor, ReificationArgument> typeParameterAndReificationArgument = extractReificationArgument(type);
if (typeParameterAndReificationArgument != null && typeParameterAndReificationArgument.getFirst().isReified()) {
TypeParameterDescriptor typeParameterDescriptor = typeParameterAndReificationArgument.getFirst();
if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) {
parentCodegen.getReifiedTypeParametersUsages().
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
}
codegen.consumeReifiedOperationMarker(typeParameterDescriptor);
v.iconst(operationKind.getId());
v.visitLdcInsn(typeParameterAndReificationArgument.getSecond().asString());
v.invokestatic(
@@ -4082,6 +4068,7 @@ The "returned" value of try expression with no finally is either the last expres
}
}
@Override
public void propagateChildReifiedTypeParametersUsages(@NotNull ReifiedTypeParametersUsages usages) {
parentCodegen.getReifiedTypeParametersUsages().propagateChildUsagesWithinContext(usages, context);
}
@@ -4203,6 +4190,7 @@ The "returned" value of try expression with no finally is either the last expres
return context.getContextDescriptor().toString();
}
@Override
@NotNull
public FrameMap getFrameMap() {
return myFrameMap;
@@ -4213,12 +4201,13 @@ The "returned" value of try expression with no finally is either the last expres
return context;
}
@Override
@NotNull
public NameGenerator getInlineNameGenerator() {
NameGenerator nameGenerator = getParentCodegen().getInlineNameGenerator();
Name name = context.getContextDescriptor().getName();
String inlinedName = name.isSpecial() ? InlineCodegenUtil.SPECIAL_TRANSFORMATION_NAME : name.asString();
return nameGenerator.subGenerator(inlinedName + InlineCodegenUtil.INLINE_CALL_TRANSFORMATION_SUFFIX);
String inlinedName = name.isSpecial() ? SPECIAL_TRANSFORMATION_NAME : name.asString();
return nameGenerator.subGenerator(inlinedName + INLINE_CALL_TRANSFORMATION_SUFFIX);
}
public Type getReturnType() {
@@ -4255,4 +4244,18 @@ The "returned" value of try expression with no finally is either the last expres
) {
return StackValue.delegate(typeMapper.mapType(variableDescriptor.getType()), delegateValue, metadataValue, variableDescriptor, this);
}
@NotNull
@Override
public InstructionAdapter getVisitor() {
return v;
}
@Override
public void consumeReifiedOperationMarker(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
if (typeParameterDescriptor.getContainingDeclaration() != context.getContextDescriptor()) {
parentCodegen.getReifiedTypeParametersUsages().
addUsedReifiedParameter(typeParameterDescriptor.getName().asString());
}
}
}

View File

@@ -229,6 +229,13 @@ public class FunctionCodegen {
}
asmMethod = CoroutineCodegenUtilKt.getImplForOpenMethod(asmMethod, v.getThisName());
// remove generic signature as it's unnecessary for synthetic methods
jvmSignature =
new JvmMethodGenericSignature(
asmMethod,
jvmSignature.getValueParameters(),
null
);
mv.visitMethodInsn(
Opcodes.INVOKESTATIC,
@@ -995,12 +1002,19 @@ public class FunctionCodegen {
capturedArgumentsCount++;
}
int maskIndex = 0;
List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
for (int index = 0; index < valueParameters.size(); index++) {
assert valueParameters.size() > 0 : "Expecting value parameters to generate default function " + functionDescriptor;
int firstMaskIndex = frameMap.enterTemp(Type.INT_TYPE);
for (int index = 1; index < valueParameters.size(); index++) {
if (index % Integer.SIZE == 0) {
maskIndex = frameMap.enterTemp(Type.INT_TYPE);
frameMap.enterTemp(Type.INT_TYPE);
}
}
//default handler or constructor marker
frameMap.enterTemp(AsmTypes.OBJECT_TYPE);
for (int index = 0; index < valueParameters.size(); index++) {
int maskIndex = firstMaskIndex + index / Integer.SIZE;
ValueParameterDescriptor parameterDescriptor = valueParameters.get(index);
Type type = mappedParameters.get(capturedArgumentsCount + index).getAsmType();

View File

@@ -31,11 +31,11 @@ import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.binding.MutableClosure;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension;
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens;
@@ -65,10 +65,7 @@ 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.org.objectweb.asm.FieldVisitor;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
@@ -79,6 +76,7 @@ import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isGenericToArray;
import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isNonGenericToArray;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtils2Kt.initDefaultSourceMappingIfNeeded;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall;
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getNotNull;
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
@@ -217,7 +215,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
v.visitSource(myClass.getContainingKtFile().getName(), null);
InlineCodegenUtil.initDefaultSourceMappingIfNeeded(context, this, state);
initDefaultSourceMappingIfNeeded(context, this, state);
writeEnclosingMethod();
@@ -348,9 +346,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
@Override
protected void generateSyntheticParts() {
protected void generateSyntheticPartsBeforeBody() {
generatePropertyMetadataArrayFieldIfNeeded(classAsmType);
}
@Override
protected void generateSyntheticPartsAfterBody() {
generateFieldForSingleton();
generateCompanionObjectBackingFieldCopies();
@@ -573,7 +574,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.ifnull(ifNull);
}
genHashCode(mv, iv, asmType);
genHashCode(mv, iv, asmType, state.getTarget());
if (ifNull != null) {
Label end = new Label();
@@ -678,7 +679,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
) {
Type thisDescriptorType = typeMapper.mapType(descriptor);
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(myClass, function), function, new FunctionGenerationStrategy() {
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOriginFromPure(myClass, function), function, new FunctionGenerationStrategy() {
@Override
public void generateBody(
@NotNull MethodVisitor mv,
@@ -778,7 +779,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
FunctionDescriptor valuesFunction =
CollectionsKt.single(descriptor.getStaticScope().getContributedFunctions(ENUM_VALUES, NoLookupLocation.FROM_BACKEND));
MethodVisitor mv = v.newMethod(
JvmDeclarationOriginKt.OtherOrigin(myClass, valuesFunction), ACC_PUBLIC | ACC_STATIC, ENUM_VALUES.asString(),
JvmDeclarationOriginKt.OtherOriginFromPure(myClass, valuesFunction), ACC_PUBLIC | ACC_STATIC, ENUM_VALUES.asString(),
"()" + type.getDescriptor(), null, null
);
if (!state.getClassBuilderMode().generateBodies) return;
@@ -796,7 +797,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
CollectionsKt.single(descriptor.getStaticScope().getContributedFunctions(ENUM_VALUE_OF, NoLookupLocation.FROM_BACKEND),
DescriptorUtilsKt::isEnumValueOfMethod);
MethodVisitor mv =
v.newMethod(JvmDeclarationOriginKt.OtherOrigin(myClass, valueOfFunction), ACC_PUBLIC | ACC_STATIC, ENUM_VALUE_OF.asString(),
v.newMethod(JvmDeclarationOriginKt.OtherOriginFromPure(myClass, valueOfFunction), ACC_PUBLIC | ACC_STATIC, ENUM_VALUE_OF.asString(),
"(Ljava/lang/String;)" + classAsmType.getDescriptor(), null, null);
if (!state.getClassBuilderMode().generateBodies) return;
@@ -814,7 +815,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (isNonCompanionObject(descriptor)) {
StackValue.Field field = StackValue.singletonViaInstance(descriptor, typeMapper);
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass),
v.newField(JvmDeclarationOriginKt.OtherOriginFromPure(myClass),
ACC_PUBLIC | ACC_STATIC | ACC_FINAL,
field.name, field.type.getDescriptor(), null, null);
@@ -835,9 +836,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Nullable KtObjectDeclaration companionObject = CollectionsKt.firstOrNull(myClass.getCompanionObjects());
int properFieldVisibilityFlag = getVisibilityAccessFlag(companionObjectDescriptor);
boolean fieldShouldBeDeprecated =
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.DeprecatedFieldForInvisibleCompanionObject) &&
(properFieldVisibilityFlag & (ACC_PRIVATE | ACC_PROTECTED)) != 0;
// TODO generate field with proper visibility in language version 1.3
int fieldAccessFlags = ACC_PUBLIC | ACC_STATIC | ACC_FINAL;
if (fieldShouldBeDeprecated) {
fieldAccessFlags |= ACC_DEPRECATED;
}
StackValue.Field field = StackValue.singleton(companionObjectDescriptor, typeMapper);
v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject == null ? myClass.getPsiOrParent() : companionObject),
ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null);
FieldVisitor fv = v.newField(JvmDeclarationOriginKt.OtherOrigin(companionObject == null ? myClass.getPsiOrParent() : companionObject),
fieldAccessFlags, field.name, field.type.getDescriptor(), null, null);
if (fieldShouldBeDeprecated) {
AnnotationCodegen.forField(fv, this, typeMapper).visitAnnotation("Ljava/lang/Deprecated;", true).visitEnd();
}
}
private void generateCompanionObjectBackingFieldCopies() {
@@ -1105,9 +1118,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
private final Map<KtDelegatedSuperTypeEntry, Field> fields = new HashMap<>();
@NotNull
@Nullable
public Field getInfo(KtDelegatedSuperTypeEntry specifier) {
return fields.get(specifier);
Field field = fields.get(specifier);
assert field != null || state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES : "No field for " + specifier.getText();
return field;
}
private void addField(KtDelegatedSuperTypeEntry specifier, PropertyDescriptor propertyDescriptor) {
@@ -1127,22 +1142,24 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (KtSuperTypeListEntry specifier : delegationSpecifiers) {
if (specifier instanceof KtDelegatedSuperTypeEntry) {
KtExpression expression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
PropertyDescriptor propertyDescriptor = expression != null
? CodegenUtil.getDelegatePropertyIfAny(expression, descriptor, bindingContext)
: null;
if (expression == null) continue;
PropertyDescriptor propertyDescriptor = CodegenUtil.getDelegatePropertyIfAny(expression, descriptor, bindingContext);
if (CodegenUtil.isFinalPropertyWithBackingField(propertyDescriptor, bindingContext)) {
result.addField((KtDelegatedSuperTypeEntry) specifier, propertyDescriptor);
}
else {
KotlinType expressionType = expression != null
? bindingContext.getType(expression)
: null;
KotlinType expressionType = bindingContext.getType(expression);
ClassDescriptor superClass = getSuperClass(specifier);
if (superClass != null) {
Type asmType = expressionType != null ? typeMapper.mapType(expressionType) : typeMapper.mapType(superClass);
result.addField((KtDelegatedSuperTypeEntry) specifier, asmType, JvmAbi.DELEGATE_SUPER_FIELD_PREFIX + n);
}
Type asmType =
expressionType != null ? typeMapper.mapType(expressionType) :
superClass != null ? typeMapper.mapType(superClass) : null;
if (asmType == null) continue;
result.addField((KtDelegatedSuperTypeEntry) specifier, asmType, JvmAbi.DELEGATE_SUPER_FIELD_PREFIX + n);
}
n++;
}
@@ -1152,7 +1169,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
@Nullable
private ClassDescriptor getSuperClass(@NotNull KtSuperTypeListEntry specifier) {
return CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext);
ClassDescriptor superClass = CodegenUtil.getSuperClassBySuperTypeListEntry(specifier, bindingContext);
assert superClass != null || state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES
: "ClassDescriptor should not be null:" + specifier.getText();
return superClass;
}
private void genCallToDelegatorByExpressionSpecifier(
@@ -1164,6 +1185,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
KtExpression expression = specifier.getDelegateExpression();
DelegationFieldsInfo.Field fieldInfo = fieldsInfo.getInfo(specifier);
if (fieldInfo == null) return;
if (fieldInfo.generateField) {
iv.load(0, classAsmType);
fieldInfo.getStackValue().store(codegen.gen(expression), iv);
@@ -1224,9 +1247,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
private void lookupInContext(@NotNull DeclarationDescriptor toLookup) {
ExpressionCodegen.lookupValuaAndLocalVariableMetadata(toLookup, StackValue.LOCAL_0, state, true, context, null);
context.lookupInContext(toLookup, StackValue.LOCAL_0, state, true);
}
@Override
@@ -1550,7 +1572,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
InstructionAdapter iv = codegen.v;
Type arrayAsmType = typeMapper.mapType(DescriptorUtilsKt.getBuiltIns(descriptor).getArrayType(INVARIANT, descriptor.getDefaultType()));
v.newField(JvmDeclarationOriginKt.OtherOrigin(myClass), ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, ENUM_VALUES_FIELD_NAME,
v.newField(JvmDeclarationOriginKt.OtherOriginFromPure(myClass), ACC_PRIVATE | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, ENUM_VALUES_FIELD_NAME,
arrayAsmType.getDescriptor(), null, null);
iv.iconst(enumEntries.size());
@@ -1609,10 +1631,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (KtSuperTypeListEntry specifier : myClass.getSuperTypeListEntries()) {
if (specifier instanceof KtDelegatedSuperTypeEntry) {
DelegationFieldsInfo.Field field = delegationFieldsInfo.getInfo((KtDelegatedSuperTypeEntry) specifier);
if (field == null) continue;
generateDelegateField(field);
KtExpression delegateExpression = ((KtDelegatedSuperTypeEntry) specifier).getDelegateExpression();
KotlinType delegateExpressionType = delegateExpression != null ? bindingContext.getType(delegateExpression) : null;
generateDelegates(getSuperClass(specifier), delegateExpressionType, field);
ClassDescriptor superClass = getSuperClass(specifier);
if (superClass == null) continue;
generateDelegates(superClass, delegateExpressionType, field);
}
}
}

View File

@@ -70,7 +70,7 @@ class InterfaceImplBodyCodegen(
return classDescriptorImpl
}
override fun generateSyntheticParts() {
override fun generateSyntheticPartsAfterBody() {
for (memberDescriptor in descriptor.defaultType.memberScope.getContributedDescriptors()) {
if (memberDescriptor !is CallableMemberDescriptor) continue

View File

@@ -94,8 +94,7 @@ class JvmStaticInCompanionObjectGenerator(
CallableMemberDescriptor.Kind.SYNTHESIZED,
false
)
val staticFunctionDescriptor = copies[descriptor]!!
return staticFunctionDescriptor
return copies[descriptor]!!
}
}
}

View File

@@ -24,14 +24,19 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.CodegenUtil;
import org.jetbrains.kotlin.codegen.annotation.AnnotatedSimple;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.inline.*;
import org.jetbrains.kotlin.codegen.inline.DefaultSourceMapper;
import org.jetbrains.kotlin.codegen.inline.NameGenerator;
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages;
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
import org.jetbrains.kotlin.fileClasses.FileClasses;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
@@ -44,8 +49,8 @@ import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.synthetics.SyntheticClassOrObjectDescriptor;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.BindingContextUtils;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
@@ -66,11 +71,15 @@ import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.*;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.*;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceWithDefaultsMember;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getInlineName;
import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.SYNTHESIZED;
import static org.jetbrains.kotlin.resolve.BindingContext.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
@@ -127,11 +136,18 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
public void generate() {
generateDeclaration();
boolean shouldGenerateSyntheticParts =
!(element instanceof KtClassOrObject) ||
state.getGenerateDeclaredClassFilter().shouldGenerateClassMembers((KtClassOrObject) element);
if (shouldGenerateSyntheticParts) {
generateSyntheticPartsBeforeBody();
}
generateBody();
if (!(element instanceof KtClassOrObject) ||
state.getGenerateDeclaredClassFilter().shouldGenerateClassMembers((KtClassOrObject) element)) {
generateSyntheticParts();
if (shouldGenerateSyntheticParts) {
generateSyntheticPartsAfterBody();
}
if (state.getClassBuilderMode().generateMetadata) {
@@ -143,9 +159,12 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
protected abstract void generateDeclaration();
protected void generateSyntheticPartsBeforeBody() {
}
protected abstract void generateBody();
protected void generateSyntheticParts() {
protected void generateSyntheticPartsAfterBody() {
}
protected abstract void generateKotlinMetadataAnnotation();
@@ -296,7 +315,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
Type classType = state.getTypeMapper().mapClass(descriptor);
ClassBuilder classBuilder = state.getFactory().newVisitor(
JvmDeclarationOriginKt.OtherOrigin(aClass, descriptor),
JvmDeclarationOriginKt.OtherOriginFromPure(aClass, descriptor),
classType, aClass.getContainingKtFile());
ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state);
new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, parentCodegen, false).generate();
@@ -437,7 +456,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
@NotNull
public NameGenerator getInlineNameGenerator() {
if (inlineNameGenerator == null) {
String prefix = InlineCodegenUtil.getInlineName(context, typeMapper, fileClassesProvider);
String prefix = getInlineName(context, typeMapper, fileClassesProvider);
inlineNameGenerator = new NameGenerator(prefix);
}
return inlineNameGenerator;
@@ -510,11 +529,8 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
StackValue provideDelegateReceiver = codegen.gen(initializer);
int indexOfDelegatedProperty = PropertyCodegen.indexOfDelegatedProperty(property);
StackValue delegateValue = PropertyCodegen.invokeDelegatedPropertyConventionMethodWithReceiver(
codegen, typeMapper, provideDelegateResolvedCall, indexOfDelegatedProperty, 1,
provideDelegateReceiver, propertyDescriptor
StackValue delegateValue = PropertyCodegen.invokeDelegatedPropertyConventionMethod(
codegen, provideDelegateResolvedCall, provideDelegateReceiver, propertyDescriptor
);
propValue.store(delegateValue, codegen.v);
@@ -594,16 +610,8 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
}
protected void generatePropertyMetadataArrayFieldIfNeeded(@NotNull Type thisAsmType) {
List<KtProperty> delegatedProperties = new ArrayList<>();
for (KtDeclaration declaration : ((KtDeclarationContainer) element).getDeclarations()) {
if (declaration instanceof KtProperty) {
KtProperty property = (KtProperty) declaration;
if (property.hasDelegate()) {
delegatedProperties.add(property);
}
}
}
if (delegatedProperties.isEmpty()) return;
List<VariableDescriptorWithAccessors> delegatedProperties = bindingContext.get(CodegenBinding.DELEGATED_PROPERTIES, thisAsmType);
if (delegatedProperties == null || delegatedProperties.isEmpty()) return;
v.newField(NO_ORIGIN, ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME,
"[" + K_PROPERTY_TYPE, null, null);
@@ -615,8 +623,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
iv.newarray(K_PROPERTY_TYPE);
for (int i = 0, size = delegatedProperties.size(); i < size; i++) {
PropertyDescriptor property =
(PropertyDescriptor) BindingContextUtils.getNotNull(bindingContext, VARIABLE, delegatedProperties.get(i));
VariableDescriptorWithAccessors property = delegatedProperties.get(i);
iv.dup();
iv.iconst(i);
@@ -626,10 +633,12 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
iv.anew(implType);
iv.dup();
// TODO: generate the container once and save to a local field instead (KT-10495)
ClosureCodegen.generateCallableReferenceDeclarationContainer(iv, property, state);
iv.aconst(property.getName().asString());
PropertyReferenceCodegen.generateCallableReferenceSignature(iv, property, state);
iv.invokespecial(
implType.getInternalName(), "<init>",
Type.getMethodDescriptor(Type.VOID_TYPE, K_DECLARATION_CONTAINER_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE), false
@@ -679,7 +688,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
protected void generateConstInstance(@NotNull Type thisAsmType, @NotNull Type fieldAsmType) {
v.newField(
JvmDeclarationOriginKt.OtherOrigin(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD,
JvmDeclarationOriginKt.OtherOriginFromPure(element), ACC_STATIC | ACC_FINAL | ACC_PUBLIC, JvmAbi.INSTANCE_FIELD,
fieldAsmType.getDescriptor(), null, null
);

View File

@@ -205,11 +205,8 @@ class MultifileClassCodegenImpl(
val packageFragment = this.packageFragment
?: throw AssertionError("File part $file of $facadeFqName: no package fragment")
val partClassFqName = file.getFileClassFqName()
val partInitializerClassFqName = FqName(partClassFqName.asString() + "__Init")
val partType = partClassFqName.toAsmType()
val partInitializerType = partInitializerClassFqName.toAsmType()
val partContext = state.rootContext.intoMultifileClassPart(packageFragment, facadeClassType, partType, partInitializerType, file)
val partType = file.getFileClassFqName().toAsmType()
val partContext = state.rootContext.intoMultifileClassPart(packageFragment, facadeClassType, partType, file)
generateNonPartClassDeclarations(file, partContext)

View File

@@ -175,8 +175,11 @@ class MultifileClassPartCodegen(
}
}
val serializer = DescriptorSerializer.createTopLevel(JvmSerializerExtension(v.serializationBindings, state))
val packageProto = serializer.packagePartProto(packageFragment.fqName, members).build()
val extension = JvmSerializerExtension(v.serializationBindings, state)
val serializer = DescriptorSerializer.createTopLevel(extension)
val builder = serializer.packagePartProto(packageFragment.fqName, members)
extension.serializeJvmPackage(builder, partType)
val packageProto = builder.build()
val extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0
@@ -186,7 +189,7 @@ class MultifileClassPartCodegen(
}
}
override fun generateSyntheticParts() {
override fun generateSyntheticPartsAfterBody() {
generateSyntheticAccessors()
}

View File

@@ -0,0 +1,36 @@
/*
* 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.descriptors.FileClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
enum class OwnerKind {
PACKAGE,
IMPLEMENTATION,
DEFAULT_IMPLS;
companion object {
fun getMemberOwnerKind(descriptor: DeclarationDescriptor): OwnerKind = when (descriptor) {
is FileClassDescriptor, is PackageFragmentDescriptor -> OwnerKind.PACKAGE
is ClassDescriptor -> OwnerKind.IMPLEMENTATION
else -> throw AssertionError("Unexpected declaration container: $this")
}
}
}

View File

@@ -119,9 +119,11 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
}
}
DescriptorSerializer serializer =
DescriptorSerializer.createTopLevel(new JvmSerializerExtension(v.getSerializationBindings(), state));
ProtoBuf.Package packageProto = serializer.packagePartProto(element.getPackageFqName(), members).build();
JvmSerializerExtension extension = new JvmSerializerExtension(v.getSerializationBindings(), state);
DescriptorSerializer serializer = DescriptorSerializer.createTopLevel(extension);
ProtoBuf.Package.Builder builder = serializer.packagePartProto(element.getPackageFqName(), members);
extension.serializeJvmPackage(builder, packagePartType);
ProtoBuf.Package packageProto = builder.build();
WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, av -> {
writeAnnotationData(av, serializer, packageProto);
@@ -130,7 +132,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
}
@Override
protected void generateSyntheticParts() {
protected void generateSyntheticPartsAfterBody() {
generateSyntheticAccessors();
}
}

View File

@@ -21,7 +21,10 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.annotation.AnnotatedWithFakeAnnotations;
import org.jetbrains.kotlin.codegen.context.*;
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil;
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
import org.jetbrains.kotlin.codegen.context.MultifileClassFacadeContext;
import org.jetbrains.kotlin.codegen.context.MultifileClassPartContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
@@ -32,7 +35,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtilKt;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorFactory;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
@@ -60,6 +62,8 @@ import static org.jetbrains.kotlin.codegen.AsmUtil.getDeprecatedAccessFlag;
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField;
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;
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
@@ -478,7 +482,7 @@ public class PropertyCodegen {
FunctionGenerationStrategy strategy;
if (accessor == null || !accessor.hasBody()) {
if (p instanceof KtProperty && ((KtProperty) p).hasDelegate()) {
strategy = new DelegatedPropertyAccessorStrategy(state, accessorDescriptor, indexOfDelegatedProperty((KtProperty) p));
strategy = new DelegatedPropertyAccessorStrategy(state, accessorDescriptor);
}
else {
strategy = new DefaultPropertyAccessorStrategy(state, accessorDescriptor);
@@ -491,39 +495,9 @@ public class PropertyCodegen {
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(accessor != null ? accessor : p, accessorDescriptor), accessorDescriptor, strategy);
}
public static int indexOfDelegatedProperty(@NotNull KtProperty property) {
PsiElement parent = property.getParent();
KtDeclarationContainer container;
if (parent instanceof KtClassBody) {
container = ((KtClassOrObject) parent.getParent());
}
else if (parent instanceof KtFile) {
container = (KtFile) parent;
}
else if (KtPsiUtil.isScriptDeclaration(property)) {
container = KtPsiUtil.getScript(property);
assert container != null : "Script declaration for property '" + property.getText() + "' should be not null!";
}
else {
throw new UnsupportedOperationException("Unknown delegated property container: " + parent);
}
int index = 0;
for (KtDeclaration declaration : container.getDeclarations()) {
if (declaration instanceof KtProperty && ((KtProperty) declaration).hasDelegate()) {
if (declaration == property) {
return index;
}
index++;
}
}
throw new IllegalStateException("Delegated property not found in its parent: " + PsiUtilsKt.getElementTextWithContext(property));
}
private static class DefaultPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased {
private final PropertyAccessorDescriptor propertyAccessorDescriptor;
public DefaultPropertyAccessorStrategy(@NotNull GenerationState state, @NotNull PropertyAccessorDescriptor descriptor) {
super(state);
propertyAccessorDescriptor = descriptor;
@@ -561,75 +535,45 @@ public class PropertyCodegen {
}
public static StackValue invokeDelegatedPropertyConventionMethod(
@NotNull PropertyDescriptor propertyDescriptor,
@NotNull ExpressionCodegen codegen,
@NotNull KotlinTypeMapper typeMapper,
@NotNull ResolvedCall<FunctionDescriptor> resolvedCall,
int indexInPropertyMetadataArray,
int propertyMetadataArgumentIndex
) {
StackValue.Property receiver = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
return invokeDelegatedPropertyConventionMethodWithReceiver(
codegen, typeMapper, resolvedCall, indexInPropertyMetadataArray, propertyMetadataArgumentIndex,
receiver, propertyDescriptor
);
}
public static StackValue invokeDelegatedPropertyConventionMethodWithReceiver(
@NotNull ExpressionCodegen codegen,
@NotNull KotlinTypeMapper typeMapper,
@NotNull ResolvedCall<FunctionDescriptor> resolvedCall,
int indexInPropertyMetadataArray,
int propertyMetadataArgumentIndex,
@Nullable StackValue receiver,
@NotNull PropertyDescriptor propertyDescriptor
) {
Type owner = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor) ?
codegen.getState().getTypeMapper().mapOwner(propertyDescriptor) :
getDelegatedPropertyMetadataOwner(codegen, typeMapper);
codegen.tempVariables.put(
resolvedCall.getCall().getValueArguments().get(propertyMetadataArgumentIndex).asElement(),
new StackValue(K_PROPERTY_TYPE) {
@Override
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
Field array = StackValue.field(
Type.getType("[" + K_PROPERTY_TYPE), owner, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, true, StackValue.none()
);
StackValue.arrayElement(
K_PROPERTY_TYPE, array, StackValue.constant(indexInPropertyMetadataArray, Type.INT_TYPE)
).put(type, v);
}
}
resolvedCall.getCall().getValueArguments().get(1).asElement(),
getDelegatedPropertyMetadata(propertyDescriptor, codegen.getBindingContext())
);
return codegen.invokeFunction(resolvedCall, receiver);
}
private static Type getDelegatedPropertyMetadataOwner(@NotNull ExpressionCodegen codegen, @NotNull KotlinTypeMapper typeMapper) {
CodegenContext<? extends ClassOrPackageFragmentDescriptor> ownerContext = codegen.getContext().getClassOrPackageParentContext();
if (ownerContext instanceof ClassContext) {
return typeMapper.mapClass(((ClassContext) ownerContext).getContextDescriptor());
}
else if (ownerContext instanceof PackageContext) {
return ((PackageContext) ownerContext).getPackagePartType();
}
else if (ownerContext instanceof MultifileClassContextBase) {
return ((MultifileClassContextBase) ownerContext).getFilePartType();
}
else {
throw new UnsupportedOperationException("Unknown context: " + ownerContext);
@NotNull
public static StackValue getDelegatedPropertyMetadata(
@NotNull VariableDescriptorWithAccessors descriptor,
@NotNull BindingContext bindingContext
) {
Type owner = bindingContext.get(DELEGATED_PROPERTY_METADATA_OWNER, descriptor);
assert owner != null : "Delegated property owner not found: " + descriptor;
List<VariableDescriptorWithAccessors> allDelegatedProperties = bindingContext.get(DELEGATED_PROPERTIES, owner);
int index = allDelegatedProperties == null ? -1 : allDelegatedProperties.indexOf(descriptor);
if (index < 0) {
throw new AssertionError("Delegated property not found in " + owner + ": " + descriptor);
}
StackValue.Field array = StackValue.field(
Type.getType("[" + K_PROPERTY_TYPE), owner, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, true, StackValue.none()
);
return StackValue.arrayElement(K_PROPERTY_TYPE, array, StackValue.constant(index, Type.INT_TYPE));
}
private static class DelegatedPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased {
private final int index;
private final PropertyAccessorDescriptor propertyAccessorDescriptor;
public DelegatedPropertyAccessorStrategy(@NotNull GenerationState state, @NotNull PropertyAccessorDescriptor descriptor, int index) {
public DelegatedPropertyAccessorStrategy(@NotNull GenerationState state, @NotNull PropertyAccessorDescriptor descriptor) {
super(state);
this.index = index;
propertyAccessorDescriptor = descriptor;
this.propertyAccessorDescriptor = descriptor;
}
@Override
@@ -641,8 +585,9 @@ public class PropertyCodegen {
bindingContext.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, propertyAccessorDescriptor);
assert resolvedCall != null : "Resolve call should be recorded for delegate call " + signature.toString();
StackValue lastValue = invokeDelegatedPropertyConventionMethod(propertyAccessorDescriptor.getCorrespondingProperty(),
codegen, state.getTypeMapper(), resolvedCall, index, 1);
PropertyDescriptor propertyDescriptor = propertyAccessorDescriptor.getCorrespondingProperty();
StackValue.Property receiver = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
StackValue lastValue = invokeDelegatedPropertyConventionMethod(codegen, resolvedCall, receiver, propertyDescriptor);
Type asmType = signature.getReturnType();
lastValue.put(asmType, v);
v.areturn(asmType);

View File

@@ -116,10 +116,11 @@ class PropertyReferenceCodegen(
generateCallableReferenceSignature(this, target, state)
}
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) {
ClosureCodegen.generateCallableReferenceDeclarationContainer(this, target, state)
}
if (!isLocalDelegatedProperty) {
generateMethod("property reference getOwner", ACC_PUBLIC, method("getOwner", K_DECLARATION_CONTAINER_TYPE)) {
ClosureCodegen.generateCallableReferenceDeclarationContainer(this, target, state)
}
generateAccessors()
}
}
@@ -194,6 +195,17 @@ class PropertyReferenceCodegen(
@JvmStatic
fun generateCallableReferenceSignature(iv: InstructionAdapter, callable: CallableDescriptor, state: GenerationState) {
if (callable is LocalVariableDescriptor) {
val asmType = state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER, callable)
val allDelegatedProperties = state.bindingContext.get(CodegenBinding.DELEGATED_PROPERTIES, asmType)
val index = allDelegatedProperties?.indexOf(callable) ?: -1
if (index < 0) {
throw AssertionError("Local delegated property is not found in $asmType: $callable")
}
iv.aconst("<v#$index>") // v = "variable"
return
}
val accessor = when (callable) {
is FunctionDescriptor -> callable
is VariableDescriptorWithAccessors ->

View File

@@ -1,241 +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 com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.org.objectweb.asm.Type;
import java.util.Arrays;
import java.util.List;
import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME;
import static org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor;
public class RangeCodegenUtil {
private static final ImmutableMap<FqName, PrimitiveType> RANGE_TO_ELEMENT_TYPE;
private static final ImmutableMap<FqName, PrimitiveType> PROGRESSION_TO_ELEMENT_TYPE;
@NotNull
public static List<PrimitiveType> supportedRangeTypes() {
return Arrays.asList(PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.LONG);
}
static {
ImmutableMap.Builder<FqName, PrimitiveType> rangeBuilder = ImmutableMap.builder();
ImmutableMap.Builder<FqName, PrimitiveType> progressionBuilder = ImmutableMap.builder();
for (PrimitiveType primitiveType : supportedRangeTypes()) {
FqName rangeClassFqName = RANGES_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Range"));
FqName progressionClassFqName = RANGES_PACKAGE_FQ_NAME.child(Name.identifier(primitiveType.getTypeName() + "Progression"));
rangeBuilder.put(rangeClassFqName, primitiveType);
progressionBuilder.put(progressionClassFqName, primitiveType);
}
RANGE_TO_ELEMENT_TYPE = rangeBuilder.build();
PROGRESSION_TO_ELEMENT_TYPE = progressionBuilder.build();
}
private RangeCodegenUtil() {}
public static boolean isRange(KotlinType rangeType) {
return !rangeType.isMarkedNullable() && getPrimitiveRangeElementType(rangeType) != null;
}
public static boolean isProgression(KotlinType rangeType) {
return !rangeType.isMarkedNullable() && getPrimitiveProgressionElementType(rangeType) != null;
}
@Nullable
private static PrimitiveType getPrimitiveRangeElementType(KotlinType rangeType) {
return getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE);
}
@Nullable
private static PrimitiveType getPrimitiveProgressionElementType(KotlinType rangeType) {
return getPrimitiveRangeOrProgressionElementType(rangeType, PROGRESSION_TO_ELEMENT_TYPE);
}
@Nullable
private static PrimitiveType getPrimitiveRangeOrProgressionElementType(
@NotNull KotlinType rangeOrProgression,
@NotNull ImmutableMap<FqName, PrimitiveType> map
) {
ClassifierDescriptor declarationDescriptor = rangeOrProgression.getConstructor().getDeclarationDescriptor();
if (declarationDescriptor == null) return null;
FqNameUnsafe fqName = DescriptorUtils.getFqName(declarationDescriptor);
if (!fqName.isSafe()) return null;
return map.get(fqName.toSafe());
}
@Nullable
public static PrimitiveType getPrimitiveRangeOrProgressionElementType(@NotNull FqName rangeOrProgressionName) {
PrimitiveType result = RANGE_TO_ELEMENT_TYPE.get(rangeOrProgressionName);
return result != null ? result : PROGRESSION_TO_ELEMENT_TYPE.get(rangeOrProgressionName);
}
public static boolean isRangeOrProgression(@NotNull FqName className) {
return getPrimitiveRangeOrProgressionElementType(className) != null;
}
public static boolean isPrimitiveNumberRangeTo(CallableDescriptor rangeTo) {
if (!"rangeTo".equals(rangeTo.getName().asString())) return false;
if (!isPrimitiveNumberClassDescriptor(rangeTo.getContainingDeclaration())) return false;
return true;
}
private static boolean isPrimitiveRangeToExtension(@NotNull CallableDescriptor descriptor) {
if (!isTopLevelInPackage(descriptor, "rangeTo", "kotlin.ranges")) return false;
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
if (extensionReceiver == null) return false;
return KotlinBuiltIns.isPrimitiveType(extensionReceiver.getType());
}
public static boolean isPrimitiveNumberDownTo(@NotNull CallableDescriptor descriptor) {
if (!isTopLevelInPackage(descriptor, "downTo", "kotlin.ranges")) return false;
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
if (extensionReceiver == null) return false;
ClassifierDescriptor extensionReceiverClassifier = extensionReceiver.getType().getConstructor().getDeclarationDescriptor();
if (!isPrimitiveNumberClassDescriptor(extensionReceiverClassifier)) return false;
return true;
}
public static boolean isPrimitiveNumberUntil(@NotNull CallableDescriptor descriptor) {
if (!isTopLevelInPackage(descriptor, "until", "kotlin.ranges")) return false;
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
if (extensionReceiver == null) return false;
ClassifierDescriptor extensionReceiverClassifier = extensionReceiver.getType().getConstructor().getDeclarationDescriptor();
if (!isPrimitiveNumberClassDescriptor(extensionReceiverClassifier)) return false;
return true;
}
public static boolean isArrayOrPrimitiveArrayIndices(@NotNull CallableDescriptor descriptor) {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false;
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
if (extensionReceiver == null) return false;
KotlinType extensionReceiverType = extensionReceiver.getType();
if (!KotlinBuiltIns.isArray(extensionReceiverType) && !KotlinBuiltIns.isPrimitiveArray(extensionReceiverType)) return false;
return true;
}
public static boolean isCollectionIndices(@NotNull CallableDescriptor descriptor) {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false;
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
if (extensionReceiver == null) return false;
KotlinType extensionReceiverType = extensionReceiver.getType();
if (!KotlinBuiltIns.isCollectionOrNullableCollection(extensionReceiverType)) return false;
return true;
}
public static boolean isCharSequenceIndices(@NotNull CallableDescriptor descriptor) {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.text")) return false;
ReceiverParameterDescriptor extensionReceiver = descriptor.getExtensionReceiverParameter();
if (extensionReceiver == null) return false;
KotlinType extensionReceiverType = extensionReceiver.getType();
if (!KotlinBuiltIns.isCharSequenceOrNullableCharSequence(extensionReceiverType)) return false;
return true;
}
public static boolean isPrimitiveRangeToExtension(@NotNull KtSimpleNameExpression operationReference, @NotNull BindingContext bindingContext) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = CallUtilKt
.getResolvedCallWithAssert(operationReference, bindingContext);
ReceiverValue receiver = resolvedCall.getDispatchReceiver();
/*
* Range is optimizable if
* 'in' receiver is expression 'rangeTo' from stdlib package
* and its argument has same primitive type as generic range parameter.
* For non-matching primitive types (e.g. int in double range)
* dispatch receiver will be null, because extension method will be called.
*/
if (!(receiver instanceof ExpressionReceiver)) return false;
ExpressionReceiver e = (ExpressionReceiver) receiver;
ResolvedCall<? extends CallableDescriptor> resolvedReceiver =
CallUtilKt.getResolvedCall(e.getExpression(), bindingContext);
if (resolvedReceiver == null) return false;
return isPrimitiveRangeToExtension(resolvedReceiver.getResultingDescriptor());
}
/*
* Checks whether for expression 'x in a..b' a..b is primitive integral range
* with same type as x.
*/
public static boolean isPrimitiveRangeSpecializationOfType(
@NotNull Type argumentType,
@NotNull KtExpression rangeExpression,
@NotNull BindingContext bindingContext
) {
if (rangeExpression instanceof KtBinaryExpression &&
((KtBinaryExpression) rangeExpression).getOperationReference().getReferencedNameElementType() == KtTokens.RANGE) {
KotlinType kotlinType = bindingContext.getType(rangeExpression);
assert kotlinType != null;
DeclarationDescriptor descriptor = kotlinType.getConstructor().getDeclarationDescriptor();
if (descriptor != null) {
FqNameUnsafe fqName = DescriptorUtils.getFqName(descriptor);
if (fqName.equals(KotlinBuiltIns.FQ_NAMES.longRange)) {
return argumentType == Type.LONG_TYPE;
}
if (fqName.equals(KotlinBuiltIns.FQ_NAMES.charRange) || fqName.equals(KotlinBuiltIns.FQ_NAMES.intRange)) {
return AsmUtil.isIntPrimitive(argumentType);
}
}
}
return false;
}
private static boolean isTopLevelInPackage(@NotNull CallableDescriptor descriptor, @NotNull String name, @NotNull String packageName) {
if (!name.equals(descriptor.getName().asString())) return false;
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (!(containingDeclaration instanceof PackageFragmentDescriptor)) return false;
String packageFqName = ((PackageFragmentDescriptor) containingDeclaration).getFqName().asString();
if (!packageName.equals(packageFqName)) return false;
return true;
}
}

View File

@@ -0,0 +1,242 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.org.objectweb.asm.Type
val supportedRangeTypes = listOf(PrimitiveType.CHAR, PrimitiveType.INT, PrimitiveType.LONG)
private val RANGE_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
supportedRangeTypes.associateBy {
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Range"))
}
private val PROGRESSION_TO_ELEMENT_TYPE: Map<FqName, PrimitiveType> =
supportedRangeTypes.associateBy {
RANGES_PACKAGE_FQ_NAME.child(Name.identifier(it.typeName.toString() + "Progression"))
}
fun isPrimitiveRange(rangeType: KotlinType) =
!rangeType.isMarkedNullable && getPrimitiveRangeElementType(rangeType) != null
fun isPrimitiveProgression(rangeType: KotlinType) =
!rangeType.isMarkedNullable && getPrimitiveProgressionElementType(rangeType) != null
fun getPrimitiveRangeElementType(rangeType: KotlinType): PrimitiveType? =
getPrimitiveRangeOrProgressionElementType(rangeType, RANGE_TO_ELEMENT_TYPE)
private fun getPrimitiveProgressionElementType(rangeType: KotlinType) =
getPrimitiveRangeOrProgressionElementType(rangeType, PROGRESSION_TO_ELEMENT_TYPE)
private fun getPrimitiveRangeOrProgressionElementType(
rangeOrProgression: KotlinType,
map: Map<FqName, PrimitiveType>
): PrimitiveType? {
val declarationDescriptor = rangeOrProgression.constructor.declarationDescriptor ?: return null
val fqName = DescriptorUtils.getFqName(declarationDescriptor).takeIf { it.isSafe } ?: return null
return map[fqName.toSafe()]
}
fun getRangeOrProgressionElementType(rangeType: KotlinType): KotlinType? {
val rangeTypeDescriptor = rangeType.constructor.declarationDescriptor ?: return null
val builtIns = rangeTypeDescriptor.builtIns
return when {
isTopLevelInPackage(rangeTypeDescriptor, "CharRange", "kotlin.ranges") -> builtIns.charType
isTopLevelInPackage(rangeTypeDescriptor, "IntRange", "kotlin.ranges") -> builtIns.intType
isTopLevelInPackage(rangeTypeDescriptor, "LongRange", "kotlin.ranges") -> builtIns.longType
isTopLevelInPackage(rangeTypeDescriptor, "CharProgression", "kotlin.ranges") -> builtIns.charType
isTopLevelInPackage(rangeTypeDescriptor, "IntProgression", "kotlin.ranges") -> builtIns.intType
isTopLevelInPackage(rangeTypeDescriptor, "LongProgression", "kotlin.ranges") -> builtIns.longType
isTopLevelInPackage(rangeTypeDescriptor, "ClosedFloatRange", "kotlin.ranges") -> builtIns.floatType
isTopLevelInPackage(rangeTypeDescriptor, "ClosedDoubleRange", "kotlin.ranges") -> builtIns.doubleType
isTopLevelInPackage(rangeTypeDescriptor, "ClosedRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type
isTopLevelInPackage(rangeTypeDescriptor, "ClosedFloatingPointRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type
isTopLevelInPackage(rangeTypeDescriptor, "ComparableRange", "kotlin.ranges") -> rangeType.arguments.singleOrNull()?.type
else -> null
}
}
fun getPrimitiveRangeOrProgressionElementType(rangeOrProgressionName: FqName): PrimitiveType? =
RANGE_TO_ELEMENT_TYPE[rangeOrProgressionName] ?:
PROGRESSION_TO_ELEMENT_TYPE[rangeOrProgressionName]
fun isRangeOrProgression(className: FqName) =
getPrimitiveRangeOrProgressionElementType(className) != null
fun isPrimitiveNumberRangeTo(rangeTo: CallableDescriptor) =
"rangeTo" == rangeTo.name.asString() && isPrimitiveNumberClassDescriptor(rangeTo.containingDeclaration) ||
isPrimitiveRangeToExtension(rangeTo)
private fun isPrimitiveRangeToExtension(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "rangeTo", "kotlin.ranges")) return false
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
return KotlinBuiltIns.isPrimitiveType(extensionReceiver.type)
}
fun isPrimitiveNumberDownTo(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "downTo", "kotlin.ranges")) return false
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
val extensionReceiverClassifier = extensionReceiver.type.constructor.declarationDescriptor
return isPrimitiveNumberClassDescriptor(extensionReceiverClassifier)
}
fun isPrimitiveNumberUntil(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "until", "kotlin.ranges")) return false
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
val extensionReceiverClassifier = extensionReceiver.type.constructor.declarationDescriptor
return isPrimitiveNumberClassDescriptor(extensionReceiverClassifier)
}
fun isArrayOrPrimitiveArrayIndices(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
val extensionReceiverType = extensionReceiver.type
return KotlinBuiltIns.isArray(extensionReceiverType) || KotlinBuiltIns.isPrimitiveArray(extensionReceiverType)
}
fun isCollectionIndices(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.collections")) return false
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
val extensionReceiverType = extensionReceiver.type
return KotlinBuiltIns.isCollectionOrNullableCollection(extensionReceiverType)
}
fun isCharSequenceIndices(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "indices", "kotlin.text")) return false
val extensionReceiver = descriptor.extensionReceiverParameter ?: return false
val extensionReceiverType = extensionReceiver.type
return KotlinBuiltIns.isCharSequenceOrNullableCharSequence(extensionReceiverType)
}
fun isComparableRangeTo(descriptor: CallableDescriptor): Boolean {
if (!isTopLevelInPackage(descriptor, "rangeTo", "kotlin.ranges")) return false
val extensionReceiver = descriptor.original.extensionReceiverParameter ?: return false
val extensionReceiverTypeDescriptor = extensionReceiver.type.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return false
val upperBoundType = extensionReceiverTypeDescriptor.upperBounds.singleOrNull() ?: return false
val upperBoundClassDescriptor = upperBoundType.constructor.declarationDescriptor as? ClassDescriptor ?: return false
if (!isTopLevelInPackage(upperBoundClassDescriptor, "Comparable", "kotlin")) return false
return true
}
fun isClosedRangeContains(descriptor: CallableDescriptor): Boolean {
if (descriptor.name.asString() != "contains") return false
val containingClassDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return false
if (!isTopLevelInPackage(containingClassDescriptor, "ClosedRange", "kotlin.ranges")) return false
return true
}
fun isPrimitiveRangeContains(descriptor: CallableDescriptor): Boolean {
if (descriptor.name.asString() != "contains") return false
val dispatchReceiverType = descriptor.dispatchReceiverParameter?.type ?: return false
if (!isPrimitiveRange(dispatchReceiverType)) return false
return true
}
fun isPrimitiveNumberRangeExtensionContainsPrimitiveNumber(descriptor: CallableDescriptor): Boolean {
if (descriptor.name.asString() != "contains") return false
val extensionReceiverType = descriptor.extensionReceiverParameter?.type ?: return false
val rangeElementType = getRangeOrProgressionElementType(extensionReceiverType) ?: return false
if (!isPrimitiveNumberType(rangeElementType)) return false
val argumentType = descriptor.valueParameters.singleOrNull()?.type ?: return false
if (!isPrimitiveNumberType(argumentType)) return false
return true
}
private fun isPrimitiveNumberType(type: KotlinType) =
KotlinBuiltIns.isByte(type) ||
KotlinBuiltIns.isShort(type) ||
KotlinBuiltIns.isInt(type) ||
KotlinBuiltIns.isChar(type) ||
KotlinBuiltIns.isLong(type) ||
KotlinBuiltIns.isFloat(type) ||
KotlinBuiltIns.isDouble(type)
fun isClosedFloatingPointRangeContains(descriptor: CallableDescriptor): Boolean {
if (descriptor.name.asString() != "contains") return false
val containingClassDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return false
if (!isTopLevelInPackage(containingClassDescriptor, "ClosedFloatingPointRange", "kotlin.ranges")) return false
return true
}
fun getClosedFloatingPointRangeElementType(rangeType: KotlinType): KotlinType? {
val classDescriptor = rangeType.constructor.declarationDescriptor as? ClassDescriptor ?: return null
if (!isTopLevelInPackage(classDescriptor, "ClosedFloatingPointRange", "kotlin.ranges")) return null
return rangeType.arguments.singleOrNull()?.type
}
private fun isTopLevelInPackage(descriptor: DeclarationDescriptor, name: String, packageName: String): Boolean {
if (name != descriptor.name.asString()) return false
val containingDeclaration = descriptor.containingDeclaration as? PackageFragmentDescriptor ?: return false
val packageFqName = containingDeclaration.fqName.asString()
return packageName == packageFqName
}
fun getAsmRangeElementTypeForPrimitiveRangeOrProgression(rangeCallee: CallableDescriptor): Type {
val rangeType = rangeCallee.returnType!!
getPrimitiveRangeElementType(rangeType)?.let {
return AsmTypes.valueTypeForPrimitive(it)
}
getPrimitiveProgressionElementType(rangeType)?.let {
return AsmTypes.valueTypeForPrimitive(it)
}
getClosedFloatingPointRangeElementType(rangeType)?.let {
when {
KotlinBuiltIns.isDouble(it) -> return Type.DOUBLE_TYPE
KotlinBuiltIns.isFloat(it) -> return Type.FLOAT_TYPE
else -> {}
}
}
throw AssertionError("Unexpected range type: $rangeType")
}

View File

@@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.SamAdapterDescriptor;
import org.jetbrains.kotlin.load.java.sam.SamAdapterDescriptor;
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor;
public class SamCodegenUtil {

View File

@@ -105,10 +105,14 @@ public class ScriptCodegen extends MemberCodegen<KtScript> {
}
@Override
protected void generateSyntheticParts() {
protected void generateSyntheticPartsBeforeBody() {
generatePropertyMetadataArrayFieldIfNeeded(classAsmType);
}
@Override
protected void generateSyntheticPartsAfterBody() {
}
@Override
protected void generateKotlinMetadataAnnotation() {
generateKotlinClassMetadataAnnotation(scriptDescriptor, true);

View File

@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.codegen;
import com.intellij.psi.tree.IElementType;
import kotlin.Unit;
import kotlin.collections.ArraysKt;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
@@ -27,8 +26,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor;
@@ -518,9 +515,11 @@ public abstract class StackValue {
descriptor
);
StackValue extensionReceiver = genReceiver(receiver, codegen, resolvedCall, callableMethod, callExtensionReceiver, true);
Type type = CallReceiver.calcType(resolvedCall, dispatchReceiverParameter, extensionReceiverParameter, codegen.typeMapper, callableMethod, codegen.getState());
assert type != null : "Could not map receiver type for " + resolvedCall;
return new CallReceiver(dispatchReceiver, extensionReceiver, type);
return CallReceiver.generateCallReceiver(
resolvedCall, codegen, callableMethod,
dispatchReceiverParameter, dispatchReceiver,
extensionReceiverParameter, extensionReceiver
);
}
return receiver;
}
@@ -569,14 +568,13 @@ public abstract class StackValue {
}
@Contract("null -> false")
private static boolean isLocalFunCall(@Nullable Callable callableMethod) {
static boolean isLocalFunCall(@Nullable Callable callableMethod) {
return callableMethod != null && callableMethod.getGenerateCalleeType() != null;
}
public static StackValue receiverWithoutReceiverArgument(StackValue receiverWithParameter) {
if (receiverWithParameter instanceof CallReceiver) {
CallReceiver callReceiver = (CallReceiver) receiverWithParameter;
return new CallReceiver(callReceiver.dispatchReceiver, none(), callReceiver.type);
return ((CallReceiver) receiverWithParameter).withoutReceiverArgument();
}
return receiverWithParameter;
}
@@ -1517,101 +1515,6 @@ public abstract class StackValue {
}
}
public static class CallReceiver extends StackValue {
private final StackValue dispatchReceiver;
private final StackValue extensionReceiver;
public CallReceiver(
@NotNull StackValue dispatchReceiver,
@NotNull StackValue extensionReceiver,
@NotNull Type type
) {
super(type, dispatchReceiver.canHaveSideEffects() || extensionReceiver.canHaveSideEffects());
this.dispatchReceiver = dispatchReceiver;
this.extensionReceiver = extensionReceiver;
}
@Nullable
public static Type calcType(
@NotNull ResolvedCall<?> resolvedCall,
@Nullable ReceiverParameterDescriptor dispatchReceiver,
@Nullable ReceiverParameterDescriptor extensionReceiver,
@NotNull KotlinTypeMapper typeMapper,
@Nullable Callable callableMethod,
@NotNull GenerationState state
) {
if (extensionReceiver != null) {
CallableDescriptor descriptor = resolvedCall.getCandidateDescriptor();
if (descriptor instanceof PropertyDescriptor &&
// hackaround: boxing changes behaviour of T.javaClass intrinsic
state.getIntrinsics().getIntrinsic((PropertyDescriptor) descriptor) != JavaClassProperty.INSTANCE
) {
ReceiverParameterDescriptor receiverCandidate = descriptor.getExtensionReceiverParameter();
assert receiverCandidate != null;
return typeMapper.mapType(receiverCandidate.getType());
}
return callableMethod != null ? callableMethod.getExtensionReceiverType() : typeMapper.mapType(extensionReceiver.getType());
}
else if (dispatchReceiver != null) {
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
if (CodegenUtilKt.isJvmStaticInObjectOrClass(descriptor)) {
return Type.VOID_TYPE;
}
if (callableMethod != null) {
return callableMethod.getDispatchReceiverType();
}
// Extract the receiver from the resolved call, workarounding the fact that ResolvedCall#dispatchReceiver doesn't have
// all the needed information, for example there's no way to find out whether or not a smart cast was applied to the receiver.
DeclarationDescriptor container = descriptor.getContainingDeclaration();
if (container instanceof ClassDescriptor) {
return typeMapper.mapClass((ClassDescriptor) container);
}
return typeMapper.mapType(dispatchReceiver);
}
else if (isLocalFunCall(callableMethod)) {
return callableMethod.getGenerateCalleeType();
}
return Type.VOID_TYPE;
}
@Override
public void putSelector(@NotNull Type type, @NotNull InstructionAdapter v) {
StackValue currentExtensionReceiver = extensionReceiver;
boolean hasExtensionReceiver = extensionReceiver != none();
if (extensionReceiver instanceof StackValue.SafeCall) {
currentExtensionReceiver.put(currentExtensionReceiver.type, v);
currentExtensionReceiver = StackValue.onStack(currentExtensionReceiver.type);
}
dispatchReceiver.put(hasExtensionReceiver ? dispatchReceiver.type : type, v);
currentExtensionReceiver
.moveToTopOfStack(hasExtensionReceiver ? type : currentExtensionReceiver.type, v, dispatchReceiver.type.getSize());
}
@Override
public void dup(@NotNull InstructionAdapter v, boolean withReceiver) {
AsmUtil.dup(v, extensionReceiver.type, dispatchReceiver.type);
}
@NotNull
public StackValue getDispatchReceiver() {
return dispatchReceiver;
}
@NotNull
public StackValue getExtensionReceiver() {
return extensionReceiver;
}
}
public abstract static class StackValueWithSimpleReceiver extends StackValue {
public final boolean isStaticPut;

View File

@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.tree.LocalVariableNode;
@@ -29,6 +28,9 @@ import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getNodeText;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.wrapWithMaxLocalCalc;
public abstract class TransformationMethodVisitor extends MethodVisitor {
private final MethodNode methodNode;
@@ -46,7 +48,7 @@ public abstract class TransformationMethodVisitor extends MethodVisitor {
this.delegate = delegate;
this.methodNode = new MethodNode(access, name, desc, signature, exceptions);
this.methodNode.localVariables = new ArrayList<>(5);
this.mv = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode);
this.mv = wrapWithMaxLocalCalc(methodNode);
}
@Override
@@ -83,7 +85,7 @@ public abstract class TransformationMethodVisitor extends MethodVisitor {
delegate.visitEnd();
}
catch (Throwable t) {
throw new CompilationException("Couldn't transform method node: " + InlineCodegenUtil.getNodeText(methodNode), t, null);
throw new CompilationException("Couldn't transform method node: " + getNodeText(methodNode), t, null);
}
}

View File

@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotatedImpl
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName
interface WrappedAnnotated : Annotated {
val originalAnnotated: Annotated
@@ -34,10 +33,6 @@ class AnnotatedWithOnlyTargetedAnnotations(original: Annotated) : Annotated {
private class UseSiteTargetedAnnotations(private val additionalAnnotations: Annotations) : Annotations {
override fun isEmpty() = true
override fun findAnnotation(fqName: FqName) = null
override fun findExternalAnnotation(fqName: FqName) = null
override fun getUseSiteTargetedAnnotations() = getAdditionalTargetedAnnotations()
override fun getAllAnnotations() = getAdditionalTargetedAnnotations()
@@ -48,4 +43,4 @@ class AnnotatedWithOnlyTargetedAnnotations(original: Annotated) : Annotated {
}
}
class AnnotatedSimple(annotations: Annotations) : AnnotatedImpl(annotations)
class AnnotatedSimple(annotations: Annotations) : AnnotatedImpl(annotations)

View File

@@ -38,8 +38,9 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.fileClasses.FileClasses;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor;
import org.jetbrains.kotlin.load.kotlin.TypeMappingConfiguration;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingContext;
@@ -370,26 +371,13 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
@NotNull
private MutableClosure recordClosure(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
return CodegenBinding.recordClosure(
bindingTrace, classDescriptor, peekFromStack(classStack), Type.getObjectType(name), fileClassesProvider
);
return CodegenBinding.recordClosure(bindingTrace, classDescriptor, peekFromStack(classStack), Type.getObjectType(name));
}
private void recordLocalVariablePropertyMetadata(LocalVariableDescriptor variableDescriptor) {
KotlinType delegateType = JvmCodegenUtil.getPropertyDelegateType(variableDescriptor, bindingContext);
if (delegateType == null) return;
LocalVariableDescriptor delegateVariableDescriptor = new LocalVariableDescriptor(
variableDescriptor.getContainingDeclaration(),
Annotations.Companion.getEMPTY(),
variableDescriptor.getName(),
delegateType,
false,
false,
SourceElement.NO_SOURCE
);
bindingTrace.record(LOCAL_VARIABLE_DELEGATE, variableDescriptor, delegateVariableDescriptor);
LocalVariableDescriptor metadataVariableDescriptor = new LocalVariableDescriptor(
variableDescriptor.getContainingDeclaration(),
Annotations.Companion.getEMPTY(),
@@ -428,12 +416,38 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
runtimeTypes.getSupertypeForPropertyReference(variableDescriptor, variableDescriptor.isVar(), /* bound = */ false);
ClassDescriptor classDescriptor = recordClassForCallable(delegate, variableDescriptor, Collections.singleton(supertype), name);
recordClosure(classDescriptor, name);
Type containerType = getMetadataOwner(property);
List<VariableDescriptorWithAccessors> descriptors = bindingTrace.get(DELEGATED_PROPERTIES, containerType);
if (descriptors == null) {
descriptors = new ArrayList<>(1);
bindingTrace.record(DELEGATED_PROPERTIES, containerType, descriptors);
}
descriptors.add(variableDescriptor);
bindingTrace.record(DELEGATED_PROPERTY_METADATA_OWNER, variableDescriptor, containerType);
}
super.visitProperty(property);
nameStack.pop();
}
@NotNull
private Type getMetadataOwner(@NotNull KtProperty property) {
for (int i = classStack.size() - 1; i >= 0; i--) {
ClassDescriptor descriptor = classStack.get(i);
// The first "real" containing class (not a synthetic class for lambda) is the owner of the delegated property metadata
if (!(descriptor instanceof SyntheticClassDescriptorForLambda)) {
ClassId classId = DescriptorUtilsKt.getClassId(descriptor);
return classId != null
? AsmUtil.asmTypeByClassId(classId)
: CodegenBinding.getAsmType(bindingContext, descriptor);
}
}
return Type.getObjectType(FileClasses.getFileClassInternalName(fileClassesProvider, property.getContainingKtFile()));
}
@Override
public void visitNamedFunction(@NotNull KtNamedFunction function) {
FunctionDescriptor functionDescriptor = (FunctionDescriptor) bindingContext.get(DECLARATION_TO_DESCRIPTOR, function);

View File

@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.codegen.SamType;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
@@ -49,7 +48,7 @@ public class CodegenBinding {
public static final WritableSlice<ClassDescriptor, Boolean> ENUM_ENTRY_CLASS_NEED_SUBCLASS = Slices.createSimpleSetSlice();
public static final WritableSlice<ClassDescriptor, Collection<ClassDescriptor>> INNER_CLASSES = Slices.createSimpleSlice();
private static final WritableSlice<ClassDescriptor, Collection<ClassDescriptor>> INNER_CLASSES = Slices.createSimpleSlice();
public static final WritableSlice<KtExpression, SamType> SAM_VALUE = Slices.createSimpleSlice();
@@ -60,18 +59,19 @@ public class CodegenBinding {
public static final WritableSlice<String, List<WhenByEnumsMapping>> MAPPINGS_FOR_WHENS_BY_ENUM_IN_CLASS_FILE =
Slices.createSimpleSlice();
public static final WritableSlice<VariableDescriptor, VariableDescriptor> LOCAL_VARIABLE_DELEGATE =
Slices.createSimpleSlice();
public static final WritableSlice<VariableDescriptor, VariableDescriptor> LOCAL_VARIABLE_PROPERTY_METADATA =
Slices.createSimpleSlice();
public static final WritableSlice<FunctionDescriptor, FunctionDescriptor> SUSPEND_FUNCTION_TO_JVM_VIEW =
Slices.createSimpleSlice();
public static final WritableSlice<ValueParameterDescriptor, ValueParameterDescriptor> PARAMETER_SYNONYM =
Slices.createSimpleSlice();
public static final WritableSlice<Type, List<VariableDescriptorWithAccessors>> DELEGATED_PROPERTIES =
Slices.createSimpleSlice();
public static final WritableSlice<VariableDescriptorWithAccessors, Type> DELEGATED_PROPERTY_METADATA_OWNER =
Slices.createSimpleSlice();
public static final WritableSlice<VariableDescriptor, VariableDescriptor> LOCAL_VARIABLE_PROPERTY_METADATA =
Slices.createSimpleSlice();
static {
BasicWritableSlice.initSliceDebugNames(CodegenBinding.class);
}
@@ -150,8 +150,7 @@ public class CodegenBinding {
@NotNull BindingTrace trace,
@NotNull ClassDescriptor classDescriptor,
@Nullable ClassDescriptor enclosing,
@NotNull Type asmType,
@NotNull JvmFileClassesProvider fileClassesManager
@NotNull Type asmType
) {
KtElement element = (KtElement) DescriptorToSourceUtils.descriptorToDeclaration(classDescriptor);
assert element != null : "No source element for " + classDescriptor;
@@ -227,32 +226,6 @@ public class CodegenBinding {
return type;
}
@NotNull
public static Collection<ClassDescriptor> getAllInnerClasses(
@NotNull BindingContext bindingContext, @NotNull ClassDescriptor outermostClass
) {
Collection<ClassDescriptor> innerClasses = bindingContext.get(INNER_CLASSES, outermostClass);
if (innerClasses == null || innerClasses.isEmpty()) return Collections.emptySet();
Set<ClassDescriptor> allInnerClasses = new HashSet<>();
Deque<ClassDescriptor> stack = new ArrayDeque<>(innerClasses);
do {
ClassDescriptor currentClass = stack.pop();
if (allInnerClasses.add(currentClass)) {
Collection<ClassDescriptor> nextClasses = bindingContext.get(INNER_CLASSES, currentClass);
if (nextClasses != null) {
for (ClassDescriptor nextClass : nextClasses) {
stack.push(nextClass);
}
}
}
}
while (!stack.isEmpty());
return allInnerClasses;
}
@NotNull
public static VariableDescriptor getDelegatedLocalVariableMetadata(
@NotNull VariableDescriptor variableDescriptor,

View File

@@ -17,16 +17,20 @@
package org.jetbrains.kotlin.codegen
import com.google.common.collect.Maps
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
import org.jetbrains.kotlin.codegen.context.PackageContext
import org.jetbrains.kotlin.codegen.coroutines.unwrapInitialDescriptorForSuspendFunction
import org.jetbrains.kotlin.codegen.inline.ReificationArgument
import org.jetbrains.kotlin.codegen.intrinsics.TypeIntrinsics
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.diagnostics.rendering.Renderers
import org.jetbrains.kotlin.diagnostics.rendering.RenderingContext
@@ -43,13 +47,13 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils.isSubclass
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
import org.jetbrains.kotlin.resolve.bindingContextUtil.getDataFlowInfoBefore
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.scopes.receivers.TransientReceiver
import org.jetbrains.kotlin.serialization.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
@@ -239,8 +243,9 @@ fun reportTarget6InheritanceErrorIfNeeded(
state.diagnostics.report(
ErrorsJvm.TARGET6_INTERFACE_INHERITANCE.on(
classElement, classDescriptor, key,
value.map { Renderers.COMPACT.render(JvmCodegenUtil.getDirectMember(it), RenderingContext.Empty) }.
joinToString(separator = "\n", prefix = "\n")
value.joinToString(separator = "\n", prefix = "\n") {
Renderers.COMPACT.render(JvmCodegenUtil.getDirectMember(it), RenderingContext.Empty)
}
)
)
}
@@ -287,14 +292,10 @@ fun calcTypeForIEEE754ArithmeticIfNeeded(expression: KtExpression?, bindingConte
val dataFlow = DataFlowValueFactory.createDataFlowValue(expression!!, ktType, bindingContext, descriptor)
val stableTypes = bindingContext.getDataFlowInfoBefore(expression).getStableTypes(dataFlow)
return stableTypes.firstNotNullResult {
if (KotlinBuiltIns.isDoubleOrNullableDouble(it)) {
TypeAndNullability(Type.DOUBLE_TYPE, TypeUtils.isNullableType(it))
}
else if (KotlinBuiltIns.isFloatOrNullableFloat(it)) {
TypeAndNullability(Type.FLOAT_TYPE, TypeUtils.isNullableType(it))
}
else {
null
when {
KotlinBuiltIns.isDoubleOrNullableDouble(it) -> TypeAndNullability(Type.DOUBLE_TYPE, TypeUtils.isNullableType(it))
KotlinBuiltIns.isFloatOrNullableFloat(it) -> TypeAndNullability(Type.FLOAT_TYPE, TypeUtils.isNullableType(it))
else -> null
}
}
}
@@ -396,3 +397,26 @@ fun InstructionAdapter.generateNewInstanceDupAndPlaceBeforeStackTop(
load(index, topStackType)
}
}
fun extractReificationArgument(type: KotlinType): Pair<TypeParameterDescriptor, ReificationArgument>? {
var type = type
var arrayDepth = 0
val isNullable = type.isMarkedNullable
while (KotlinBuiltIns.isArray(type)) {
arrayDepth++
type = type.arguments[0].type
}
val parameterDescriptor = TypeUtils.getTypeParameterDescriptorOrNull(type) ?: return null
return Pair(parameterDescriptor, ReificationArgument(parameterDescriptor.name.asString(), isNullable, arrayDepth))
}
fun unwrapInitialSignatureDescriptor(function: FunctionDescriptor): FunctionDescriptor =
function.initialSignatureDescriptor ?: function
fun ExpressionCodegen.generateCallReceiver(rangeCall: ResolvedCall<out CallableDescriptor>): StackValue =
generateReceiverValue(rangeCall.extensionReceiver ?: rangeCall.dispatchReceiver!!, false)
fun ExpressionCodegen.generateCallSingleArgument(rangeCall: ResolvedCall<out CallableDescriptor>): StackValue =
gen(ExpressionCodegen.getSingleArgumentExpression(rangeCall)!!)

View File

@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.load.java.JavaVisibilities;
import org.jetbrains.kotlin.load.java.descriptors.SamConstructorDescriptor;
import org.jetbrains.kotlin.load.java.sam.SamConstructorDescriptor;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.storage.LockBasedStorageManager;
@@ -248,10 +248,9 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull PackageFragmentDescriptor descriptor,
@NotNull Type multifileClassType,
@NotNull Type filePartType,
@NotNull Type filePartInitializerType,
@NotNull KtFile sourceFile
) {
return new MultifileClassPartContext(descriptor, this, multifileClassType, filePartType, filePartInitializerType, sourceFile);
return new MultifileClassPartContext(descriptor, this, multifileClassType, filePartType, sourceFile);
}
@NotNull

View File

@@ -55,9 +55,12 @@ public interface LocalLookup {
boolean idx = localLookup != null && localLookup.lookupLocal(vd);
if (!idx) return null;
VariableDescriptor delegateVariableDescriptor = state.getBindingContext().get(LOCAL_VARIABLE_DELEGATE, vd);
KotlinType delegateType =
vd instanceof VariableDescriptorWithAccessors
? JvmCodegenUtil.getPropertyDelegateType((VariableDescriptorWithAccessors) vd, state.getBindingContext())
: null;
Type sharedVarType = state.getTypeMapper().getSharedVarType(vd);
Type localType = state.getTypeMapper().mapType(delegateVariableDescriptor != null ? delegateVariableDescriptor : vd);
Type localType = state.getTypeMapper().mapType(delegateType != null ? delegateType : vd.getType());
Type type = sharedVarType != null ? sharedVarType : localType;
String fieldName = "$" + vd.getName();

View File

@@ -24,19 +24,16 @@ import org.jetbrains.org.objectweb.asm.Type;
public class MultifileClassPartContext extends MultifileClassContextBase implements DelegatingToPartContext, FacadePartWithSourceFile {
private final KtFile sourceFile;
private final Type partInitializerType;
public MultifileClassPartContext(
PackageFragmentDescriptor descriptor,
CodegenContext parent,
Type multifileClassType,
Type filePartType,
Type partInitializerType,
@NotNull KtFile sourceFile
) {
super(descriptor, parent, multifileClassType, filePartType);
this.sourceFile = sourceFile;
this.partInitializerType = partInitializerType;
}
@Nullable
@@ -45,11 +42,6 @@ public class MultifileClassPartContext extends MultifileClassContextBase impleme
return getFilePartType();
}
@NotNull
public Type getPartInitializerType() {
return partInitializerType;
}
@NotNull
@Override
public KtFile getSourceFile() {

View File

@@ -43,11 +43,6 @@ public class PackageContext extends FieldOwnerContext<PackageFragmentDescriptor>
return "Package: " + getContextDescriptor().getName();
}
@Nullable
public Type getPackagePartType() {
return packagePartType;
}
@Nullable
@Override
public Type getImplementationOwnerClassType() {

View File

@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.context.ClosureContext
import org.jetbrains.kotlin.codegen.context.MethodContext
import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
import org.jetbrains.kotlin.coroutines.isSuspendLambda
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.serialization.DescriptorSerializer
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -192,7 +194,7 @@ class CoroutineCodegenForLambda private constructor(
if (allFunctionParameters().size <= 1) {
val delegate = typeMapper.mapSignatureSkipGeneric(createCoroutineDescriptor).asmMethod
val bridgeParameters = (1..delegate.argumentTypes.size - 1).map { AsmTypes.OBJECT_TYPE } + delegate.argumentTypes.last()
val bridgeParameters = (1 until delegate.argumentTypes.size).map { AsmTypes.OBJECT_TYPE } + delegate.argumentTypes.last()
val bridge = Method(delegate.name, delegate.returnType, bridgeParameters.toTypedArray())
generateBridge(bridge, delegate)
@@ -288,7 +290,7 @@ class CoroutineCodegenForLambda private constructor(
private fun allFunctionParameters() =
originalSuspendFunctionDescriptor.extensionReceiverParameter.let(::listOfNotNull) +
originalSuspendFunctionDescriptor.valueParameters.orEmpty()
originalSuspendFunctionDescriptor.valueParameters
private fun ParameterDescriptor.getFieldInfoForCoroutineLambdaParameter() =
createHiddenFieldInfo(type, COROUTINE_LAMBDA_PARAMETER_PREFIX + (this.safeAs<ValueParameterDescriptor>()?.index ?: ""))
@@ -310,6 +312,7 @@ class CoroutineCodegenForLambda private constructor(
return CoroutineTransformerMethodVisitor(
mv, access, name, desc, null, null,
obtainClassBuilderForCoroutineState = { v },
element = element,
containingClassInternalName = v.thisName,
isForNamedFunction = false
)
@@ -474,8 +477,10 @@ class CoroutineCodegenForNamedFunction private constructor(
}
override fun generateKotlinMetadataAnnotation() {
writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0) {
// Do not write method metadata for raw coroutine state machines
writeKotlinMetadata(v, state, KotlinClassHeader.Kind.SYNTHETIC_CLASS, 0) { av ->
val serializer = DescriptorSerializer.createForLambda(JvmSerializerExtension(v.serializationBindings, state))
val functionProto = serializer.functionProto(createFreeFakeLambdaDescriptor(suspendFunctionJvmView)).build()
AsmUtil.writeAnnotationData(av, serializer, functionProto)
}
}

View File

@@ -17,17 +17,21 @@
package org.jetbrains.kotlin.codegen.coroutines
import com.intellij.util.containers.Stack
import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
import org.jetbrains.kotlin.codegen.inline.MaxStackFrameSizeAndLocalsCalculator
import org.jetbrains.kotlin.codegen.inline.isAfterSuspendMarker
import org.jetbrains.kotlin.codegen.inline.isBeforeSuspendMarker
import org.jetbrains.kotlin.codegen.inline.isInlineMarker
import org.jetbrains.kotlin.codegen.optimization.DeadCodeEliminationMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.common.*
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.utils.sure
@@ -50,6 +54,7 @@ class CoroutineTransformerMethodVisitor(
private val containingClassInternalName: String,
obtainClassBuilderForCoroutineState: () -> ClassBuilder,
private val isForNamedFunction: Boolean,
private val element: KtElement,
// It's only matters for named functions, may differ from '!isStatic(access)' in case of DefaultImpls
private val needDispatchReceiver: Boolean = false,
// May differ from containingClassInternalName in case of DefaultImpls
@@ -59,8 +64,8 @@ class CoroutineTransformerMethodVisitor(
private val classBuilderForCoroutineState: ClassBuilder by lazy(obtainClassBuilderForCoroutineState)
private val continuationIndex = if (isForNamedFunction) getLastParameterIndex(desc, access) else 0
var dataIndex = if (isForNamedFunction) -1 else 1
var exceptionIndex = if (isForNamedFunction) -1 else 2
private var dataIndex = if (isForNamedFunction) -1 else 1
private var exceptionIndex = if (isForNamedFunction) -1 else 2
override fun performTransformations(methodNode: MethodNode) {
val suspensionPoints = collectSuspensionPoints(methodNode)
@@ -106,11 +111,16 @@ class CoroutineTransformerMethodVisitor(
methodNode.instructions.apply {
val startLabel = LabelNode()
val defaultLabel = LabelNode()
val firstToInsertBefore = actualCoroutineStart
val tableSwitchLabel = LabelNode()
val lineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0
// tableswitch(this.label)
insertBefore(firstToInsertBefore,
insertBefore(actualCoroutineStart,
insnListOf(
*withInstructionAdapter { loadCoroutineSuspendedMarker() }.toArray(),
tableSwitchLabel,
// Allow debugger to stop on enter into suspend function
LineNumberNode(lineNumber, tableSwitchLabel),
VarInsnNode(Opcodes.ASTORE, suspendMarkerVarIndex),
VarInsnNode(Opcodes.ALOAD, continuationIndex),
createInsnForReadingLabel(),
@@ -293,7 +303,7 @@ class CoroutineTransformerMethodVisitor(
// It doesn't introduce an additional state to the corresponding coroutine's FSM.
suspensionPoints.forEach {
if (dceResult.isAlive(it.suspensionCallBegin) && dceResult.isRemoved(it.suspensionCallEnd)) {
methodNode.instructions.remove(it.suspensionCallBegin)
it.removeBeforeSuspendMarker(methodNode)
}
}
@@ -302,17 +312,15 @@ class CoroutineTransformerMethodVisitor(
private fun collectSuspensionPoints(methodNode: MethodNode): MutableList<SuspensionPoint> {
val suspensionPoints = mutableListOf<SuspensionPoint>()
val beforeSuspensionPointMarkerStack = Stack<MethodInsnNode>()
val beforeSuspensionPointMarkerStack = Stack<AbstractInsnNode>()
for (methodInsn in methodNode.instructions.toArray().filterIsInstance<MethodInsnNode>()) {
if (methodInsn.owner != COROUTINE_MARKER_OWNER) continue
when (methodInsn.name) {
BEFORE_SUSPENSION_POINT_MARKER_NAME -> {
beforeSuspensionPointMarkerStack.add(methodInsn)
when {
isBeforeSuspendMarker(methodInsn) -> {
beforeSuspensionPointMarkerStack.add(methodInsn.previous)
}
AFTER_SUSPENSION_POINT_MARKER_NAME -> {
isAfterSuspendMarker(methodInsn) -> {
suspensionPoints.add(SuspensionPoint(beforeSuspensionPointMarkerStack.pop(), methodInsn))
}
}
@@ -326,10 +334,8 @@ class CoroutineTransformerMethodVisitor(
private fun dropSuspensionMarkers(methodNode: MethodNode, suspensionPoints: List<SuspensionPoint>) {
// Drop markers
suspensionPoints.forEach {
// before-marker
methodNode.instructions.remove(it.suspensionCallBegin)
// after-marker
methodNode.instructions.remove(it.suspensionCallEnd)
it.removeBeforeSuspendMarker(methodNode)
it.removeAfterSuspendMarker(methodNode)
}
}
@@ -463,6 +469,8 @@ class CoroutineTransformerMethodVisitor(
): LabelNode {
val continuationLabel = LabelNode()
val continuationLabelAfterLoadedResult = LabelNode()
val suspendElementLineNumber = CodegenUtil.getLineNumberForElement(element, false) ?: 0
val nextLineNumberNode = suspension.suspensionCallEnd.findNextOrNull { it is LineNumberNode } as? LineNumberNode
with(methodNode.instructions) {
// Save state
insertBefore(suspension.suspensionCallBegin,
@@ -479,6 +487,10 @@ class CoroutineTransformerMethodVisitor(
ifacmpne(continuationLabelAfterLoadedResult.label)
// Exit
val returnLabel = LabelNode()
visitLabel(returnLabel.label)
// Special line number to stop in debugger before suspend return
visitLineNumber(suspendElementLineNumber, returnLabel.label)
load(suspendMarkerVarIndex, AsmTypes.OBJECT_TYPE)
areturn(AsmTypes.OBJECT_TYPE)
// Mark place for continuation
@@ -503,7 +515,18 @@ class CoroutineTransformerMethodVisitor(
load(dataIndex, AsmTypes.OBJECT_TYPE)
visitLabel(continuationLabelAfterLoadedResult.label)
// Extend next instruction linenumber. Can't use line number of suspension point here because both non-suspended execution
// and re-entering after suspension passes this label.
val afterSuspensionPointLineNumber = nextLineNumberNode?.line ?: suspendElementLineNumber
visitLineNumber(afterSuspensionPointLineNumber, continuationLabelAfterLoadedResult.label)
})
if (nextLineNumberNode != null) {
// Remove the line number instruction as it now covered with line number on continuation label.
// If both linenumber are present in bytecode, debugger will trigger line specific events twice.
remove(nextLineNumberNode)
}
}
return continuationLabel
@@ -589,18 +612,30 @@ private fun Type.normalize() =
/**
* Suspension call may consists of several instructions:
* INVOKESTATIC beforeSuspensionMarker
* ICONST_0
* INVOKESTATIC InlineMarker.mark()
* INVOKEVIRTUAL suspensionMethod()Ljava/lang/Object; // actually it could be some inline method instead of plain call
* CHECKCAST Type
* INVOKESTATIC afterSuspensionMarker
* ICONST_1
* INVOKESTATIC InlineMarker.mark()
*/
private class SuspensionPoint(
// INVOKESTATIC beforeSuspensionMarker
// ICONST_0
val suspensionCallBegin: AbstractInsnNode,
// INVOKESTATIC afterSuspensionMarker
// INVOKESTATIC InlineMarker.mark()
val suspensionCallEnd: AbstractInsnNode
) {
lateinit var tryCatchBlocksContinuationLabel: LabelNode
fun removeBeforeSuspendMarker(methodNode: MethodNode) {
methodNode.instructions.remove(suspensionCallBegin.next)
methodNode.instructions.remove(suspensionCallBegin)
}
fun removeAfterSuspendMarker(methodNode: MethodNode) {
methodNode.instructions.remove(suspensionCallEnd.previous)
methodNode.instructions.remove(suspensionCallEnd)
}
}
private fun getLastParameterIndex(desc: String, access: Int) =
@@ -681,7 +716,7 @@ private fun findSafelyReachableReturns(methodNode: MethodNode): Array<Set<Int>?>
}
if (!insn.isMeaningful || insn.opcode in SAFE_OPCODES || insn.isInvisibleInDebugVarInsn(methodNode) ||
InlineCodegenUtil.isInlineMarker(insn)) {
isInlineMarker(insn)) {
setOf()
}
else null
@@ -693,6 +728,7 @@ private fun findSafelyReachableReturns(methodNode: MethodNode): Array<Set<Int>?>
for (index in 0 until insns.size()) {
if (insns[index].opcode == Opcodes.ARETURN) continue
@Suppress("RemoveExplicitTypeArguments")
val newResult =
controlFlowGraph
.getSuccessorsIndices(index).plus(index)
@@ -720,4 +756,4 @@ private fun AbstractInsnNode?.isInvisibleInDebugVarInsn(methodNode: MethodNode):
}
private val SAFE_OPCODES =
((Opcodes.DUP..Opcodes.DUP2_X2) + Opcodes.POP + Opcodes.POP2 + (Opcodes.IFEQ..Opcodes.GOTO)).toSet()
((Opcodes.DUP..Opcodes.DUP2_X2) + Opcodes.NOP + Opcodes.POP + Opcodes.POP2 + (Opcodes.IFEQ..Opcodes.GOTO)).toSet()

View File

@@ -57,6 +57,7 @@ class SuspendFunctionGenerationStrategy(
return CoroutineTransformerMethodVisitor(
mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState,
isForNamedFunction = true,
element = declaration,
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
internalNameForDispatchReceiver = containingClassInternalNameOrNull()
).also {

View File

@@ -52,11 +52,6 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.commons.Method
import org.jetbrains.org.objectweb.asm.tree.MethodNode
// These classes do not actually exist at runtime
const val COROUTINE_MARKER_OWNER = "kotlin/coroutines/Markers"
const val BEFORE_SUSPENSION_POINT_MARKER_NAME = "beforeSuspensionPoint"
const val AFTER_SUSPENSION_POINT_MARKER_NAME = "afterSuspensionPoint"
const val COROUTINE_LABEL_FIELD_NAME = "label"
const val SUSPEND_FUNCTION_CREATE_METHOD_NAME = "create"
const val DO_RESUME_METHOD_NAME = "doResume"

View File

@@ -144,7 +144,7 @@ internal fun performRefinedTypeAnalysis(methodNode: MethodNode, thisName: String
}
})
val refinedFrames = Array(basicFrames.size) {
return Array(basicFrames.size) {
insnIndex ->
val current = Frame(basicFrames[insnIndex] ?: return@Array null)
@@ -158,8 +158,6 @@ internal fun performRefinedTypeAnalysis(methodNode: MethodNode, thisName: String
current
}
return refinedFrames
}
private fun AbstractInsnNode.isIntLoad() = opcode == Opcodes.ILOAD

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,10 +14,8 @@
* limitations under the License.
*/
package org.jetbrains.kotlin.java.model.elements
package org.jetbrains.kotlin.codegen.descriptors
import org.jetbrains.kotlin.java.model.JeElement
import org.jetbrains.kotlin.descriptors.ClassDescriptor
interface JeElementRenderer {
fun render(element: JeElement): String
}
interface FileClassDescriptor : ClassDescriptor

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
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.serialization.DescriptorSerializer
import java.util.*
/**
* Given a function descriptor, creates another function descriptor with type parameters copied from outer context(s).
* This is needed because once we're serializing this to a proto, there's no place to store information about external type parameters.
*/
fun createFreeFakeLambdaDescriptor(descriptor: FunctionDescriptor): FunctionDescriptor {
return createFreeDescriptor(descriptor)
}
private fun <D : CallableMemberDescriptor> createFreeDescriptor(descriptor: D): D {
@Suppress("UNCHECKED_CAST")
val builder = descriptor.newCopyBuilder() as CallableMemberDescriptor.CopyBuilder<D>
val typeParameters = ArrayList<TypeParameterDescriptor>(0)
builder.setTypeParameters(typeParameters)
var container: DeclarationDescriptor? = descriptor.containingDeclaration
while (container != null) {
if (container is ClassDescriptor) {
typeParameters.addAll(container.declaredTypeParameters)
}
else if (container is CallableDescriptor && container !is ConstructorDescriptor) {
typeParameters.addAll(container.typeParameters)
}
container = container.containingDeclaration
}
return if (typeParameters.isEmpty()) descriptor else builder.build()!!
}
/**
* Given a local delegated variable descriptor, creates a descriptor of a property that should be observed
* when using reflection on that local variable at runtime.
* Only members used by [DescriptorSerializer.propertyProto] are implemented correctly in this property descriptor.
*/
fun createFreeFakeLocalPropertyDescriptor(descriptor: LocalVariableDescriptor): PropertyDescriptor {
val property = PropertyDescriptorImpl.create(
descriptor.containingDeclaration, descriptor.annotations, Modality.FINAL, descriptor.visibility, descriptor.isVar,
descriptor.name, CallableMemberDescriptor.Kind.DECLARATION, descriptor.source, false, descriptor.isConst,
false, false, false, @Suppress("DEPRECATION") descriptor.isDelegated
)
property.setType(descriptor.type, descriptor.typeParameters, descriptor.dispatchReceiverParameter, descriptor.extensionReceiverParameter)
property.initialize(
descriptor.getter?.run {
PropertyGetterDescriptorImpl(property, annotations, modality, visibility, true, isExternal, isInline, kind, null, source).apply {
initialize(this@run.returnType)
}
},
descriptor.setter?.run {
PropertySetterDescriptorImpl(property, annotations, modality, visibility, true, isExternal, isInline, kind, null, source).apply {
initialize(this@run.valueParameters.single())
}
}
)
return createFreeDescriptor(property)
}

View File

@@ -1,101 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen.forLoop
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.codegen.ExpressionCodegen
import org.jetbrains.kotlin.codegen.RangeCodegenUtil
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.org.objectweb.asm.Type
fun ExpressionCodegen.getForLoopGenerator(forExpression: KtForExpression) : AbstractForLoopGenerator {
getLoopRangeResolvedCall(forExpression, bindingContext)?.let { loopRangeCall ->
createOptimizedForLoopGeneratorOrNull(forExpression, loopRangeCall)?.let {
return it
}
}
val loopRange = forExpression.loopRange!!
val loopRangeType = bindingContext.getType(loopRange)!!
val asmLoopRangeType = asmType(loopRangeType)
return when {
asmLoopRangeType.sort == Type.ARRAY ->
ForInArrayLoopGenerator(this, forExpression)
RangeCodegenUtil.isRange(loopRangeType) ->
ForInRangeInstanceLoopGenerator(this, forExpression)
RangeCodegenUtil.isProgression(loopRangeType) ->
ForInProgressionExpressionLoopGenerator(this, forExpression)
isSubtypeOfCharSequence(loopRangeType, state.module.builtIns) ->
ForInCharSequenceLoopGenerator(this, forExpression)
else ->
IteratorForLoopGenerator(this, forExpression)
}
}
private fun isSubtypeOfCharSequence(type: KotlinType, builtIns: KotlinBuiltIns) =
KotlinTypeChecker.DEFAULT.isSubtypeOf(type, builtIns.getBuiltInClassByName(Name.identifier("CharSequence")).defaultType)
private fun ExpressionCodegen.createOptimizedForLoopGeneratorOrNull(
forExpression: KtForExpression,
loopRangeCall: ResolvedCall<out CallableDescriptor>
): AbstractForLoopGenerator? {
val loopRangeCallee = loopRangeCall.resultingDescriptor
return when {
RangeCodegenUtil.isPrimitiveNumberRangeTo(loopRangeCallee) ->
ForInRangeLiteralLoopGenerator(this, forExpression, loopRangeCall)
RangeCodegenUtil.isPrimitiveNumberDownTo(loopRangeCallee) ->
ForInDownToProgressionLoopGenerator(this, forExpression, loopRangeCall)
RangeCodegenUtil.isPrimitiveNumberUntil(loopRangeCallee) ->
ForInUntilRangeLoopGenerator(this, forExpression, loopRangeCall)
RangeCodegenUtil.isArrayOrPrimitiveArrayIndices(loopRangeCallee) ->
ForInArrayIndicesRangeLoopGenerator(this, forExpression, loopRangeCall)
RangeCodegenUtil.isCollectionIndices(loopRangeCallee) ->
ForInCollectionIndicesRangeLoopGenerator(this, forExpression, loopRangeCall)
RangeCodegenUtil.isCharSequenceIndices(loopRangeCallee) ->
ForInCharSequenceIndicesRangeLoopGenerator(this, forExpression, loopRangeCall)
else -> null
}
}
private fun getLoopRangeResolvedCall(forExpression: KtForExpression, bindingContext: BindingContext): ResolvedCall<out CallableDescriptor>? {
val loopRange = KtPsiUtil.deparenthesize(forExpression.loopRange)
if (loopRange is KtQualifiedExpression) {
val qualifiedExpression = loopRange as KtQualifiedExpression?
val selector = qualifiedExpression!!.selectorExpression
if (selector is KtCallExpression || selector is KtSimpleNameExpression) {
return selector.getResolvedCall(bindingContext)
}
}
else if (loopRange is KtSimpleNameExpression || loopRange is KtCallExpression) {
return loopRange.getResolvedCall(bindingContext)
}
else if (loopRange is KtBinaryExpression) {
return loopRange.operationReference.getResolvedCall(bindingContext)
}
return null
}

View File

@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.ClassBuilder
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.coroutines.COROUTINE_IMPL_ASM_TYPE
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.isThis0
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.Companion.NO_ORIGIN
import org.jetbrains.org.objectweb.asm.*
@@ -49,7 +48,7 @@ class AnonymousObjectTransformer(
val classBuilder = createRemappingClassBuilderViaFactory(inliningContext)
val methodsToTransform = ArrayList<MethodNode>()
createClassReader().accept(object : ClassVisitor(InlineCodegenUtil.API, classBuilder.visitor) {
createClassReader().accept(object : ClassVisitor(API, classBuilder.visitor) {
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces)
if (COROUTINE_IMPL_ASM_TYPE.internalName == superName) {
@@ -79,11 +78,11 @@ class AnonymousObjectTransformer(
override fun visitField(access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor? {
addUniqueField(name)
if (InlineCodegenUtil.isCapturedFieldName(name)) {
return null
return if (isCapturedFieldName(name)) {
null
}
else {
return classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, name, desc, signature, value)
classBuilder.newField(JvmDeclarationOrigin.NO_ORIGIN, access, name, desc, signature, value)
}
}
@@ -96,14 +95,14 @@ class AnonymousObjectTransformer(
}, ClassReader.SKIP_FRAMES)
if (!inliningContext.isInliningLambda) {
if (debugInfo != null && !debugInfo!!.isEmpty()) {
sourceMapper = SourceMapper.createFromSmap(SMAPParser.parse(debugInfo!!))
sourceMapper = if (debugInfo != null && !debugInfo!!.isEmpty()) {
SourceMapper.createFromSmap(SMAPParser.parse(debugInfo!!))
}
else {
//seems we can't do any clever mapping cause we don't know any about original class name
sourceMapper = IdenticalSourceMapper
IdenticalSourceMapper
}
if (sourceInfo != null && !InlineCodegenUtil.GENERATE_SMAP) {
if (sourceInfo != null && !GENERATE_SMAP) {
classBuilder.visitSource(sourceInfo!!, debugInfo)
}
}
@@ -139,7 +138,7 @@ class AnonymousObjectTransformer(
}
deferringMethods.forEach { method ->
InlineCodegenUtil.removeFinallyMarkers(method.intermediate)
removeFinallyMarkers(method.intermediate)
method.visitEnd()
}
@@ -286,7 +285,7 @@ class AnonymousObjectTransformer(
val intermediateMethodNode = MethodNode(constructor!!.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY)
inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor!!, constructorInlineBuilder, true)
InlineCodegenUtil.removeFinallyMarkers(intermediateMethodNode)
removeFinallyMarkers(intermediateMethodNode)
val first = intermediateMethodNode.instructions.first
val oldStartLabel = if (first is LabelNode) first.label else null
@@ -429,8 +428,8 @@ class AnonymousObjectTransformer(
val parent = parentFieldRemapper.parent as? RegeneratedLambdaFieldRemapper ?:
throw AssertionError("Expecting RegeneratedLambdaFieldRemapper, but ${parentFieldRemapper.parent}")
val ownerType = Type.getObjectType(parent.originalLambdaInternalName)
val desc = CapturedParamDesc(ownerType, InlineCodegenUtil.THIS, ownerType)
val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, InlineCodegenUtil.`THIS$0`/*outer lambda/object*/, false)
val desc = CapturedParamDesc(ownerType, THIS, ownerType)
val recapturedParamInfo = capturedParamBuilder.addCapturedParam(desc, THIS_0/*outer lambda/object*/, false)
val composed = StackValue.LOCAL_0
recapturedParamInfo.remapValue = composed
allRecapturedParameters.add(desc)
@@ -458,16 +457,16 @@ class AnonymousObjectTransformer(
}
private fun getNewFieldName(oldName: String, originalField: Boolean): String {
if (InlineCodegenUtil.`THIS$0` == oldName) {
if (!originalField) {
return oldName
if (THIS_0 == oldName) {
return if (!originalField) {
oldName
}
else {
//rename original 'this$0' in declaration site lambda (inside inline function) to use this$0 only for outer lambda/object access on call site
return addUniqueField(oldName + InlineCodegenUtil.INLINE_FUN_THIS_0_SUFFIX)
addUniqueField(oldName + INLINE_FUN_THIS_0_SUFFIX)
}
}
return addUniqueField(oldName + InlineCodegenUtil.INLINE_TRANSFORMATION_SUFFIX)
return addUniqueField(oldName + INLINE_TRANSFORMATION_SUFFIX)
}
private fun addUniqueField(name: String): String {

View File

@@ -38,7 +38,7 @@ abstract class CoveringTryCatchNodeProcessor(parameterSize: Int) {
open fun processInstruction(curInstr: AbstractInsnNode, directOrder: Boolean) {
if (curInstr is VarInsnNode || curInstr is IincInsnNode) {
val argSize = InlineCodegenUtil.getLoadStoreArgSize(curInstr.opcode)
val argSize = getLoadStoreArgSize(curInstr.opcode)
val varIndex = if (curInstr is VarInsnNode) curInstr.`var` else (curInstr as IincInsnNode).`var`
nextFreeLocalIndex = Math.max(nextFreeLocalIndex, varIndex + argSize)
}

View File

@@ -22,7 +22,7 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
class DeferredMethodVisitor(
val intermediate: MethodNode,
val resultNode: () -> MethodVisitor
) : MethodVisitor(InlineCodegenUtil.API, intermediate) {
) : MethodVisitor(API, intermediate) {
override fun visitEnd() {
super.visitEnd()

View File

@@ -35,7 +35,7 @@ open class FieldRemapper(
protected open fun canProcess(fieldOwner: String, fieldName: String, isFolding: Boolean): Boolean {
return fieldOwner == originalLambdaInternalName &&
//don't process general field of anonymous objects
InlineCodegenUtil.isCapturedFieldName(fieldName)
isCapturedFieldName(fieldName)
}
fun foldFieldAccessChainIfNeeded(capturedFieldAccess: List<AbstractInsnNode>, node: MethodNode): AbstractInsnNode? =
@@ -68,7 +68,7 @@ open class FieldRemapper(
val insnNode = capturedFieldAccess[currentInstruction] as FieldInsnNode
if (canProcess(insnNode.owner, insnNode.name, true)) {
insnNode.name = InlineCodegenUtil.CAPTURED_FIELD_FOLD_PREFIX + getFieldNameForFolding(insnNode)
insnNode.name = CAPTURED_FIELD_FOLD_PREFIX + getFieldNameForFolding(insnNode)
insnNode.opcode = Opcodes.GETSTATIC
node.remove(InsnSequence(capturedFieldAccess[0], insnNode))

View File

@@ -25,7 +25,9 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.getLoadStoreArgSize;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.API;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.getLoadStoreArgSize;
public class InlineAdapter extends InstructionAdapter {
private final SourceMapper sourceMapper;
@@ -36,7 +38,7 @@ public class InlineAdapter extends InstructionAdapter {
private int nextLocalIndexBeforeInline = -1;
public InlineAdapter(@NotNull MethodVisitor mv, int localsSize, @NotNull SourceMapper sourceMapper) {
super(InlineCodegenUtil.API, mv);
super(API, mv);
this.nextLocalIndex = localsSize;
this.sourceMapper = sourceMapper;
}
@@ -86,7 +88,7 @@ public class InlineAdapter extends InstructionAdapter {
@Override
public void visitLineNumber(int line, @NotNull Label start) {
if (InlineCodegenUtil.GENERATE_SMAP) {
if (GENERATE_SMAP) {
line = sourceMapper.mapLineNumber(line);
}
//skip not mapped lines

View File

@@ -0,0 +1,704 @@
/*
* 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.inline
import com.intellij.psi.PsiElement
import com.intellij.util.ArrayUtil
import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment
import org.jetbrains.kotlin.codegen.*
import org.jetbrains.kotlin.codegen.AsmUtil.*
import org.jetbrains.kotlin.codegen.coroutines.createMethodNodeForSuspendCoroutineOrReturn
import org.jetbrains.kotlin.codegen.coroutines.isBuiltInSuspendCoroutineOrReturnInJvm
import org.jetbrains.kotlin.codegen.intrinsics.bytecode
import org.jetbrains.kotlin.codegen.intrinsics.classId
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.isInlineOnly
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinableParameterExpression
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral
import org.jetbrains.kotlin.types.expressions.LabelResolver
import org.jetbrains.org.objectweb.asm.Opcodes
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.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import java.util.*
abstract class InlineCodegen<out T: BaseExpressionCodegen>(
protected val codegen: T,
protected val state: GenerationState,
function: FunctionDescriptor,
private val typeParameterMappings: TypeParameterMappings,
protected val sourceCompiler: SourceCompilerForInline
) {
init {
assert(InlineUtil.isInline(function) || InlineUtil.isArrayConstructorWithLambda(function)) {
"InlineCodegen can inline only inline functions and array constructors: " + function
}
}
// TODO: implement AS_FUNCTION inline strategy
private val asFunctionInline = false
protected val typeMapper = state.typeMapper
private val initialFrameSize = codegen.frameMap.currentSize
private val reifiedTypeInliner = ReifiedTypeInliner(typeParameterMappings)
protected val functionDescriptor: FunctionDescriptor =
if (InlineUtil.isArrayConstructorWithLambda(function))
FictitiousArrayConstructor.create(function as ConstructorDescriptor)
else
function.original
protected val jvmSignature: JvmMethodGenericSignature
private val isSameModule: Boolean
protected val invocationParamBuilder = ParametersBuilder.newBuilder()
protected val expressionMap = linkedMapOf<Int, LambdaInfo>()
protected var activeLambda: LambdaInfo? = null
private val defaultSourceMapper = sourceCompiler.lazySourceMapper
protected var delayedHiddenWriting: Function0<Unit>? = null
protected val maskValues = ArrayList<Int>()
protected var maskStartIndex = -1
protected var methodHandleInDefaultMethodIndex = -1
init {
sourceCompiler.initializeInlineFunctionContext(functionDescriptor)
jvmSignature = typeMapper.mapSignatureWithGeneric(functionDescriptor, sourceCompiler.contextKind)
isSameModule = sourceCompiler.isCallInsideSameModuleAsDeclared(functionDescriptor)
if (functionDescriptor !is FictitiousArrayConstructor) {
reportIncrementalInfo(functionDescriptor, sourceCompiler.compilationContextFunctionDescriptor.original, jvmSignature, state)
val functionOrAccessorName = typeMapper.mapAsmMethod(function).name
//track changes for property accessor and @JvmName inline functions/property accessors
if (functionOrAccessorName != functionDescriptor.name.asString()) {
val scope = getMemberScope(functionDescriptor)
//Fake lookup to track track changes for property accessors and @JvmName functions/property accessors
scope?.getContributedFunctions(Name.identifier(functionOrAccessorName), sourceCompiler.lookupLocation)
}
}
}
protected fun throwCompilationException(
nodeAndSmap: SMAPAndMethodNode?, e: Exception, generateNodeText: Boolean
): CompilationException {
val contextDescriptor = sourceCompiler.compilationContextDescriptor
val element = DescriptorToSourceUtils.descriptorToDeclaration(contextDescriptor)
val node = nodeAndSmap?.node
throw CompilationException(
"Couldn't inline method call '" + functionDescriptor.name + "' into\n" +
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
(element?.text ?: "<no source>") +
if (generateNodeText) "\nCause: " + node.nodeText else "",
e, sourceCompiler.callElement as? PsiElement
)
}
protected fun generateStub(resolvedCall: ResolvedCall<*>?, codegen: BaseExpressionCodegen) {
leaveTemps()
assert(resolvedCall != null)
val message = "Call is part of inline cycle: " + resolvedCall!!.call.callElement.text
AsmUtil.genThrow(codegen.v, "java/lang/UnsupportedOperationException", message)
}
protected fun endCall(result: InlineResult) {
leaveTemps()
codegen.propagateChildReifiedTypeParametersUsages(result.reifiedTypeParametersUsages)
state.factory.removeClasses(result.calcClassesToRemove())
codegen.markLineNumberAfterInlineIfNeeded()
}
fun performInline(
resolvedCall: ResolvedCall<*>?,
callDefault: Boolean,
codegen: BaseExpressionCodegen
) {
if (!state.inlineCycleReporter.enterIntoInlining(resolvedCall)) {
generateStub(resolvedCall, codegen)
return
}
var nodeAndSmap: SMAPAndMethodNode? = null
try {
nodeAndSmap = createInlineMethodNode(functionDescriptor, jvmSignature, codegen, callDefault, resolvedCall, state, sourceCompiler)
endCall(inlineCall(nodeAndSmap, callDefault))
}
catch (e: CompilationException) {
throw e
}
catch (e: InlineException) {
throw throwCompilationException(nodeAndSmap, e, false)
}
catch (e: Exception) {
throw throwCompilationException(nodeAndSmap, e, true)
}
finally {
state.inlineCycleReporter.exitFromInliningOf(resolvedCall)
}
}
protected fun inlineCall(nodeAndSmap: SMAPAndMethodNode, callDefault: Boolean): InlineResult {
assert(delayedHiddenWriting == null) { "'putHiddenParamsIntoLocals' should be called after 'processAndPutHiddenParameters(true)'" }
defaultSourceMapper.callSiteMarker = CallSiteMarker(codegen.lastLineNumber)
val node = nodeAndSmap.node
if (callDefault) {
val defaultLambdas = expandMaskConditionsAndUpdateVariableNodes(
node, maskStartIndex, maskValues, methodHandleInDefaultMethodIndex,
extractDefaultLambdaOffsetAndDescriptor(jvmSignature, functionDescriptor)
)
for (lambda in defaultLambdas) {
invocationParamBuilder.buildParameters().getParameterByDeclarationSlot(lambda.offset).lambda = lambda
val prev = expressionMap.put(lambda.offset, lambda)
assert(prev == null) { "Lambda with offset ${lambda.offset} already exists: $prev" }
}
}
val reificationResult = reifiedTypeInliner.reifyInstructions(node)
generateClosuresBodies()
//through generation captured parameters will be added to invocationParamBuilder
putClosureParametersOnStack()
addInlineMarker(codegen.v, true)
val parameters = invocationParamBuilder.buildParameters()
val info = RootInliningContext(
expressionMap, state, codegen.inlineNameGenerator.subGenerator(jvmSignature.asmMethod.name),
sourceCompiler, sourceCompiler.inlineCallSiteInfo, reifiedTypeInliner, typeParameterMappings
)
val inliner = MethodInliner(
node, parameters, info, FieldRemapper(null, null, parameters), isSameModule,
"Method inlining " + sourceCompiler.callElementText,
createNestedSourceMapper(nodeAndSmap, defaultSourceMapper), info.callSiteInfo,
if (functionDescriptor.isInlineOnly()) InlineOnlySmapSkipper(codegen) else null
) //with captured
val remapper = LocalVarRemapper(parameters, initialFrameSize)
val adapter = createEmptyMethodNode()
//hack to keep linenumber info, otherwise jdi will skip begin of linenumber chain
adapter.visitInsn(Opcodes.NOP)
val result = inliner.doInline(adapter, remapper, true, LabelOwner.SKIP_ALL)
result.reifiedTypeParametersUsages.mergeAll(reificationResult)
val labels = sourceCompiler.getContextLabels()
val infos = MethodInliner.processReturns(adapter, LabelOwner { labels.contains(it) }, true, null)
sourceCompiler.generateAndInsertFinallyBlocks(
adapter, infos, (remapper.remap(parameters.argsSizeOnStack + 1).value as StackValue.Local).index
)
removeStaticInitializationTrigger(adapter)
if (!sourceCompiler.isFinallyMarkerRequired()) {
removeFinallyMarkers(adapter)
}
adapter.accept(MethodBodyVisitor(codegen.v))
addInlineMarker(codegen.v, false)
defaultSourceMapper.callSiteMarker = null
return result
}
private fun generateClosuresBodies() {
for (info in expressionMap.values) {
info.generateLambdaBody(sourceCompiler, reifiedTypeInliner)
}
}
protected fun putArgumentOrCapturedToLocalVal(
type: Type,
stackValue: StackValue,
capturedParamIndex: Int,
parameterIndex: Int,
kind: ValueKind
) {
val isDefaultParameter = kind === ValueKind.DEFAULT_PARAMETER
if (!isDefaultParameter && shouldPutGeneralValue(type, stackValue)) {
stackValue.put(type, codegen.v)
}
if (!asFunctionInline && Type.VOID_TYPE !== type) {
//TODO remap only inlinable closure => otherwise we could get a lot of problem
val couldBeRemapped = !shouldPutGeneralValue(type, stackValue) && kind !== ValueKind.DEFAULT_PARAMETER
val remappedValue = if (couldBeRemapped) stackValue else null
val info: ParameterInfo
if (capturedParamIndex >= 0) {
val capturedParamInfoInLambda = activeLambda!!.capturedVars[capturedParamIndex]
info = invocationParamBuilder.addCapturedParam(capturedParamInfoInLambda, capturedParamInfoInLambda.fieldName, false)
info.setRemapValue(remappedValue)
}
else {
info = invocationParamBuilder.addNextValueParameter(type, false, remappedValue, parameterIndex)
}
recordParameterValueInLocalVal(
false,
isDefaultParameter || kind === ValueKind.DEFAULT_LAMBDA_CAPTURED_PARAMETER,
info
)
}
}
protected fun recordParameterValueInLocalVal(delayedWritingToLocals: Boolean, skipStore: Boolean, vararg infos: ParameterInfo): Function0<Unit>? {
val index = IntArray(infos.size) { i ->
if (!infos[i].isSkippedOrRemapped) {
codegen.frameMap.enterTemp(infos[i].getType())
}
else -1
}
val possibleLazyTask = {
for (i in infos.indices.reversed()) {
val info = infos[i]
if (!info.isSkippedOrRemapped) {
val type = info.type
val local = StackValue.local(index[i], type)
if (!skipStore) {
local.store(StackValue.onStack(type), codegen.v)
}
if (info is CapturedParamInfo) {
info.setRemapValue(local)
info.isSynthetic = true
}
}
}
}
if (delayedWritingToLocals) return possibleLazyTask
possibleLazyTask()
return null
}
private fun leaveTemps() {
invocationParamBuilder.listAllParams().asReversed().forEach {
param ->
if (!param.isSkippedOrRemapped || CapturedParamInfo.isSynthetic(param)) {
codegen.frameMap.leaveTemp(param.type)
}
}
}
private fun putClosureParametersOnStack() {
for (next in expressionMap.values) {
//closure parameters for bounded callable references are generated inplace
if (next is ExpressionLambda && next.isBoundCallableReference) continue
putClosureParametersOnStack(next, null)
}
}
abstract protected fun putClosureParametersOnStack(next: LambdaInfo, functionReferenceReceiver: StackValue?)
protected fun rememberCapturedForDefaultLambda(defaultLambda: DefaultLambda) {
for ((paramIndex, captured) in defaultLambda.capturedVars.withIndex()) {
putArgumentOrCapturedToLocalVal(
captured.type,
//HACK: actually parameter would be placed on stack in default function
// also see ValueKind.DEFAULT_LAMBDA_CAPTURED_PARAMETER check
StackValue.onStack(captured.type),
paramIndex,
paramIndex,
ValueKind.DEFAULT_LAMBDA_CAPTURED_PARAMETER
)
defaultLambda.parameterOffsetsInDefault.add(invocationParamBuilder.nextParameterOffset)
}
}
protected fun processDefaultMaskOrMethodHandler(value: StackValue, kind: ValueKind): Boolean {
if (kind !== ValueKind.DEFAULT_MASK && kind !== ValueKind.METHOD_HANDLE_IN_DEFAULT) {
return false
}
assert(value is StackValue.Constant) { "Additional default method argument should be constant, but " + value }
val constantValue = (value as StackValue.Constant).value
if (kind === ValueKind.DEFAULT_MASK) {
assert(constantValue is Int) { "Mask should be of Integer type, but " + constantValue }
maskValues.add(constantValue as Int)
if (maskStartIndex == -1) {
maskStartIndex = invocationParamBuilder.listAllParams().sumBy {
if (it is CapturedParamInfo) 0 else it.type.size
}
}
}
else {
assert(constantValue == null) { "Additional method handle for default argument should be null, but " + constantValue!! }
methodHandleInDefaultMethodIndex = maskStartIndex + maskValues.size
}
return true
}
companion object {
private fun getMemberScope(functionOrAccessor: FunctionDescriptor): MemberScope? {
val callableMemberDescriptor = JvmCodegenUtil.getDirectMember(functionOrAccessor)
val classOrPackageFragment = callableMemberDescriptor.containingDeclaration
return when (classOrPackageFragment) {
is ClassDescriptor -> classOrPackageFragment.unsubstitutedMemberScope
is PackageFragmentDescriptor -> classOrPackageFragment.getMemberScope()
else -> null
}
}
internal fun createInlineMethodNode(
functionDescriptor: FunctionDescriptor,
jvmSignature: JvmMethodSignature,
codegen: BaseExpressionCodegen,
callDefault: Boolean,
resolvedCall: ResolvedCall<*>?,
state: GenerationState,
sourceCompilerForInline: SourceCompilerForInline
): SMAPAndMethodNode {
if (isSpecialEnumMethod(functionDescriptor)) {
val arguments = resolvedCall!!.typeArguments
val node = createSpecialEnumMethodBody(
codegen,
functionDescriptor.name.asString(),
arguments.keys.single().defaultType,
state.typeMapper
)
return SMAPAndMethodNode(node, SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1))
}
else if (functionDescriptor.isBuiltInSuspendCoroutineOrReturnInJvm()) {
return SMAPAndMethodNode(
createMethodNodeForSuspendCoroutineOrReturn(
functionDescriptor, state.typeMapper
),
SMAPParser.parseOrCreateDefault(null, null, "fake", -1, -1)
)
}
val asmMethod = if (callDefault)
state.typeMapper.mapDefaultMethod(functionDescriptor, sourceCompilerForInline.contextKind)
else
jvmSignature.asmMethod
val methodId = MethodId(DescriptorUtils.getFqNameSafe(functionDescriptor.containingDeclaration), asmMethod)
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
if (!isBuiltInArrayIntrinsic(functionDescriptor) && directMember !is DeserializedCallableMemberDescriptor) {
return sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod)
}
val resultInCache = state.inlineCache.methodNodeById.getOrPut(methodId
) {
doCreateMethodNodeFromCompiled(directMember, state, asmMethod)
?: throw IllegalStateException("Couldn't obtain compiled function body for " + functionDescriptor)
}
return resultInCache.copyWithNewNode(cloneMethodNode(resultInCache.node))
}
private fun getDirectMemberAndCallableFromObject(functionDescriptor: FunctionDescriptor): CallableMemberDescriptor {
val directMember = JvmCodegenUtil.getDirectMember(functionDescriptor)
return (directMember as? ImportedFromObjectCallableDescriptor<*>)?.callableFromObject ?: directMember
}
private fun cloneMethodNode(methodNode: MethodNode): MethodNode {
methodNode.instructions.resetLabels()
return MethodNode(
API, methodNode.access, methodNode.name, methodNode.desc, methodNode.signature,
ArrayUtil.toStringArray(methodNode.exceptions)
).also(methodNode::accept)
}
private fun doCreateMethodNodeFromCompiled(
callableDescriptor: CallableMemberDescriptor,
state: GenerationState,
asmMethod: Method
): SMAPAndMethodNode? {
if (isBuiltInArrayIntrinsic(callableDescriptor)) {
val classId = classId
val bytes = state.inlineCache.classBytes.getOrPut(classId) { bytecode }
return getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, classId.asString())
}
assert(callableDescriptor is DeserializedCallableMemberDescriptor) { "Not a deserialized function or proper: " + callableDescriptor }
val containingClasses = state.typeMapper.getContainingClassesForDeserializedCallable(callableDescriptor as DeserializedCallableMemberDescriptor)
val containerId = containingClasses.implClassId
val bytes = state.inlineCache.classBytes.getOrPut(containerId) {
findVirtualFile(state, containerId)?.contentsToByteArray() ?:
throw IllegalStateException("Couldn't find declaration file for " + containerId)
}
val methodNode = getMethodNode(bytes, asmMethod.name, asmMethod.descriptor, containerId.asString()) ?: return null
// KLUDGE: Inline suspend function built with compiler version less than 1.1.4/1.2-M1 did not contain proper
// before/after suspension point marks, so we detect those functions here and insert the corresponding marks
if (isLegacySuspendInlineFunction(callableDescriptor)) {
insertLegacySuspendInlineMarks(methodNode.node)
}
return methodNode
}
private fun isBuiltInArrayIntrinsic(callableDescriptor: CallableMemberDescriptor): Boolean {
if (callableDescriptor is FictitiousArrayConstructor) return true
val name = callableDescriptor.name.asString()
return (name == "arrayOf" || name == "emptyArray") && callableDescriptor.containingDeclaration is BuiltInsPackageFragment
}
private fun removeStaticInitializationTrigger(methodNode: MethodNode) {
val insnList = methodNode.instructions
var insn: AbstractInsnNode? = insnList.first
while (insn != null) {
if (MultifileClassPartCodegen.isStaticInitTrigger(insn)) {
val clinitTriggerCall = insn
insn = insn.next
insnList.remove(clinitTriggerCall)
}
else {
insn = insn.next
}
}
}
/*descriptor is null for captured vars*/
private fun shouldPutGeneralValue(type: Type, stackValue: StackValue): Boolean {
//remap only inline functions (and maybe non primitives)
//TODO - clean asserion and remapping logic
if (isPrimitive(type) != isPrimitive(stackValue.type)) {
//don't remap boxing/unboxing primitives - lost identity and perfomance
return true
}
if (stackValue is StackValue.Local) {
return false
}
var field = stackValue
if (stackValue is StackValue.FieldForSharedVar) {
field = stackValue.receiver
}
//check that value corresponds to captured inlining parameter
if (field is StackValue.Field) {
val varDescriptor = field.descriptor
//check that variable is inline function parameter
return !(varDescriptor is ParameterDescriptor &&
InlineUtil.isInlineLambdaParameter(varDescriptor) &&
InlineUtil.isInline(varDescriptor.containingDeclaration))
}
return true
}
fun getDeclarationLabels(lambdaOrFun: PsiElement?, descriptor: DeclarationDescriptor): Set<String> {
val result = HashSet<String>()
if (lambdaOrFun != null) {
val label = LabelResolver.getLabelNameIfAny(lambdaOrFun)
if (label != null) {
result.add(label.asString())
}
}
if (!isFunctionLiteral(descriptor)) {
if (!descriptor.name.isSpecial) {
result.add(descriptor.name.asString())
}
result.add(FIRST_FUN_LABEL)
}
return result
}
fun createNestedSourceMapper(nodeAndSmap: SMAPAndMethodNode, parent: SourceMapper): SourceMapper {
return NestedSourceMapper(parent, nodeAndSmap.sortedRanges, nodeAndSmap.classSMAP.sourceInfo)
}
internal fun reportIncrementalInfo(
sourceDescriptor: FunctionDescriptor,
targetDescriptor: FunctionDescriptor,
jvmSignature: JvmMethodSignature,
state: GenerationState
) {
val incrementalCache = state.incrementalCacheForThisTarget ?: return
val classFilePath = sourceDescriptor.getClassFilePath(state.typeMapper, incrementalCache)
val sourceFilePath = targetDescriptor.sourceFilePath
val method = jvmSignature.asmMethod
incrementalCache.registerInline(classFilePath, method.name + method.descriptor, sourceFilePath)
}
}
}
val BaseExpressionCodegen.v: InstructionAdapter
get() = visitor
class PsiInlineCodegen(
codegen: ExpressionCodegen,
state: GenerationState,
function: FunctionDescriptor,
typeParameterMappings: TypeParameterMappings,
sourceCompiler: SourceCompilerForInline
) : InlineCodegen<ExpressionCodegen>(codegen, state, function, typeParameterMappings, sourceCompiler), CallGenerator {
override fun genCallInner(
callableMethod: Callable,
resolvedCall: ResolvedCall<*>?,
callDefault: Boolean,
codegen: ExpressionCodegen
) {
performInline(resolvedCall, callDefault, codegen)
}
override fun processAndPutHiddenParameters(justProcess: Boolean) {
if (getMethodAsmFlags(functionDescriptor, sourceCompiler.contextKind, state) and Opcodes.ACC_STATIC == 0) {
invocationParamBuilder.addNextParameter(AsmTypes.OBJECT_TYPE, false)
}
for (param in jvmSignature.valueParameters) {
if (param.kind == JvmMethodParameterKind.VALUE) {
break
}
invocationParamBuilder.addNextParameter(param.asmType, false)
}
invocationParamBuilder.markValueParametersStart()
val hiddenParameters = invocationParamBuilder.buildParameters().parameters
delayedHiddenWriting = recordParameterValueInLocalVal(justProcess, false, *hiddenParameters.toTypedArray())
}
override fun putClosureParametersOnStack(next: LambdaInfo, functionReferenceReceiver: StackValue?) {
activeLambda = next
when (next) {
is ExpressionLambda -> codegen.pushClosureOnStack(next.classDescriptor, true, this, functionReferenceReceiver)
is DefaultLambda -> rememberCapturedForDefaultLambda(next)
else -> throw RuntimeException("Unknown lambda: $next")
}
activeLambda = null
}
private fun getBoundCallableReferenceReceiver(
argumentExpression: KtExpression
): KtExpression? {
val deparenthesized = KtPsiUtil.deparenthesize(argumentExpression)
if (deparenthesized is KtCallableReferenceExpression) {
val receiverExpression = deparenthesized.receiverExpression
if (receiverExpression != null) {
val lhs = state.bindingContext.get(BindingContext.DOUBLE_COLON_LHS, receiverExpression)
if (lhs is DoubleColonLHS.Expression) return receiverExpression
}
}
return null
}
/*lambda or callable reference*/
private fun isInliningParameter(expression: KtExpression, valueParameterDescriptor: ValueParameterDescriptor): Boolean {
//TODO deparenthisise typed
val deparenthesized = KtPsiUtil.deparenthesize(expression)
return InlineUtil.isInlineLambdaParameter(valueParameterDescriptor) && isInlinableParameterExpression(deparenthesized)
}
override fun genValueAndPut(
valueParameterDescriptor: ValueParameterDescriptor,
argumentExpression: KtExpression,
parameterType: Type,
parameterIndex: Int
) {
if (isInliningParameter(argumentExpression, valueParameterDescriptor)) {
val lambdaInfo = rememberClosure(argumentExpression, parameterType, valueParameterDescriptor)
val receiver = getBoundCallableReferenceReceiver(argumentExpression)
if (receiver != null) {
val receiverValue = codegen.gen(receiver)
putClosureParametersOnStack(lambdaInfo, StackValue.coercion(receiverValue, receiverValue.type.boxReceiverForBoundReference()))
}
}
else {
val value = codegen.gen(argumentExpression)
putValueIfNeeded(parameterType, value, ValueKind.GENERAL, valueParameterDescriptor.index)
}
}
private fun rememberClosure(expression: KtExpression, type: Type, parameter: ValueParameterDescriptor): LambdaInfo {
val ktLambda = KtPsiUtil.deparenthesize(expression)
assert(isInlinableParameterExpression(ktLambda)) { "Couldn't find inline expression in ${expression.text}" }
return ExpressionLambda(
ktLambda!!, typeMapper, parameter.isCrossinline, getBoundCallableReferenceReceiver(expression) != null
).also { lambda ->
val closureInfo = invocationParamBuilder.addNextValueParameter(type, true, null, parameter.index)
closureInfo.lambda = lambda
expressionMap.put(closureInfo.index, lambda)
}
}
override fun putValueIfNeeded(parameterType: Type, value: StackValue, kind: ValueKind, parameterIndex: Int) {
if (processDefaultMaskOrMethodHandler(value, kind)) return
assert(maskValues.isEmpty()) { "Additional default call arguments should be last ones, but " + value }
putArgumentOrCapturedToLocalVal(parameterType, value, -1, parameterIndex, kind)
}
override fun putCapturedValueOnStack(stackValue: StackValue, valueType: Type, paramIndex: Int) {
putArgumentOrCapturedToLocalVal(stackValue.type, stackValue, paramIndex, paramIndex, ValueKind.CAPTURED)
}
override fun reorderArgumentsIfNeeded(actualArgsWithDeclIndex: List<ArgumentAndDeclIndex>, valueParameterTypes: List<Type>) = Unit
override fun putHiddenParamsIntoLocals() {
assert(delayedHiddenWriting != null) { "processAndPutHiddenParameters(true) should be called before putHiddenParamsIntoLocals" }
delayedHiddenWriting!!.invoke()
delayedHiddenWriting = null
}
}

View File

@@ -22,10 +22,9 @@ import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.MethodNode
@@ -33,8 +32,9 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
class InlineCodegenForDefaultBody(
function: FunctionDescriptor,
codegen: ExpressionCodegen,
val state: GenerationState
) : CallGenerator() {
val state: GenerationState,
private val sourceCompilerForInline: SourceCompilerForInline
) : CallGenerator {
private val sourceMapper: SourceMapper = codegen.parentCodegen.orCreateSourceMapper
@@ -45,12 +45,12 @@ class InlineCodegenForDefaultBody(
function.original
private val context = InlineCodegen.getContext(
functionDescriptor, state,
DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor)?.containingFile as? KtFile
)
init {
sourceCompilerForInline.initializeInlineFunctionContext(functionDescriptor)
}
private val jvmSignature = state.typeMapper.mapSignatureWithGeneric(functionDescriptor, context.contextKind)
private val jvmSignature: JvmMethodGenericSignature
private val methodStartLabel = Label()
@@ -58,6 +58,9 @@ class InlineCodegenForDefaultBody(
assert(InlineUtil.isInline(function)) {
"InlineCodegen can inline only inline functions and array constructors: " + function
}
sourceCompilerForInline.initializeInlineFunctionContext(functionDescriptor)
jvmSignature = state.typeMapper.mapSignatureWithGeneric(functionDescriptor, sourceCompilerForInline.contextKind)
InlineCodegen.reportIncrementalInfo(functionDescriptor, codegen.context.functionDescriptor.original, jvmSignature, state)
//InlineCodegenForDefaultBody created just after visitCode call
@@ -65,7 +68,7 @@ class InlineCodegenForDefaultBody(
}
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
val nodeAndSmap = InlineCodegen.createMethodNode(functionDescriptor, jvmSignature, codegen, context, callDefault, null)
val nodeAndSmap = InlineCodegen.createInlineMethodNode(functionDescriptor, jvmSignature, codegen, callDefault, null, state, sourceCompilerForInline)
val childSourceMapper = InlineCodegen.createNestedSourceMapper(nodeAndSmap, sourceMapper)
val node = nodeAndSmap.node
@@ -84,7 +87,7 @@ class InlineCodegenForDefaultBody(
}
})
transformedMethod.accept(MethodBodyVisitor(codegen.v))
transformedMethod.accept(MethodBodyVisitor(codegen.visitor))
}
override fun genValueAndPut(valueParameterDescriptor: ValueParameterDescriptor, argumentExpression: KtExpression, parameterType: Type, parameterIndex: Int) {

View File

@@ -1,593 +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.inline;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.codegen.AsmUtil;
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
import org.jetbrains.kotlin.codegen.MemberCodegen;
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
import org.jetbrains.kotlin.codegen.context.CodegenContext;
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil;
import org.jetbrains.kotlin.codegen.context.InlineLambdaContext;
import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructorsKt;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.codegen.when.WhenByEnumsMapping;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.fileClasses.FileClasses;
import org.jetbrains.kotlin.fileClasses.JvmFileClassesProvider;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.KtFile;
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.util.OperatorNameConventions;
import org.jetbrains.org.objectweb.asm.*;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import org.jetbrains.org.objectweb.asm.tree.*;
import org.jetbrains.org.objectweb.asm.util.Printer;
import org.jetbrains.org.objectweb.asm.util.Textifier;
import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.List;
import java.util.ListIterator;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.ENUM_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_CLASS_TYPE;
public class InlineCodegenUtil {
public static final boolean GENERATE_SMAP = true;
public static final int API = Opcodes.ASM5;
private static final String CAPTURED_FIELD_PREFIX = "$";
private static final String NON_CAPTURED_FIELD_PREFIX = "$$";
public static final String THIS$0 = "this$0";
public static final String THIS = "this";
private static final String RECEIVER$0 = "receiver$0";
private static final String NON_LOCAL_RETURN = "$$$$$NON_LOCAL_RETURN$$$$$";
public static final String FIRST_FUN_LABEL = "$$$$$ROOT$$$$$";
public static final String NUMBERED_FUNCTION_PREFIX = "kotlin/jvm/functions/Function";
private static final String INLINE_MARKER_CLASS_NAME = "kotlin/jvm/internal/InlineMarker";
private static final String INLINE_MARKER_BEFORE_METHOD_NAME = "beforeInlineCall";
private static final String INLINE_MARKER_AFTER_METHOD_NAME = "afterInlineCall";
private static final String INLINE_MARKER_FINALLY_START = "finallyStart";
private static final String INLINE_MARKER_FINALLY_END = "finallyEnd";
public static final String SPECIAL_TRANSFORMATION_NAME = "$special";
public static final String INLINE_TRANSFORMATION_SUFFIX = "$inlined";
public static final String INLINE_CALL_TRANSFORMATION_SUFFIX = "$" + INLINE_TRANSFORMATION_SUFFIX;
public static final String INLINE_FUN_THIS_0_SUFFIX = "$inline_fun";
public static final String INLINE_FUN_VAR_SUFFIX = "$iv";
public static final String DEFAULT_LAMBDA_FAKE_CALL = "$$$DEFAULT_LAMBDA_FAKE_CALL$$$";
public static final String CAPTURED_FIELD_FOLD_PREFIX = "$$$";
@Nullable
public static SMAPAndMethodNode getMethodNode(
byte[] classData,
@NotNull String methodName,
@NotNull String methodDescriptor,
@NotNull String classInternalName
) {
ClassReader cr = new ClassReader(classData);
MethodNode[] node = new MethodNode[1];
String[] debugInfo = new String[2];
int[] lines = new int[2];
lines[0] = Integer.MAX_VALUE;
lines[1] = Integer.MIN_VALUE;
//noinspection PointlessBitwiseExpression
cr.accept(new ClassVisitor(API) {
@Override
public void visitSource(String source, String debug) {
super.visitSource(source, debug);
debugInfo[0] = source;
debugInfo[1] = debug;
}
@Override
public MethodVisitor visitMethod(
int access,
@NotNull String name,
@NotNull String desc,
String signature,
String[] exceptions
) {
if (methodName.equals(name) && methodDescriptor.equals(desc)) {
node[0] = new MethodNode(API, access, name, desc, signature, exceptions) {
@Override
public void visitLineNumber(int line, @NotNull Label start) {
super.visitLineNumber(line, start);
lines[0] = Math.min(lines[0], line);
lines[1] = Math.max(lines[1], line);
}
};
return node[0];
}
return null;
}
}, ClassReader.SKIP_FRAMES | (GENERATE_SMAP ? 0 : ClassReader.SKIP_DEBUG));
if (node[0] == null) {
return null;
}
if (IntrinsicArrayConstructorsKt.getClassId().asString().equals(classInternalName)) {
// Don't load source map for intrinsic array constructors
debugInfo[0] = null;
}
SMAP smap = SMAPParser.parseOrCreateDefault(debugInfo[1], debugInfo[0], classInternalName, lines[0], lines[1]);
return new SMAPAndMethodNode(node[0], smap);
}
public static void initDefaultSourceMappingIfNeeded(
@NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state
) {
if (state.isInlineDisabled()) return;
CodegenContext<?> parentContext = context.getParentContext();
while (parentContext != null) {
if (parentContext.isInlineMethodContext()) {
//just init default one to one mapping
codegen.getOrCreateSourceMapper();
break;
}
parentContext = parentContext.getParentContext();
}
}
@Nullable
public static VirtualFile findVirtualFile(@NotNull GenerationState state, @NotNull ClassId classId) {
return VirtualFileFinder.SERVICE.getInstance(state.getProject()).findVirtualFileWithHeader(classId);
}
@Nullable
public static VirtualFile findVirtualFileImprecise(@NotNull GenerationState state, @NotNull String internalClassName) {
FqName packageFqName = JvmClassName.byInternalName(internalClassName).getPackageFqName();
String classNameWithDollars = StringsKt.substringAfterLast(internalClassName, "/", internalClassName);
//TODO: we cannot construct proper classId at this point, we need to read InnerClasses info from class file
// we construct valid.package.name/RelativeClassNameAsSingleName that should work in compiler, but fails for inner classes in IDE
return findVirtualFile(state, new ClassId(packageFqName, Name.identifier(classNameWithDollars)));
}
@NotNull
public static String getInlineName(
@NotNull CodegenContext codegenContext,
@NotNull KotlinTypeMapper typeMapper,
@NotNull JvmFileClassesProvider fileClassesManager
) {
return getInlineName(codegenContext, codegenContext.getContextDescriptor(), typeMapper, fileClassesManager);
}
@NotNull
private static String getInlineName(
@NotNull CodegenContext codegenContext,
@NotNull DeclarationDescriptor currentDescriptor,
@NotNull KotlinTypeMapper typeMapper,
@NotNull JvmFileClassesProvider fileClassesProvider
) {
if (currentDescriptor instanceof PackageFragmentDescriptor) {
PsiFile file = DescriptorToSourceUtils.getContainingFile(codegenContext.getContextDescriptor());
Type implementationOwnerType;
if (file == null) {
implementationOwnerType = CodegenContextUtil.getImplementationOwnerClassType(codegenContext);
}
else {
implementationOwnerType = FileClasses.getFileClassType(fileClassesProvider, (KtFile) file);
}
if (implementationOwnerType == null) {
DeclarationDescriptor contextDescriptor = codegenContext.getContextDescriptor();
//noinspection ConstantConditions
throw new RuntimeException(
"Couldn't find declaration for " +
contextDescriptor.getContainingDeclaration().getName() + "." + contextDescriptor.getName() +
"; context: " + codegenContext
);
}
return implementationOwnerType.getInternalName();
}
else if (currentDescriptor instanceof ClassifierDescriptor) {
Type type = typeMapper.mapType((ClassifierDescriptor) currentDescriptor);
return type.getInternalName();
}
else if (currentDescriptor instanceof FunctionDescriptor) {
ClassDescriptor descriptor =
typeMapper.getBindingContext().get(CodegenBinding.CLASS_FOR_CALLABLE, (FunctionDescriptor) currentDescriptor);
if (descriptor != null) {
return typeMapper.mapType(descriptor).getInternalName();
}
}
//TODO: add suffix for special case
String suffix = currentDescriptor.getName().isSpecial() ? "" : currentDescriptor.getName().asString();
//noinspection ConstantConditions
return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper, fileClassesProvider) + "$" + suffix;
}
public static boolean isInvokeOnLambda(@NotNull String owner, @NotNull String name) {
return OperatorNameConventions.INVOKE.asString().equals(name) &&
owner.startsWith(NUMBERED_FUNCTION_PREFIX) &&
isInteger(owner.substring(NUMBERED_FUNCTION_PREFIX.length()));
}
public static boolean isAnonymousConstructorCall(@NotNull String internalName, @NotNull String methodName) {
return "<init>".equals(methodName) && isAnonymousClass(internalName);
}
public static boolean isWhenMappingAccess(@NotNull String internalName, @NotNull String fieldName) {
return fieldName.startsWith(WhenByEnumsMapping.MAPPING_ARRAY_FIELD_PREFIX) &&
internalName.endsWith(WhenByEnumsMapping.MAPPINGS_CLASS_NAME_POSTFIX);
}
public static boolean isAnonymousSingletonLoad(@NotNull String internalName, @NotNull String fieldName) {
return JvmAbi.INSTANCE_FIELD.equals(fieldName) && isAnonymousClass(internalName);
}
public static boolean isAnonymousClass(@NotNull String internalName) {
String shortName = getLastNamePart(internalName);
int index = shortName.lastIndexOf("$");
if (index < 0) {
return false;
}
String suffix = shortName.substring(index + 1);
return isInteger(suffix);
}
@NotNull
private static String getLastNamePart(@NotNull String internalName) {
int index = internalName.lastIndexOf("/");
return index < 0 ? internalName : internalName.substring(index + 1);
}
@NotNull
public static MethodVisitor wrapWithMaxLocalCalc(@NotNull MethodNode methodNode) {
return new MaxStackFrameSizeAndLocalsCalculator(API, methodNode.access, methodNode.desc, methodNode);
}
private static boolean isInteger(@NotNull String string) {
if (string.isEmpty()) {
return false;
}
for (int i = 0; i < string.length(); i++) {
if (!Character.isDigit(string.charAt(i))) {
return false;
}
}
return true;
}
public static boolean isCapturedFieldName(@NotNull String fieldName) {
// TODO: improve this heuristic
return fieldName.startsWith(CAPTURED_FIELD_PREFIX) &&
!fieldName.startsWith(NON_CAPTURED_FIELD_PREFIX) ||
THIS$0.equals(fieldName) ||
RECEIVER$0.equals(fieldName);
}
public static boolean isReturnOpcode(int opcode) {
return opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN;
}
//marked return could be either non-local or local in case of labeled lambda self-returns
public static boolean isMarkedReturn(@NotNull AbstractInsnNode returnIns) {
return getMarkedReturnLabelOrNull(returnIns) != null;
}
@Nullable
public static String getMarkedReturnLabelOrNull(@NotNull AbstractInsnNode returnInsn) {
if (!isReturnOpcode(returnInsn.getOpcode())) {
return null;
}
AbstractInsnNode previous = returnInsn.getPrevious();
if (previous instanceof MethodInsnNode) {
MethodInsnNode marker = (MethodInsnNode) previous;
if (NON_LOCAL_RETURN.equals(marker.owner)) {
return marker.name;
}
}
return null;
}
public static void generateGlobalReturnFlag(@NotNull InstructionAdapter iv, @NotNull String labelName) {
iv.invokestatic(NON_LOCAL_RETURN, labelName, "()V", false);
}
@NotNull
public static Type getReturnType(int opcode) {
switch (opcode) {
case Opcodes.RETURN:
return Type.VOID_TYPE;
case Opcodes.IRETURN:
return Type.INT_TYPE;
case Opcodes.DRETURN:
return Type.DOUBLE_TYPE;
case Opcodes.FRETURN:
return Type.FLOAT_TYPE;
case Opcodes.LRETURN:
return Type.LONG_TYPE;
default:
return AsmTypes.OBJECT_TYPE;
}
}
public static void insertNodeBefore(@NotNull MethodNode from, @NotNull MethodNode to, @NotNull AbstractInsnNode beforeNode) {
ListIterator<AbstractInsnNode> iterator = from.instructions.iterator();
while (iterator.hasNext()) {
AbstractInsnNode next = iterator.next();
to.instructions.insertBefore(beforeNode, next);
}
}
@NotNull
public static MethodNode createEmptyMethodNode() {
return new MethodNode(API, 0, "fake", "()V", null, null);
}
@NotNull
public static LabelNode firstLabelInChain(@NotNull LabelNode node) {
LabelNode curNode = node;
while (curNode.getPrevious() instanceof LabelNode) {
curNode = (LabelNode) curNode.getPrevious();
}
return curNode;
}
@NotNull
public static String getNodeText(@Nullable MethodNode node) {
Textifier textifier = new Textifier();
if (node == null) {
return "Not generated";
}
node.accept(new TraceMethodVisitor(textifier));
StringWriter sw = new StringWriter();
textifier.print(new PrintWriter(sw));
sw.flush();
return node.name + " " + node.desc + ":\n" + sw.getBuffer().toString();
}
@NotNull
public static String getInsnText(@Nullable AbstractInsnNode node) {
if (node == null) return "<null>";
Textifier textifier = new Textifier();
node.accept(new TraceMethodVisitor(textifier));
StringWriter sw = new StringWriter();
textifier.print(new PrintWriter(sw));
sw.flush();
return sw.toString().trim();
}
@NotNull
public static String getInsnOpcodeText(@Nullable AbstractInsnNode node) {
return node == null ? "null" : Printer.OPCODES[node.getOpcode()];
}
@NotNull
/* package */ static ClassReader buildClassReaderByInternalName(@NotNull GenerationState state, @NotNull String internalName) {
//try to find just compiled classes then in dependencies
try {
OutputFile outputFile = state.getFactory().get(internalName + ".class");
if (outputFile != null) {
return new ClassReader(outputFile.asByteArray());
}
VirtualFile file = findVirtualFileImprecise(state, internalName);
if (file != null) {
return new ClassReader(file.contentsToByteArray());
}
throw new RuntimeException("Couldn't find virtual file for " + internalName);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void generateFinallyMarker(@NotNull InstructionAdapter v, int depth, boolean start) {
v.iconst(depth);
v.invokestatic(INLINE_MARKER_CLASS_NAME, start ? INLINE_MARKER_FINALLY_START : INLINE_MARKER_FINALLY_END, "(I)V", false);
}
public static boolean isFinallyEnd(@NotNull AbstractInsnNode node) {
return isFinallyMarker(node, INLINE_MARKER_FINALLY_END);
}
public static boolean isFinallyStart(@NotNull AbstractInsnNode node) {
return isFinallyMarker(node, INLINE_MARKER_FINALLY_START);
}
public static boolean isFinallyMarker(@Nullable AbstractInsnNode node) {
return node != null && (isFinallyStart(node) || isFinallyEnd(node));
}
private static boolean isFinallyMarker(@NotNull AbstractInsnNode node, String name) {
if (!(node instanceof MethodInsnNode)) return false;
MethodInsnNode method = (MethodInsnNode) node;
return INLINE_MARKER_CLASS_NAME.equals(method.owner) && name.equals(method.name);
}
public static boolean isFinallyMarkerRequired(@NotNull MethodContext context) {
return context.isInlineMethodContext() || context instanceof InlineLambdaContext;
}
public static int getConstant(@NotNull AbstractInsnNode ins) {
int opcode = ins.getOpcode();
if (opcode >= Opcodes.ICONST_0 && opcode <= Opcodes.ICONST_5) {
return opcode - Opcodes.ICONST_0;
}
else if (opcode == Opcodes.BIPUSH || opcode == Opcodes.SIPUSH) {
return ((IntInsnNode) ins).operand;
}
else {
LdcInsnNode index = (LdcInsnNode) ins;
return (Integer) index.cst;
}
}
public static void removeFinallyMarkers(@NotNull MethodNode intoNode) {
InsnList instructions = intoNode.instructions;
AbstractInsnNode curInstr = instructions.getFirst();
while (curInstr != null) {
if (isFinallyMarker(curInstr)) {
AbstractInsnNode marker = curInstr;
//just to assert
getConstant(marker.getPrevious());
curInstr = curInstr.getNext();
instructions.remove(marker.getPrevious());
instructions.remove(marker);
continue;
}
curInstr = curInstr.getNext();
}
}
public static void addInlineMarker(@NotNull InstructionAdapter v, boolean isStartNotEnd) {
v.visitMethodInsn(
Opcodes.INVOKESTATIC, INLINE_MARKER_CLASS_NAME,
isStartNotEnd ? INLINE_MARKER_BEFORE_METHOD_NAME : INLINE_MARKER_AFTER_METHOD_NAME,
"()V", false
);
}
public static boolean isInlineMarker(@NotNull AbstractInsnNode insn) {
return isInlineMarker(insn, null);
}
private static boolean isInlineMarker(@NotNull AbstractInsnNode insn, @Nullable String name) {
if (!(insn instanceof MethodInsnNode)) {
return false;
}
MethodInsnNode methodInsnNode = (MethodInsnNode) insn;
return insn.getOpcode() == Opcodes.INVOKESTATIC &&
methodInsnNode.owner.equals(INLINE_MARKER_CLASS_NAME) &&
(name != null ? methodInsnNode.name.equals(name)
: methodInsnNode.name.equals(INLINE_MARKER_BEFORE_METHOD_NAME) ||
methodInsnNode.name.equals(INLINE_MARKER_AFTER_METHOD_NAME));
}
public static boolean isBeforeInlineMarker(@NotNull AbstractInsnNode insn) {
return isInlineMarker(insn, INLINE_MARKER_BEFORE_METHOD_NAME);
}
public static boolean isAfterInlineMarker(@NotNull AbstractInsnNode insn) {
return isInlineMarker(insn, INLINE_MARKER_AFTER_METHOD_NAME);
}
public static int getLoadStoreArgSize(int opcode) {
return opcode == Opcodes.DSTORE || opcode == Opcodes.LSTORE || opcode == Opcodes.DLOAD || opcode == Opcodes.LLOAD ? 2 : 1;
}
public static boolean isStoreInstruction(int opcode) {
return opcode >= Opcodes.ISTORE && opcode <= Opcodes.ASTORE;
}
public static int calcMarkerShift(@NotNull Parameters parameters, @NotNull MethodNode node) {
int markerShiftTemp = getIndexAfterLastMarker(node);
return markerShiftTemp - parameters.getRealParametersSizeOnStack() + parameters.getArgsSizeOnStack();
}
private static int getIndexAfterLastMarker(@NotNull MethodNode node) {
int result = -1;
for (LocalVariableNode variable : node.localVariables) {
if (isFakeLocalVariableForInline(variable.name)) {
result = Math.max(result, variable.index + 1);
}
}
return result;
}
public static boolean isFakeLocalVariableForInline(@NotNull String name) {
return name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_FUNCTION) ||
name.startsWith(JvmAbi.LOCAL_VARIABLE_NAME_PREFIX_INLINE_ARGUMENT);
}
public static boolean isThis0(@NotNull String name) {
return THIS$0.equals(name);
}
public static boolean isSpecialEnumMethod(@NotNull FunctionDescriptor functionDescriptor) {
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
if (!(containingDeclaration instanceof PackageFragmentDescriptor)) {
return false;
}
if (!((PackageFragmentDescriptor) containingDeclaration).getFqName().equals(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME)) {
return false;
}
if (functionDescriptor.getTypeParameters().size() != 1) {
return false;
}
String name = functionDescriptor.getName().asString();
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters();
return "enumValues".equals(name) && parameters.size() == 0 ||
"enumValueOf".equals(name) && parameters.size() == 1 && KotlinBuiltIns.isString(parameters.get(0).getType());
}
public static MethodNode createSpecialEnumMethodBody(
@NotNull ExpressionCodegen codegen,
@NotNull String name,
@NotNull KotlinType type,
@NotNull KotlinTypeMapper typeMapper
) {
boolean isValueOf = "enumValueOf".equals(name);
Type invokeType = typeMapper.mapType(type);
String desc = getSpecialEnumFunDescriptor(invokeType, isValueOf);
MethodNode node = new MethodNode(API, Opcodes.ACC_STATIC, "fake", desc, null, null);
codegen.putReifiedOperationMarkerIfTypeIsReifiedParameter(type, ReifiedTypeInliner.OperationKind.ENUM_REIFIED, new InstructionAdapter(node));
if (isValueOf) {
node.visitInsn(Opcodes.ACONST_NULL);
node.visitVarInsn(Opcodes.ALOAD, 0);
node.visitMethodInsn(Opcodes.INVOKESTATIC, ENUM_TYPE.getInternalName(), "valueOf",
Type.getMethodDescriptor(ENUM_TYPE, JAVA_CLASS_TYPE, AsmTypes.JAVA_STRING_TYPE), false);
}
else {
node.visitInsn(Opcodes.ICONST_0);
node.visitTypeInsn(Opcodes.ANEWARRAY, ENUM_TYPE.getInternalName());
}
node.visitInsn(Opcodes.ARETURN);
node.visitMaxs(isValueOf ? 3 : 2, isValueOf ? 1 : 0);
return node;
}
@NotNull
public static String getSpecialEnumFunDescriptor(@NotNull Type type, boolean isValueOf) {
return isValueOf ? Type.getMethodDescriptor(type, AsmTypes.JAVA_STRING_TYPE) : Type.getMethodDescriptor(AsmUtil.getArrayType(type));
}
}

View File

@@ -23,7 +23,7 @@ class RootInliningContext(
expressionMap: Map<Int, LambdaInfo>,
state: GenerationState,
nameGenerator: NameGenerator,
val callElement: KtElement,
val sourceCompilerForInline: SourceCompilerForInline,
override val callSiteInfo: InlineCallSiteInfo,
val inlineMethodReifier: ReifiedTypeInliner,
typeParameterMappings: TypeParameterMappings

View File

@@ -22,7 +22,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.codegen.optimization.common.UtilKt;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
@@ -34,7 +33,7 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.*;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.*;
import static org.jetbrains.kotlin.codegen.inline.MethodInlinerUtilKt.getNextMeaningful;
public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
@@ -106,7 +105,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
private int initAndGetVarIndexForNonLocalReturnValue() {
MaxLocalsCalculator tempCalcNode = new MaxLocalsCalculator(
InlineCodegenUtil.API,
API,
inlineFun.access, inlineFun.desc, null
);
inlineFun.accept(tempCalcNode);
@@ -126,8 +125,8 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
processInstruction(curIns, false);
//At this point only global return is possible, local one already substituted with: goto endLabel
if (!InlineCodegenUtil.isReturnOpcode(curIns.getOpcode()) ||
!InlineCodegenUtil.isMarkedReturn(curIns)) {
if (!isReturnOpcode(curIns.getOpcode()) ||
!isMarkedReturn(curIns)) {
curIns = curIns.getPrevious();
continue;
}
@@ -147,7 +146,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
AbstractInsnNode nextPrev = instrInsertFinallyBefore.getPrevious();
assert markedReturn.getNext() instanceof LabelNode : "Label should be occurred after non-local return";
LabelNode newFinallyEnd = (LabelNode) markedReturn.getNext();
Type nonLocalReturnType = InlineCodegenUtil.getReturnType(markedReturn.getOpcode());
Type nonLocalReturnType = getReturnType(markedReturn.getOpcode());
//Generally there could be several tryCatch blocks (group) on one code interval (same start and end labels, but maybe different handlers) -
// all of them refer to one try/*catches*/finally or try/catches.
@@ -216,7 +215,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
finallyBlockCopy.visitLabel(insertedBlockEnd);
//Copying finally body before non-local return instruction
InlineCodegenUtil.insertNodeBefore(finallyBlockCopy, inlineFun, instrInsertFinallyBefore);
insertNodeBefore(finallyBlockCopy, inlineFun, instrInsertFinallyBefore);
updateExceptionTable(clusterBlocks, newFinallyStart, newFinallyEnd,
tryCatchBlockInlinedInFinally, labelsInsideFinally, (LabelNode) insertedBlockEnd.info);
@@ -251,7 +250,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
int depthShift
) {
if (isInsOrJumpInsideFinally) {
if (InlineCodegenUtil.isFinallyMarker(currentIns.getNext())) {
if (isFinallyMarker(currentIns.getNext())) {
Integer constant = getConstant(currentIns);
finallyBlockCopy.visitLdcInsn(constant + depthShift);
} else {
@@ -455,7 +454,7 @@ public class InternalFinallyBlockInliner extends CoveringTryCatchNodeProcessor {
AbstractInsnNode current = meaningful.getNext();
while (endFinallyChainExclusive != current) {
current = current.getNext();
if (InlineCodegenUtil.isFinallyEnd(current)) {
if (isFinallyEnd(current)) {
Integer currentDepth = getConstant(current.getPrevious());
if (currentDepth.equals(finallyDepth)) {
endFinallyChainExclusive = current.getNext();

View File

@@ -55,7 +55,7 @@ abstract class LambdaInfo(@JvmField val isCrossInline: Boolean) : LabelOwner {
lateinit var node: SMAPAndMethodNode
abstract fun generateLambdaBody(codegen: ExpressionCodegen, reifiedTypeInliner: ReifiedTypeInliner)
abstract fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner)
fun addAllParameters(remapper: FieldRemapper): Parameters {
val builder = ParametersBuilder.initializeBuilderFrom(AsmTypes.OBJECT_TYPE, invokeMethod.descriptor, this)
@@ -105,11 +105,14 @@ class DefaultLambda(
override fun isMyLabel(name: String): Boolean = false
override fun generateLambdaBody(codegen: ExpressionCodegen, reifiedTypeInliner: ReifiedTypeInliner) {
val classReader = InlineCodegenUtil.buildClassReaderByInternalName(codegen.state, lambdaClassType.internalName)
var originalBoundReceiverType: Type? = null
private set
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
val classReader = buildClassReaderByInternalName(sourceCompiler.state, lambdaClassType.internalName)
var isPropertyReference = false
var isFunctionReference = false
classReader.accept(object: ClassVisitor(InlineCodegenUtil.API){
classReader.accept(object: ClassVisitor(API){
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array<out String>?) {
isPropertyReference = superName?.startsWith("kotlin/jvm/internal/PropertyReference") ?: false
isFunctionReference = "kotlin/jvm/internal/FunctionReference" == superName
@@ -128,7 +131,7 @@ class DefaultLambda(
}
val descriptor = Type.getMethodDescriptor(Type.VOID_TYPE, *capturedArgs)
val constructor = InlineCodegenUtil.getMethodNode(
val constructor = getMethodNode(
classReader.b,
"<init>",
descriptor,
@@ -141,7 +144,8 @@ class DefaultLambda(
capturedVars =
if (isFunctionReference || isPropertyReference)
constructor?.desc?.let { Type.getArgumentTypes(it) }?.singleOrNull()?.let {
listOf(capturedParamDesc(AsmUtil.RECEIVER_NAME, it))
originalBoundReceiverType = it
listOf(capturedParamDesc(AsmUtil.RECEIVER_NAME, it.boxReceiverForBoundReference()))
} ?: emptyList()
else
constructor?.findCapturedFieldAssignmentInstructions()?.map {
@@ -153,10 +157,10 @@ class DefaultLambda(
invokeMethod = Method(
(if (isPropertyReference) OperatorNameConventions.GET else OperatorNameConventions.INVOKE).asString(),
codegen.state.typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor).asmMethod.descriptor
sourceCompiler.state.typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor).asmMethod.descriptor
)
node = InlineCodegenUtil.getMethodNode(
node = getMethodNode(
classReader.b,
invokeMethod.name,
invokeMethod.descriptor,
@@ -169,6 +173,9 @@ class DefaultLambda(
}
}
fun Type.boxReceiverForBoundReference() = AsmUtil.boxType(this)
class ExpressionLambda(
expression: KtExpression,
private val typeMapper: KotlinTypeMapper,
@@ -237,7 +244,9 @@ class ExpressionLambda(
}
if (closure.captureReceiverType != null) {
val type = typeMapper.mapType(closure.captureReceiverType!!)
val type = typeMapper.mapType(closure.captureReceiverType!!).let {
if (isBoundCallableReference) it.boxReceiverForBoundReference() else it
}
val descriptor = EnclosedValueDescriptor(
AsmUtil.CAPTURED_RECEIVER_FIELD, null,
StackValue.field(type, lambdaClassType, AsmUtil.CAPTURED_RECEIVER_FIELD, false, StackValue.LOCAL_0),
@@ -260,24 +269,17 @@ class ExpressionLambda(
val isPropertyReference: Boolean
get() = propertyReferenceInfo != null
override fun generateLambdaBody(codegen: ExpressionCodegen, reifiedTypeInliner: ReifiedTypeInliner) {
val closureContext =
if (isPropertyReference)
codegen.getContext().intoAnonymousClass(classDescriptor, codegen, OwnerKind.IMPLEMENTATION)
else
codegen.getContext().intoClosure(invokeMethodDescriptor, codegen, typeMapper)
val context = closureContext.intoInlinedLambda(invokeMethodDescriptor, isCrossInline, isPropertyReference)
override fun generateLambdaBody(sourceCompiler: SourceCompilerForInline, reifiedTypeInliner: ReifiedTypeInliner) {
val jvmMethodSignature = typeMapper.mapSignatureSkipGeneric(invokeMethodDescriptor)
val asmMethod = jvmMethodSignature.asmMethod
val methodNode = MethodNode(
InlineCodegenUtil.API, AsmUtil.getMethodAsmFlags(invokeMethodDescriptor, context.contextKind, codegen.state),
API, AsmUtil.getMethodAsmFlags(invokeMethodDescriptor, OwnerKind.IMPLEMENTATION, sourceCompiler.state),
asmMethod.name, asmMethod.descriptor, null, null
)
node = InlineCodegenUtil.wrapWithMaxLocalCalc(methodNode).let { adapter ->
val smap = InlineCodegen.generateMethodBody(
adapter, invokeMethodDescriptor, context, functionWithBodyOrCallableReference, jvmMethodSignature, codegen, this
node = wrapWithMaxLocalCalc(methodNode).let { adapter ->
val smap = sourceCompiler.generateLambdaBody(
adapter, jvmMethodSignature, this
)
adapter.visitMaxs(-1, -1)
SMAPAndMethodNode(methodNode, smap)

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.codegen.inline
import jdk.internal.org.objectweb.asm.Opcodes
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.load.kotlin.getContainingKotlinJvmBinaryClass
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
// KLUDGE: Inline suspend function built with compiler version less than 1.1.4/1.2-M1 did not contain proper
// before/after suspension point marks, so we detect those functions here and insert the corresponding marks
fun insertLegacySuspendInlineMarks(node: MethodNode) {
with (node.instructions) {
// look for return instruction before the end and insert "afterSuspendMarker" there
insertBefore(findLastReturn(last) ?: return, produceSuspendMarker(false).instructions)
// insert "beforeSuspendMarker" at the beginning
insertBefore(first, produceSuspendMarker(true).instructions)
}
node.maxStack = node.maxStack.coerceAtLeast(2) // min stack need for suspend marker before return
}
fun findLastReturn(node: AbstractInsnNode?): AbstractInsnNode? {
var cur = node
while (cur != null && cur.opcode != Opcodes.ARETURN) cur = cur.previous
return cur
}
private fun produceSuspendMarker(isStartNotEnd: Boolean): MethodNode =
MethodNode().also { addSuspendMarker(InstructionAdapter(it), isStartNotEnd) }
fun isLegacySuspendInlineFunction(descriptor: CallableMemberDescriptor): Boolean {
if (descriptor !is FunctionDescriptor) return false
if (!descriptor.isSuspend || !descriptor.isInline) return false
val jvmBytecodeVersion = descriptor.getContainingKotlinJvmBinaryClass()?.classHeader?.bytecodeVersion ?: return false
return !jvmBytecodeVersion.isAtLeast(1, 0, 2)
}

View File

@@ -103,7 +103,7 @@ class LocalVarRemapper(private val params: Parameters, private val additionalShi
val remapInfo = remap(`var`)
val value = remapInfo.value
if (value is StackValue.Local) {
val isStore = InlineCodegenUtil.isStoreInstruction(opcode)
val isStore = isStoreInstruction(opcode)
if (remapInfo.parameterInfo != null) {
//All remapped value parameters can't be rewritten except case of default ones.
//On remapping default parameter to actual value there is only one instruction that writes to it according to mask value

View File

@@ -23,10 +23,12 @@ import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.TypePath;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.API;
public class MethodBodyVisitor extends InstructionAdapter {
public MethodBodyVisitor(MethodVisitor mv) {
super(InlineCodegenUtil.API, mv);
super(API, mv);
}
@Override

View File

@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.ClosureCodegen
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.*
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.optimization.FixStackWithLabelNormalizationMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
@@ -87,7 +87,7 @@ class MethodInliner(
transformedNode.instructions.resetLabels()
val resultNode = MethodNode(
InlineCodegenUtil.API, transformedNode.access, transformedNode.name, transformedNode.desc,
API, transformedNode.access, transformedNode.name, transformedNode.desc,
transformedNode.signature, transformedNode.exceptions?.toTypedArray()
)
val visitor = RemapVisitor(resultNode, remapper, nodeRemapper)
@@ -130,7 +130,7 @@ class MethodInliner(
AsmTypeRemapper(remapper, result)
)
val markerShift = InlineCodegenUtil.calcMarkerShift(parameters, node)
val markerShift = calcMarkerShift(parameters, node)
val lambdaInliner = object : InlineAdapter(remappingMethodAdapter, parameters.argsSizeOnStack, sourceMapper) {
private var transformationInfo: TransformationInfo? = null
@@ -312,11 +312,11 @@ class MethodInliner(
val realParametersSize = parameters.realParametersSizeOnStack
val transformedNode = object : MethodNode(
InlineCodegenUtil.API, node.access, node.name,
API, node.access, node.name,
Type.getMethodDescriptor(Type.getReturnType(node.desc), *(Type.getArgumentTypes(node.desc) + parameters.capturedTypes)),
node.signature, node.exceptions?.toTypedArray()
) {
private val GENERATE_DEBUG_INFO = InlineCodegenUtil.GENERATE_SMAP && inlineOnlySmapSkipper == null
private val GENERATE_DEBUG_INFO = GENERATE_SMAP && inlineOnlySmapSkipper == null
private val isInliningLambda = nodeRemapper.isInsideInliningLambda
@@ -343,11 +343,15 @@ class MethodInliner(
}
override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) {
if (InlineCodegenUtil.DEFAULT_LAMBDA_FAKE_CALL == owner) {
val index = name.substringAfter(InlineCodegenUtil.DEFAULT_LAMBDA_FAKE_CALL).toInt()
if (DEFAULT_LAMBDA_FAKE_CALL == owner) {
val index = name.substringAfter(DEFAULT_LAMBDA_FAKE_CALL).toInt()
val lambda = getLambdaIfExists(index) as DefaultLambda
lambda.parameterOffsetsInDefault.zip(lambda.capturedVars).asReversed().forEach {
(_, captured) ->
val originalBoundReceiverType = lambda.originalBoundReceiverType
if (lambda.isBoundCallableReference && AsmUtil.isPrimitive(originalBoundReceiverType)) {
StackValue.onStack(originalBoundReceiverType!!).put(captured.type, InstructionAdapter(this))
}
super.visitFieldInsn(
Opcodes.PUTSTATIC, captured.containingLambdaName, CAPTURED_FIELD_FOLD_PREFIX + captured.fieldName, captured.type.descriptor
)
@@ -362,7 +366,7 @@ class MethodInliner(
name: String, desc: String, signature: String?, start: Label, end: Label, index: Int
) {
if (isInliningLambda || GENERATE_DEBUG_INFO) {
val varSuffix = if (inliningContext.isRoot && !InlineCodegenUtil.isFakeLocalVariableForInline(name)) INLINE_FUN_VAR_SUFFIX else ""
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))
}
@@ -400,9 +404,9 @@ class MethodInliner(
awaitClassReification = true
}
else if (cur is MethodInsnNode) {
if (InlineCodegenUtil.isFinallyStart(cur)) {
if (isFinallyStart(cur)) {
//TODO deep index calc could be more precise
currentFinallyDeep = InlineCodegenUtil.getConstant(cur.previous)
currentFinallyDeep = getConstant(cur.previous)
}
val owner = cur.owner
@@ -615,11 +619,11 @@ class MethodInliner(
}
private fun wrapException(originalException: Throwable, node: MethodNode, errorSuffix: String): RuntimeException {
if (originalException is InlineException) {
return InlineException("$errorPrefix: $errorSuffix", originalException)
return if (originalException is InlineException) {
InlineException("$errorPrefix: $errorSuffix", originalException)
}
else {
return InlineException("$errorPrefix: $errorSuffix\nCause: ${getNodeText(node)}", originalException)
InlineException("$errorPrefix: $errorSuffix\nCause: ${node.nodeText}", originalException)
}
}
@@ -668,18 +672,18 @@ class MethodInliner(
insertBeforeInsn: AbstractInsnNode,
sourceValueFrame: Frame<SourceValue>
) {
assert(InlineCodegenUtil.isReturnOpcode(returnInsn.opcode)) { "return instruction expected" }
assert(isReturnOpcode(returnInsn.opcode)) { "return instruction expected" }
assert(returnOpcode < 0 || returnOpcode == returnInsn.opcode) { "Return op should be " + Printer.OPCODES[returnOpcode] + ", got " + Printer.OPCODES[returnInsn.opcode] }
returnOpcode = returnInsn.opcode
localReturns.add(LocalReturn(returnInsn, insertBeforeInsn, sourceValueFrame))
if (returnInsn.opcode != Opcodes.RETURN) {
if (returnInsn.opcode == Opcodes.LRETURN || returnInsn.opcode == Opcodes.DRETURN) {
returnVariableSize = 2
returnVariableSize = if (returnInsn.opcode == Opcodes.LRETURN || returnInsn.opcode == Opcodes.DRETURN) {
2
}
else {
returnVariableSize = 1
1
}
}
}
@@ -712,10 +716,9 @@ class MethodInliner(
"Captured field template should start with $CAPTURED_FIELD_FOLD_PREFIX prefix"
}
val fin = FieldInsnNode(node.opcode, node.owner, node.name.substring(3), node.desc)
val field = fieldRemapper.findField(fin) ?: throw IllegalStateException(
return fieldRemapper.findField(fin) ?: throw IllegalStateException(
"Couldn't find captured field ${node.owner}.${node.name} in ${fieldRemapper.originalLambdaInternalName}"
)
return field
}
private fun analyzeMethodNodeWithoutMandatoryTransformations(node: MethodNode): Array<Frame<SourceValue>?> {
@@ -771,9 +774,9 @@ class MethodInliner(
var cur: AbstractInsnNode? = node.instructions.first
while (cur != null) {
if (cur is MethodInsnNode && InlineCodegenUtil.isFinallyMarker(cur)) {
if (cur is MethodInsnNode && isFinallyMarker(cur)) {
val constant = cur.previous
val curDeep = InlineCodegenUtil.getConstant(constant)
val curDeep = getConstant(constant)
node.instructions.insert(constant, LdcInsnNode(curDeep + finallyDeepShift))
node.instructions.remove(constant)
}
@@ -829,9 +832,9 @@ class MethodInliner(
val instructions = node.instructions
var insnNode: AbstractInsnNode? = instructions.first
while (insnNode != null) {
if (InlineCodegenUtil.isReturnOpcode(insnNode.opcode)) {
if (isReturnOpcode(insnNode.opcode)) {
var isLocalReturn = true
val labelName = InlineCodegenUtil.getMarkedReturnLabelOrNull(insnNode)
val labelName = getMarkedReturnLabelOrNull(insnNode)
if (labelName != null) {
isLocalReturn = labelOwner.isMyLabel(labelName)
@@ -842,9 +845,13 @@ class MethodInliner(
}
if (isLocalReturn && endLabel != null) {
val nop = InsnNode(Opcodes.NOP)
instructions.insert(insnNode, nop)
val labelNode = endLabel.info as LabelNode
val jumpInsnNode = JumpInsnNode(Opcodes.GOTO, labelNode)
instructions.insert(insnNode, jumpInsnNode)
instructions.insert(nop, jumpInsnNode)
instructions.remove(insnNode)
insnNode = jumpInsnNode
}

View File

@@ -121,7 +121,7 @@ fun MethodNode.findCapturedFieldAssignmentInstructions(): Sequence<FieldInsnNode
val prevPrev = fieldNode.previous?.previous as? VarInsnNode
fieldNode.opcode == Opcodes.PUTFIELD &&
InlineCodegenUtil.isCapturedFieldName(fieldNode.name) &&
isCapturedFieldName(fieldNode.name) &&
fieldNode.previous is VarInsnNode && prevPrev != null && prevPrev.`var` == 0
}
}

View File

@@ -37,7 +37,7 @@ abstract class ObjectTransformer<out T : TransformationInfo>(@JvmField val trans
val classBuilder = state.factory.newVisitor(
JvmDeclarationOrigin.NO_ORIGIN,
Type.getObjectType(transformationInfo.newClassName),
inliningContext.root.callElement.containingFile
inliningContext.root.sourceCompilerForInline.callsiteFile!!
)
return RemappingClassBuilder(
@@ -47,7 +47,7 @@ abstract class ObjectTransformer<out T : TransformationInfo>(@JvmField val trans
}
fun createClassReader(): ClassReader {
return InlineCodegenUtil.buildClassReaderByInternalName(state, transformationInfo.oldClassName)
return buildClassReaderByInternalName(state, transformationInfo.oldClassName)
}
}
@@ -64,7 +64,7 @@ class WhenMappingTransformer(
/*MAPPING File could contains mappings for several enum classes, we should filter one*/
val methodNodes = arrayListOf<MethodNode>()
val fieldNode = transformationInfo.fieldNode
classReader.accept(object : ClassVisitor(InlineCodegenUtil.API, classBuilder.visitor) {
classReader.accept(object : ClassVisitor(API, classBuilder.visitor) {
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces)
}

View File

@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.org.objectweb.asm.Type
internal class ParametersBuilder private constructor() {
class ParametersBuilder private constructor() {
private val params = arrayListOf<ParameterInfo>()

View File

@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.codegen.inline
import org.jetbrains.kotlin.codegen.StackValue
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.CAPTURED_FIELD_FOLD_PREFIX
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil.THIS
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.FieldInsnNode
@@ -67,7 +65,7 @@ class RegeneratedLambdaFieldRemapper(
val field = findFieldInSuper(fin) ?:
//search in parent
findFieldInSuper(FieldInsnNode(
Opcodes.GETSTATIC, originalLambdaInternalName, InlineCodegenUtil.`THIS$0`,
Opcodes.GETSTATIC, originalLambdaInternalName, THIS_0,
Type.getObjectType(parent!!.originalLambdaInternalName!!).descriptor
))?.also { fromParent = true } ?:
throw AssertionError("Couldn't find captured this $originalLambdaInternalName for $fieldName")

View File

@@ -169,7 +169,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
) = rewriteNextTypeInsn(insn, Opcodes.CHECKCAST) { stubCheckcast: AbstractInsnNode ->
if (stubCheckcast !is TypeInsnNode) return false
val newMethodNode = MethodNode(InlineCodegenUtil.API)
val newMethodNode = MethodNode(API)
generateAsCast(InstructionAdapter(newMethodNode), kotlinType, asmType, safe)
instructions.insert(insn, newMethodNode.instructions)
@@ -189,7 +189,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
) = rewriteNextTypeInsn(insn, Opcodes.INSTANCEOF) { stubInstanceOf: AbstractInsnNode ->
if (stubInstanceOf !is TypeInsnNode) return false
val newMethodNode = MethodNode(InlineCodegenUtil.API)
val newMethodNode = MethodNode(API)
generateIsCheck(InstructionAdapter(newMethodNode), kotlinType, asmType)
instructions.insert(insn, newMethodNode.instructions)
@@ -231,14 +231,14 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
if (next3 is MethodInsnNode && next3.name == "valueOf") {
instructions.remove(next1)
next3.owner = parameter.internalName
next3.desc = InlineCodegenUtil.getSpecialEnumFunDescriptor(parameter, true)
next3.desc = getSpecialEnumFunDescriptor(parameter, true)
return true
}
}
else if (next1.opcode == Opcodes.ICONST_0 && next2.opcode == Opcodes.ANEWARRAY) {
instructions.remove(next1)
instructions.remove(next2)
val desc = InlineCodegenUtil.getSpecialEnumFunDescriptor(parameter, false)
val desc = getSpecialEnumFunDescriptor(parameter, false)
instructions.insert(insn, MethodInsnNode(Opcodes.INVOKESTATIC, parameter.internalName, "values", desc, false))
return true
}

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