Compare commits

..

704 Commits

Author SHA1 Message Date
Vyacheslav Gerasimov
c9ab1f7521 Prettify changelog for 1.1.2 again 2017-04-25 17:27:30 +03:00
Vyacheslav Gerasimov
53e9f2caef Prettify changelog for 1.1.2 2017-04-25 16:55:27 +03:00
Dmitry Petrov
2ff7e27634 Turn off captured vars optimization in 1.1.2 2017-04-25 14:56:32 +03:00
Vyacheslav Gerasimov
8c8ed411c6 Update 1.1.2 changelog 2017-04-24 14:06:32 +03:00
Sergey Igushkin
e6e7f334bd Changed to prepending annotation processor path instead of appending it
to classpath and existing annotation processors.

(cherry picked from commit 2360d5f)
2017-04-20 20:37:30 +03:00
Pavel V. Talanov
1775856d8e 1.1.2: turn off lighter classes for classes and objects 2017-04-20 15:46:00 +03:00
Pavel V. Talanov
df423cfb61 Light classes: do not rely on dummy resolve for members with DeprecationLevel.HIDDEN
Use heuristic psi check to determine such cases
2017-04-20 15:37:34 +03:00
Dmitry Jemerov
85033abc7c Correctly honor expected type when converting string templates to UAST
#KT-17315 Fixed
 #KT-17316 Fixed

(cherry picked from commit 03cef30)
2017-04-19 11:47:51 +02:00
Ilya Chernikov
2ebfe809b3 Relax error reporting on script dependencies resolving
to avoid exceptions reported on the gradle model problems, e.g. missing
dependencies
2017-04-18 19:58:49 +02:00
Ilya Chernikov
a682d35edd Attempt to eliminate crashes if script template is broken
Attempts to fix issues similar to EA-100334 completely
2017-04-18 14:15:31 +02:00
Ilya Chernikov
81f6ea621e Restore another part of script template resolving for even older legacy code
complements d284979
Fixes EA-100334
2017-04-18 12:19:33 +02:00
Pavel V. Talanov
1b55bbc5da Codegen: fix NPE in NO_ANNOTATION_VISITOR
EA-100245 fixed
2017-04-17 14:07:22 +03:00
Pavel V. Talanov
0b7576f246 Light class codegen: do not apply compiler plugins
Applying plugins leads to failures when matching members in LazyLightClassDataHolder
    because plugins rely on analysis results
This decision has its drawbacks (java won't see results of plugin execution)
    but more work on light classes is needed if we want to support this usecase
We can argue that plugins should only generate synthetic members
    but there is no such restriction atm
2017-04-17 14:07:20 +03:00
Pavel V. Talanov
30fb24911c KtLazyLightClass: do not store references to LightClassDataHolder
Otherwise any cached reference to light class can lead to severe memory leaks in IDE
    since LightClassBuiderResult holds GenerationState which holds ModuleDescriptor
2017-04-17 14:07:18 +03:00
Pavel V. Talanov
6f69a9c96e IDELightClassContexts#isDummyResolveApplicable: add missing check
Missing check caused exact resolve being applied to every class that had 'equals' overridden
2017-04-17 14:07:15 +03:00
Pavel V. Talanov
90db318cc7 PsiBasedClassResolver: get default imports without resolution facade
Using DefaultImportProvider is expensive in this scenario
2017-04-17 14:07:13 +03:00
Pavel V. Talanov
4d2e9dd070 TargetPlatform#getDefaultImports(): cache result in all implementations 2017-04-17 14:07:11 +03:00
Pavel V. Talanov
9ab9fb45fb Minor: fix erroneous refactoring 2017-04-17 14:07:09 +03:00
Alexey Tsvetkov
22514a132e Delete daemon client file when Gradle process stops
#KT-17177 fixed
2017-04-13 23:05:37 +03:00
Alexey Tsvetkov
6dbe3ae123 Minor: rename test KotlinDaemonAdvaced->KotlinDaemonIT 2017-04-13 23:05:32 +03:00
Ilya Chernikov
d28497987d Restore parts of the template resolving code in the compiler...
that was moved to the script-runtime, that it a row caused the incompatibility
with old GSK implementations. Now the legacy template resolving related code
is restored, marked obsolete and wrapped for compatibility with the new code.
2017-04-12 17:57:48 +02:00
Vyacheslav Gerasimov
9ebdd5ebaf Update changelog for 1.1.2 EAP 2 2017-04-11 15:45:58 +03:00
Ilya Gorbunov
cae95e5247 Rebuild sources for kotlin-daemon-client and compiler-client-embeddable in maven build
Do not build these sources in ant.
Do not require them as artifact dependencies.

(cherry picked from commit e7dc7ec)
2017-04-11 03:02:34 +03:00
Ilya Gorbunov
e56ea84084 Do not produce javadoc for kotlin-compiler and do not attach it to maven artifacts
(cherry picked from commit c740c0b177)
2017-04-11 02:33:34 +03:00
Anton Bannykh
8fa55ccbde JS: polyfill ArrayBuffer.isView in order to support PhantomJS
(cherry picked from commit 3eb5ce7d9a)
2017-04-11 02:33:25 +03:00
Yan Zhulanow
6f2ab29889 Kapt: Support specifying javac options (KT-17245) 2017-04-10 22:47:35 +03:00
Sergey Igushkin
708b813ef2 Fixed duplicated kapt options caused by multiple call to args setup
Separated kapt args from other plugin options.

Issues: #KT-16965 Fixed

Fix indentation

(cherry picked from commit 8cdb08c)
2017-04-10 21:54:28 +03:00
Sergey Igushkin
15cd5411de Implemented resolving the compiler jar using the class loader
Added resolving the compiler jar using the class loader urls as the
first step with the fallback to the original resolution method. Also
helps if the compiler is not present in the classpath dependencies.

Issues: #KT-16580 Fixed

Changed to getting plugin version from the applied plugin instead of
the plugin JAR name.

Removed unnecessary working with version of AbstractKotlinPlugin.

(cherry picked from commit ea3adb0)
2017-04-10 21:54:07 +03:00
Sergey Igushkin
093c2bfeda Filling in and reverting annotationProcessor
Added reverting processor path back.
Appending processor path instead of setting it.

Issues: #KT-17255 Fixed

(cherry picked from commit 843844b)

Added a test checking that -processorpath is set for all Gradle versions

(cherry picked from commit bda59e5)
2017-04-10 21:53:37 +03:00
Sergey Igushkin
8746113e08 Refactoring in AnnotationProcessingManager.kt.
(cherry picked from commit 64278a0)
2017-04-10 21:53:14 +03:00
Sergey Igushkin
8e2d24341f Partial fix for the processor path not being set up properly.
Issues: #KT-17255

(cherry picked from commit 80daae9)
2017-04-10 21:52:59 +03:00
Alexey Tsvetkov
79c52eeaa0 Avoid changing java.rmi.server.hostname property 2017-04-10 20:42:53 +03:00
Alexey Tsvetkov
4221fc8813 Import 'implement' dependency of platform project transitively
#KT-16926 fixed
2017-04-10 20:42:47 +03:00
Alexey Tsvetkov
97b66cdeb6 Minor: fix maven IC tests with custom local repository 2017-04-10 20:42:39 +03:00
Alexey Tsvetkov
478caf27e1 Invalidate cache version if corresponding file is empty
Sometimes an expression `versionFile.readText()`
returns an empty string, so that `toInt()` fails
with `NumberFormatException`.

It can happen in with both JPS and Gradle.
I could not reproduce the problem,
and it seems to be impossible (under normal circumstances),
because we always write a non-empty string,
and the file is checked to exist before reading.
Maybe it could be caused by an FS error.

The only "solution" to the problem I could think
is to swallow the exception, and assume
that cache version is not valid (so it would cause a rebuild of a module).

    #KT-17125 fixed
2017-04-10 20:42:33 +03:00
Alexey Tsvetkov
4f6edbaf69 Fix printing daemon client messages
Fixing the problem introduced in the commit 9819de1abd:
the daemon client messages should be reported
when the debug log level is enabled
or when the connection not successful

    #KT-17199 fixed
2017-04-10 20:42:28 +03:00
Alexey Tsvetkov
b7e1cd95a6 Provide incremental compilation for Maven
#KT-11916 fixed

To use the IC either:
1. set the `kotlin.compiler.incremental` property to `true` in a pom.xml:
```
<properties>
    <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
</properties>
```
2. pass the `kotlin.compiler.incremental` property in a command line:
```
mvn install -Dkotlin.compiler.incremental=true
```

When IC is on Kotlin plugin is expected to print the warning in the log:
```
Using experimental Kotlin incremental compilation
```

After each call an incremental compiler will also log how many files it has compiled:
```
Compiled %SOME_NUMBER% Kotlin files using incremental compiler
```

Note that the first build will be non-incremental.

For more diagnostic information (such as an exact list of compiled files) use the `kotlin.compiler.incremental.log.level` system property:
```
mvn install -Dkotlin.compiler.incremental=true -Dkotlin.compiler.incremental.log.level=info
```

To force the rebuild just run the 'clean' goal:
```
mvn clean install
```
2017-04-10 20:42:20 +03:00
Mikhael Bogdanov
05fb47531a Delete clean reference instructions on dereferencing captured variables
Codegen generates clean instructions for ref values (captured vars)
on block exit so we should delete them on dereferencing captured values.

  #KT-17200 FIXED

(cherry picked from commit b51cb9a)
2017-04-10 15:49:46 +02:00
Mikhael Bogdanov
59caeff3db Don't eliminate redundant casts to multi-dimension arrays
Dex doesn't recognize ANEWARRAY [Ljava/lang/Object; types as Object [][], but Object [].
It's not clear is it bug in dex or not

 #KT-17200 InProgress

(cherry picked from commit f3e2abf)
2017-04-10 15:49:41 +02:00
Vyacheslav Gerasimov
adc74268f4 Implement getTypeElement for UastKotlinPsiVariable
#KT-16849 Fixed

(cherry picked from commit 107879a)
2017-04-10 12:54:44 +03:00
Vyacheslav Gerasimov
63e109b061 Register Android api quickfixes for inlined api inspection
#KT-14857 Fixed

(cherry picked from commit 1d134ff)
2017-04-10 12:54:44 +03:00
Vyacheslav Gerasimov
e73f70d323 Fix NoSwingUnderWriteActionException in KotlinAndroidAddStringResource
(cherry picked from commit 70d24d0)
2017-04-10 12:54:43 +03:00
Pavel V. Talanov
591b972bfd Light classes: do not rely on dummy context when data class autogenerated members conflict with declared members
Fix related issues with nested classes
2017-04-09 15:33:46 +03:00
Pavel V. Talanov
f113624180 Light class test: avoid checking method visibility when NoLaziness is not specified
Allows to avoid putting NoLaziness flag on every test that mentions 'override' modifier
2017-04-09 15:33:44 +03:00
Pavel V. Talanov
0ca1481fd6 Light classes: generate ACC_STATIC for DefaultImpls classes
To provide consistency between light classes and their delegates

IdeLightClass#testExtendingInterfaceWithDefaultImpls still failing since
    we do not generate implementations delegating to DefaultImpls of superinterfaces
2017-04-09 15:33:42 +03:00
Pavel V. Talanov
84ca3735ff Light classes: test consistency for inner classes 2017-04-09 15:33:40 +03:00
Pavel V. Talanov
99f9b5e4a9 Light class builder: do not generate methods delegating to DefaultImpls in kotlin classes
Class APIs from java point of view stays the same so we can avoid generating those methods
Otherwise we have to calculate all supertypes when getMethods() is called,
    which imposes severe performance penalties
We have to pretend these methods are not 'abstract' (also we consider them 'default' for safety)
    so java highlighting does not report "class should be abstract" for all inheritors
We have to manually report "class should be abstract" on some of the java inheritors,
    specifically those that are implementing interfaces directly
	    as opposed to extending kotlin classes implementing those interfaces
2017-04-09 15:33:38 +03:00
Pavel V. Talanov
6a4e7c8c3e Minor, refactor: Move hasBody() to KtProperty 2017-04-09 15:14:15 +03:00
Pavel V. Talanov
716efa9ba2 LazyLightClassDataHolder: minor, improve diagnostics 2017-04-09 15:14:12 +03:00
Pavel V. Talanov
4fe07270e6 AbstractIdeLightClassTest: minor, refactor 2017-04-09 15:14:10 +03:00
Vyacheslav Gerasimov
ecd828e479 Fix MovePropertyToConstructorIntention applicability and type rendering
#KT-17238 Fixed

(cherry picked from commit 6b92420)
2017-04-07 14:51:34 +03:00
Ilya Chernikov
98d842841a Fix environment arg parsing regex - avoid SO on the long strings 2017-04-06 18:51:59 +02:00
Ilya Chernikov
ab82ab0a9b minor: Fix daemon shutdown livelock
due to wrong minimal aliveness, daemon was in some situations livelocked
in the last session state on shutdown.
2017-04-06 10:23:03 +02:00
Ilya Chernikov
b4af84f44e Fix CRLF handling in source-sections plugin 2017-04-06 10:23:02 +02:00
Ilya Chernikov
5412f0ca00 Add new compiler argument for passing script resolver environment 2017-04-06 10:23:01 +02:00
Ilya Chernikov
03508e309a minor: improve daemon start failure diagnostic 2017-04-06 10:23:00 +02:00
Ilya Chernikov
194ea17413 Add actual sources to compiler and daemon client jars 2017-04-06 10:22:59 +02:00
Ilya Chernikov
5219033917 minor: remove redundant runWhenSmart on index changes notification 2017-04-06 10:22:58 +02:00
Ilya Chernikov
ce267dca54 Port compiler to the script-runtime with script base classes 2017-04-06 10:22:57 +02:00
Ilya Chernikov
f6d652a5d4 Add new artifact kotlin-compiler-client-embeddable.jar 2017-04-06 10:22:56 +02:00
Ilya Chernikov
5a73faf09c minor: move native platform launcher to separate file to make native-platform dependency optional 2017-04-06 10:22:55 +02:00
mglukhikh
1a4cbb4687 Find enclosing element for object literal in delegate #KT-8187 Fixed
(cherry picked from commit 9fa1636)
2017-04-05 20:22:38 +03:00
mglukhikh
baa7fe71b8 Do not add a new label to labeled loop
Relevant situation: break / continue in when #KT-16128 Fixed

(cherry picked from commit 6277476)
2017-04-05 20:22:23 +03:00
mglukhikh
b39bb3d10d Don't suggest destructuring if at least half components not used
So #KT-16828 Fixed

(cherry picked from commit feb9dd4)
2017-04-05 20:22:09 +03:00
Anton Bannykh
41bb820083 JS: make tests dependent on primitive array is checks pass even when -Xtypedarray is disabled (related: KT-17137)
(cherry picked from commit 867bd13)
2017-04-05 15:39:07 +03:00
Anton Bannykh
a9d66e30a2 JS: fix maven SeleniumTest
(cherry picked from commit 7d4c26c)
2017-04-05 15:39:07 +03:00
Anton Bannykh
15539122c9 JS: fixed <Type>Array.iterator methods; added -Xtypedarray compiler key
The <Type>Array.iterator used to lack next<Type>() method (KT-16626).

The -Xtypedarray compiler key enables translation of primitive arrays
to TypedArrays, and primitive array`is`-checks (KT-15358, KT-14007,
KT-14614, KT-16056).

(cherry picked from commit 9b34e21)
2017-04-05 15:39:07 +03:00
mglukhikh
24376fd857 KT-15870: run getTargetDirectory() in write action
(cherry picked from commit 1b2edf6)
2017-04-05 13:13:18 +03:00
mglukhikh
6c9fe38ff7 Set startInWrite... in intention-based quick fix as in intention
So #KT-15870 Fixed

(cherry picked from commit ee239d5)
2017-04-05 13:13:02 +03:00
Mikhail Glukhikh
80432d7b71 Fix "must not be null" in KotlinInlineFunctionDialog #KT-17233 Fixed
(cherry picked from commit 318314f)
2017-04-05 13:12:08 +03:00
mglukhikh
056d631a65 Make destructure intention work on library data classes
So #KT-16468 Fixed
So #KT-14402 Fixed

(cherry picked from commit f139977)
2017-04-05 13:11:10 +03:00
mglukhikh
27d389f9e5 KT-16828: use _ when appropriate in destructure intention
(cherry picked from commit 8a02ce3)
2017-04-05 13:10:45 +03:00
Mikhail Glukhikh
917da3d445 Introduce UNUSED_ANONYMOUS_PARAMETER for anonymous functions
It is not reported for 1.0 language version because
renaming to _ is not possible. It has weak warning severity

So #KT-8813 Fixed
So #KT-16875 Fixed

(cherry picked from commit 7a53b2f)
2017-04-05 13:09:14 +03:00
Dmitry Jemerov
441148fa9e KotlinAnnotatedElementsSearcher optimization
When possible, try to resolve references in types using only the PSI
without building the full resolve session.

(cherry picked from commit 296fe69)
2017-04-04 12:41:00 +02:00
Nikolay Krasko
62510f6ead Ad hoc solution to avoid resolution in language injection by receiver (KT-16995)
#KT-16995 Fixed

(cherry picked from commit eb4e6e6)
2017-04-03 19:56:09 +03:00
Mikhail Zarechenskiy
41c8efc688 Do not show warning about useless elvis for error function types
#KT-17214 Fixed
 #KT-12112 Fixed
2017-04-03 16:33:03 +03:00
Mikhail Zarechenskiy
1f31aa82f3 Warn for unnecessary (!!) assertion after method with generics
#KT-12276 Fixed
2017-04-03 16:33:01 +03:00
Mikhail Zarechenskiy
6e506fccde Fix warning about useless elvis when generics are involved
#KT-13648 Fixed
2017-04-03 16:33:00 +03:00
Vyacheslav Gerasimov
5317abb00d Add link to previous release to changelog 2017-03-31 21:15:31 +03:00
Ilya Chernikov
5595bea2ea Remove xerces from compiler uberjar, pack compiler with explicit jar names
xercesImpl was unnecessarily added to the compiler uberjar during migration
to the idea platform 171. This caused NCDFE about classes from org.w3c
package.
And to simplify application of this commit and to ensure that only required
jars are packed into the uberjar, the build.xml was altered to use
explicit list of the jars from the ideaSdk/core directory, rather than
a mask.

Fixes #KT-17143 and #KT-17157
2017-03-30 19:28:46 +02:00
Mikhail Glukhikh
36a6288dee Inline function: add extra tests taken from intellij-community
(cherry picked from commit 8cfcd7e)
2017-03-30 19:51:05 +03:00
Mikhail Glukhikh
411962ee57 Inline function: keep the function if some usages are not processed
(cherry picked from commit b8b7d1f)
2017-03-30 19:50:49 +03:00
Mikhail Glukhikh
6532442701 Inline function: process usages in children-first order
(cherry picked from commit 091e875)
2017-03-30 19:50:34 +03:00
Mikhail Glukhikh
53cfd2095d Inline function: use "function" in GUI messages
(cherry picked from commit fc0bf47)
2017-03-30 19:50:19 +03:00
Mikhail Glukhikh
6b47229cf8 Inline function: handle callable references through lambdas
(cherry picked from commit 93b624f)
2017-03-30 19:50:05 +03:00
Mikhail Glukhikh
6991eadcf5 Inline function: handle recursive calls
(cherry picked from commit 75bb599)
2017-03-30 19:49:49 +03:00
Mikhail Glukhikh
25ed1553d1 Introduce dialog for function inlining #KT-6159 Fixed
See KotlinInlineFunctionProcessor and KotlinInlineFunctionDialog

(cherry picked from commit e79f006)
2017-03-30 19:49:34 +03:00
Mikhail Glukhikh
279bbb4732 KT-6159: generate Unit while code inlining when needed
(cherry picked from commit b6803af)
2017-03-30 19:49:17 +03:00
Mikhail Glukhikh
d6f86b7c05 Minor: deprecation fix in ScopeUtils
(cherry picked from commit 7de0197)
2017-03-30 19:49:03 +03:00
Mikhail Glukhikh
61664c02cd Fix code inlining for expression body with multiple occurrences
So #KT-17022 Fixed

(cherry picked from commit 081caad)
2017-03-30 19:48:43 +03:00
Mikhail Glukhikh
52a33cc494 Minor: style fix in KotlinInlineFunctionHandler
(cherry picked from commit 96846d0)
2017-03-30 19:48:24 +03:00
Mikhail Glukhikh
f80e78ac57 KT-6159: rename duplicates met
(cherry picked from commit 7788834)
2017-03-30 19:48:10 +03:00
Mikhail Glukhikh
d3587bb028 Do not perform function inlining if it's not supported
(cherry picked from commit 342118d)
2017-03-30 19:47:55 +03:00
Mikhail Glukhikh
2aff73b432 KT-6159: allow local / private functions inlining
(cherry picked from commit de86106)
2017-03-30 19:47:41 +03:00
Mikhail Glukhikh
f08fd888a8 Some inline tests that do not work
(cherry picked from commit 127b7c8)
2017-03-30 19:47:19 +03:00
Mikhail Glukhikh
08abb61e12 KT-6159: Inline function refactoring enabled
(cherry picked from commit 1d5b8ea)
2017-03-30 19:47:01 +03:00
Dmitry Jemerov
ef6669e865 Optimize isReferenceTo() when searching for PsiMethod usages
Avoid resolving references when we know from context that a reference
at given location can't resolve to a PsiMethod.

(cherry picked from commit f255f2a)
2017-03-30 15:34:48 +02:00
Mikhail Glukhikh
e7f7673123 Use library-only sources as resolve scope from library #KT-12264 Fixed
(cherry picked from commit e3f0a60)
2017-03-30 14:02:00 +03:00
Mikhail Glukhikh
e85ca8de52 Evaluate allImplementingModules lazily #KT-17136 Fixed
(cherry picked from commit a35b770)
2017-03-29 18:22:01 +03:00
Simon Ogorodnik
c6385f9309 Fix ImportFixBase to compute suggestions not on EDT
(cherry picked from commit ddcff3c)
2017-03-29 17:36:47 +03:00
Vyacheslav Gerasimov
c2417ac243 Add changelog for 1.1.2
(cherry picked from commit 94b261d)
2017-03-29 16:12:39 +03:00
Dmitry Petrov
9e236c4a23 KT-16264 Forbid usage of _ without backticks
Forbid underscore-only (_, __, ___, ...) names as callees and as types.

If CHECK_TYPE directive is on, filter out UNDERSCORE_USAGE_WITHOUT_BACKTICKS messages.
2017-03-29 15:54:34 +03:00
Yan Zhulanow
dd32987eb2 Fix 'kotlin-spring' and 'kotlin-noarg' Gradle plugin importing (KT-17049)
Allopen and Noarg plugins now use 'presets' that should be handled in the Gradle importer as well.
2017-03-29 13:52:00 +03:00
Pavel V. Talanov
b141f3754a KtLightElements: fix KtLightMember not extending KtLightDeclaration
Fix problem introduced in 4b85fd9fbe
2017-03-28 19:48:19 +03:00
Yan Zhulanow
2fc74d2819 Minor: fix failing CliTestGenerated#testPluginSimple test
Add missing Android Dialog stub cause Android Extensions plugin now generates the synthetic property for Dialog.
2017-03-28 16:09:23 +03:00
Dmitry Jemerov
6c6e163881 Log fallbacks to plain text search when searching expressions of type
This will help diagnose performance problems in IDEA inspections.

(cherry picked from commit 8ec70f4)
2017-03-28 13:07:50 +02:00
Sergey Igushkin
0ee4ddfda9 Support omitting version of org.jetbrains.kotlin dependencies
Related to #KT-12792

(cherry picked from commit ae2b4f5)
2017-03-28 08:39:35 +03:00
Sergey Igushkin
01c92992c9 Fixed classes copying fail in cases when destinationDir has changed
Added @Input to the property returning classes dirs: it will make
Gradle fall back to non-incremental input when the property value
changes.

Issues: #KT-16820 Fixed

(cherry picked from commit 9ba84df)
2017-03-28 08:39:11 +03:00
Jonathan Leitschuh
4154bba5a3 Java IC compatibility fix for Gradle 2.14+
Added version check to switch between old and new approaches because
Gradle versions before 2.14 have a bug in Java IC.
Added Kotlin classes to Java task input.
Added  annotationsFile into task input to include it into up-to-date check.

Related issues: #KT-16585 Fixed

(cherry picked from commit cc0ac36)
2017-03-28 08:38:51 +03:00
Ilya Gorbunov
cf6cef71e2 Remove 'nearly_stateless' category, do not mention statefulness for terminal operations.
#KT-16994

(cherry picked from commit c98c2d9)
2017-03-28 00:11:53 +03:00
Ilya Gorbunov
ce5a104eb2 Sequence operation classification regarding their statefulness and laziness.
#KT-16994 Fixed

(cherry picked from commit 4018db6)
2017-03-28 00:11:46 +03:00
Simon Ogorodnik
94b5148d5b Revert: Fix Sample reference to resolve cross-module packages correctly 2017-03-27 21:41:07 +03:00
Pavel V. Talanov
5c0831d5ad findDecompiledDeclaration: find builtIns more accurately
Use resolveScope of a reference to help searching for builtIn binaries
Do not search non-builtIn descriptors in random scopes
2017-03-27 21:23:40 +03:00
Alexander Udalov
894f85d822 Disallow using named arguments for members of header classes
#KT-17083 Fixed

(cherry picked from commit ccd3781403)
2017-03-27 20:12:17 +03:00
Alexander Udalov
9e1a4992d8 Allow impl declarations to have flexible types
Types of the corresponding parameters (or type parameter bounds, types
in supertypes, etc) are now compatible not only if they're equal, but
also if values of those types are mutually assignable (if "a" is subtype
of "b" and "b" is subtype of "a")

 #KT-17005 Fixed

(cherry picked from commit b971ac9312)
2017-03-27 20:12:15 +03:00
Alexander Udalov
1b7198cb03 Allow impl declarations to have non-stable parameter names
#KT-17027 Fixed

(cherry picked from commit 116380a826)
2017-03-27 20:12:14 +03:00
Alexander Udalov
24182e39d8 Render incompatible impl member in "no impl for header" diagnostic
(cherry picked from commit 633798db18)
2017-03-27 20:12:12 +03:00
Alexander Udalov
b6e32cc03d Serialize and deserialize 'header' modifier for descriptors
This fixes KT-17001 because now 'header' modifier is loaded correctly
for deserialized members and the standard disambiguation in
OverloadingConflictResolver.compareCallsByUsedArguments takes place,
where header members are discriminated against the corresponding impl
members

 #KT-17001 Fixed

(cherry picked from commit db1f039586)
2017-03-27 20:12:10 +03:00
Pavel V. Talanov
4518c5bac6 Light class tests: hidden deprecated affects codegen
Provide fix later
2017-03-27 18:02:43 +03:00
Pavel V. Talanov
58ad4b1386 Lazy light classes: can't use laziness for classes with supertypes delegates 2017-03-27 18:02:41 +03:00
Pavel V. Talanov
1f62636400 KtLightMethod: isVarArgs() does not trigger exact delegate computation 2017-03-27 18:02:39 +03:00
Pavel V. Talanov
b10adf2de0 Light members: allow to get modifier list without computing delegate 2017-03-27 18:02:38 +03:00
Pavel V. Talanov
5befeb4ccf LazyLightClassDataHolder: rollback optimization on suspected inherited internal visibility
Internal visibility affects member names
2017-03-27 18:02:36 +03:00
Pavel V. Talanov
614a4fec22 Light classes: refactor, move getOrigin to corresponding classes 2017-03-27 18:02:34 +03:00
Pavel V. Talanov
bd45c70083 Lazy light classes: fix visibility modifier in case of inherited protected visibility 2017-03-27 18:02:33 +03:00
Pavel V. Talanov
2961301297 LightClassTest: test corner cases related to inherited visiblity
EA-99155
 #KT-16899 Fixed
2017-03-27 18:02:31 +03:00
Pavel V. Talanov
bdde75a6a3 Refactor light members: introduce KtLightMemberImpl
Holds common code for fields and methods
2017-03-27 18:02:29 +03:00
Pavel V. Talanov
e325523034 Introduce KotlinOverridableInternalMembersShortNameIndex
Keeping track of all potentially overridable internal members
To optimize certain scenarios in light classes
2017-03-27 18:02:27 +03:00
Pavel V. Talanov
84f17ba1a1 Minor, stubs: isTrait -> isInterface 2017-03-27 18:02:25 +03:00
Alexander Udalov
c649752e8e Do not use CoreJavaFileManager in KotlinCliJavaFileManagerImpl
The inheritance is still needed because of the code in intellij-core,
specifically in JavaCoreProjectEnvironment.addSourcesToClasspath and
CoreJavaDirectoryService.getPackage, which assumes that the
JavaFileManager instance in the project is a CoreJavaFileManager

(cherry picked from commit 1c7ac2da5a)
2017-03-27 17:20:10 +03:00
Alexander Udalov
9cace66246 Support nested classes in KotlinCliJavaFileManagerImpl.findClass
findClass(String, GlobalSearchScope) is invoked for example when we're
resolving supertypes of classes in Java libraries. Previously, it never
found nested classes and falled back to CoreJavaFileManager's
implementation, which lacks a fix for the original issue (KT-12664,
which was fixed in JvmDependenciesIndex in 5a533a52 and 164c72e8)

 #KT-16931 Fixed

(cherry picked from commit c67eb84369)
2017-03-27 17:20:08 +03:00
Alexander Udalov
6375fb773d Refactor JvmDependenciesIndex
- Move collectKnownClassNamesInPackage to the only place where it's used
- Fix warnings/inspections and simplify implementation a bit

(cherry picked from commit f1a1ebae01)
2017-03-27 17:20:07 +03:00
Alexander Udalov
b6f1cf8107 Refactor KotlinJavaPsiFacade.KotlinPsiElementFinderImpl
Split KotlinPsiElementFinderImpl into two classes: one is used in the
compiler (boolean field isCliFileManager previously handled that), the
other is used in IDE and possibly other non-CLI scenarios.

Also avoid a possible class cast exception in
KotlinJavaPsiFacade.knownClassNamesInPackage

(cherry picked from commit 801a93edbc)
2017-03-27 17:20:05 +03:00
Ilya Gorbunov
86ced88e0d Run gradle unit tests with Java 8
(cherry picked from commit d54f114)
2017-03-27 11:39:32 +03:00
Ilya Gorbunov
06e909acad Fix missing kotlin-test dependencies
(previously it was bundled to kotlin-compiler-embeddable)

(cherry picked from commit 6dc4056)
2017-03-27 11:39:32 +03:00
Vyacheslav Gerasimov
95d774697c Fix MovePropertyToConstructorIntention and broken tests
(cherry picked from commit 8c41e44)
2017-03-27 11:39:32 +03:00
Alexey Sedunov
7bc246f614 Move: Fix conflict checking when switching between similar libraries
#KT-17006 Fixed

(cherry picked from commit 298ee26)
2017-03-26 16:28:49 +03:00
Alexey Sedunov
a2bb0ace05 Resolution Facade: Add explicit property for file target platform
(cherry picked from commit 45b8cd2)
2017-03-26 16:28:33 +03:00
Alexey Sedunov
3594294d0a Move: Fix runtime unconfiguration for multiple modules
(cherry picked from commit 87ea13b)
2017-03-26 16:28:13 +03:00
Alexey Sedunov
fca79f9bf9 Move: Fix processing of calls and callable references
Fix CCE on callable references to Java methods.
Fix qualification of callable references without receivers.
Fix processing of calls/callable references to object extensions
and extension members.
Do not explicate short companion references

 #KT-16809 Fixed

(cherry picked from commit 1d01624)
2017-03-26 16:28:00 +03:00
Alexey Sedunov
fd5bb25349 Move: Perform extension import insertion after reference shortening
(cherry picked from commit 5849555)
2017-03-26 16:27:46 +03:00
Alexey Sedunov
5fbd738f24 Refactor KotlinShortenReferencesRefactringHelper
Rename refactoring helper and its infrastructure
Add support for different request types

(cherry picked from commit b3274ac)
2017-03-26 16:27:34 +03:00
Alexey Sedunov
63e4beab76 Move: Do not shorten references unaffected by the refactoring
(cherry picked from commit dc04b20)
2017-03-26 16:27:12 +03:00
Alexey Sedunov
89caa70987 Shorten References: Skip companion receivers on callable references
This is temporary fix due to KT-13934 which prevents resolution
of references like X::foo where foo is a member or extension
of X companion object

(cherry picked from commit aad11ff)
2017-03-26 16:26:58 +03:00
Alexey Sedunov
ea8b082355 Move: Fix "scanEntireFile" values after the refactoring
#KT-17032 Fixed

(cherry picked from commit d71cefe)
2017-03-26 16:26:01 +03:00
Alexey Sedunov
ae0218431c Kotlin Facet: Detect module platform by 'kotlin'/'kotlin2js' plugin
(cherry picked from commit b818ef0)
2017-03-26 16:25:23 +03:00
Alexey Sedunov
77dff7b7f5 Kotlin Facet: Fix settings initialization
(cherry picked from commit 0ad2822)
2017-03-26 16:24:40 +03:00
Alexander Udalov
15502b4153 Update to ASM 6-alpha from intellij 171
Will be needed to read module-info files
2017-03-24 20:17:43 +03:00
Alexander Udalov
b9891c36e2 Remove unused library 'intellij-core-analysis' 2017-03-24 20:17:40 +03:00
Yan Zhulanow
d3a9008bd3 Kapt3: Fix Maven build on CI
'tools_jar_profile' Maven profile is activated only if 'kotlin-annotation-processing-maven-build.txt' exists.
It already works this say for the 'kotlin-annotation-processing' artifact.
2017-03-24 20:06:09 +03:00
Yan Zhulanow
249a3a0ec9 Kapt3: Use 'compilerArgs' safely (KT-16990)
'android-apt' (com.neenbedankt) adds the 'File' instance to 'compilerArgs' (List<String>).
2017-03-24 20:06:02 +03:00
Alexey Tsvetkov
0a4c43a5f1 Fallback to ProcessBuilder when native ProcessLauncher fails
#KT-16902 fixed
2017-03-24 19:03:41 +03:00
Alexey Tsvetkov
9d95c841a6 Use connect-and-lease when using daemon in JPS & Gradle
Relates to KT-15562 "Service is dying".

This commit includes multiple changes:
 1. JPS & Gradle daemon clients are refactored to use `connectAndLease` from `KotlinCompilerClient`.
 `connectAndLease` was introduced in previous commits
 2. `withKotlin` was removed because `connectAndLease` already covers retrying on connection error
 3. Gradle flag files creation is changed:
   * client-alive flag file lives as long as Gradle instance lives,
   * session-alive flag file lives until the end of a build.
2017-03-24 19:03:36 +03:00
Alexey Tsvetkov
9819de1abd Improve daemon client debug reports
Before this change a daemon client debug messages were printed
only when the client could not connect and the 'kotlin.daemon.verbose'
system property was set up.

Now messages are printed if the debug logging is enabled and
the 'kotlin.daemon.verbose' is set up.
2017-03-24 19:03:32 +03:00
Alexey Tsvetkov
c5324fcc50 Speed up daemon startup when DNS timeouts
#KT-16917 fixed

The daemon code contained the following code:
```
ManagementFactory.getRuntimeMXBean().name
```

As it turns out `RuntimeImpl#getName` calls `VMManagementImpl#getVmId`,
which in turn calls `InetAddress.getLocalHost().getHostName()`.

`InetAddress.getLocalHost()` tries to resolve by making a DNS-request.
In case of a DNS-problem or a network misconfiguration,
resolving localhost can be very slow,
so a daemon client can disconnect
by the timeout (10 seconds) and fallback to the non-daemon compilation.

This change removes the call `getRuntimeMXBean().name`
(it is only used for logs).
2017-03-24 19:03:28 +03:00
Alexey Tsvetkov
da24a99b91 Set 'java.rmi.server.hostname' property on client too
The RMI documentation (http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/javarmiproperties.html)
says it is useful to set up a `java.rmi.server.hostname`
system property on a client and a server.
When the property is set up on a client, I saw that "RenewClean" threads
stopped listening to my external IP, so all client and server threads
are now only listening the loopback interface.

I also changed the way the property is set up on the server side:
before the change it was passed in jvmargs at a process launcher.
I moved this code directly to the main method of the daemon,
because it is easy to forget to set up the property,
when running the main for debug purposes.
2017-03-24 19:03:24 +03:00
Alexey Tsvetkov
f748dc625c Minor: print errors to stderr when gradle test build
It takes time to find compile errors or exceptions,
when a Gradle test build fails, because a debug log
is very verbose.
This change prints all error messages from Gradle
when a test build fails unexpectedly.
2017-03-24 19:03:19 +03:00
Dmitry Jemerov
961d83fcd4 Bump code cache size (64m is no longer enough under JDK 8) 2017-03-24 16:40:23 +01:00
Dmitry Jemerov
859e3e17b4 Bump code cache size (64m is no longer enough under JDK 8) 2017-03-24 16:37:11 +01:00
Vyacheslav Gerasimov
543f59bf54 Add new quickfix for CanBePrimaryConstructorPropertyInspection
MovePropertyToConstructorIntention is used as quick fix
2017-03-24 17:38:52 +03:00
mglukhikh
4700936f66 DFA: count null comparison as identity comparison #KT-16538 Fixed
+ minor parameter refactoring
2017-03-24 17:33:42 +03:00
Mikhail Glukhikh
b5aa529901 Make inspection "lambda->reference" off by default #KT-17002 Fixed 2017-03-24 16:20:07 +03:00
Mikhail Glukhikh
b121990368 Don't suggest 'remove let' when 'it' is used multiple times
So #KT-16857 Fixed
2017-03-24 16:20:00 +03:00
Mikhail Glukhikh
4687a867c3 Anti-KNPE refactoring of RedundantSamConstructorInspection
So EA-84354 fixed
2017-03-24 16:19:47 +03:00
Mikhail Glukhikh
6f4ae2585b Fix "surround with null check": place check correctly for unsafe call
So #KT-16928 Fixed
2017-03-24 16:19:32 +03:00
Mikhail Glukhikh
bbdcf19123 Fix "secondary constructor -> primary" in case of implicit super call
So #KT-16903 Fixed
2017-03-24 16:19:18 +03:00
Mikhail Glukhikh
0baae16601 Don't apply "object->lambda" if 'this' is used inside #KT-15250 Fixed 2017-03-24 16:19:04 +03:00
Mikhail Glukhikh
ca92ec0b7b Fix "Specify explicit lambda signature" when no parameters exists
So #KT-15075 Fixed
2017-03-24 16:18:56 +03:00
Vyacheslav Gerasimov
f60a7ffab0 Add intentions to move property from/to primary constructor
#KT-4578 Fixed
2017-03-24 15:22:50 +03:00
Alexander Udalov
fef4c8ccd8 Fix VerifyError on bound function reference on generic property
Also add a test for obsolete KT-14755

 #KT-16929 Fixed
2017-03-24 11:06:15 +03:00
Dmitry Petrov
fc38479f48 References to enum entries should be always generated as GET_ENUM 2017-03-24 10:06:10 +03:00
Dmitry Petrov
64013171e8 KT-16905 Wrong IR for call to inner class constructor through typealias 2017-03-24 10:06:10 +03:00
Dmitry Petrov
d05de88e3e KT-16904 Wrong IR when applying some operators to superclass properties in constructor
Use property accessors for assignment generation for inherited properties in constructor.
2017-03-24 10:06:10 +03:00
Nikolay Krasko
5405c81106 Minor: remove warnings in KotlinDebuggerTestBase 2017-03-23 21:01:42 +03:00
Nikolay Krasko
dfd7b0f388 Delegate step into command to kotlin command provider first 2017-03-23 21:01:42 +03:00
Nikolay Krasko
2c4f702d50 Remove stored contexts in tests to avoid leaks 2017-03-23 21:01:42 +03:00
Nikolay Krasko
2aa1b19ec9 Replace CompilingEvaluatorUtils methods with ClassLoadingUtils 2017-03-23 21:01:42 +03:00
Ilya Chernikov
3b60d56c0b minor: fixing maven plugin tests 2017-03-23 18:11:40 +01:00
Ilya Chernikov
4d7e64614a Make daemon tests more stable
Probably due to switching to the JDK8, the daemon tests became more flaky.
Making it less reliable on the log file closing. And try to close log files
on the daemon side.
Also improving diagnostics on many tests.

Also weaken parallel daemon start test a bit since it seems it is failing
on the RMI timeouts now.
2017-03-23 18:11:39 +01:00
Ilya Chernikov
c034a73d72 Extract and reuse JarFS-related IO fallback configurator function
Partly fixes #KT-16927
2017-03-23 18:11:38 +01:00
Ilya Chernikov
e59f6741c4 Move GradleScriptTemplatesProvider to the optional gradle part of "plugin.xml"
Fixes #KT-16649
2017-03-23 18:11:37 +01:00
Ilya Chernikov
8eaeadddfa Disable flaky statistical benchmark tests for source sections plugin and JSR 223 2017-03-23 18:11:36 +01:00
Ilya Chernikov
3061862d31 Fix classloader extraction from script template
fixes #KT-16699
2017-03-23 18:11:35 +01:00
Ilya Chernikov
6b477e9f38 Remove jna from compiler-embeddable
It is considered in fact unused in the compiler
Fixes #KT-16862
2017-03-23 18:10:55 +01:00
Ilya Chernikov
319440718c Add more JSR 223 and repl tests, fix double aggregation of GenericRepl state
- repl test with compilation error
- JSR 223 compilable tests
2017-03-23 18:07:45 +01:00
Ilya Chernikov
adc541c3b1 minor: Move sameSignature function into single use site to avoid local build problems 2017-03-23 18:07:44 +01:00
Dmitry Jemerov
b24ce04dea Convert IntentionTestGenerated to light fixture test case 2017-03-23 15:48:33 +01:00
Dmitry Jemerov
5af423f1b4 Allow configuring kotlin.test in KotlinLightCodeInsightFixtureTestCase 2017-03-23 15:48:33 +01:00
Dmitry Jemerov
036b87a001 KotlinJdkAndLibraryProjectDescriptor: J2K 2017-03-23 15:48:33 +01:00
Dmitry Jemerov
1435f11a9f KotlinJdkAndLibraryProjectDescriptor: rename to .kt 2017-03-23 15:48:33 +01:00
Dmitry Jemerov
24bdf994a9 AbstractIntentionTest: J2K 2017-03-23 15:48:33 +01:00
Dmitry Jemerov
68ec8b3077 AbstractIntentionTest: rename to .kt 2017-03-23 15:48:33 +01:00
Dmitry Jemerov
199ce6706b Convert AbstractConcatenatedStringGeneratorTest to light test case
Remove explicit library configuration; rely on
getProjectDescriptorFromFileDirective() instead.
2017-03-23 15:48:33 +01:00
Mikhail Glukhikh
1780f7c9a2 Put not-null original type as last possible smart cast target
This fixes muted tests testSmartCast (IDE highlighting) and
testNestedSealed (Diagnostics).
Together with commit 555b3f12 this makes #KT-15901 Fixed
2017-03-23 17:17:37 +03:00
Ilya Gorbunov
1cb4580380 Refactor: rename 'check' helper function with more descriptive name, remove 'var result' 2017-03-23 16:48:38 +03:00
Ilya Gorbunov
dce0da68c6 Cleanup: post-cleanup after deprecation cleanup in compiler
Replace `takeIf { !expr }` with `takeUnless { expr }`.
Cleanup redundant parethesis as in `listOf((expr))`.
Replace `listOf(expr)` with `expr.let(::listOf)` where the former caused significant indentation change.
2017-03-23 16:48:38 +03:00
Nikolay Krasko
e599688733 "Go to Type Declaration" for extension receiver and 'it' (KT-13013)
#KT-13013 Fixed
2017-03-23 13:37:06 +03:00
Nikolay Krasko
daaa59a1ad Navigate to receiver from this in extension function (KT-16991)
#KT-16991 Fixed
 #KT-13013 In Progress
2017-03-23 13:37:05 +03:00
Nikolay Krasko
9dfc92c55e Navigate to lambda declaration from generated 'it' (KT-16992)
#KT-16992 Fixed
 #KT-13013 In Progress
2017-03-23 13:37:05 +03:00
Nikolay Krasko
c976c3d909 Refactoring: extract common function (some usages were slightly changed) 2017-03-23 13:37:05 +03:00
Alexander Udalov
ccfa42289c Fix compilation of kotlin-script-util
'check' was removed in 579238c3be
2017-03-23 11:46:26 +03:00
Nikolay Krasko
84c473d800 Speed up debugger tests by replacing base output preprocessor
Avoid calling InetAddress.getLocalHost() that can be very slow.
Exact connection or disconnection string isn't relevant for tests
anyway.
2017-03-23 00:31:43 +03:00
Nikolay Krasko
9ad705a60a Remove all allFiles*.out from debugger output 2017-03-23 00:31:42 +03:00
Yan Zhulanow
cba523958e Android Extensions: Support Dialog classes (KT-16957) 2017-03-22 22:03:22 +03:00
Yan Zhulanow
f1e303e18d Minor: Update kapt tests for Kotlin 1.1 2017-03-22 22:03:21 +03:00
Yan Zhulanow
9d8adc1882 Minor: Execute kapt in IDEA tests 2017-03-22 22:03:20 +03:00
Yan Zhulanow
e93bc4c00d Kapt3, minor: Enable parameter name saving in javac ClassReader 2017-03-22 22:03:19 +03:00
Yan Zhulanow
7535778ed4 AllOpen, NoArg: Check for the Gradle plugin in the classpath properly
Path segments in the plugin classpath entries are separated by the system file separator, not by '/'.

This fixes KT-16901
2017-03-22 22:03:19 +03:00
Yan Zhulanow
0379254918 Kapt3: Fix compatibility with IC (KT-16753)
Kapt does not support incremental compilation for stubs so we should delete source stubs before running annotation processing.
2017-03-22 22:03:18 +03:00
Yan Zhulanow
8ac14ab930 Android Extensions: Allow to disable IDE support (KT-12741)
Enable IDE plugin only if it is enabled in the build.gradle file.
2017-03-22 22:03:17 +03:00
Yan Zhulanow
5d4cefcc30 AllOpen: Do not make private members open (KT-16627) 2017-03-22 22:03:00 +03:00
Yan Zhulanow
bb0a46ac17 Kapt3: Ignore inner classes with clashing names (KT-16458)
Ignore classes (and references to such classes in declaration signatures) if one of the containing classes has the same simple name. This is forbidden in Java, thus should not be present in kapt source stubs.
2017-03-22 22:02:30 +03:00
Yan Zhulanow
2afc27a462 Initial implementation of kapt for Maven (KT-14478) 2017-03-22 22:02:29 +03:00
Yan Zhulanow
40fa5fb758 Kapt3: Support 'processors' option in Gradle plugin (KT-8558)
Also warn if kapt3 options are used without the "apply plugin: 'kotlin-kapt'" specified.
2017-03-22 22:02:28 +03:00
Yan Zhulanow
47ab47d6d1 Kapt3: Support 'processors' option in the compiler plugin (KT-8558)
Support specifying qualified names of annotation processors in the kapt3 compiler plugin (feature-parity with javac).
2017-03-22 22:02:27 +03:00
Yan Zhulanow
d30dbf25b5 Kapt1: Allow to use spaces in the collected identifiers (KT-12769) 2017-03-22 22:02:26 +03:00
Yan Zhulanow
948207be30 AllOpen, NoArg: Use the bundled plugins in Maven projects
Use the bundled compiler plugins for Maven projects (as we do for Gradle projects already) because the plugin provided as a dependency in the POM file may have an incompatible version.
2017-03-22 22:02:25 +03:00
Yan Zhulanow
4a2e409948 Kapt3: Support Kotlin sources generation (KT-14070) 2017-03-22 22:02:24 +03:00
Ilya Gorbunov
3088586ac3 Add runnable samples for trimIndent and trimMargin.
#KT-9786 Fixed
2017-03-22 21:54:46 +03:00
Alexander Udalov
579238c3be Remove deprecated declarations from project code, cleanup usages 2017-03-22 20:25:54 +03:00
Alexander Udalov
6a049c9ab5 Fix Java6BuiltInsWithJDKMembersTest
After update of the project to JDK 8, the default JDK at java.home is
now JDK 8. However, this test relied on the fact that the default is JDK
6. Pass the path to the JDK 6 explicitly
2017-03-22 20:24:28 +03:00
Alexander Udalov
e4ae7ca4ce Use type substitution when matching header-impl members
Previously, type substitution, which is critical for matching generic
header/impl members with each other, was only performed when
checkImplementationHasHeaderDeclaration was called for impl class
(areCompatibleClassifiers creates the correct substitutor). This was
done in areCompatibleClassifiers: a substitutor which maps type
parameters of the header class to type parameters of the impl class was
created.

Now we create the same substitutor when
checkImplementationHasHeaderDeclaration is called for an impl member of
an impl class as well, manually.

 #KT-15230 Fixed
2017-03-22 20:19:14 +03:00
Alexander Udalov
4c868be869 Minor, render "header" or "impl" in LazyClassDescriptor.toString
This makes debugging of multi-platform compilation much easier
2017-03-22 20:19:13 +03:00
Alexander Udalov
81774926fa Discriminate header class in resolution from sources in AbstractLazyMemberScope
Similarly to getFirstClassifierDiscriminateHeaders, we select the first
non-header class if possible, otherwise we select just the first class.
This makes sure that a reference will never be resolved to a header
class if the corresponding impl class is present.

Note that overall the issue may not be fixed yet, because there are
other scopes where header classes are not yet discriminated
(LazyImportScope, DeserializedMemberScope). However, at this point I
cannot reproduce this problem with these other scopes

 #KT-15521 Fixed
2017-03-22 20:18:16 +03:00
Alexander Udalov
93e3bdc1ab Improve multi-platform integration test
Compile the platform-specific code two times: once with the common file
first and the platform file second, and once with the platform file
first and the common file second in the compilation arguments. This is
needed because some issues in the compiler are only reproducible in one
of these two scenarios
2017-03-22 20:18:04 +03:00
Alexander Udalov
82c5c586b1 Minor, remove unnecessary test data files 2017-03-22 20:11:02 +03:00
Dmitry Jemerov
3caf7f112a Disable JAnsi in tests
Workaround for https://github.com/fusesource/jansi/issues/66
2017-03-22 16:22:40 +01:00
Mikhail Zarechenskiy
2a93dea0c4 Use concrete candidate to resolve collection literal
This helps to avoid resolution errors when there is local array-like function with the same signature as in built-ins
2017-03-22 17:59:58 +03:00
Mikhail Zarechenskiy
222f101d10 Extract collection literal resolve components to separate Kotlin file 2017-03-22 17:59:58 +03:00
Mikhail Zarechenskiy
8466270bdb Check that arguments of array function call in annotation are constants
#KT-16956 Fixed
2017-03-22 17:59:58 +03:00
Mikhail Zarechenskiy
a2ea518b1a Allow to use collection literals only in annotations 2017-03-22 17:59:58 +03:00
Mikhail Zarechenskiy
bfe2ddf7c1 Introduce language feature for array literals in annotations 2017-03-22 17:59:58 +03:00
Mikhail Zarechenskiy
0f1acab40d Support collection literals in the JVM backend 2017-03-22 17:59:58 +03:00
Mikhail Zarechenskiy
859bccb9fc Propagate resolution results without ambiguity to constant evaluator
This allows to get rid of useless diagnostics that some value is not a constant
2017-03-22 17:59:58 +03:00
Mikhail Zarechenskiy
e49b2811ec Apply constant folding for collection literals to use in annotations
Currently this is achieved with several hacks:
- Postpone computation of argument type info when there is no candidate resolver. We have to do this, because we don't have expected type and therefore we could write wrong information to trace
- Presume that for annotation calls there is only one candidate resolver and then resolve arguments with expected type (see `getArgumentTypeInfo`), otherwise because of quadratic complexity of the algorithm resolve would be slow
2017-03-22 17:59:58 +03:00
Mikhail Zarechenskiy
c85f6e7d0e Resolve collection literal expression as special array-like function 2017-03-22 17:59:58 +03:00
Mikhail Zarechenskiy
d3fd96ceed Parse collection literals as atomic expressions 2017-03-22 17:59:58 +03:00
Dmitry Jemerov
3c7678092e Don't mark compiler-created PSI elements as generated
This saves some memory on storing the generated flag in the PsiElement
userdata and time required to store the flag.
2017-03-22 13:59:21 +01:00
Alexander Udalov
dc3aa26e3f Ignore getMembersOfStandardJavaClasses light analysis test
See #KT-16616
2017-03-22 14:33:57 +03:00
Alexey Sedunov
56d22277b7 Move: Filter out ConflictUsageInfo instances before running the refactoring
#KT-16556 Fixed
2017-03-22 13:36:19 +03:00
Alexey Sedunov
2f136dae1c Move: KT-8955
Fix NPE on moving directory where at least one Kotlin file
contains package directive unmatched by the containing directory

 #KT-8955 Fixed
2017-03-22 13:36:18 +03:00
Alexey Sedunov
d1857d68bc Move: Fix element listener retrieval
Get element listener before original declaration is invalidated by the refactoring
2017-03-22 13:36:17 +03:00
Alexey Sedunov
1a8aa6091a Move: Fix incorrect FqName when moving declaration to default package
#KT-15586 Fixed
2017-03-22 13:36:16 +03:00
Alexey Sedunov
1331922963 Move: Fix file rename of move
Avoid temporary file rename if the current name doesn't conflict
with other files in the target directory.
Improve protection against exceptions during the refactoring
which may prevent final rename
2017-03-22 13:36:15 +03:00
Alexey Sedunov
92fbca452d Move: Do not report conflict on usages of inherited protected members
#KT-15190 Fixed
2017-03-22 13:36:14 +03:00
Alexey Sedunov
e82b256640 Move: Implement conflict checking for internal members
#KT-13190 Fixed
2017-03-22 13:36:13 +03:00
Alexey Sedunov
6f5249ecc7 Move: Fix processing of references to non-real members of companion object
#KT-15559 Fixed
2017-03-22 13:36:12 +03:00
Alexey Sedunov
bab762b761 Implement post-refactoring optimization of unused imports
#KT-15822 Fixed
 #KT-13755 Fixed
2017-03-22 13:36:11 +03:00
Alexey Sedunov
7d185349c8 Move: Fix broken tests
Check that constructor call corresponds to class being moved before
transforming outer instance to argument
2017-03-22 13:36:10 +03:00
Alexey Sedunov
13de9aea81 Move: Fix processing of conflicting usages
Exclude conflict-associated usages from refactoring.
Move search of file internal usages to MoveKotlinDeclarationsProcessor
2017-03-22 13:36:09 +03:00
Alexey Sedunov
a21f19d613 Move: Use Kotlin declaration mover to handle KtFile
IDEA-provided file mover does not process conflicts

 #KT-13911 Fixed
2017-03-22 13:36:08 +03:00
Alexey Sedunov
9a3ace423a Move: Update test data for tests with conflicts
Check refactoring result for the case when conflicts are ignored.
Fix move destination when moving to another source root
2017-03-22 13:36:07 +03:00
Alexey Sedunov
38f9e99d91 Kotlin Facet: Fix argument merging
#KT-16982 Fixed
2017-03-22 13:36:06 +03:00
Alexey Sedunov
7c7e41592a Kotlin Facet: KT-16980
Avoid reinitialization of module-level settings on each run of
the analyzer in the absence of Kotlin facet

 #KT-16980 Fixed
2017-03-22 13:36:05 +03:00
Alexander Udalov
43f1c843ce Minor, fix typo in docs on built-ins 2017-03-22 13:27:38 +03:00
Dmitry Jemerov
93cb12fed0 Don't keep around an empty value parameters list in FunctionDescriptor 2017-03-22 10:40:19 +01:00
Dmitry Jemerov
3aedf2548c Don't create empty list for Call arguments 2017-03-22 10:40:19 +01:00
Dmitry Jemerov
51c7fc9f73 Don't use UserDataHolder in SlicedMapImpl, use KeyFMap directly 2017-03-22 10:37:07 +01:00
Dmitry Jemerov
f45511b983 Don't recreate Name instances for special resolve constructs 2017-03-22 10:35:16 +01:00
Matthew Brener
adc19b433e its --> it's in Char.kt (#1041) 2017-03-22 10:29:39 +01:00
Yan Zhulanow
7a5f94129c Add ClassBuilderMode.KAPT3 tests 2017-03-21 20:49:36 +03:00
Yan Zhulanow
e25e19c4d6 Refactoring: Remove light analysis test data
The light analysis test data is not needed anymore cause the light analysis result is now automatically checked against the one from the full analysis.
2017-03-21 20:49:36 +03:00
Yan Zhulanow
c50881fd02 Refactoring: Extract light analysis tests from box tests 2017-03-21 20:49:34 +03:00
Mikhail Glukhikh
23848fa728 Suggest bound references in "Lambda --> Reference" for 1.1+ only 2017-03-21 20:32:15 +03:00
Ilya Chernikov
0f21db1ecb Copy base script classes to script-runtime before building bootstrap 2017-03-21 16:30:51 +01:00
Ilya Chernikov
08f6b6c93c minor: get rid of the compiler-test dependency in source-sections test 2017-03-21 16:30:50 +01:00
Ilya Chernikov
1eab936618 minor: Bump rubygrapefruit native-platform version to 0.14 2017-03-21 16:30:49 +01:00
Ilya Chernikov
d439c13fb5 minor: correct measurement error in eval bench test 2017-03-21 16:30:48 +01:00
Ilya Chernikov
4043f491da minor: replace Pair with data class in daemon client connectAndLease call
backport from 1.0.7
2017-03-21 16:30:47 +01:00
Ilya Chernikov
4b430b49a7 Implement source sections compiler plugin
allows to compile only parts of the source files, denoted by top-level
"sections" (function with lambda param calls), but preserving original
file line/column numbers for easier diagnostics. Allow e.g. to compile
gradle "buildscript" section without preprocessing original file in
advance. See tests for examples.
2017-03-21 16:30:46 +01:00
Ilya Chernikov
63c276d444 Create extension points and register plugins earlier...
to allow plugins to affect source files creation
2017-03-21 16:30:45 +01:00
Alexander Udalov
7dfa3bea18 Update tools & libraries projects to use JDK 8 when needed 2017-03-21 17:45:53 +03:00
Alexander Udalov
33a0ae0fcd Skip kotlin-maven-plugin integration test if "skipTests" is defined
Similarly to kotlin-maven-plugin-test/pom.xml
2017-03-21 17:45:51 +03:00
Alexander Udalov
4273357adf Skip kotlin-maven-plugin-test tests if "skipTests" property is defined
"mvn -DskipTests ..." or "mvn -DskipTests=true ..." should not invoke
any tests
2017-03-21 17:45:51 +03:00
Sergey Igushkin
132393cc64 Fix for androidTest Gradle build
Replaced adding Kotlin sources with dependency on copy*KotlinClasses,
which might not be called since Android Gradle plugin sometimes
bypasses the tasks in finalizedBy .
Added a test for androidTest build apart from general build.

Issues: #KT-16897 Fixed
2017-03-21 17:30:59 +03:00
Dmitry Jemerov
ba9213234c Increase -Xmx for running Ant from AntTaskTestGenerated
The current value is no longer sufficient when running under JDK 8.
2017-03-21 15:19:55 +01:00
Sergey Igushkin
498c4dddea Fix for compatibility with Android Gradle plugin 2.4.0-alpha1
Deferred resolution of JAR-to-AAR mapping, since the Android Gradle
plugin now resolves dependencies at execution phase.
Dropped the code related to the Jack toolchain compatibility.
Throwing a build error when Jack is enabled.
Changed warning about Jack into a build error.
2017-03-21 16:56:09 +03:00
Simon Ogorodnik
439e158fb2 Fix failing test after migration to IDEA 171
BasicCompletionWeigherTestGenerated$ExpectedInfo.testPreferMatchingThis
Looks like IDEA now rearranges elements with same weight by length and
then alphabetically
2017-03-21 16:47:16 +03:00
Dmitry Jemerov
f0b7891d41 Turn off API usage inspection 2017-03-21 14:44:20 +01:00
Pavel V. Talanov
a03e9d340e Wrap sourceScope() and binaryScope() using sourceFilterScope
To avoid having to wrap at call site
2017-03-21 16:20:02 +03:00
Pavel V. Talanov
06fd1f3c44 Drop unused LibrarySourceHacks 2017-03-21 16:20:02 +03:00
Pavel V. Talanov
dec9fa0324 SourceNavigationHelper: fix navigation to callables
Previously we could differentiate between callables with the same name
    when relevant type declaration were in the same file only
Problem manifested most severely when several copies of sources were attached
    to the same library
2017-03-21 16:20:01 +03:00
Pavel V. Talanov
d9a9d50602 KotlinScriptConfigurationManager#notifyRootsChanges: run synchronously in tests
Allows to unmute some of the ScriptConfigurationNavigation tests
2017-03-21 16:20:00 +03:00
Pavel V. Talanov
88447d69cb Introduce ScriptDependenciesSourceModuleInfo
Implement SourceForBinaryModuleInfo api to support navigation
Support in getModuleInfo and KotlinCacheServiceImpl
2017-03-21 16:19:59 +03:00
Pavel V. Talanov
434018f679 ScriptConfigurationNavigationTest: test navigation to kotlin library 2017-03-21 16:19:59 +03:00
Pavel V. Talanov
115474b90f SourceNavigationHelper: use API to narrow search scope 2017-03-21 16:19:58 +03:00
Pavel V. Talanov
4dee108afe J2K SourceNavigationHelper: convert to Kotlin and prettify 2017-03-21 16:19:57 +03:00
Pavel V. Talanov
aa74ccf163 J2K SourceNavigationHelper: rename file 2017-03-21 16:19:57 +03:00
Pavel V. Talanov
4c94d931fa findDecompiledDeclaration: narrow decompiled declaration search scope
Search scope of library that descriptor originated from
Introduce API that matches binaries and its' sources via IdeaModuleInfos
2017-03-21 16:19:56 +03:00
Pavel V. Talanov
569e7ac593 getModuleInfo, minor: clarify parameter parameter 2017-03-21 16:19:55 +03:00
Pavel V. Talanov
c7f147d058 Introduce NavigationWithMultipleLibrariesTest
Test navigation to library decompiled and source declaration when
there are multiple copies of the same library in project
Related to ba1ee99e97
2017-03-21 16:19:54 +03:00
Pavel V. Talanov
47e77201d5 AbstractNavigateToLibraryTest: refactor, extract utility code 2017-03-21 16:19:54 +03:00
Alexander Udalov
2d1b15b6fb Drop usages of '-XX:MaxPermSize' in run configurations on JDK 8 2017-03-21 16:09:18 +03:00
Dmitry Jemerov
04b64fa30c Sort Kotlin versions loaded from Maven by number
Otherwise we get 1.0.7 on top of 1.1.1, which is suboptimal
2017-03-21 14:03:25 +01:00
Dmitry Jemerov
8f8db75bb4 getNonConfiguredModules(project, configurator) excludes modules already configured with other configurators
#KT-16381 Fixed
2017-03-21 14:02:05 +01:00
Dmitry Jemerov
95bc0813f8 Don't show "Configure Kotlin" notification with an empty list of configurators (context: KT-16070) 2017-03-21 14:02:05 +01:00
Dmitry Jemerov
9f8af1feea Refactor getNonConfiguredModules(Project)
Rename to getNonConfiguredModulesWithKotlinFiles() to match what it
actually does, remove duplicate configurator status check, extract code
for collecting all configurators
2017-03-21 14:02:05 +01:00
Dmitry Jemerov
b86fe60a24 Don't report "can be configured" status if the file is already configured with another Gradle configurator 2017-03-21 14:02:05 +01:00
Dmitry Jemerov
1f96ead801 "Configure Kotlin in project" handles modules from Gradle source roots
THose modules are now always collapsed to their base modules.
 #KT-11828 Fixed
2017-03-21 14:02:05 +01:00
Dmitry Jemerov
b1a65e4c74 Don't show pre-1.1.0 version of Kotlin in version chooser when configuring JS projects
#KT-16400 Fixed
2017-03-21 14:02:05 +01:00
Dmitry Jemerov
8e26d5257f Don't add stdlib-jre7 or stdlib-jre8 dependencies when configuring Kotlin with pre-1.1 version
#KT-16401 Fixed
2017-03-21 14:02:05 +01:00
Dmitry Jemerov
cd4636a1e5 Add current version to "Configure Kotlin in project" version chooser if it is a release version and it wasn't found in the search results
#KT-16571 Fixed
2017-03-21 14:01:37 +01:00
Dmitry Jemerov
0f21595e4b Don't show "Configure Kotlin" if module is configured, project is not
Report CAN_BE_CONFIGURED from Gradle configurator only if we didn't
find any file containing valid configuration (normally the top-level
project file in an Android project doesn't have any Kotlin
configuration, so we report CAN_BE_CONFIGURED even though the module
file contains valid configuration)
2017-03-21 14:01:37 +01:00
Dmitry Jemerov
b48b3b3237 Show "Configure Kotlin" notification at most once after project opening
Don't show notification after every sync; trigger it from
rootsChanged handler because the root model is not yet updated at
syncDone point
 #KT-16590 Fixed
2017-03-21 14:01:37 +01:00
Dmitry Jemerov
0a586291b6 Check jar name before trying to load JS library version
#KT-16596 Fixed
2017-03-21 14:01:37 +01:00
Dmitry Jemerov
09b60e3f77 JsLibraryStdDetectionUtil: J2K 2017-03-21 14:01:37 +01:00
Dmitry Jemerov
dffff77a5d JsLibraryStdDetectionUtil: rename to .kt 2017-03-21 14:01:37 +01:00
Dmitry Jemerov
ad3be8f8b5 Add test for checking JS runtime version 2017-03-21 14:01:37 +01:00
Dmitry Jemerov
1c0acee989 Remove obsolete code for removing obsolete JS library 2017-03-21 14:01:37 +01:00
shiraji
27e1462b00 Apply quick-fix "Make visible" for INVISIBLE_FAKE #KT-16131 Fixed 2017-03-21 13:50:49 +03:00
Alexander Udalov
d4500878cb Do not strip some classes from xercesImpl.jar in compiler.pro
Note that with this config, the kotlin-compiler.jar's size is increased
by 1.5Mb

 #KT-16968 Fixed
2017-03-21 13:03:19 +03:00
Alexander Udalov
af5fbef4ea Use JDK 1.6 to compile modules under "core"
Outputs of these modules go into kotlin-stdlib and kotlin-reflect, both
of which must be usable on Java 6
2017-03-21 13:03:18 +03:00
Dmitry Jemerov
d80891e823 Add xercesImpl.jar to core classpath as it's now required for JDOMUtil 2017-03-20 18:46:13 +01:00
Alexey Sedunov
2e3617adbb Spring Support: Fix tests in IDEA 2017.1
Filter out duplicate reference targets.
Fix test data as directory references are available
inside of string literals.
Fix test data as Spring @Autowired inspection
no more reports parameterless methods.
Fix gutter checking as configuration bean references now resolve
to @ComponentScan annotation
2017-03-20 18:46:12 +01:00
Simon Ogorodnik
2804264289 Fix regression of completion inside string templates
CompletionContributor should not store offsets inside
replacement zone(part of file which are replaced with
dummy identifier) in offsetMap
 #KT-16848 fixed
2017-03-20 18:46:11 +01:00
Dmitry Jemerov
cf18c2243f Fix test: check highlighting only in one direction
Otherwise, when we check the highlighting on one of the files, the text
of the other still contains the <lineMarker> annotation and can't be
indexed as valid Kotlin code.
2017-03-20 18:46:10 +01:00
Alexander Udalov
555b3f12ee Use LinkedHashSet instead of HashSet in DataFlowInfo.getCollectedTypes
This fixes DiagnosticsTestGenerated$Tests.testImplicitIntersection,
which began to fail after update to JDK 8 because the iteration order of
HashMap/HashSet has changed in JDK 8:
http://openjdk.java.net/jeps/180
http://hg.openjdk.java.net/jdk8/jdk8/jdk/rev/43bd5ee0205e
2017-03-20 18:46:09 +01:00
Mikhael Bogdanov
211b58ac6e kt1770.kt test rewrote during migration to 171 platform 2017-03-20 18:46:08 +01:00
Dmitry Jemerov
10aedaf0f4 Adjust test data for IDEA 2017.1
Since https://github.com/JetBrains/intellij-community/commit/9c8003c
deprecated methods are considered to be entry points, so the Safe
Delete quickfix is no longer available for them.
2017-03-20 18:46:08 +01:00
Alexander Udalov
999e1061b8 Update test data for ant task tests
Looks like javac 1.8 started to report compilation errors a bit
differently here
2017-03-20 18:46:07 +01:00
Alexander Udalov
449d1f6ad2 Fix KotlinVersionsTest, use SAX parser instead of DOM 2017-03-20 18:46:06 +01:00
Alexander Udalov
33e9e660c4 Fix JvmRuntimeDescriptorLoaderTestGenerated
- Use FULL_JDK instead of mock JDK in some tests because mock JDK is
  created from JDK 6 and full JDK is now JDK 8, so there are differences
  in the behavior in the compiler and at runtime
- Remove some '*.runtime.txt' files which were workarounds to JDK 6
  reflection issues regarding generic inner classes; code in these tests
  is now loaded exactly the same in the compiler and at runtime
- Change supertype in SupertypesAndBounds.kt: the class in the supertype
  is not relevant to that test, it checks that annotations can be loaded
  on types
2017-03-20 18:46:05 +01:00
Alexander Udalov
3c96099f7c Fix compileJavaAgainstKotlin tests
- Use another API to get file name out of a javac diagnostic
  (.getSource().getName()'s behavior changed in JDK 8)
- Delete .txt files for those tests which check that javac reported a
  compilation error; the order and content of declarations in those
  files is undefined
2017-03-20 18:46:05 +01:00
Nikolay Krasko
4edfd0d960 Move getting source position to manager thread in tests
Real usages are performed in this thread too. Using AWT now fails
under runInReadActionWithWriteActionPriorityWithRetries added in
b0e995b41e
2017-03-20 18:46:04 +01:00
Alexey Sedunov
ecd56c6a40 Safe Delete: Fix tests in IDEA 2017.1
Now Java refactoring checks for side effects when deleting
arguments, so instantiation of Kotlin FunctionN is treated as
"unsafe"
2017-03-20 18:46:03 +01:00
Alexey Sedunov
b65460c12f Move: Fix tests in IDEA 2017.1
Do not prevent usages search if target directory is not known yet.
Force content root configuration for multi-module tests
2017-03-20 18:46:02 +01:00
Mikhael Bogdanov
496a21254b Black box update 2017-03-20 18:46:01 +01:00
Alexey Tsvetkov
40574d31ac JPS tests: avoid using deprecated API 2017-03-20 18:46:00 +01:00
Dmitry Jemerov
3a8cf68541 Keep class file version during shrinking; generate Java 8 bytecode
sometimes
2017-03-20 18:45:59 +01:00
Dmitry Jemerov
4cae0538a8 Don't warn about ElementTraversal
IDEA now (since commit 6ff87c6) uses this class to build classpath
for Xerces, and we don't use Xerces
2017-03-20 18:45:59 +01:00
Dmitry Jemerov
0638106bf3 Fix NPE in tests when ProjectFileIndex is not available 2017-03-20 18:45:51 +01:00
Dmitry Jemerov
0d86bdd216 Remove Java 6/7 warning from expected output of the compiler 2017-03-20 18:45:51 +01:00
Dmitry Jemerov
2adacf74ac Reduce -Xmx of "All Non-Compiler Tests" configuration
This should prevent VM crashes on TeamCity
2017-03-20 18:45:50 +01:00
Dmitry Jemerov
a8bd529871 Register MetaLanguage.EP_NAME in J2K test 2017-03-20 18:45:49 +01:00
Dmitry Jemerov
61f157e89d Remove write action around finishLookup(), according to IJ 2017.1 req 2017-03-20 18:45:48 +01:00
Dmitry Jemerov
b9f326bfa1 Register MetaLanguage extension point in ParsingTestCase 2017-03-20 18:45:47 +01:00
Dmitry Jemerov
097ba45783 Fix service and EP registration according to changes in 2017.1
Remove ControlFlowFactory (which is now registered in the platform),
register MetaLanguage (new in 2017.1)
2017-03-20 18:45:46 +01:00
Dmitry Jemerov
a539939388 Fix testdata according to contract inference changes in 2017.1 2017-03-20 18:45:46 +01:00
Dmitry Jemerov
ad821e83bd Fix testdata according to comment selection changes in 2017.1 2017-03-20 18:45:45 +01:00
Dmitry Jemerov
d6709b726e Fix testdata according to changes in automatic renaming rules in 17.1 2017-03-20 18:45:44 +01:00
Dmitry Jemerov
374cf517e1 Don't try to create "add modifier" fix for read-only elements
This fixes a failure of KotlinCleanupInspectionTest on IDEA 17.1.
2017-03-20 18:45:43 +01:00
Dmitry Jemerov
3d98237304 Fix GradleFacetImportTest: run write action only in EDT 2017-03-20 18:45:43 +01:00
Dmitry Jemerov
49a4625368 Fix testdata: Android projects use kotlin-stdlib-jre7 2017-03-20 18:45:42 +01:00
Dmitry Jemerov
12fc89f35d Update to 171.SNAPSHOT to pick up fix for IDEA-169570; fix compilation 2017-03-20 18:45:41 +01:00
Nikolay Krasko
1d29c81346 ! (TODO) Update build test data in 171 2017-03-20 18:45:40 +01:00
Nikolay Krasko
7da424d53f Port setInPerformanceTest -> setInStressTest 2017-03-20 18:45:39 +01:00
Nikolay Krasko
e57b3651c2 Replace removed method in LibraryPresentationProviders 2017-03-20 18:45:39 +01:00
Nikolay Krasko
615f9d3a1f Try to avoid exception in getOffset() call 2017-03-20 18:45:38 +01:00
Nikolay Krasko
eb8415a1f3 Use new api from idea 171 in KotlinStepOverInlinedLinesHint 2017-03-20 18:45:37 +01:00
Nikolay Krasko
bcf29e6fbf Run tests in read action and not in EDT thread
Otherwise test will fail because of runInReadActionWithWriteActionPriority call in EDT
2017-03-20 18:45:36 +01:00
Nikolay Krasko
82a2a705fb Do not wrap analyze into write action priority in tests
In tests the code is executed in EDT and runInReadActionWithWriteActionPriority fails

See: MergingUpdateQueue.setPassThrough() and ExternalToolPassFactory() constructor
2017-03-20 18:45:36 +01:00
Nikolay Krasko
95061885b0 Update after separating JPS builders into two modules 2017-03-20 18:45:35 +01:00
Nikolay Krasko
3e6f57b684 Updated nullability in RunLineMarkerContributor 2017-03-20 18:45:34 +01:00
Nikolay Krasko
4f079d2768 LightQuickFixTestCase.parseActionHint() method was removed 2017-03-20 18:45:33 +01:00
Nikolay Krasko
d5aac7df25 Copy dropped method nameToCompare() to test utils 2017-03-20 18:45:33 +01:00
Nikolay Krasko
9f51b12193 Update guava 19.0 sources jar 2017-03-20 18:45:32 +01:00
Nikolay Krasko
ed9e083008 Remove unused import 2017-03-20 18:45:31 +01:00
Mikhail Glukhikh
e6cefba98b Fix imports vs 2016.3 (ResourceFoldingBuilder) 2017-03-20 18:45:30 +01:00
Mikhail Glukhikh
83a8b041ad Fix ConfigureProjectTestGenerated / GradleConfigureProject ... for branch 163 (jre7->jre8) 2017-03-20 18:45:29 +01:00
Nikolay Krasko
2eb6c393a4 Move android modules to Java 8 SDK 2017-03-20 18:45:29 +01:00
Dmitry Jemerov
715410a9bc Workaround for hanging test 2017-03-20 18:45:28 +01:00
Dmitry Jemerov
60a2151a33 Fix compilation
(cherry picked from commit 46b9041)
2017-03-20 18:45:27 +01:00
Yan Zhulanow
0995f2700e doMoveFile() now accepts not-null PsiDirectory
(cherry picked from commit 8a16c90)
2017-03-20 18:45:26 +01:00
Yan Zhulanow
59055e28ee CreateFileResourceQuickFix now accepts ResourceFolderType instead of ResourceType
(cherry picked from commit 55f350f)
2017-03-20 18:45:26 +01:00
Ilya Chernikov
4be5fcc14a Fix test code after UsefulTestCase api changes 2017-03-20 18:45:25 +01:00
Vyacheslav Gerasimov
180ae070ee Fixed KotlinAndroidResourceQuickFixProvider for AS 2.2 2017-03-20 18:45:24 +01:00
Dmitry Jemerov
594e2b6a77 fix compilation 2017-03-20 18:45:23 +01:00
Dmitry Jemerov
ab5067a0d3 remove write action around closeAndDeleteProject() 2017-03-20 18:45:23 +01:00
Dmitry Jemerov
b10073465c fix compilation of new lint checks against IDEA 163 2017-03-20 18:45:22 +01:00
Alexey Tsvetkov
05f278ce20 JPS: implement tracking of null annotations
#KT-12933 fixed
    #KT-14266 fixed
2017-03-20 18:45:21 +01:00
Alexey Tsvetkov
6d958eb32b Fix dist by ignoring some library classes during compiler shrinking 2017-03-20 18:45:20 +01:00
Dmitry Jemerov
b101550cae Advance idea.plugins.compatible.build 2017-03-20 18:45:19 +01:00
Dmitry Jemerov
e51018406f register PsiElementFinder extensions before JavaPsiFacade is registered 2017-03-20 18:45:18 +01:00
Dmitry Jemerov
036bfed984 Add resources_en.jar to properties plugin classpath 2017-03-20 18:45:18 +01:00
Konstantin Bulenkov
fcdd5e0a19 update Kotlin icons according to new IntelliJ style 2017-03-20 18:45:17 +01:00
Dmitry Jemerov
aced2e7eb4 Update compatible build number range 2017-03-20 18:45:16 +01:00
Dmitry Jemerov
a2b0b3d6eb fix compilation against branch 163 2017-03-20 18:45:15 +01:00
Yan Zhulanow
24c9b6e171 Migrate IDEA plugin code to Android Studio 2.2 (br 145) 2017-03-20 18:45:15 +01:00
Dmitry Jemerov
99af2a809b Update IDEA to 171.2613.7 2017-03-20 18:45:14 +01:00
Dmitry Jemerov
4d10b18fe1 Fix for 171 platform 2017-03-20 18:44:14 +01:00
Ilya Gorbunov
87c055cc61 Fix progression iterators to respect the Iterator contract.
#KT-16923 Fixed
2017-03-20 20:13:54 +03:00
Ilya Gorbunov
e5a28311bc Fix infinite sequence being terminated prematurely when being iterated without calling hasNext
#KT-16922 Fixed
2017-03-20 20:13:54 +03:00
Valentin Kipyatkov
f00ab135d6 Do not insert redundant space 2017-03-20 19:08:03 +03:00
Valentin Kipyatkov
3ec28f1242 Attempt to preserve partial substitution when detecting expected type for smart completion 2017-03-20 19:08:03 +03:00
Valentin Kipyatkov
b5dd2cc540 Completion of lambda parameters
Also changed policy for sorting of smart completion items in basic completion

 #KT-16800 Fixed
 #KT-12002 Fixed
2017-03-20 19:08:02 +03:00
Nikolay Krasko
c6b9aebfcf Minor: remove warning 2017-03-20 17:49:23 +03:00
Nikolay Krasko
afc0892d1f Synchronize state of parser and lexer for LONG_TEMPLATE_ENTRY (KT-14865)
Lexer monitors "long string template" state end and will produce
LONG_TEMPLATE_ENTRY_END token when it is reached. If parser continues
without waiting for it, it will eventually get handling token that
will produce irrelevant error. Such behaviour also breaks lazy
elements (LAMBDA_EXPRESSION in this case) contract: range of parsed text
in eager mode should be same to one parsed in lazy mode.

 #KT-14865 Fixed
2017-03-20 17:47:29 +03:00
Alexander Udalov
87ff70ee0f Replace JS metadata version with '$ABI_VERSION$' in tests
Similarly to the JVM metadata version, this is done in order to avoid
changing any test data when the version is increased
2017-03-20 17:22:29 +03:00
Alexander Udalov
e6f6b0dad5 JS: merge LibrarySourcesConfig into JsConfig 2017-03-20 17:22:29 +03:00
Alexander Udalov
bf90cb5cc0 JS: support -Xskip-metadata-version-check for incompatible ABI libraries
Allow the compiler to read such libraries without any errors, at the
risk of crashing with an exception.

Also fix a minor bug in the diagnostic message in LibrarySourcesConfig
and in the corresponding test in KotlinJpsBuildTest
2017-03-20 17:22:29 +03:00
Alexander Udalov
30dfd5cc1b JS: support '-Xskip-metadata-version-check' to allow pre-release libraries 2017-03-20 17:22:29 +03:00
Alexey Sedunov
a795a256f4 Configuration: Fix behavior of "output directory" control
Do not show file chooser twice.
Disable/enable control on component initialization and change of
"Use project settings" option

 #KT-16952 Fixed
 #KT-16953 Fixed
2017-03-20 17:19:13 +03:00
Simon Ogorodnik
f56af41d1e Fix TypeAliasConstructorDescriptor's to create only once when required
Some IDE features relates onto that same descriptors will remain same
between resolve calls
Fix it to be true for TypeAliasConstructorDescriptor's

 #KT-16265 fixed
2017-03-20 16:55:40 +03:00
Sergey Mashkov
23cbb83c75 IDL2K: drop garbage code, refactor to improve readability 2017-03-20 16:51:32 +03:00
Mikhail Zarechenskiy
1a4b9cb228 Show warning for mod from built-ins since API=1.1 2017-03-20 00:45:18 +03:00
Mikhail Zarechenskiy
e4188f889e Do not show warning for mod from built-ins when LV=1.0
#KT-16372 Fixed
2017-03-20 00:41:58 +03:00
Alexey Sedunov
071744a57f Extract Superclass/Interface: show inapplicability error before choosing the extraction container
#KT-15339 Fixed
2017-03-19 17:20:32 +03:00
Alexey Sedunov
eb9c775476 Navigation: Support NEW_AS_CONSTRUCTOR flag for constructor calls
#KT-15398 Fixed
 #KT-15536 Fixed
2017-03-19 17:20:24 +03:00
Alexey Sedunov
5e8cd654ec Find Usages: Fix processing of label references in 'return' expressions
#KT-7516 Fixed
2017-03-19 17:20:17 +03:00
Alexey Sedunov
275cdbbea7 Rename: Fix renaming of function by label reference inside of lambda argument
#KT-7520 Fixed
2017-03-19 17:20:10 +03:00
Alexey Sedunov
b1df91395a Minor: Use handler autodetection in some rename tests 2017-03-19 17:20:02 +03:00
Alexey Sedunov
871d42f05a Rename: Support renaming class by short reference to companion object
#KT-16108 Fixed
2017-03-19 17:19:55 +03:00
Alexey Sedunov
834cdd63ab Create from Usage: Support class generation by class literal expression
#KT-16188 Fixed
2017-03-19 17:19:48 +03:00
Alexey Sedunov
505a6bcbf2 JPS: Copy project-level settings before use
Sharing these settings for reading/writing
between different module during JPS build
may lead to compiler settings
(plugionOptions, in particular) of several
modules to be mixed

 #KT-16888 Fixed
2017-03-19 17:19:40 +03:00
Alexey Sedunov
2e1b4cd692 Misc: Fix test 2017-03-19 17:19:33 +03:00
Alexey Sedunov
2bb7bdfc3f Kotlin Facet: Fix reading of v1 configuration
Favor language/api version specified in <versionInfo> element
in case it differs from the one in
<option name="_commonCompilerArguments">

#KT-16861 Fixed
2017-03-19 17:19:26 +03:00
Alexey Sedunov
ca46100581 Kotlin Facet: Add tab for compiler plugin options
#KT-15768 Fixed
2017-03-19 17:19:18 +03:00
Alexey Sedunov
c264a2e15f Configuration: Improve presentation of the settings override warning 2017-03-17 21:08:44 +03:00
Alexey Sedunov
7c1249746f Kotlin Facet: Show scripting section only if target platform is JVM
#KT-16316 Fixed
2017-03-17 21:03:29 +03:00
Alexey Sedunov
f63828ff20 Configuration: Make UI improvements
Fix layout
Fix label names
Replace "Generate no warnings" checkbox with "Report compiler warnings"
2017-03-17 21:03:22 +03:00
Nikolay Krasko
f38753ee3c Remove explicit AppScheduledExecutorService shutdown (commit revert)
Revert "Problem: manually shutdown AppScheduledExecutorService to allow compiler stop properly"

The commit was added during update to 162.1024.1 to fix hangs in ant
tasks on teamcity because of some thread created in
AppScheduledExecutorService service.

Remove the commit because can't reproduce those hangs under 162.2946
(Probably 12a079ef41 fixed the hangs).

This should also be addressed in fix for https://youtrack.jetbrains.com/issue/IDEA-169562

This reverts commit 99a75021e1.
2017-03-17 18:02:11 +03:00
Nikolay Krasko
a63953432e Set "weak warning" severity for SameParameterValue inspection 2017-03-17 17:27:54 +03:00
Nikolay Krasko
52789df812 Minor: fix warnings in AbstractKotlinParsing.java 2017-03-17 17:27:53 +03:00
Sergey Mashkov
49c2f40f7d KT-16572 Add links to Mozilla Developer Network to kdocs of classes that we generate from IDL
regenerate
2017-03-17 13:04:34 +03:00
Sergey Mashkov
8842b6894e KT-16572 Add links to Mozilla Developer Network to kdocs of classes that we generate from IDL 2017-03-17 13:04:34 +03:00
Sergey Mashkov
02721a0b7f KT-16252 IDL2K: Add ItemArrayLike interface implementation to collection-like classes
regenerate
2017-03-17 13:04:33 +03:00
Sergey Mashkov
496795dd56 IDL2K eliminate attribute modality change caused by inheritance
always override attributes in class if it is inherited from an interface
2017-03-17 13:04:33 +03:00
Sergey Mashkov
a5d6541f1e KT-16252 IDL2K: Add ItemArrayLike interface implementation to collection-like classes 2017-03-17 13:04:32 +03:00
Vyacheslav Gerasimov
a795313c7d Add inspection for usages of Kotlin internal declarations in Java
#KT-11393 Fixed
2017-03-16 21:12:05 +03:00
Alexander Udalov
bd53922c64 Minor, don't shade com.sampullara in compiler-embeddable
See 73b879e
2017-03-16 15:40:06 +03:00
Alexander Udalov
332a0f5adc Use 'languageVersionSettings' extension instead of key directly
Also fix compilation of kotlin-script-util
2017-03-16 14:18:01 +03:00
Alexey Sedunov
0e4c3ec202 Kotlin Facet: Do not present imported -d/-cp in "Additional arguments" 2017-03-16 03:14:41 +03:00
Alexey Sedunov
88a394e892 Kotlin Facet: Validate "additional arguments"
Validate consistency of "additional arguments" with respect to settings specified in other UI controls
2017-03-16 03:14:40 +03:00
Alexey Sedunov
fa06965ed6 Kotlin Facet: Add import test for Maven project with submodule 2017-03-16 03:14:39 +03:00
Alexey Sedunov
cf9d7a0470 Kotlin Facet: Detect platform by stdlib dependency in android-gradle projects
#KT-16827 Fixed
2017-03-16 03:14:38 +03:00
Alexey Sedunov
040f5f88f2 Configuration: Show warning in project settings if they'are overridden in some modules(s) 2017-03-16 03:14:37 +03:00
Alexey Sedunov
5dc5ca551f Configuration: Make UI improvements
Use JTextField for output file prefix/postfix.
Use TextFieldWithBrowseButton for output directory
Improve layout
2017-03-16 03:14:36 +03:00
Alexey Sedunov
ee36abd73a Kotlin Facet: Drop obsolete facet detection infrastructure 2017-03-16 03:14:35 +03:00
Alexey Sedunov
5c55b9fbbe Configuration: Check that project-level common arguments are not changed through platform-specific holders 2017-03-16 03:14:34 +03:00
Alexey Sedunov
ce434585e3 J2K: Convert BaseKotlinCompilerSettings and its inheritors 2017-03-16 03:14:32 +03:00
Alexey Sedunov
f8e5065845 J2K: Convert BaseKotlinCompilerSettings and its inheritors (rename to .kt) 2017-03-16 03:14:31 +03:00
Pavel V. Talanov
f1c0d5316f Refactor delegate members to light members conversion 2017-03-15 20:55:42 +03:00
Pavel V. Talanov
eedcc19209 J2K KtLightClassBase: rename file 2017-03-15 20:55:41 +03:00
Pavel V. Talanov
04591bb938 LightClassDataHolder: refactor, extract subinterfaces 2017-03-15 20:55:40 +03:00
Pavel V. Talanov
6d595e30c2 ClassFileFactory, minor: make done() public and use in LightClassDataProvider 2017-03-15 20:55:40 +03:00
Pavel V. Talanov
d62db8dc6b LightClassGenerationSupport: refactor, minor
Use typealias where appropriate
Less verbose method names
2017-03-15 20:55:39 +03:00
Pavel V. Talanov
a645dc109a KotlinLightClassBuilderFactory, LightClassBuilder: refactor, clarify 2017-03-15 20:55:38 +03:00
Pavel V. Talanov
c73e58516b Refactor LightClassDataProvider: drop LightClassDataProvider class
Move code to inheritors
Improve api to avoid getting empty file lists in random places
2017-03-15 20:55:37 +03:00
Pavel V. Talanov
ab0d939626 searchHelpers: remove hack relying on light classes triggering resolve 2017-03-15 20:55:08 +03:00
Pavel V. Talanov
feae5079ed Light classes: refactor, introduce lazyPub util to reduce verbosity 2017-03-15 20:55:07 +03:00
Pavel V. Talanov
ba185d7616 LightClassDataProvider: refactor, extract class filters to separate classes 2017-03-15 20:55:05 +03:00
Pavel V. Talanov
48cae0e480 KtLightField/Method: Use equality in equivalence checks
Avoid computing delegate to determine equivalence
2017-03-15 20:55:03 +03:00
Pavel V. Talanov
8054020f61 IDELightClassContexts: @PublishedApi affects codegen 2017-03-15 20:55:02 +03:00
Pavel V. Talanov
d846d05527 PsiElementChecker: minor
Check own members before inners' since it triggers the computation of outer stub
2017-03-15 20:55:01 +03:00
Pavel V. Talanov
d34b73befb Light class codegen: all objects are considered static
Simplify code handling access flag computation
Fix a problem where kotlin nested object wasn't producing a nested light class
2017-03-15 20:55:01 +03:00
Pavel V. Talanov
d94da5af40 Frontend: create component functions for properties with error types
Fixes an inconsistency in light classes where we could have different
  class structure depending on whether the type was resolved
2017-03-15 20:55:00 +03:00
Pavel V. Talanov
fa58f1b4d7 KtLightMethod(Field): use dummyDelegate to determine modifier properties 2017-03-15 20:54:59 +03:00
Pavel V. Talanov
abf206a134 KtLightMethod(Field): do not use clsDelegate in hashCode && equality checks 2017-03-15 20:54:58 +03:00
Pavel V. Talanov
fee29c47c8 KtLightMethod: use dummy delegate to compute parameter count and isContructor 2017-03-15 20:54:56 +03:00
Pavel V. Talanov
3e7357a5d7 IDELightClassTest: provide tools to check laziness of light class construction
StubComputationTracker knows which context was used to construct light class
2017-03-15 20:54:55 +03:00
Pavel V. Talanov
daef8a0eed Light classes in IDE: Make light class delegate construction a two step process
Step 0: Light class object is created, no delegates are computed
Step 1: constructs dummy delegate which can not be relied upon to know signature of any member
		It can be used to construct light field and light method objects
		(which can correctly respond to some queries) before constructing real delegate
Step 2:
		Construct real delegate if dummy delegate is not enough to respond to a query

This speeds up multiple scenarios where getMethods() and getFields() are called on numerous classes

Dummy delegate's faster consruction is achieved by using specially setup dumb analysis instead of ide analysis

Introduce LazyLightClassDataHolder: which manages creation of Step 1 and Step 2 delegates
Introduce MemberIndex: keeping track of member creation order, helps matching light class delegates created in different contexts
KtLightMethod and Field: make use of dummy delegate
KtLightMethod no longer extends LightMethod since it requires eager delegate construction
KtLightMethod now implements PsiAnnotationMethod for convenience (ClsMethodImpl implements PsiAnnotationMethod)
2017-03-15 20:54:55 +03:00
Pavel V. Talanov
ed9e94c632 KtLightModifierListWithExplicitModifiers: fix equals 2017-03-15 20:53:59 +03:00
Pavel V. Talanov
d01aaeb65c Refactor light classes: Delegate LightClassDataHolder construction to LightClassGenerationSupport 2017-03-15 20:53:58 +03:00
Pavel V. Talanov
00e84fb483 Light classes: Refactor construction
Introduce LightClassDataHolder: which now is reponsible for constructing clsDelegate
Move out light big chunk of delegate building logic out of LightClassDataProvider into LightClassBuilder
LightClassData only holds information about single class
2017-03-15 20:53:37 +03:00
Pavel V. Talanov
22fb9ec5e1 Refactor light classes: move light members creation to their respective classes 2017-03-15 20:52:51 +03:00
Pavel V. Talanov
15b063d236 J2K LightClassGenerationSupport: rename file 2017-03-15 20:52:50 +03:00
Pavel V. Talanov
dd2d9c1dc2 J2K LightClassGenerationSupport: convert code 2017-03-15 20:52:49 +03:00
Pavel V. Talanov
71161e218b Refactor LightClassData: remove redundant entities 2017-03-15 20:52:48 +03:00
Pavel V. Talanov
0a0e628068 Refactor: move code to new package 2017-03-15 20:52:26 +03:00
Pavel V. Talanov
ac368ac182 Light classes test: test methods & fields with same name 2017-03-15 20:52:25 +03:00
Pavel V. Talanov
955fe9e1e6 Light class tests: add tests
- test Jvm* annotations with wrong arguments
  - test JvmStatic annotation
  - test JvmName annotation
2017-03-15 20:52:24 +03:00
Pavel V. Talanov
dbcd141a46 Extract superclass from AnnotationResolver 2017-03-15 20:52:24 +03:00
Pavel V. Talanov
8794005234 JvmPlatform#getDefaultImports: avoid recomputing JvmBuiltins
We need to use LockBasedStorageManager() (instead of NO_LOCKS) since getDefaultImports()
    can be called concurrently in certain scenarios
2017-03-15 20:52:23 +03:00
Pavel V. Talanov
bbe3b3cabe WrappedType: introduce WrappedTypeFactory to encapsulate wrapped types creation 2017-03-15 20:52:22 +03:00
Pavel V. Talanov
85420d1ffd MemberCodegen: Do not try to write inner class metadata for inner class 2017-03-15 20:51:22 +03:00
Pavel V. Talanov
1441aea2ea Light classes: allow light classes for inner/nested classes to be build separately
Avoid analyzing/generating bytecode for outers
2017-03-15 20:51:22 +03:00
Pavel V. Talanov
6924ddeace Clarify logic in KotlinTypeMapper.mapType() dealing with enum entries
This allows to write correct class signatures for enum entries
    regardless of whether ASM_TYPE slice was written to
2017-03-15 20:51:20 +03:00
Pavel V. Talanov
6f6a595fef Refactor FileScopeFactory 2017-03-15 20:51:19 +03:00
Pavel V. Talanov
d7c1993194 FileScopeFactory: postpone default import resolver construction 2017-03-15 20:51:18 +03:00
Pavel V. Talanov
babb3b557d J2K ImportPath: kotlinify 2017-03-15 20:51:17 +03:00
Pavel V. Talanov
50d0f5bde6 J2K ImportPath: autoconvert 2017-03-15 20:50:12 +03:00
Pavel V. Talanov
91e8d9e211 J2K ImportPath: rename file 2017-03-15 20:49:22 +03:00
Simon Ogorodnik
e7753c31db Minor: Add Dokka format param to build-docs script
To have an ability to change it in TeamCity between custom builds
2017-03-15 19:43:14 +03:00
Simon Ogorodnik
38047240d3 Fix documentation for stdlib
Add forgotten files to file list used by
Dokka when generating documentation
2017-03-15 18:26:52 +03:00
Simon Ogorodnik
5c4ba53f42 Optimization of Basic Code Completion
Now we first search for simple reference variants, then for extensions
 Because extension search is slow
 #KT-16856
2017-03-15 17:50:29 +03:00
Simon Ogorodnik
4906ddfc29 Optimization of Basic Code Completion
Now we don't perform code formatting on temporary psi used
  in ShadowedDeclarationFilter
  #KT-16856
2017-03-15 17:50:20 +03:00
Mikhail Glukhikh
bbab0f11ca Cleanup: fix some "leaking this" warnings 2017-03-15 17:36:08 +03:00
Mikhail Glukhikh
045a23ae10 Cleanup: apply "Convert lambda to reference" 2017-03-15 17:36:02 +03:00
Mikhail Glukhikh
b121bf8802 Cleanup: fix some compiler warnings (mostly deprecations, javaClass) 2017-03-15 17:35:31 +03:00
Mikhail Glukhikh
d0cc1635db Cleanup: apply "Use synthetic property access syntax" 2017-03-15 16:13:40 +03:00
Mikhail Glukhikh
1375267996 Cleanup: apply redundant curly braces in string template inspection 2017-03-15 16:13:22 +03:00
Mikhail Glukhikh
e37800d056 Cleanup: apply redundant string template inspection 2017-03-15 16:12:59 +03:00
Igor Chevdar
10ea2883f7 Supported KProperty2 and KMutableProperty2 for delegated properties
Consider this code:
object Delegate {
    operator fun getValue(t: Any?, p: KProperty<*>): String {
        return ""
    }
}

class A {
    val String.ext by Delegate
}

then the type of <p> is KProperty2 (it has 2 receivers).

Test fix + review fixes
2017-03-15 12:20:57 +03:00
Alexander Udalov
d58d75c6ef Refactor "do not check impl" flag for multi-platform projects
Instead of LanguageFeature, make it an AnalysisFlag, which is more clear
2017-03-15 11:03:05 +03:00
Alexander Udalov
56201a6dc4 Refactor skipMetadataVersionCheck flag
To make addition of other flags easier in the future, provide a more
abstract 'isFlagEnabled' in LanguageVersionSettings
2017-03-15 11:03:04 +03:00
Alexander Udalov
7a240b63c7 Use LanguageFeature.State enum instead of CoroutineSupport 2017-03-15 11:03:03 +03:00
Alexander Udalov
34e131c928 Refactor LanguageVersionSettings.isApiVersionExplicit
Pass it in the CompilerConfiguration instead of LanguageVersionSettings.
This is better because LanguageVersionSettings is accessible everywhere
in front-end and back-end, and this flag should not be used there
2017-03-15 11:03:01 +03:00
Alexander Udalov
32826c1686 Introduce LanguageFeature.State, drop coroutines-related pseudofeatures
Previously there were three LanguageFeature instances -- Coroutines,
DoNotWarnOnCoroutines and ErrorOnCoroutines -- which were handled very
awkwardly in the compiler and in the IDE to basically support a language
feature with a more complex state: not just enabled/disabled, but also
enabled with warning and enabled with error. Introduce a new enum
LanguageFeature.State for this and allow LanguageVersionSettings to get
the state of any language feature with 'getFeatureSupport'.

One noticeable drawback of this approach is that looking at the API, one
may assume that any language feature can be in one of the four states
(enabled, warning, error, disabled). This is not true however; there's
only one language feature at the moment (coroutines) for which these
intermediate states (warning, error) are handled in any way. This may be
refactored further by abstracting the logic that checks the language
feature availability so that it would work exactly the same for any
feature.

Another issue is that the difference among ENABLED_WITH_ERROR and
DISABLED is not clear. They are left as separate states because at the
moment, different diagnostics are reported in these two cases and
quick-fixes in IDE rely on that
2017-03-15 11:03:00 +03:00
Alexander Udalov
cf7048dd0f Do not inject CompilerConfiguration into compiler front-end
Inject LanguageVersionSettings instead; all information relevant to the
analysis should be now passed via an instance of LanguageVersionSettings
(which should be renamed to a more general name in the future).

This is partially a revert of d499998 and related commits
2017-03-15 11:02:59 +03:00
Alexander Udalov
a879cb0cfd Minor, take LanguageVersionSettings in CompilerDeserializationConfiguration 2017-03-15 11:02:58 +03:00
Alexander Udalov
ac530ac49c Move skipMetadataVersionCheck flag to LanguageVersionSettings
This makes it possible to avoid the CompilerConfiguration instance in
injectors, because CompilerDeserializationConfiguration was the only
left component that required it.

LanguageVersionSettings is not a good name for this entity anymore, it
should be renamed in the future
2017-03-15 11:02:58 +03:00
Alexander Udalov
f5d4dd33da Inject JvmTarget into some JVM-specific call checkers
This makes it possible to drop CompilerConfiguration from
CallCheckerContext, which in turn helps to avoid passing the entire
CompilerConfiguration instance through front-end
2017-03-15 11:02:57 +03:00
Alexander Udalov
573c6ab5d4 Move JvmTarget to frontend.java, introduce TargetPlatformVersion
Previously JvmTarget was declared in module 'util' which is accessible
for example from 'frontend', which is not very good.

Also add a superinterface named TargetPlatformVersion which is going to
be used in platform-independent injectors in 'frontend' in the following
commits. Use it in one place (LanguageVersionSettingsProviderImpl.kt)
instead of DescriptionAware because TargetPlatformVersion sounds like a
better abstraction than DescriptionAware here
2017-03-15 11:02:56 +03:00
Denis Zharkov
d2cd5d46fa Minor. Use static method from super class
It was a code with warning
2017-03-15 10:47:12 +03:00
Denis Zharkov
dcc98e3839 Improve check for statements-only postfix templates
Before this change the check was quite complicated
because of cases like:
for (i in 1..9)
    foo(i)<caret>

It's not located in a block, but in the same time it's a stament.
So we had a tricky heuristics that if is parent is not a block, then
we should check if element isn't used as expression.

Of course this heuristics is wrong, e.g. for import/package nodes.

The solution is to reuse similar logic from BasicExpressionTypingVisitor.
it has been checked once that statement container is one of:
- KtBlockExpression
- KtContainerNodeForControlStructureBody
- KtWhenEntry

So there's no need to check anything else

 #KT-14986 Fixed
 #KT-14483 Fixed
2017-03-15 10:47:12 +03:00
Denis Zharkov
78ffe47bf8 Fix samples for 'iter' postfix template
#KT-14727 Fixed
2017-03-15 10:47:12 +03:00
Denis Zharkov
bd88919411 Refine predicate for 'iter' postfix template
Use IterableTypesDetection to determine if the given expression may be iterated

 #KT-14134 Fixed
 #KT-14129 Fixed
2017-03-15 10:47:12 +03:00
Denis Zharkov
465a424af4 Refactor postfix template selector
Allow to specify predicate by KtExpression instead of type predicate
It will be used for `for` template which need a context to determine
whether the expression is iterable
2017-03-15 10:47:12 +03:00
Vyacheslav Gerasimov
b8ebc087e2 Add inspection for calls of function with lambda expression body
Added "Unused return value of a function with lambda expression body" inspection with quickfix "Remove '=' token from function declaration"

#KT-10393 Fixed
2017-03-15 00:22:31 +03:00
Vyacheslav Gerasimov
087551ad61 Implement quick fix for "Invalid type of annotation member"
Quickfix changes array of boxed type to array of primitive type

#KT-8568 Fixed
2017-03-15 00:21:24 +03:00
Vyacheslav Gerasimov
b8563f7fcf Fix KotlinUastTypesTest.testCycleInTypeParameters 2017-03-15 00:20:40 +03:00
Mikhail Glukhikh
cab80812ef KT-13111: lambda --> reference supports also object members 2017-03-14 18:45:08 +03:00
Mikhail Glukhikh
631f58f27f Lambda --> reference: correct handling of companion references
Reference receivers are named more accurately now #KT-13341 Fixed
2017-03-14 18:45:06 +03:00
Mikhail Glukhikh
2c692de98f KT-13111: lambda --> reference support methods called via this now 2017-03-14 18:45:05 +03:00
Mikhail Glukhikh
19db4869e6 Lambda --> reference: correct handling of parameter-less function
Issue #KT-15556 Fixed
2017-03-14 18:45:04 +03:00
Mikhail Glukhikh
b6974a88c5 Refactoring: convert lambda --> reference intention 2017-03-14 18:45:02 +03:00
Mikhail Glukhikh
3a14a5c461 Lambda --> reference supports bound references now #KT-13111 Fixed 2017-03-14 18:45:01 +03:00
Mikhail Glukhikh
831467891c Reference --> lambda supports bound references now #KT-16292 Fixed 2017-03-14 18:45:00 +03:00
Yan Zhulanow
f6734e74e1 Minor, SamWithReceiver: Fix services for kotlinc CLI execution
Move service files to META-INF to support execution from CLI (using PluginCliParser).
2017-03-14 18:36:40 +03:00
Mikhael Bogdanov
23698f93e0 Fix reification for crossinline lambdas inlined into object literal
Inline lambda could capture reified parameter of containing inline function ('a' function)
when it is inlined in another one.
If it's inlined in any anonymous object we should track it and
add reification marker to such anonymous object instance creation
to rewrite it on inlining bytecode of 'a' function.

  #KT-15997 Fixed
2017-03-14 15:54:13 +01:00
Alexey Sedunov
6b6d7a5030 Configuration: Don't create kotlinc.xml if the settings don't differ from the defaults
#KT-16647 Fixed
2017-03-14 15:33:11 +03:00
Alexey Sedunov
e8749e639c Kotlin Facet: Add link to project-level compiler settings UI
#KT-16022 Fixed
2017-03-14 15:33:10 +03:00
Alexey Sedunov
8c91dc579a Kotlin Facet: Show project-level settings when "Use project settings" is selected
#KT-16023 Fixed
2017-03-14 15:33:09 +03:00
Alexey Sedunov
9bbea47f93 Kotlin Facet: Parse and merge compiler arguments specified in <arg> elements instead of appending them (to avoid duplication)
#KT-16776 Fixed
2017-03-14 15:33:08 +03:00
Alexey Sedunov
e5a128ab2e JPS: Parse and merge additional arguments with primary ones instead of
appending them (to avoid duplication)
 #KT-16788 Fixed
2017-03-14 15:33:07 +03:00
Alexey Sedunov
73b879ea89 Misc: Include cli-parser 1.1.2 sources into the project under different package and drop original library dependency
This would allow building the project with Kotlin JPS plugin on TeamCity where older library takes precendence due to appearing earlier in JPS classpath
2017-03-14 15:33:06 +03:00
Dmitry Jemerov
e037e9de39 Do not cache contents in VFS when reading contents of .jar files
This follows the standard IDEA policy of caching file contents.
2017-03-14 13:06:47 +01:00
Dmitry Jemerov
8d1d76cdae Try to recover from corrupt VFS data for a .kotlin_module file
#KT-13135 Fixed
2017-03-14 13:06:29 +01:00
Mikhail Zarechenskiy
da53317357 Fix exception when type parameters appear in object declaration
#KT-14536 Fixed
2017-03-14 01:10:00 +03:00
Mikhail Zarechenskiy
0568bc3ef1 Add note about JS to the changelog 2017-03-13 21:09:17 +03:00
Mikhail Zarechenskiy
fd80c0d1d1 Remove KT-15200 from the changelog
It was postponed until 1.1.2
2017-03-13 20:38:43 +03:00
Mikhail Zarechenskiy
05ef705609 Add IGNORE_BACKEND directive for native automatically
Also parse correctly case IGNORE_BACKEND: JS, NATIVE
2017-03-13 19:56:13 +03:00
Dmitry Jemerov
006062499c Optimize imports (to fix compilation under 171 branch) 2017-03-13 16:34:48 +01:00
Mikhail Zarechenskiy
774aa720b4 Update Changelog for version 1.1.1 2017-03-13 16:45:25 +03:00
Dmitry Petrov
a0a8beee82 Handle TypeAliasDescriptor in AdaptiveClassifierNamePolicy
(as ClassDescriptor)
2017-03-13 14:15:27 +03:00
Mikhael Bogdanov
ce3b455f57 Fix for KT-16801: Accessors of @PublishedApi property gets mangled
#KT-16801 Fixed
2017-03-13 10:51:10 +01:00
Dmitry Petrov
c46164481a KT-15871 Unnecessary boxing for equality operator on inlined primitive values
Allow kotlin.jvm.internal.Intrinsics#areEqual for boxed values.
Rewrite to primitive equality.

NB we can't do that for Float and Double, because java.lang.Float#equals
and java.lang.Double#equals behave differently from primitive equality comparisons.
2017-03-13 09:04:31 +03:00
Dmitry Petrov
a087ea559f Eliminate redundant CHECKCAST instructions
CHECKCAST is redundant if the corresponding static type exactly matches the target type.
CHECKCAST instructions to-be-reified should not be eliminated.

KT-14811 Unnecessary checkcast generated in parameterized functions
KT-14963 unnecessary checkcast java/lang/Object
2017-03-13 09:04:31 +03:00
Dmitry Petrov
ec403bfdbc KT-16245 Redundant null-check generated for a cast of already non-nullable value
KT-16194 Code with unnecessary safe call contains redundant boxing/unboxing for primitive values
KT-12839 Two null checks are generated when manually null checking platform type

Recognize some additional cases of trivial null checks and trivial instance-of checks.

A variable is "checked for null", if it is:
- a function parameter checked with 'INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull'
- checked for nullability with 'IFNULL/IFNONNULL'
- checked for nullability with 'INSTANCEOF'
  (if objectref is instance-of T, then objectref is non-null)

Before analyzing nullability, introduce synthetic assumptions for execution branches
where a variable is guaranteed to be null or not null. For example, the following bytecode:

     ALOAD 1 // Ljava/lang/String;
     IFNULL L
     <non-null branch>
  L:
     <null branch>

is transformed to

     ALOAD 1
     IFNULL L1
     NEW java/lang/String
     ASTORE 1            // tells analyzer that variable 1 is non-null
     <non-null branch>
  L:
     <null branch>
  L1:
     ACONST_NULL
     ASTORE 1            // tells analyzer that variable 1 is null
     GOTO L

After the analysis is performed on a preprocessed method,
remember the results for "interesting" instructions
and revert the preprocessing transformations.

After that, perform bytecode transformations as usual.

Do not transform INSTANCEOF to-be-reified, because reification at call site
can introduce null checks. E.g.,

    inline fun <reified T> isNullable() = null is T
    ...
    assert(isNullable<String?>())
2017-03-13 09:04:31 +03:00
Dmitry Petrov
3c09a26e16 KT-5248 Don't wrap variable if it is captured only in inlined closures
Remove non-escaping Ref's on bytecode postprocessing pass.
2017-03-13 09:04:31 +03:00
Dmitry Petrov
3fc106572e Make redundant null check optimization independent of boxing optimization algorithm.
Run DCE after each single redundant null check optimization pass.
2017-03-13 09:04:31 +03:00
Ilya Matveev
eda43c8b45 Mute tests with standard collection extensions in native 2017-03-10 19:59:37 +03:00
Ilya Matveev
29e5ad5abe Mute tests with '::class' in native backend 2017-03-10 19:59:37 +03:00
Ilya Matveev
8a3fa2e4e5 Fix expected SMAPs after test muting for native 2017-03-10 19:59:37 +03:00
Ilya Matveev
a5e4e0284e Mute some box tests for native backend
This patch mutes the following test categories:
   * Tests with java dependencies (System class,
     java stdlib, jvm-oriented annotations etc).
   * Coroutines tests.
   * Reflection tests.
   * Tests with an inheritance from the standard
     collections.
2017-03-10 19:59:37 +03:00
Alexander Udalov
d21d362f0f Allow enum entries in double colon LHS with LV = 1.0
#KT-16782 Fixed
2017-03-10 19:44:00 +03:00
Denis Zharkov
39055229a1 Add diagnostic info to assertion on type argument consistency 2017-03-10 18:17:50 +03:00
Vyacheslav Gerasimov
830bf62d94 Fix SOE from UAST in containsLocalType
containsLocalType now properly handles start projections
#KT-16680 Fixed
2017-03-10 17:30:21 +03:00
Simon Ogorodnik
4e98394c38 Fix Sample reference to resolve cross-module packages correctly
Now @sample links to FqName in IDE will be resolved correctly
 Cause now we resolve packages over all modules in project
 #KT-14710 fixed
2017-03-10 15:33:47 +03:00
Nikolay Krasko
688802de51 Check breakpoints work in delegate initializer
Additional test after review
2017-03-10 14:59:37 +03:00
Nikolay Krasko
e6ee933b27 Fix "smart step into" for classes with complex hierarchy (KT-16667)
#KT-16667 Fixed
2017-03-10 14:58:21 +03:00
Nikolay Krasko
6d9b519bb2 Use new utility method for getting lexical scope
It's expected that for call expressing some nearest parent will have
lexical scope written in binding context. Under this circumstances it's
refactoring.
2017-03-10 14:58:17 +03:00
Nikolay Krasko
0a7a73d4be Refactoring: extract method for getting lexical scope without facade 2017-03-10 14:58:16 +03:00
Nikolay Krasko
9120ccc054 Fix breakpoints in inline calls in fields initialization (KT-16525)
Backend generates properties initializer in constructor context

 #KT-16525 Fixed
2017-03-10 14:58:15 +03:00
Nikolay Krasko
d886cd7d06 Fix breakpoints when inline call is in qualified expression (KT-16062)
Scope is stored for DOT_QUALIFIED_EXPRESSION not directly for
CALL_EXPRESSION.

 #KT-16062 Fixed
2017-03-10 14:58:14 +03:00
Nikolay Krasko
2719016539 Fix search of correspondent call expression by element (KT-11234)
getStrictParentOfType() looks for nearest parent of given type

In complex expressions like:

SamConversion.doAction({
  inlineCall {
    {
      // here <--
    }()
  }
})

doAction was found twice, while inlineCall was skipped.

See code:
// call(param, { <it> })
lambdaExpression?.typedParent<KtValueArgument>()?.typedParent<KtValueArgumentList>()?.typedParent<KtCallExpression>() ?:

// call { <it> }
lambdaExpression?.typedParent<KtLambdaArgument>()?.typedParent<KtCallExpression>()

 #KT-11234 Fixed
2017-03-10 14:58:13 +03:00
Nikolay Krasko
b240ae791c Minor: extract variable 2017-03-10 14:58:12 +03:00
Denis Zharkov
52d11eb22b Minor. Revert workarounds for problem on KClass from annotation
See KT-9453 for clarification
2017-03-10 13:49:07 +03:00
Denis Zharkov
82d7a269ed Minor. Make sure that implicit contract of mapSignature is satisfied
For ordinary functions mapSignature doesn't use original descriptor
and maps the given descriptor itself, but for constructor it obtained
the original value parameters.

Necessary `getOriginal` calls were added to the call-sites
2017-03-10 13:49:06 +03:00
Denis Zharkov
394c68c326 Minor. Move unwrapping of FunctionImportedFromObject
It should not affect the semantics, because mapSignatureWithCustomParameters
can only be called with FunctionImportedFromObject from mapSignature.

At the same time it's very nice to have all of these kinds
of custom unwrapping in the same place
2017-03-10 13:49:06 +03:00
Denis Zharkov
530214fcee Minor. Simplify mapping to callable method
There's no need in unwrapping for TypeAliasConstructorDescriptor
because mapSignatureSkipGeneric/mapDefaultMethod already do it
in some moment, and ConstructorDescriptor has getConstructedClass method
for mapping its owner
2017-03-10 13:49:05 +03:00
Denis Zharkov
be90f7d331 Make type aliases constructors return correct original descriptors
The problem was that when resolving super-calls we used known substitutor
when creating a type alias constructor, thus its original return itself,
while it's expected that it should return the descriptor before substitution

The main idea of the fix that `createIfAvailable` should always return
unsubstituted constructor.

Note that known substitutor for type alias constructor should be based
on abbreviation.

The test change seems to be correct as PROJECTION_IN_IMMEDIATE_ARGUMENT_TO_SUPERTYPE
is already reported.
Beside this, resolution behavior isn't expected to be changed dramatically
2017-03-10 13:49:05 +03:00
Denis Zharkov
2b21280ba9 Unwrap underlying typealias constructor earlier
The problem is very subtle (see the test): when generating a signature
for an object literal we also were mapping its super-class
(a type alias here).

Although we did unwrap its underlying constructor to map it properly
we did too late (after obtaining value parameters from the type alias constructor descriptor).

Another problem is that TypeAliasConstructorDescriptor.getOriginal
in the case does return itself, while it's expected to return
unsubstituted version

Note: everything works for common calls for such constructors
because they mapped through mapCallableMethod which contains
another custom unwrapping of type alias constructors

 #KT-16555 Fixed
2017-03-10 13:45:37 +03:00
Denis Zharkov
8761ef6694 Minor. Rename mapSignature overload to mapSignatureWithCustomParameters 2017-03-10 13:45:37 +03:00
Denis Zharkov
7173e56393 Make computation of arguments for raw types lazy
See how we translate raw types to Kotlin model:
RawType(A) = A<ErasedUpperBound(T1), ...>
ErasedUpperBound(T : G<t>) = G<*> // UpperBound(T) is a type G<t> with arguments
ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F

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

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

The solution is to make arguments calculating for raw types lazy

 #KT-16528 Fixed
2017-03-10 13:30:33 +03:00
Mikhael Bogdanov
f2fea9a04a Generate unboxing operation on boxed class not Number.class when possible 2017-03-10 10:04:30 +01:00
Mikhael Bogdanov
5e80d80797 Fix for KT-16732: Type 'java/lang/Number' (current frame, stack[0]) is not assignable to 'java/lang/Character
#KT-16732 Fixed
2017-03-10 10:04:29 +01:00
Mikhail Glukhikh
32bdb6becb KT-16714 related refactoring of tryRunWriteAction (now runWriteAction is not used if intention is called from J2K) 2017-03-10 10:46:49 +03:00
Alexey Sedunov
faa0dff649 Kotlin Facet: Do no present compiler plugin classpaths and options in additional arguments string
#KT-16313 Fixed
2017-03-09 23:06:52 +03:00
Alexey Sedunov
cc20c66bfc Kotlin Facet: Fix platform detection by Maven execution goals
#KT-15947 Fixed
 #KT-16342 Fixed
2017-03-09 23:06:47 +03:00
Alexey Sedunov
e8640b441d JPS: Fix earlier configurations with incorrect combination of language and API version 2017-03-09 23:06:42 +03:00
Alexey Sedunov
811b8978c2 Kotlin Facet: Escape additional compiler arguments when converting them to string and unescape before parsing
#KT-16700 Fixed
2017-03-09 23:06:38 +03:00
Alexey Sedunov
c5ee28da05 Kotlin Facet: Detect module platform by gradle plugin
#KT-16703 Fixed
 #KT-16342 Fixed
2017-03-09 23:06:33 +03:00
Alexey Sedunov
26537cd8fc Kotlin Facet: Distinguish compiler arguments specified for different source sets
#KT-16698 Fixed
2017-03-09 23:06:28 +03:00
Alexey Sedunov
0e583aa929 Kotlin Facet: Update Gradle import test data to use 1.1.0 plugin 2017-03-09 23:06:23 +03:00
Alexey Sedunov
278cc71c4a Kotlin Facet: Reuse configuration serialization in JPS (previous implementation is not usable after configuration refactoring) 2017-03-09 23:06:18 +03:00
Alexey Sedunov
641a9a7153 Kotlin Facet: Get rid of duplicating data in facet configuration 2017-03-09 23:06:12 +03:00
Alexey Sedunov
19ea18a340 Kotlin Facet: Correctly enable/disable "output directory" field when changing "Use project settings" option
#KT-16317 Fixed
2017-03-09 22:48:44 +03:00
Dmitry Jemerov
01a9d9a284 Support lazy conversion of parent chain; correctly check expected class 2017-03-09 17:07:43 +01:00
Dmitry Jemerov
8c3936a0ee Update to UAST 0.12 2017-03-09 17:07:43 +01:00
Simon Ogorodnik
3bf7223448 Internal Kotlin packages now should be completable in parent packages
Internal packages which are hard-excluded from completion and
 imports now should be visible there if file package are parent of
 excluded one
 e.g kotlin.jvm.internal.* now visible from kotlin and kotlin.jvm
 #KT-16214 fixed
2017-03-09 19:05:10 +03:00
Dmitry Petrov
27bf51c73f All multifile class tests should have 'TARGET_BACKEND: JVM' directive. 2017-03-09 17:22:28 +03:00
Dmitry Petrov
6a68eb218f KT-16077 Redundant private getter for private var in a class within a JvmMultifileClass annotated file 2017-03-09 17:22:28 +03:00
Dmitry Jemerov
c9df227fef Add more tests for coroutines; use higher-level API to check that changes have been applied 2017-03-09 13:57:45 +01:00
Dmitry Jemerov
73a2c8c436 Test quickfixes for updating language/API version and coroutine support in Gradle projects 2017-03-09 13:41:57 +01:00
Dmitry Jemerov
5d461ec6df Support updating language/API level specified with compact options 2017-03-09 13:41:57 +01:00
Dmitry Jemerov
4261880340 Add test for enabling coroutines/bumping language level, fix several breakages 2017-03-09 13:41:57 +01:00
Sergey Igushkin
999ef51653 Added gradle-plugins properties with fqnames
Added .property files to make the plugins available by fqnames in
order to publish them to Gradle Plugin Portal.

#KT-5756

(cherry picked from commit 991de64)
2017-03-09 14:13:40 +03:00
Dmitry Jemerov
cbccb68948 Fix logic for searching inner classes in LazyResolveBasedCache.findInPackageFragments()
#KT-14058 Fixed
2017-03-09 11:47:21 +01:00
Alexander Udalov
9f2ce3c521 Refactor synthesized invokes creation in resolution
Instead of verifying that the container of an 'invoke' is a
FunctionClassDescriptor instance, make sure that it's a function class
checking its FQ name instead (classId + isBuiltinFunctionClass calls).
This makes sure that we will create synthesized invokes in a setting
where function classes are not FunctionClassDescriptor instances
synthesized by the compiler, but ordinary classes from sources or
binaries as well, as is going to be the case in kotlin-native
2017-03-09 11:29:39 +03:00
Dmitry Petrov
d188de3086 KT-6014 Wrong ABSTRACT_MEMBER_NOT_IMPLEMENTED for toString implemented by delegation
Members declared in interface or overriding members declared in super-interfaces
can be implemented by delegation even if they override members declared in super-class
(NB for interface this can be only 'kotlin.Any').
2017-03-09 09:38:48 +03:00
Mikhail Glukhikh
5e8afd26e1 Do not run write actions from J2K #KT-16714 Fixed
Also #EA-97363 Fixed
2017-03-09 09:37:35 +03:00
Dmitry Petrov
f950ff4b8f 'ConstructorDescriptor#getConstructedClass()' should be used to obtain a descriptor for constructed class
(it can be different from 'getContainingDeclaration()' in case of type alias constructor).

KT-15109 Subclass from a type alias with named parameter in constructor will produce compiler exception
KT-15192 Compiler crashes on certain companion objects: "Error generating constructors of class Companion with kind IMPLEMENTATION"
2017-03-09 09:23:38 +03:00
Dmitry Petrov
9a2c9ed30e KT-13342 Unqualified super call should not resolve to a method of supertype overridden in another supertype 2017-03-09 09:16:21 +03:00
Dmitry Jemerov
954c1d853d Correctly locate build.gradle for modules created from source sets
(cherry picked from commit ecce92d)
2017-03-08 15:08:41 +01:00
Dmitry Jemerov
a2f7808ab1 Don't check Java version in LauncherScriptTest 2017-03-08 14:07:47 +01:00
Dmitry Jemerov
263cf85c5c Fix project leak in IdeReplExecutionTest 2017-03-08 13:47:09 +01:00
Dmitry Petrov
11caa03427 KT-16713 Insufficient maximum stack size
1. Analyze method node with fake jumps for loops to make sure that
all instructions reachable only through break/continue jumps are processed.
2. Fix stack for break/continue jumps.
3. Drop fake jumps for loops, analyze method node again.
4. Fix stack for try/catch and beforeInline.
2017-03-08 09:56:08 +01:00
Mikhail Glukhikh
80063b6f91 Quick-fix for DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE added #KT-15966 Fixed 2017-03-07 19:06:16 +03:00
Ilya Gorbunov
b83b534374 Add missing SinceKotlin to IntStream.toList. 2017-03-07 18:22:11 +03:00
Ilya Gorbunov
c038d3e9a3 Mark all api in kotlin.reflect.full package with SinceKotlin(1.1), since it actually appeared in that package only in 1.1. #KT-16557 Fixed.
It doesn't matter that some functions were since 1.0 in the old package.
2017-03-07 18:22:11 +03:00
Kirill Rakhman
646f50dd66 Extract method refactoring should order parameters by first usage
Fixes #KT-16198
2017-03-07 18:10:02 +03:00
Ilya Gorbunov
1296c5444b Fix warning that failed maven plugin smoke test. 2017-03-07 13:56:11 +03:00
Ilya Gorbunov
61e8848aa2 Add samples for sequence building API. 2017-03-07 13:32:39 +03:00
Ilya Gorbunov
a04e6de047 Add groupingBy and eachCount sample. 2017-03-07 13:31:44 +03:00
Ilya Gorbunov
75ae42121b Improve sample comments.
Improve sample for lastIndex property.
2017-03-07 13:31:44 +03:00
Mikhail Zarechenskiy
578dd1dc42 Update Changelog for Kotlin 1.1.1-RC 2017-03-07 12:12:04 +03:00
Dmitry Petrov
d096f1d381 'while' and 'do-while' loop generator fixes.
Generate 'do-while' loop body as IrComposite, because variables declared
in loop body should be visible in loop condition.
Wrap 'do-while' loop in IrBlock so that variables declared in loop body
are not visible outside of the loop.

Generate 'while' and 'do-while' loops as expressions of type Unit.
2017-03-07 11:56:52 +03:00
Dmitry Petrov
cb61c358ea Always generate primitive boolean constants as expressions of type 'kotlin.Boolean'. 2017-03-07 11:56:52 +03:00
Dmitry Petrov
1bbbc1ca1c KT-16684 hashCode doesn't check data class property value of generic type for null 2017-03-07 11:56:52 +03:00
Dmitry Petrov
68fab55251 Minor: cleanup unused imports 2017-03-07 11:56:52 +03:00
Dmitry Petrov
6bc6c1b6cc KT-16671 Calls to members imported from objects should be desugared in PSI2IR 2017-03-07 11:56:52 +03:00
Dmitry Petrov
4ba8268a29 KT-16669 Exception in PSI2IR on type alias constructor in supertypes list 2017-03-07 11:56:52 +03:00
Dmitry Petrov
e4683a1e9f KT-16666 IMPLICIT_INTEGER_COERCION expression should have non-nullable type 2017-03-07 11:56:52 +03:00
Dmitry Petrov
8c32719f3d Render 'type' for IrTypeOperatorCall expressions, update testData. 2017-03-07 11:56:52 +03:00
Dmitry Petrov
b3aeddac85 Refactor: generalize postfix order transformation in InsertImplicitCasts 2017-03-07 11:56:52 +03:00
Dmitry Petrov
8e8f83656f KT-16618 IMPLICIT_INTEGER_COERCION isn't generated for global properties and default parameters 2017-03-07 11:56:52 +03:00
Sergey Igushkin
ee6aae7219 Enabled incremental compilation by default in Gradle plugin.
#KT-16546 Fixed

(cherry picked from commit 06715c5)
2017-03-07 11:32:26 +03:00
Alexey Andreev
ef38761dc2 JS: unmute now passing tests and mute test that passed by accident. 2017-03-07 10:46:09 +03:00
Alexey Andreev
a6ca2906d8 JS: add tests for reflection against external classes 2017-03-07 10:46:08 +03:00
Alexey Andreev
723c9be5a0 JS: fix class literal expression with primitive classes. See KT-16545 2017-03-07 10:46:08 +03:00
Alexey Andreev
8567db10b5 JS: fix coroutine transformation of callable references to local functions. See KT-16164 2017-03-07 10:46:07 +03:00
Dmitry Petrov
18fb70b32f Potential fix for KT-16673
See also:
http://stackoverflow.com/questions/42571812/unsupportedoperationexception-while-building-a-kotlin-project-in-idea

'original' for SamAdapterFunctionScope.MyFunctionDescriptor#doSubstitute should exactly match 'this.original',
so we can just provide it by default in SamAdapterFunctionScope.MyFunctionDescriptor#newCopyBuilder.
2017-03-06 22:00:09 +03:00
Dmitry Jemerov
268f7b715c "Configure Kotlin plugin updates" shows 1.2 and doesn't show 1.0.x 2017-03-06 19:50:58 +01:00
Ilya Chernikov
50e7973fc0 Implement verification workaround for annotation-like class InvalidScriptResolverAnnotation
fixes #KT-16621
2017-03-06 16:31:52 +01:00
Sergey Mashkov
243f718193 EA-88059 - assert: CompositeElement.addChild
ensure parent element for anchor elements so we never try to insert at wrong place
2017-03-06 17:34:36 +03:00
Sergey Mashkov
4637dcde33 EA-86479 - ISE: PomFile.<init>
don't apply any inspections for inappropriate pom files
2017-03-06 17:34:35 +03:00
Mikhael Bogdanov
ff9fe85507 Fix for KT-16614: Report inability to inline 1.8 bytecode into 1.6 bytecode as an error, no as an exception 2017-03-06 15:15:22 +01:00
Vyacheslav Gerasimov
5e4459f41d Fix broken MultiFileHighlightingTest
Android resource folding builder should not run in non-Android projects
2017-03-06 14:31:01 +03:00
Alexander Udalov
0111c4d581 Allow references to nested class constructors in objects in LV = 1.0
#KT-16598 Fixed
2017-03-06 11:03:24 +03:00
Alexander Udalov
7c22113c34 Refactor serialization of package FQ name extension
Instead of requiring to pass it in SerializerExtensionBase's
constructor, pass it always in serializePackage. This is more
straightforward and helps in a situation where one SerializerExtension
instance is used for the whole module, not one per-package
2017-03-06 11:03:24 +03:00
Kirill Rakhman
c952e26cbb Fix NPE caused by Rename Refactoring of backing field when caret is after the last character
#KT-16605 Fixed
2017-03-06 11:01:38 +03:00
Kirill Rakhman
1bad04db50 Fix Can't rename implicit lambda parameter 'it' when caret is placed right after the last character
#KT-14401 Fixed
2017-03-06 11:01:38 +03:00
Ilya Chernikov
e3391175d9 Rewrite parallel daemon start test to make it tougher but more robust 2017-03-05 11:29:54 +01:00
Anton Bannykh
4c6b9b695c JS: mute some tests with extension functions in external declarations 2017-03-03 21:39:40 +03:00
Anton Bannykh
fcffd190d0 JS: prohibited extension function arguments in external functions; removed extension receiver in jQuery declarations. 2017-03-03 20:37:59 +03:00
Sergey Igushkin
73e94ffde0 Added a test for the fix of KT-16434.
(cherry picked from commit 5a6d06f)
2017-03-03 18:04:23 +03:00
Sergey Igushkin
6605ba80e7 Fix for androidTest variants of Android Gradle build.
Added a workaround reflection call to TaskManager to create a
javac task since it is missing for androidTest variants with jack.
Added source configuration with the tested variant to make
the tested sources visible to the compiler.

#KT-16434 Fixed

(cherry picked from commit 84efd05)
2017-03-03 18:04:12 +03:00
Mikhail Glukhikh
0432e2e947 Quick-fix to add noinline to parameter with suspend function type + AddInlineModifierFix refactoring #KT-16074 Fixed 2017-03-03 17:28:37 +03:00
Mikhail Glukhikh
d9710ea4ff #EA-97027 Fixed 2017-03-03 17:28:35 +03:00
Mikhail Glukhikh
8965bb8977 Navigation: new icons for header <---> impl #KT-15842 Fixed 2017-03-03 17:28:34 +03:00
Vyacheslav Gerasimov
1376c8f8cf Implement quickfixes for Android Lint api issues
#KT-16624 Fixed
#KT-16625 Fixed
#KT-14947 Fixed
2017-03-03 16:22:36 +03:00
Vyacheslav Gerasimov
a907ec92b5 Implement Android resource reference folding
#KT-15451 Fixed
2017-03-03 16:18:20 +03:00
Vyacheslav Gerasimov
39010ab847 Fix broken isReferenceTo checking code for Android extensions
#KT-16132 Fixed
2017-03-03 16:17:52 +03:00
Alexander Udalov
25c1828288 JS: write and load pre-release flag on binaries 2017-03-03 13:33:51 +03:00
Alexander Udalov
de8dd37e44 Change DeserializedContainerSource.presentableFqName to String
To allow outputting something other than "Class 'XXX'" in the diagnostic
message for declarations deserialized from JS
2017-03-03 13:33:51 +03:00
Alexander Udalov
f120865350 Combine cls stub builders for built-ins and JS 2017-03-03 13:33:51 +03:00
Alexander Udalov
297eb952bc Extract common parts of built-ins and JS decompilers 2017-03-03 13:33:51 +03:00
Alexander Udalov
b52b90c182 Extract serialization of packageFqName extension to SerializerExtensionBase 2017-03-03 13:33:51 +03:00
Alexander Udalov
4e91dadfab Combine decompiler deserializers for built-ins and JS 2017-03-03 13:33:50 +03:00
Alexander Udalov
bafa0ec1ee Minor, don't throw exception on empty proto message 2017-03-03 13:33:50 +03:00
Alexander Udalov
5a00a97cf1 Extract common parts from deserialization of built-ins and JS 2017-03-03 13:33:50 +03:00
Alexander Udalov
3cb8f1ab20 Drop BuiltIns protobuf message, use ProtoBuf.PackageFragment instead 2017-03-03 13:33:50 +03:00
Alexander Udalov
a36e457c12 Introduce PackageFragment protobuf message for kjsm/builtins/common metadata 2017-03-03 13:33:50 +03:00
Alexander Udalov
2b1b1fb0d4 Merge VirtualFileKotlinClassFinder into VirtualFileFinder
VirtualFileKotlinClassFinder was the only direct subclass of VirtualFileFinder
2017-03-03 13:33:50 +03:00
Alexander Udalov
abb5bc6aba Simplify VirtualFileFinder and their factories' hierarchy
Since there's no JsVirtualFileFinder anymore, inline JvmVirtualFileFinder into
VirtualFileFinder and drop "Jvm" prefix everywhere
2017-03-03 13:33:50 +03:00
Alexander Udalov
ee0874a26d Drop JsVirtualFileFinder and its factory, refactor nearby
The only remaining usage was in KotlinRuntimeLibraryUtil.kt where we only
needed to check whether there's at least one file in a given package indexed by
KotlinJavaScriptMetaFileIndex. Move that logic to a public extension, drop
everything else
2017-03-03 13:33:50 +03:00
Alexander Udalov
67699bf17e Rename metadata version index and its subclasses 2017-03-03 13:33:50 +03:00
Alexander Udalov
57877bb007 Add default value to js_code_binary_version in js.proto
By default, assume the version is 1.0.0
2017-03-03 13:33:49 +03:00
Mikhael Bogdanov
a03ed6f742 Fix for KT-16581: VerifyError when calling default value parameter with jvm-target 1.8
#KT-16581 Fixed
2017-03-03 11:21:42 +01:00
Ilya Chernikov
ffe3453937 Do not pollute IDEA log with fake script dependencies 2017-03-03 10:59:28 +01:00
Mikhail Glukhikh
3060ecc066 Minor build fix: "Convert to apply" is now applicable only with 2+ calls with the same receiver 2017-03-03 11:10:01 +03:00
Dmitry Petrov
634d9834de Wrong receiver is generated for variable-as-function call on object.
Move 'generateExpressionForReferencedDescriptor' to CallGenerator,
use it in 'generateCall',
add PSI-free versions of some utility methods so that call elements can
be generated when we're already deep in ResolvedCall generation
and have forgotten about PSI.
2017-03-03 10:15:59 +03:00
Mikhail Zarechenskiy
d573962259 Add test for class delegation with private constructor
#KT-16583 Obsolete
2017-03-02 18:34:59 +03:00
Mikhail Zarechenskiy
e2dcec62d3 Fix access to top-level declarations inside anonymous initializer
#KT-16583 Fixed
2017-03-02 18:34:51 +03:00
shiraji
0e5603f644 Implement an intention converting several calls with same receiver to with/apply/run #KT-12183 Fixed 2017-03-02 16:56:56 +03:00
shiraji
c2e5fc5215 Move KtDotQualifiedExpression.deleteFirstReceiver to Utils.kt 2017-03-02 16:56:53 +03:00
Alexander Udalov
39d0cd7237 Test that all Kotlin versions in the project are consistent
There are two different tests: the one that checks that all versions are
consistent (but not equal, because some versions are major.minor.patch,
but some only major.minor), and the one that checks that versions of all
subprojects of the Maven projects are exactly equal (1.1-SNAPSHOT
currently)

 #KT-16455 Fixed
2017-03-02 16:36:51 +03:00
Denis Zharkov
6fb83c2ba3 Force wrapping java classes from annotation methods into KClasses
Before this change such wrapping happened only during coercion,
i.e. when a call-site expected a KClass instance.

But when call-site expects Any, for example, no wrapping happened,
and raw j.l.Class instance was left on stack.

The solution is to put wrapping code closer to generation of annotation's
method call itself to guarantee that necessary wrapping will happen.

 #KT-9453 Fixed
2017-03-02 15:19:09 +03:00
Denis Zharkov
415c3d57af Fix substitutor for synthetic SAM adapters
When synthetic member comes not from the receiver type itself,
but from one of its supertypes it doesn't make sense to subsitute
the member with receiver type, we should obtain relevant supertype
and use it instead.

 #KT-16578 Fixed
2017-03-02 15:06:59 +03:00
Anton Bannykh
9e5ecc11b7 JS: fixed Double.NaN behaviour (KT-13610). 2017-03-02 14:29:50 +03:00
Dmitry Petrov
f636ab21f8 Use proper descriptor for (generic) property assignment.
Insert IMPLICIT_INTEGER_COERCION only if Int is coerced to an integer type.
2017-03-02 14:25:58 +03:00
Dmitry Petrov
97fbbc74e6 KT-16440 ClassConstructorDescriptorImpl has null returnType
Set constructor return type in FunctionDescriptorResolver#createConstructorDescriptor
(it seems to be the only place where ClassConstructorDescriptorImpl#initialize(...)
is called, but returnType is not set).
2017-03-02 14:25:58 +03:00
Dmitry Petrov
dc1d92855d KT-16438 Strange dispatch receiver for descriptors of delegated members
Provide proper dispatch receiver parameter for delegated members.
Use dispatch receiver parameter for delegated members in IR generation
for delegated member body (and check that the receiver has corresponding type).
2017-03-02 14:25:58 +03:00
Dmitry Petrov
c92f118e5e Refactoring: introduce CopyBuilder for CallableMemberDescriptor and PropertyDescriptor.
Allow providing new dispatchReceiverParameter via CopyBuilder
(required for proper dispatch receiver for delegates).
2017-03-02 14:25:58 +03:00
Dmitry Petrov
9baaf607a3 KT-16566 Support destructuring declarations for lambda parameter in psi2ir 2017-03-02 14:25:58 +03:00
Dmitry Petrov
c226707a80 KT-16554 Local function with default arguments have no IR elements for them 2017-03-02 14:25:58 +03:00
Igor Chevdar
ab3681e164 Package level delegated properties have no dispatch receiver. 2017-03-02 12:33:01 +03:00
Igor Chevdar
3ef612f05a Added dispatch receiver to delegation implementing property 2017-03-02 12:33:01 +03:00
Simon Ogorodnik
6dd75f697a Fix Show implementation to show inheritance through type-aliases
Show implementation(Ctrl-Hover) now should show classes which inherit such class through type-alias
 #KT-15200 fixed
2017-03-01 23:05:19 +03:00
Yan Zhulanow
593fbadc98 Force using the 'kotlin-stdlib-jre7' artifact when configuring Android modules with JDK >= 1.8 as Dex can't process our 'kotlin-stdlib-jre8' artifact.
This fixes KT-16530: Configure Kotlin in Project inserts dependency to kotlin-stdlib-jre8 in Android projects.
2017-03-01 18:50:22 +03:00
Yan Zhulanow
060095d39f Remove kotlin-annotation-processing artifact from the serialized compiler options. It is unused in kapt3 (or if no annotation processor dependencies are provided) but is still imported into the IDEA module files. This leads to compilation error due to the plugin incompatibility.
Incompatibility reason: kotlin-annotation-processing has references to the shaded intellij-core, so, being provided to the unshaded kotlinc from the Kotlin plugin, it throws the AbstractMethodError.

This fixes #KT-16184.
2017-03-01 18:50:22 +03:00
Kirill Rakhman
2506bb6673 Inspection checking that destructuring variable name matches the name of different component #KT-12004 Fixed 2017-03-01 18:24:48 +03:00
Dmitry Jemerov
af7de9a0c5 Warn when running the compiler under Java 6 or 7
(cherry picked from commit 5537800)

(cherry picked from commit 5614874)
2017-03-01 16:21:57 +01:00
Simon Ogorodnik
000da2f6d0 Fix of <ERROR CLASS>-es pointing to public TypeAliases 2017-03-01 16:09:24 +01:00
Dmitry Jemerov
78b4cbdb69 Don't generate documentation for option that doesn't work in Gradle 2017-03-01 16:09:23 +01:00
Alexey Andreev
0c0e0aab09 JS: add some docs to declarations related to interop 2017-03-01 16:09:21 +01:00
Dmitry Jemerov
322379e6ae Assorted stdlib KDocs 2017-03-01 16:09:01 +01:00
Dmitry Jemerov
1d86bd5610 Build multiplatform stdlib docs 2017-03-01 16:08:38 +01:00
Dmitry Jemerov
adc937c57d Extract separate target for preprocessing JS stdlib sources 2017-03-01 16:08:28 +01:00
Kirill Rakhman
8d425a6f94 Add intention to add missing components to destructuring assignment #KT-16258 Fixed 2017-03-01 18:00:55 +03:00
Mikhael Bogdanov
4d47c0fd63 Partial fix for KT-16193: Incremental compilation generates invalid bytecode for crossinlined functions; avoid IllegalAccessError 2017-03-01 14:45:11 +01:00
Alexander Udalov
3ad4f18e1a Update grammar to Kotlin 1.1
Also drop obsolete comments and inline some trivial rules
2017-03-01 14:50:36 +03:00
Mikhail Zarechenskiy
875fdef917 Add tests for obsolete issues
#KT-15913 Obsolete
 #KT-12248 Obsolete
2017-03-01 14:07:09 +03:00
Anton Bannykh
318014e4ab Test vararg with Java behaviour only for JVM backends 2017-03-01 13:58:57 +03:00
Mikhail Glukhikh
91cd590395 Change log: note about javaClass added 2017-03-01 10:14:57 +03:00
Denis Zharkov
a7fc32c8da Add diagnostic on calling inner classes constructors without receiver
Otherwise there will be just an unresolved reference that doesn't give
any useful information

 #KT-8959 Fixed
2017-03-01 09:59:01 +03:00
Denis Zharkov
1e0ae04aba Minor. Convert if to when 2017-03-01 09:59:00 +03:00
Denis Zharkov
b5a8ffaddc Fix resolution of callable references
When there is unsuccessful (e.g invisible) result of one kind (static/non-static)
and there is a successful candidate for another kind, choose the latter one.

Note, that we have to postpone commiting trace until we choose one of the results,
otherwise errors of unsuccessful results are reported

TODO: Maybe it makes sense to report all results when all of them are
unsuccessful (NONE_APPLICABLE or something like this)

 #KT-16278 Fixed
2017-03-01 09:59:00 +03:00
Dmitry Petrov
dd61a5b2c6 KT-16553 Underscore variable values shall not be evaluated
Do not generate 'componentN' calls for '_' in destructuring assignment.
2017-03-01 09:25:38 +03:00
Dmitry Petrov
63b16e14d8 KT-16536 Wrong IR generated for '++x'
Make psi2ir confirm to JVM BE behavior for prefix increment/decrement.
TODO reconsider after design decision (in 1.2?).
2017-03-01 09:25:38 +03:00
Dmitry Petrov
885f397cdd KT-16535 'provideDelegate' convention is not supported in IR
Implement provideDelegate convention support.
NB delegate type now depends on 'provideDelegate' convention resolution.
2017-03-01 09:25:38 +03:00
Dmitry Petrov
6046b25f56 Minor: silence that irritating KT-14030 2017-03-01 09:25:38 +03:00
Dmitry Petrov
045a12ddc6 Minor: constructor IrExpressionBodyImpl(IrExpression) 2017-03-01 09:25:38 +03:00
Dmitry Petrov
e66c2621af KT-16436 Incorrect primitive constants handling
Expression '1.unaryMinus()' is resolved as Int::unaryMinus call with Int receiver.
However, this expression is implicitly coerced to a different integral type (Byte, Short, Long)
based on results of constant evaluation.

Introduce IMPLICIT_INTEGER_COERCION type operator to handle such cases.

TODO: should we use it for simple constant expressions like '1' and '-1'?
2017-03-01 09:25:38 +03:00
Dmitry Petrov
d0134f2c64 KT-16437 Incorrect type inference for some when coerced to Unit
If the result of 'when' is not used in an expression,
this 'when' expression has type 'Unit' despite of whatever FE has inferred.
2017-03-01 09:25:38 +03:00
Dmitry Petrov
e2e57e5b6d KT-16439 Generated methods of data classes have no expression for default arguments
Provide default argument expressions for generated 'copy' declaration.
2017-03-01 09:25:38 +03:00
Dmitry Petrov
0f1f354ba6 KT-16486 Strange IR for delegated members
Delegated implementations should refer to delegate field:
  $this: GET_FIELD <delegate_field> ...
    receiver: <this_for_containing_class>
2017-03-01 09:25:38 +03:00
Alexander Udalov
abbbdb5771 Update KotlinVersion.CURRENT to 1.1.2 2017-02-28 20:24:33 +03:00
Alexander Udalov
559da842c0 Clear reflection caches in black box codegen tests
To prevent tests from altering outcomes of the subsequent tests.

Also expose the clearCaches method (in the internal class
ReflectionFactoryImpl) so that it can be used in other places in similar
circumstances
2017-02-28 20:19:58 +03:00
Alexander Udalov
e19c1b5364 Drop MockTypeAliasDescriptor, use MockClassDescriptor instead
It's irrelevant whether the non-found classifier is a class or a
typealias
2017-02-28 20:19:58 +03:00
Alexander Udalov
12b48f86e7 Do not load error classes in ReflectionTypes
Previously ReflectionTypes.find returned an error class in case a class
is not found in the module dependencies. The problem with this approach
is that each call site should call ErrorUtils.isError on the result and
report an error if needed, in order to stop this type from reaching the
codegen, which can't handle error types.

Now we create a MockClassDescriptor instance instead. It's not an error
class, so it'll be handled correctly in the codegen. Also its scope is
empty and errors are reported on any non-trivial usage (see
MissingDependencyClassChecker), so this approach is not worse than error
classes

 #KT-16484 Fixed
2017-02-28 20:19:58 +03:00
Alexander Udalov
794cc1e3be Refactor API of NotFoundClasses
Move deserialization-related stuff to TypeDeserializer, because it's
going to be used in other places besides deserialization
2017-02-28 20:19:58 +03:00
Alexander Udalov
86994f81c3 Refactor ClassId.getOuterClassId, make it nullable 2017-02-28 20:19:57 +03:00
7427 changed files with 77094 additions and 73829 deletions

2
.idea/ant.xml generated
View File

@@ -3,7 +3,7 @@
<component name="AntConfiguration">
<buildFile url="file://$PROJECT_DIR$/compiler/frontend/buildLexer.xml" />
<buildFile url="file://$PROJECT_DIR$/build.xml">
<antCommandLine value="-J-XX:MaxPermSize=100m -J-ea" />
<antCommandLine value="-J-ea" />
<maximumHeapSize value="1024" />
</buildFile>
<buildFile url="file://$PROJECT_DIR$/update_dependencies.xml" />

View File

@@ -11,7 +11,6 @@
<element id="directory" name="META-INF">
<element id="dir-copy" path="$PROJECT_DIR$/jps-plugin/src/META-INF" />
</element>
<element id="extracted-dir" path="$PROJECT_DIR$/dependencies/cli-parser-1.1.2.jar" path-in-jar="/" />
<element id="module-output" name="cli-common" />
<element id="module-output" name="idea-jps-common" />
<element id="module-output" name="jps-plugin" />

7
.idea/dictionaries/4u7.xml generated Normal file
View File

@@ -0,0 +1,7 @@
<component name="ProjectDictionaryState">
<dictionary name="4u7">
<words>
<w>foldable</w>
</words>
</dictionary>
</component>

View File

@@ -1,7 +1,6 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0" is_locked="false">
<profile version="1.0">
<option name="myName" value="idea.default" />
<option name="myLocal" value="false" />
<inspection_tool class="AbstractMethodCallInConstructor" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="ArchaicSystemPropertyAccess" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="AssignmentToForLoopParameter" enabled="true" level="WARNING" enabled_by_default="true">
@@ -236,10 +235,6 @@
<scope name="idea openapi" level="WARNING" enabled="true" />
<scope name="runtime.classes" level="ERROR" enabled="true" />
</inspection_tool>
<inspection_tool class="LoggerInitializedWithForeignClass" enabled="false" level="WARNING" enabled_by_default="false">
<option name="loggerClassName" value="org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger" />
<option name="loggerFactoryMethodName" value="getLogger,getLogger,getLog,getLogger" />
</inspection_tool>
<inspection_tool class="LoopToCallChain" enabled="false" level="INFO" enabled_by_default="false" />
<inspection_tool class="MethodMayBeStatic" enabled="true" level="WARNING" enabled_by_default="true">
<option name="m_onlyPrivateOrFinal" value="false" />
@@ -347,11 +342,12 @@
<constraint name="__context__" script="&quot;&quot;" within="" contains="" />
</searchConfiguration>
</inspection_tool>
<inspection_tool class="SameParameterValue" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="SetReplaceableByEnumSet" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SetupCallsSuperSetup" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SetupIsPublicVoidNoArg" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="SimplifiableIfStatement" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="Since15" enabled="true" level="ERROR" enabled_by_default="true">
<inspection_tool class="Since15" enabled="false" level="ERROR" enabled_by_default="false">
<scope name="IDEA Test Sources" level="ERROR" enabled="false" />
</inspection_tool>
<inspection_tool class="SocketResource" enabled="true" level="WARNING" enabled_by_default="true">

View File

@@ -8,7 +8,7 @@
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
<root url="jar://$PROJECT_DIR$/dependencies/asm-src.zip!/" />
</SOURCES>
</library>
</component>

View File

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

View File

@@ -4,11 +4,11 @@
<root url="file://$PROJECT_DIR$/annotations" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/guava-17.0.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/guava-19.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/guava-17.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/dependencies/guava-19.0-sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -9,9 +9,9 @@
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/guava-17.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
<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!/" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/lib" recursive="false" />
</library>

View File

@@ -9,9 +9,9 @@
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/guava-17.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
<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!/" />
</SOURCES>
<jarDirectory url="file://$PROJECT_DIR$/ideaSDK/core" recursive="false" />
</library>

View File

@@ -1,17 +0,0 @@
<component name="libraryTable">
<library name="intellij-core-analysis">
<ANNOTATIONS>
<root url="file://$PROJECT_DIR$/annotations" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$PROJECT_DIR$/ideaSDK/core-analysis/intellij-core-analysis.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
<root url="jar://$PROJECT_DIR$/dependencies/guava-17.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
</SOURCES>
</library>
</component>

View File

@@ -5,6 +5,7 @@
</ANNOTATIONS>
<CLASSES>
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/properties/lib/properties.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/plugins/properties/lib/resources_en.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>

3
.idea/misc.xml generated
View File

@@ -6,7 +6,6 @@
</properties>
</component>
<component name="EntryPointsManager">
<entry_points version="2.0" />
<list size="1">
<item index="0" class="java.lang.String" itemvalue="javax.inject.Inject" />
</list>
@@ -49,7 +48,7 @@
<component name="ProjectResources">
<default-html-doctype>http://www.w3.org/1999/xhtml</default-html-doctype>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" default="false" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" default="false" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
<component name="SuppressABINotification">

1
.idea/modules.xml generated
View File

@@ -92,6 +92,7 @@
<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$/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" />
<module fileurl="file://$PROJECT_DIR$/compiler/tests-common/tests-common.iml" filepath="$PROJECT_DIR$/compiler/tests-common/tests-common.iml" group="compiler" />
<module fileurl="file://$PROJECT_DIR$/compiler/tests-ir-jvm/tests-ir-jvm.iml" filepath="$PROJECT_DIR$/compiler/tests-ir-jvm/tests-ir-jvm.iml" group="compiler/ir" />
<module fileurl="file://$PROJECT_DIR$/plugins/uast-kotlin/uast-kotlin.iml" filepath="$PROJECT_DIR$/plugins/uast-kotlin/uast-kotlin.iml" group="plugins/lint" />

View File

@@ -13,7 +13,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 -XX:ReservedCodeCacheSize=64m -Djna.nosys=true" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx1250m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true" />
<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="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx900m -XX:MaxPermSize=320m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=64m -Djna.nosys=true" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true" />
<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="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx1100m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx900m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true -Dkotlin.colors.enabled=false" />
<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="-Xmx1250m -XX:ReservedCodeCacheSize=64m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Djna.nosys=true" />
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=128m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Djna.nosys=true" />
<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="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx700m -XX:MaxPermSize=300m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=64m -Djna.nosys=true" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -Xmx1024m -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true -Dkotlin.colors.enabled=false" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="IDEA" type="Application" factoryName="Application" singleton="true">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=64m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=128m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />

View File

@@ -2,7 +2,7 @@
<configuration default="false" name="IDEA (No ProcessCanceledException)" type="Application" factoryName="Application" singleton="true">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=64m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Didea.ProcessCanceledException=disabled -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
<option name="VM_PARAMETERS" value="-Xmx1250m -XX:ReservedCodeCacheSize=128m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Didea.ProcessCanceledException=disabled -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
<option name="PROGRAM_PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />

View File

@@ -13,7 +13,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 -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=64m -Djna.nosys=true" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=128m -Djna.nosys=true -Dkotlin.colors.enabled=false" />
<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="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="package" />
<option name="VM_PARAMETERS" value="-ea -XX:+HeapDumpOnOutOfMemoryError -XX:+UseCodeCacheFlushing -XX:ReservedCodeCacheSize=64m -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="-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="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$" />
<option name="ENV_VARIABLES" />

File diff suppressed because it is too large Load Diff

View File

@@ -29,8 +29,8 @@ internal object KotlinAntTaskUtil {
private val libPath: File by lazy {
// Find path of kotlin-ant.jar in the filesystem and find kotlin-compiler.jar in the same directory
val resourcePath = "/" + javaClass.name.replace('.', '/') + ".class"
val jarConnection = javaClass.getResource(resourcePath).openConnection() as? JarURLConnection
val resourcePath = "/" + this::class.java.name.replace('.', '/') + ".class"
val jarConnection = this::class.java.getResource(resourcePath).openConnection() as? JarURLConnection
?: throw UnsupportedOperationException("Kotlin compiler Ant task should be loaded from the JAR file")
val antTaskJarPath = File(jarConnection.jarFileURL.toURI())
@@ -54,7 +54,7 @@ internal object KotlinAntTaskUtil {
val cached = classLoaderRef.get()
if (cached != null) return cached
val myLoader = javaClass.classLoader
val myLoader = this::class.java.classLoader
if (myLoader !is AntClassLoader) return myLoader
val classLoader = ClassPreloadingUtils.preloadClasses(listOf(compilerJar), Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE, myLoader, null)

View File

@@ -19,9 +19,9 @@ package org.jetbrains.kotlin.compilerRunner;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ComparatorUtil;
import com.sampullara.cli.Argument;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments;
import org.jetbrains.kotlin.cli.common.parser.com.sampullara.cli.Argument;
import java.lang.reflect.Field;
import java.util.ArrayList;

View File

@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import java.io.File
import java.io.IOException
private val NORMAL_VERSION = 8
private val EXPERIMENTAL_VERSION = 4
@@ -40,8 +41,16 @@ class CacheVersion(
) {
private val isEnabled by lazy(isEnabled)
private val actualVersion: Int
get() = versionFile.readText().toInt()
private val actualVersion: Int?
get() = try {
versionFile.readText().toInt()
}
catch (e: NumberFormatException) {
null
}
catch (e: IOException) {
null
}
private val expectedVersion: Int
get() {

View File

@@ -43,7 +43,6 @@ import org.jetbrains.kotlin.serialization.deserialization.TypeTable
import org.jetbrains.kotlin.serialization.deserialization.supertypes
import org.jetbrains.kotlin.serialization.jvm.BitEncoding
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
import org.jetbrains.kotlin.utils.singletonOrEmptyList
import org.jetbrains.org.objectweb.asm.*
import java.io.File
import java.security.MessageDigest
@@ -272,7 +271,7 @@ open class IncrementalCacheImpl<Target>(
ProtoBuf.Class::getPropertyList
) + classData.classProto.enumEntryList.map { classData.nameResolver.getString(it.name) }
val companionObjectChanged = createChangeInfo(classFqName.parent(), classFqName.shortName().asString().singletonOrEmptyList())
val companionObjectChanged = createChangeInfo(classFqName.parent(), listOfNotNull(classFqName.shortName().asString()))
val companionObjectMembersChanged = createChangeInfo(classFqName, memberNames)
listOf(companionObjectMembersChanged, companionObjectChanged)
@@ -780,7 +779,7 @@ sealed class ChangeInfo(val fqName: FqName) {
protected open fun toStringProperties(): String = "fqName = $fqName"
override fun toString(): String {
return this.javaClass.simpleName + "(${toStringProperties()})"
return this::class.java.simpleName + "(${toStringProperties()})"
}
}

View File

@@ -50,5 +50,5 @@ class LocalFileKotlinClass private constructor(
override fun hashCode(): Int = file.hashCode()
override fun equals(other: Any?): Boolean = other is LocalFileKotlinClass && file == other.file
override fun toString(): String = "$javaClass: $file"
override fun toString(): String = "${this::class.java}: $file"
}

View File

@@ -42,7 +42,7 @@ import java.util.*
fun Iterable<File>.javaSourceRoots(roots: Iterable<File>): Iterable<File> =
filter { it.isJavaFile() }
filter(File::isJavaFile)
.map { findSrcDirRoot(it, roots) }
.filterNotNull()
@@ -145,7 +145,7 @@ fun LookupStorage.update(
filesToCompile: Iterable<File>,
removedFiles: Iterable<File>
) {
if (lookupTracker !is LookupTrackerImpl) throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker.javaClass}")
if (lookupTracker !is LookupTrackerImpl) throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}")
removeLookupsFrom(filesToCompile.asSequence() + removedFiles.asSequence())

View File

@@ -46,7 +46,7 @@ abstract class BasicMap<K : Comparable<K>, V>(
fun dump(): String {
return with(StringBuilder()) {
with(Printer(this)) {
println(this@BasicMap.javaClass.simpleName)
println(this@BasicMap::class.java.simpleName)
pushIndent()
for (key in storage.keys.sorted()) {

View File

@@ -131,7 +131,7 @@ object ConstantsMapExternalizer : DataExternalizer<Map<String, Any>> {
output.writeByte(Kind.STRING.ordinal)
IOUtil.writeString(value, output)
}
else -> throw IllegalStateException("Unexpected constant class: ${value.javaClass}")
else -> throw IllegalStateException("Unexpected constant class: ${value::class.java}")
}
}
}

View File

@@ -144,7 +144,7 @@ private fun classFileToString(classFile: File): String {
out.write("\n------ string table types proto -----\n${DebugJvmProtoBuf.StringTableTypes.parseDelimitedFrom(input)}")
if (!classHeader!!.metadataVersion.isCompatible()) {
if (!classHeader.metadataVersion.isCompatible()) {
error("Incompatible class ($classHeader): $classFile")
}

View File

@@ -81,8 +81,8 @@ fun getModificationsToPerform(
val rules = mapOf<String, (String, File) -> Modification>(
newSuffix to { path, file -> ModifyContent(path, file) },
touchSuffix to { path, file -> TouchFile(path, touchPolicy) },
deleteSuffix to { path, file -> DeleteFile(path) }
touchSuffix to { path, _ -> TouchFile(path, touchPolicy) },
deleteSuffix to { path, _ -> DeleteFile(path) }
)
val modifications = ArrayList<Modification>()
@@ -130,7 +130,7 @@ fun getModificationsToPerform(
abstract class Modification(val path: String) {
abstract fun perform(workDir: File, mapping: MutableMap<File, File>)
override fun toString(): String = "${javaClass.simpleName} $path"
override fun toString(): String = "${this::class.java.simpleName} $path"
}
class ModifyContent(path: String, val dataFile: File) : Modification(path) {

View File

@@ -1,11 +1,11 @@
<project name="Kotlin" default="dist" xmlns:if="ant:if" xmlns:unless="ant:unless">
<project xmlns:if="ant:if" xmlns:unless="ant:unless" name="Kotlin" default="dist">
<import file="common.xml" optional="false"/>
<property file="resources/kotlinManifest.properties"/>
<!-- Set to false to disable proguard run on kotlin-compiler.jar. Speeds up the build -->
<property name="shrink" value="true"/>
<!-- Set to false to disable compiler's javadoc generation. Speeds up the build -->
<property name="generate.javadoc" value="true"/>
<property name="generate.javadoc" value="false"/>
<!-- Set to false to prevent jarjar and metadata stripping on kotlin-reflect.jar and reflection sources. Use to debug reflection -->
<property name="obfuscate.reflect" value="true"/>
@@ -28,7 +28,8 @@
<property name="protobuf-lite.jar" value="${basedir}/dependencies/protobuf-2.6.1-lite.jar"/>
<property name="javax.inject.jar" value="${basedir}/lib/javax.inject.jar"/>
<property name="java.target" value="1.6"/>
<property name="java.target" value="1.8"/>
<property name="java.target.1.6" value="1.6"/>
<condition property="bootstrap.or.local.build" value="true">
<or>
@@ -72,7 +73,6 @@
<fileset dir="${basedir}/lib" includes="**/*.jar"/>
<fileset dir="${dependencies}" includes="jansi.jar"/>
<fileset dir="${dependencies}" includes="jline.jar"/>
<fileset dir="${dependencies}" includes="cli-parser-1.1.2.jar"/>
<fileset dir="${basedir}/ideaSDK/jps" includes="jps-model.jar"/>
</path>
@@ -406,9 +406,12 @@
byline="true" encoding="UTF-8" />
</target>
<target name="js-stdlib">
<property environment="env"/>
<target name="js-stdlib-preprocess">
<kotlin-pp src="libraries/stdlib/src" output="${intermediate-sources}/stdlib/js" profile="JS" />
</target>
<target name="js-stdlib" depends="js-stdlib-preprocess">
<property environment="env"/>
<cleandir dir="${js.stdlib.output.dir}"/>
<!-- We don't want descriptors for built-ins to be serialized, so we compile these files separately. -->
@@ -474,7 +477,7 @@
<copy file="${kotlin-home}/lib/kotlin-stdlib-js.jar" tofile="${kotlin-home}/lib/kotlin-jslib.jar" />
</target>
<target name="pack-js-stdlib-sources">
<target name="pack-js-stdlib-sources" depends="js-stdlib-preprocess">
<jar destfile="${kotlin-home}/lib/kotlin-stdlib-js-sources.jar" duplicate="fail">
<resources refid="js.lib.files" />
<fileset refid="kotlin.builtin.files" />
@@ -581,12 +584,22 @@
</fileset>
<zipgroupfileset dir="${basedir}/lib" includes="*.jar"/>
<zipgroupfileset dir="${basedir}/ideaSDK/core" includes="*.jar" excludes="util.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/annotations.jar"/>
<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/jna.jar"/>
<zipfileset src="${basedir}/ideaSDK/core/log4j.jar"/>
<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}/jps/jps-model.jar"/>
<zipfileset src="${dependencies}/jline.jar"/>
<zipfileset src="${dependencies}/cli-parser-1.1.2.jar"/>
<zipfileset src="${protobuf.jar}"/>
<manifest>
@@ -764,24 +777,44 @@
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.daemon-client}"/>
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.daemon.client}"/>
<attribute name="Implementation-Version" value="${build.number}"/>
</manifest>
</jar>
</target>
<jar jarfile="${output}/kotlin-daemon-client-sources.jar">
<fileset dir="compiler/daemon/daemon-common/src"/>
<fileset dir="compiler/daemon/daemon-client/src"/>
<target name="compiler-client-embeddable">
<cleandir dir="${output}/classes/compiler-client-embeddable"/>
<javac2 destdir="${output}/classes/compiler-client-embeddable" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
<withKotlin modulename="compiler-deps">
<compilerarg value="-version"/>
</withKotlin>
<src>
<pathelement path="compiler/daemon/daemon-common/src"/>
<pathelement path="compiler/cli/cli-common/"/>
</src>
<classpath>
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
<pathelement path="${idea.sdk}/core/intellij-core.jar"/>
</classpath>
</javac2>
<taskdef name="jarjar" classname="com.tonicsystems.jarjar.JarJarTask" classpath="dependencies/jarjar.jar"/>
<jarjar jarfile="${kotlin-home}/lib/kotlin-compiler-client-embeddable.jar">
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
<zipfileset src="${kotlin-home}/lib/kotlin-daemon-client.jar" excludes="net/rubygrapefruit/platform/** net/ net/rubygrapefruit/"/>
<fileset dir="${output}/classes/compiler-client-embeddable"
includes="META-INF/** org/jetbrains/kotlin/daemon/common/** org/jetbrains/kotlin/cli/common/messages/CompilerMessage* org/jetbrains/kotlin/cli/common/messages/Message* org/jetbrains/kotlin/cli/common/repl/**"/>
<manifest>
<attribute name="Built-By" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Vendor" value="${manifest.impl.vendor}"/>
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.daemon.client.sources}"/>
<attribute name="Implementation-Title" value="${manifest.impl.title.kotlin.compiler.client.embeddable}"/>
<attribute name="Implementation-Version" value="${build.number}"/>
<attribute name="Class-Path" value="kotlin-stdlib.jar"/>
</manifest>
</jar>
</jarjar>
</target>
<target name="android-extensions-compiler">
@@ -876,6 +909,29 @@
</jar>
</target>
<target name="source-sections-compiler-plugin">
<cleandir dir="${output}/classes/source-sections-compiler-plugin"/>
<javac2 destdir="${output}/classes/source-sections-compiler-plugin" debug="true" debuglevel="lines,vars,source" includeAntRuntime="false">
<withKotlin modulename="source-sections">
<compilerarg value="-version"/>
</withKotlin>
<skip pattern="kotlin/Metadata"/>
<src>
<pathelement path="plugins/source-sections/source-sections-compiler/src"/>
</src>
<classpath>
<pathelement path="${idea.sdk}/core/intellij-core.jar"/>
<pathelement path="${kotlin-home}/lib/kotlin-compiler.jar"/>
</classpath>
</javac2>
<jar destfile="${kotlin-home}/lib/source-sections-compiler-plugin.jar">
<fileset dir="${output}/classes/source-sections-compiler-plugin"/>
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
<fileset dir="${basedir}/plugins/source-sections/source-sections-compiler/src" includes="META-INF/services/**"/>
</jar>
</target>
<target name="annotation-processing-under-jdk8">
<property environment="env"/>
@@ -1013,7 +1069,7 @@
</java>
<javac2 srcdir="${toString:src.dirset}" destdir="@{output}" debug="true" debuglevel="lines,vars,source"
includeAntRuntime="false" source="${java.target}" target="${java.target}">
includeAntRuntime="false" source="${java.target.1.6}" target="${java.target.1.6}">
<skip pattern="kotlin/Metadata"/>
<classpath>
<path refid="classpath.path"/>
@@ -1032,13 +1088,13 @@
<sequential>
<java classname="org.jetbrains.kotlin.preloading.Preloader" failonerror="true" fork="true" maxmemory="${max.heap.size.for.forked.jvm}">
<classpath>
<pathelement location="${kotlin-home}/lib/kotlin-preloader.jar"/>
<pathelement location="${bootstrap.compiler.home}/lib/kotlin-preloader.jar"/>
</classpath>
<assertions>
<enable/>
</assertions>
<arg value="-cp"/>
<arg value="${kotlin-home}/lib/kotlin-compiler.jar"/>
<arg value="${bootstrap.compiler.home}/lib/kotlin-compiler.jar"/>
<arg value="org.jetbrains.kotlin.preprocessor.PreprocessorCLI"/>
<arg value="@{src}"/>
<arg value="@{output}"/>
@@ -1338,11 +1394,11 @@
depends="builtins,stdlib,kotlin-test,core,reflection,pack-runtime,pack-runtime-sources,script-runtime,mock-runtime-for-test"/>
<target name="dist"
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,ant-tools,runtime,kotlin-js-stdlib,android-extensions-compiler,allopen-compiler-plugin,noarg-compiler-plugin,sam-with-receiver-compiler-plugin,annotation-processing-under-jdk8,daemon-client,kotlin-build-common-test"
depends="clean,init,prepare-dist,preloader,runner,serialize-builtins,compiler,compiler-sources,ant-tools,runtime,kotlin-js-stdlib,android-extensions-compiler,allopen-compiler-plugin,noarg-compiler-plugin,sam-with-receiver-compiler-plugin,source-sections-compiler-plugin,annotation-processing-under-jdk8,daemon-client,compiler-client-embeddable,kotlin-build-common-test"
description="Builds redistributables from sources"/>
<target name="dist-quick"
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler-quick,ant-tools,runtime,kotlin-js-stdlib,android-extensions-compiler,allopen-compiler-plugin,noarg-compiler-plugin,sam-with-receiver-compiler-plugin,annotation-processing-under-jdk8"
depends="clean,init,prepare-dist,preloader,serialize-builtins,compiler-quick,ant-tools,runtime,kotlin-js-stdlib,android-extensions-compiler,allopen-compiler-plugin,noarg-compiler-plugin,sam-with-receiver-compiler-plugin,source-sections-compiler-plugin,annotation-processing-under-jdk8"
description="Builds everything, but classes are reused from project out dir, doesn't run proguard and javadoc"/>
<target name="dist-quick-compiler-only"

View File

@@ -29,8 +29,8 @@ public class AndroidJpsBuildTestCase extends BaseKotlinJpsBuildTestCase {
public void doTest() {
initProject();
rebuildAll();
makeAll().assertSuccessful();
rebuildAllModules();
buildAllModules().assertSuccessful();
}
@Override

View File

@@ -91,7 +91,7 @@ object CodegenUtil {
else if (traitMember is PropertyDescriptor) {
for (traitAccessor in traitMember.accessors) {
for (inheritedAccessor in (copy as PropertyDescriptor).accessors) {
if (inheritedAccessor.javaClass == traitAccessor.javaClass) { // same accessor kind
if (inheritedAccessor::class.java == traitAccessor::class.java) { // same accessor kind
result.put(traitAccessor, inheritedAccessor)
}
}
@@ -161,6 +161,6 @@ object CodegenUtil {
val fakeFunctionCall = StringBuilder("callableReferenceFakeCall(")
fakeFunctionCall.append(referencedFunction.valueParameters.map { "p${it.index}" }.joinToString(", "))
fakeFunctionCall.append(")")
return KtPsiFactory(project).createExpression(fakeFunctionCall.toString()) as KtCallExpression
return KtPsiFactory(project, markGenerated = false).createExpression(fakeFunctionCall.toString()) as KtCallExpression
}
}

View File

@@ -103,5 +103,5 @@ abstract class DataClassMethodGenerator(private val declaration: KtClassOrObject
.map { bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, it)!! }
private val primaryConstructorParameters: List<KtParameter>
get() = (declaration as? KtClass)?.getPrimaryConstructorParameters().orEmpty()
get() = (declaration as? KtClass)?.primaryConstructorParameters.orEmpty()
}

View File

@@ -65,7 +65,17 @@ public abstract class AnnotationCodegen {
new JvmFlagAnnotation("kotlin.jvm.Synchronized", Opcodes.ACC_SYNCHRONIZED)
);
private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM5) {};
private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM5) {
@Override
public AnnotationVisitor visitAnnotation(String name, @NotNull String desc) {
return safe(super.visitAnnotation(name, desc));
}
@Override
public AnnotationVisitor visitArray(String name) {
return safe(super.visitArray(name));
}
};
private final InnerClassConsumer innerClassConsumer;
private final KotlinTypeMapper typeMapper;

View File

@@ -77,9 +77,13 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
}
}
generatePrimaryConstructorProperties();
generateConstructors();
generateDefaultImplsIfNeeded();
boolean generateNonClassMembers = shouldGenerateNonClassMembers();
if (generateNonClassMembers) {
generatePrimaryConstructorProperties();
generateConstructors();
generateDefaultImplsIfNeeded();
}
// Generate _declared_ companions
for (KtObjectDeclaration companion : companions) {
@@ -92,23 +96,30 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
genSyntheticClassOrObject((SyntheticClassOrObjectDescriptor) companionObjectDescriptor);
}
if (!DescriptorUtils.isInterface(descriptor)) {
for (DeclarationDescriptor memberDescriptor : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
if (memberDescriptor instanceof CallableMemberDescriptor) {
CallableMemberDescriptor member = (CallableMemberDescriptor) memberDescriptor;
if (!member.getKind().isReal() && ImplKt.findInterfaceImplementation(member) == null) {
if (member instanceof FunctionDescriptor) {
functionCodegen.generateBridges((FunctionDescriptor) member);
if (generateNonClassMembers) {
generateBridges();
}
}
private void generateBridges() {
if (DescriptorUtils.isInterface(descriptor)) {
return;
}
for (DeclarationDescriptor memberDescriptor : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
if (memberDescriptor instanceof CallableMemberDescriptor) {
CallableMemberDescriptor member = (CallableMemberDescriptor) memberDescriptor;
if (!member.getKind().isReal() && ImplKt.findInterfaceImplementation(member) == null) {
if (member instanceof FunctionDescriptor) {
functionCodegen.generateBridges((FunctionDescriptor) member);
}
else if (member instanceof PropertyDescriptor) {
PropertyGetterDescriptor getter = ((PropertyDescriptor) member).getGetter();
if (getter != null) {
functionCodegen.generateBridges(getter);
}
else if (member instanceof PropertyDescriptor) {
PropertyGetterDescriptor getter = ((PropertyDescriptor) member).getGetter();
if (getter != null) {
functionCodegen.generateBridges(getter);
}
PropertySetterDescriptor setter = ((PropertyDescriptor) member).getSetter();
if (setter != null) {
functionCodegen.generateBridges(setter);
}
PropertySetterDescriptor setter = ((PropertyDescriptor) member).getSetter();
if (setter != null) {
functionCodegen.generateBridges(setter);
}
}
}
@@ -116,6 +127,11 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
}
}
private boolean shouldGenerateNonClassMembers() {
return !(myClass instanceof KtClassOrObject) ||
state.getGenerateDeclaredClassFilter().shouldGenerateClassMembers((KtClassOrObject) myClass);
}
protected void generateConstructors() {
}
@@ -130,7 +146,9 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
protected void generateDeclaration(KtDeclaration declaration) {
if (declaration instanceof KtProperty || declaration instanceof KtNamedFunction || declaration instanceof KtTypeAlias) {
genSimpleMember(declaration);
if (shouldGenerateNonClassMembers()) {
genSimpleMember(declaration);
}
}
else if (declaration instanceof KtClassOrObject) {
if (declaration instanceof KtEnumEntry && !enumEntryNeedSubclass(bindingContext, (KtEnumEntry) declaration)) {

View File

@@ -55,20 +55,12 @@ public class ClassBuilderFactories {
throw new IllegalStateException();
}
};
public static ClassBuilderFactory TEST_KAPT3 = new TestClassBuilderFactory(false) {
@NotNull
@Override
public ClassBuilderMode getClassBuilderMode() {
return ClassBuilderMode.KAPT3;
}
};
public static ClassBuilderFactory TEST = new TestClassBuilderFactory(false);
public static ClassBuilderFactory TEST_WITH_SOURCE_RETENTION_ANNOTATIONS = new TestClassBuilderFactory(true);
private static class TestClassBuilderFactory implements ClassBuilderFactory {
public static class TestClassBuilderFactory implements ClassBuilderFactory {
private final boolean generateSourceRetentionAnnotations;
public TestClassBuilderFactory(boolean generateSourceRetentionAnnotations) {

View File

@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.TestOnly;
public class ClassBuilderMode {
public final boolean generateBodies;
public final boolean generateMetadata;
@@ -73,4 +75,11 @@ public class ClassBuilderMode {
/* metadata = */ true,
/* sourceRetention = */ true,
/* generateMultiFileFacadePartClasses = */ true);
@TestOnly
public final static ClassBuilderMode LIGHT_ANALYSIS_FOR_TESTS = new ClassBuilderMode(
/* bodies = */ false,
/* metadata = */ true,
/* sourceRetention = */ false,
/* generateMultiFileFacadePartClasses = */ true);
}

View File

@@ -82,7 +82,7 @@ public class ClassFileFactory implements OutputFileCollection {
return answer;
}
void done() {
public void done() {
if (!isDone) {
isDone = true;
writeModuleMappings();

View File

@@ -323,7 +323,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
Type[] myParameterTypes = bridge.getArgumentTypes();
List<ParameterDescriptor> calleeParameters = CollectionsKt.plus(
org.jetbrains.kotlin.utils.CollectionsKt.<ParameterDescriptor>singletonOrEmptyList(funDescriptor.getExtensionReceiverParameter()),
CollectionsKt.listOfNotNull(funDescriptor.getExtensionReceiverParameter()),
funDescriptor.getValueParameters()
);

View File

@@ -54,7 +54,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
contextKind: OwnerKind,
classOrObject: KtPureClassOrObject
) {
val methodElement = classOrObject.getPrimaryConstructor() ?: classOrObject
val methodElement = classOrObject.primaryConstructor ?: classOrObject
if (generateOverloadsIfNeeded(methodElement, constructorDescriptor, constructorDescriptor, contextKind, classBuilder, memberCodegen)) {
return
@@ -135,7 +135,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
(if (isStatic) Opcodes.ACC_STATIC else 0) or
(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.mapSignature(functionDescriptor, contextKind, remainingParameters, false)
val signature = typeMapper.mapSignatureWithCustomParameters(functionDescriptor, contextKind, remainingParameters, false)
val mv = classBuilder.newMethod(OtherOrigin(methodElement, functionDescriptor), flags,
signature.asmMethod.name,
signature.asmMethod.descriptor,
@@ -251,7 +251,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
val classDescriptor = constructorDescriptor.constructedClass
if (classDescriptor.kind != ClassKind.CLASS) return false
if (classOrObject.isLocal()) return false
if (classOrObject.isLocal) return false
if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false
@@ -265,6 +265,6 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
}
private fun hasSecondaryConstructorsWithNoParameters(klass: KtClass) =
klass.getSecondaryConstructors().any { it.valueParameters.isEmpty() }
klass.secondaryConstructors.any { it.valueParameters.isEmpty() }
}

View File

@@ -33,10 +33,10 @@ abstract class DelegatingClassBuilderFactory(
abstract override fun newClassBuilder(origin: JvmDeclarationOrigin): DelegatingClassBuilder
override fun asBytes(builder: ClassBuilder?): ByteArray? {
return delegate.asBytes((builder as DelegatingClassBuilder).getDelegate())
return delegate.asBytes((builder as DelegatingClassBuilder).delegate)
}
override fun asText(builder: ClassBuilder?): String? {
return delegate.asText((builder as DelegatingClassBuilder).getDelegate())
return delegate.asText((builder as DelegatingClassBuilder).delegate)
}
}

View File

@@ -1919,11 +1919,6 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return asmType(varType);
}
private static boolean isSharedVarType(@NotNull Type type) {
return type.getSort() == Type.OBJECT && type.getInternalName().startsWith(REF_TYPE_PREFIX);
}
private void putDescriptorIntoFrameMap(@NotNull KtElement statement) {
if (statement instanceof KtDestructuringDeclaration) {
KtDestructuringDeclaration multiDeclaration = (KtDestructuringDeclaration) statement;
@@ -2677,6 +2672,15 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
return invokeFunction(resolvedCall, receiver);
}
@Override
public StackValue visitCollectionLiteralExpression(
@NotNull KtCollectionLiteralExpression expression, StackValue data
) {
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(COLLECTION_LITERAL_CALL, expression);
assert resolvedCall != null : "No resolved call for " + PsiUtilsKt.getTextWithLocation(expression);
return invokeFunction(resolvedCall, data);
}
@Nullable
private StackValue genSamInterfaceValue(
@NotNull KtExpression probablyParenthesizedExpression,
@@ -3361,7 +3365,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
KotlinType receiverExpressionType = expressionJetType(expression.getReceiverExpression());
Type receiverAsmType = receiverExpressionType != null ? asmType(receiverExpressionType) : null;
StackValue receiverValue = receiverExpressionType != null ? gen(expression.getReceiverExpression()) : null;
StackValue receiverValue =
receiverExpressionType != null ? StackValue.coercion(gen(expression.getReceiverExpression()), receiverAsmType) : null;
FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
if (functionDescriptor != null) {
@@ -4320,6 +4325,8 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
private static ReceiverValue getConstructorReceiver(@NotNull ResolvedCall<?> resolvedCall) {
CallableDescriptor constructor = resolvedCall.getResultingDescriptor();
if (constructor.getExtensionReceiverParameter() != null) {
// see comment on `withDispatchReceiver` parameter in
// org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl.Companion.createIfAvailable
assert constructor instanceof TypeAliasConstructorDescriptor :
"Only type alias constructor can have an extension receiver: " + constructor;
return resolvedCall.getExtensionReceiver();
@@ -4888,7 +4895,7 @@ The "returned" value of try expression with no finally is either the last expres
}
private Call makeFakeCall(ReceiverValue initializerAsReceiver) {
KtSimpleNameExpression fake = KtPsiFactoryKt.KtPsiFactory(state.getProject()).createSimpleName("fake");
KtSimpleNameExpression fake = KtPsiFactoryKt.KtPsiFactory(state.getProject(), false).createSimpleName("fake");
return CallMaker.makeCall(fake, initializerAsReceiver);
}

View File

@@ -920,17 +920,23 @@ public class FunctionCodegen {
// enum constructors have two additional synthetic parameters which somewhat complicate this task
AnnotationCodegen.forMethod(mv, memberCodegen, typeMapper).genAnnotations(functionDescriptor, defaultMethod.getReturnType());
if (state.getClassBuilderMode().generateBodies) {
if (this.owner instanceof MultifileClassFacadeContext) {
mv.visitCode();
generateFacadeDelegateMethodBody(mv, defaultMethod, (MultifileClassFacadeContext) this.owner);
if (!state.getClassBuilderMode().generateBodies) {
if (this.owner instanceof MultifileClassFacadeContext)
endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
}
else {
mv.visitCode();
generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen, defaultMethod);
else
endVisit(mv, "default method", getSourceFromDescriptor(functionDescriptor));
}
return;
}
if (this.owner instanceof MultifileClassFacadeContext) {
mv.visitCode();
generateFacadeDelegateMethodBody(mv, defaultMethod, (MultifileClassFacadeContext) this.owner);
endVisit(mv, "default method delegation", getSourceFromDescriptor(functionDescriptor));
}
else {
mv.visitCode();
generateDefaultImplBody(owner, functionDescriptor, mv, loadStrategy, function, memberCodegen, defaultMethod);
endVisit(mv, "default method", getSourceFromDescriptor(functionDescriptor));
}
}

View File

@@ -173,7 +173,7 @@ public class FunctionReferenceGenerationStrategy extends FunctionGenerationStrat
) {
if (receiver == null) return null;
KtExpression receiverExpression = KtPsiFactoryKt.KtPsiFactory(state.getProject()).createExpression("callableReferenceFakeReceiver");
KtExpression receiverExpression = KtPsiFactoryKt.KtPsiFactory(state.getProject(), false).createExpression("callableReferenceFakeReceiver");
codegen.tempVariables.put(receiverExpression, receiverParameterStackValue(signature, codegen));
return ExpressionReceiver.Companion.create(receiverExpression, receiver.getType(), BindingContext.EMPTY);
}

View File

@@ -85,9 +85,11 @@ import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.JAVA_STRING_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin.NO_ORIGIN;
import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL;
import static org.jetbrains.kotlin.types.Variance.INVARIANT;
import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isLocalFunction;
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
import static org.jetbrains.org.objectweb.asm.Type.getObjectType;
public class ImplementationBodyCodegen extends ClassBodyCodegen {
private static final String ENUM_VALUES_FIELD_NAME = "$VALUES";
@@ -113,7 +115,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
boolean isLocal
) {
super(aClass, context, v, state, parentCodegen);
this.classAsmType = typeMapper.mapClass(descriptor);
this.classAsmType = getObjectType(typeMapper.classInternalName(descriptor));
this.isLocal = isLocal;
delegationFieldsInfo = getDelegationFieldsInfo(myClass.getSuperTypeListEntries());
}
@@ -127,55 +129,47 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
boolean isAbstract = false;
boolean isInterface = false;
boolean isFinal = false;
boolean isStatic;
boolean isAnnotation = false;
boolean isEnum = false;
ClassKind kind = descriptor.getKind();
if (kind == ClassKind.OBJECT) {
isStatic = isCompanionObject(descriptor);
isFinal = true;
Modality modality = descriptor.getModality();
if (modality == Modality.ABSTRACT || modality == Modality.SEALED) {
isAbstract = true;
}
else {
Modality modality = descriptor.getModality();
if (modality == Modality.ABSTRACT || modality == Modality.SEALED) {
isAbstract = true;
}
if (kind == ClassKind.INTERFACE) {
isAbstract = true;
isInterface = true;
}
else if (kind == ClassKind.ANNOTATION_CLASS) {
isAbstract = true;
isInterface = true;
isAnnotation = true;
}
else if (kind == ClassKind.ENUM_CLASS) {
isAbstract = hasAbstractMembers(descriptor);
isEnum = true;
}
if (kind == ClassKind.INTERFACE) {
isAbstract = true;
isInterface = true;
}
else if (kind == ClassKind.ANNOTATION_CLASS) {
isAbstract = true;
isInterface = true;
isAnnotation = true;
}
else if (kind == ClassKind.ENUM_CLASS) {
isAbstract = hasAbstractMembers(descriptor);
isEnum = true;
}
if (modality != Modality.OPEN && !isAbstract) {
// Light-class mode: Do not make enum classes final since PsiClass corresponding to enum is expected to be inheritable from
isFinal = !(kind == ClassKind.ENUM_CLASS && !state.getClassBuilderMode().generateBodies);
}
isStatic = !descriptor.isInner();
if (modality != Modality.OPEN && !isAbstract) {
isFinal = kind == ClassKind.OBJECT ||
// Light-class mode: Do not make enum classes final since PsiClass corresponding to enum is expected to be inheritable from
!(kind == ClassKind.ENUM_CLASS && !state.getClassBuilderMode().generateBodies);
}
int access = 0;
if (!state.getClassBuilderMode().generateBodies && !DescriptorUtils.isTopLevelDeclaration(descriptor)) {
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES && !DescriptorUtils.isTopLevelDeclaration(descriptor)) {
// !ClassBuilderMode.generateBodies means we are generating light classes & looking at a nested or inner class
// Light class generation is implemented so that Cls-classes only read bare code of classes,
// without knowing whether these classes are inner or not (see ClassStubBuilder.EMPTY_STRATEGY)
// Thus we must write full accessibility flags on inner classes in this mode
access |= getVisibilityAccessFlag(descriptor);
// Same for STATIC
if (isStatic) {
if (!descriptor.isInner()) {
access |= ACC_STATIC;
}
}
@@ -332,7 +326,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (String kotlinMarkerInterface : kotlinMarkerInterfaces) {
sw.writeInterface();
sw.writeAsmType(Type.getObjectType(kotlinMarkerInterface));
sw.writeAsmType(getObjectType(kotlinMarkerInterface));
sw.writeInterfaceEnd();
}
@@ -374,6 +368,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (context.closure != null)
genClosureFields(context.closure, v, typeMapper);
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) return;
for (ExpressionCodegenExtension extension : ExpressionCodegenExtension.Companion.getInstances(state.getProject())) {
extension.generateClassSyntheticParts(this);
}
@@ -1207,9 +1203,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
}
else if (descriptor instanceof VariableDescriptor) {
if (descriptor.getContainingDeclaration() instanceof ConstructorDescriptor) {
ClassDescriptor classDescriptor =
(ClassDescriptor) descriptor.getContainingDeclaration().getContainingDeclaration();
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration instanceof ConstructorDescriptor) {
ClassDescriptor classDescriptor = ((ConstructorDescriptor) containingDeclaration).getConstructedClass();
if (classDescriptor == ImplementationBodyCodegen.this.descriptor) return;
}
lookupInContext(descriptor);
@@ -1313,14 +1309,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
CodegenUtilKt.reportTarget6InheritanceErrorIfNeeded(descriptor, myClass.getPsiOrParent(), restrictedInheritance, state);
}
private void generateDelegationToDefaultImpl(@NotNull final FunctionDescriptor traitFun, @NotNull final FunctionDescriptor inheritedFun) {
private void generateDelegationToDefaultImpl(@NotNull final FunctionDescriptor interfaceFun, @NotNull final FunctionDescriptor inheritedFun) {
functionCodegen.generateMethod(
JvmDeclarationOriginKt.DelegationToDefaultImpls(descriptorToDeclaration(traitFun), traitFun),
new JvmDeclarationOrigin(CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL, descriptorToDeclaration(interfaceFun), interfaceFun),
inheritedFun,
new FunctionGenerationStrategy.CodegenBased(state) {
@Override
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
DeclarationDescriptor containingDeclaration = traitFun.getContainingDeclaration();
DeclarationDescriptor containingDeclaration = interfaceFun.getContainingDeclaration();
if (!DescriptorUtils.isInterface(containingDeclaration)) return;
DeclarationDescriptor declarationInheritedFun = inheritedFun.getContainingDeclaration();
@@ -1332,12 +1328,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ClassDescriptor containingTrait = (ClassDescriptor) containingDeclaration;
Type traitImplType = typeMapper.mapDefaultImpls(containingTrait);
Method traitMethod = typeMapper.mapAsmMethod(traitFun.getOriginal(), OwnerKind.DEFAULT_IMPLS);
Method traitMethod = typeMapper.mapAsmMethod(interfaceFun.getOriginal(), OwnerKind.DEFAULT_IMPLS);
Type[] argTypes = signature.getAsmMethod().getArgumentTypes();
Type[] originalArgTypes = traitMethod.getArgumentTypes();
assert originalArgTypes.length == argTypes.length + 1 :
"Invalid trait implementation signature: " + signature + " vs " + traitMethod + " for " + traitFun;
"Invalid trait implementation signature: " + signature + " vs " + traitMethod + " for " + interfaceFun;
InstructionAdapter iv = codegen.v;
iv.load(0, OBJECT_TYPE);

View File

@@ -29,8 +29,8 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtPureClassOrObject
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.diagnostics.DelegationToDefaultImpls
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.org.objectweb.asm.MethodVisitor
@@ -48,8 +48,10 @@ class InterfaceImplBodyCodegen(
get() = (v as InterfaceImplClassBuilder).isAnythingGenerated
override fun generateDeclaration() {
val codegenFlags = ACC_PUBLIC or ACC_FINAL or ACC_SUPER
val flags = if (state.classBuilderMode == ClassBuilderMode.LIGHT_CLASSES) codegenFlags or ACC_STATIC else codegenFlags
v.defineClass(
myClass.psiOrParent, state.classFileVersion, ACC_PUBLIC or ACC_FINAL or ACC_SUPER,
myClass.psiOrParent, state.classFileVersion, flags,
typeMapper.mapDefaultImpls(descriptor).internalName,
null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY
)
@@ -113,7 +115,10 @@ class InterfaceImplBodyCodegen(
if (delegateTo is JavaMethodDescriptor) return
functionCodegen.generateMethod(
DelegationToDefaultImpls(DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor),
JvmDeclarationOrigin(
JvmDeclarationOriginKind.DEFAULT_IMPL_DELEGATION_TO_SUPERINTERFACE_DEFAULT_IMPL,
DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor
),
descriptor,
object : FunctionGenerationStrategy.CodegenBased(state) {
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {

View File

@@ -127,7 +127,10 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
generateBody();
generateSyntheticParts();
if (!(element instanceof KtClassOrObject) ||
state.getGenerateDeclaredClassFilter().shouldGenerateClassMembers((KtClassOrObject) element)) {
generateSyntheticParts();
}
if (state.getClassBuilderMode().generateMetadata) {
generateKotlinMetadataAnnotation();
@@ -342,17 +345,19 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
}
private void writeInnerClass(@NotNull ClassDescriptor innerClass) {
writeInnerClass(innerClass, typeMapper, v);
if (!ErrorUtils.isError(innerClass)) {
writeInnerClass(innerClass, typeMapper, v);
}
}
public static void writeInnerClass(@NotNull ClassDescriptor innerClass, @NotNull KotlinTypeMapper typeMapper, @NotNull ClassBuilder v) {
DeclarationDescriptor containing = innerClass.getContainingDeclaration();
String outerClassInternalName = null;
if (containing instanceof ClassDescriptor) {
outerClassInternalName = typeMapper.mapClass((ClassDescriptor) containing).getInternalName();
outerClassInternalName = typeMapper.classInternalName((ClassDescriptor) containing);
}
String innerName = innerClass.getName().isSpecial() ? null : innerClass.getName().asString();
String innerClassInternalName = typeMapper.mapClass(innerClass).getInternalName();
String innerClassInternalName = typeMapper.classInternalName(innerClass);
v.visitInnerClass(innerClassInternalName, outerClassInternalName, innerName, calculateInnerClassAccessFlags(innerClass));
}

View File

@@ -176,7 +176,7 @@ class MultifileClassPartCodegen(
}
val serializer = DescriptorSerializer.createTopLevel(JvmSerializerExtension(v.serializationBindings, state))
val packageProto = serializer.packagePartProto(members).build()
val packageProto = serializer.packagePartProto(packageFragment.fqName, members).build()
val extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0

View File

@@ -129,7 +129,7 @@ public class PackagePartCodegen extends MemberCodegen<KtFile> {
final DescriptorSerializer serializer =
DescriptorSerializer.createTopLevel(new JvmSerializerExtension(v.getSerializationBindings(), state));
final ProtoBuf.Package packageProto = serializer.packagePartProto(members).build();
final ProtoBuf.Package packageProto = serializer.packagePartProto(element.getPackageFqName(), members).build();
WriteAnnotationUtilKt.writeKotlinMetadata(v, state, KotlinClassHeader.Kind.FILE_FACADE, 0, new Function1<AnnotationVisitor, Unit>() {
@Override

View File

@@ -57,7 +57,6 @@ import java.util.List;
import static org.jetbrains.kotlin.codegen.AsmUtil.getDeprecatedAccessFlag;
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityForBackingField;
import static org.jetbrains.kotlin.codegen.AsmUtil.isPropertyWithBackingFieldCopyInOuterClass;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
@@ -189,7 +188,7 @@ public class PropertyCodegen {
if (isCompanionObject(descriptor.getContainingDeclaration())) return true;
// Non-const properties from multifile classes have accessors regardless of visibility
if (!descriptor.isConst() && JvmFileClassUtilKt.isInsideJvmMultifileClassFile(declaration)) return true;
if (isNonConstTopLevelPropertyInMultifileClass(declaration, descriptor)) return true;
// Private class properties have accessors only in cases when those accessors are non-trivial
if (Visibilities.isPrivate(descriptor.getVisibility())) {
@@ -199,6 +198,15 @@ public class PropertyCodegen {
return true;
}
private static boolean isNonConstTopLevelPropertyInMultifileClass(
@NotNull KtProperty declaration,
@NotNull PropertyDescriptor descriptor
) {
return !descriptor.isConst() &&
descriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor &&
JvmFileClassUtilKt.isInsideJvmMultifileClassFile(declaration);
}
private static boolean areAccessorsNeededForPrimaryConstructorProperty(
@NotNull PropertyDescriptor descriptor
) {

View File

@@ -27,7 +27,7 @@ import org.jetbrains.org.objectweb.asm.FieldVisitor
import org.jetbrains.org.objectweb.asm.MethodVisitor
abstract class SignatureCollectingClassBuilderFactory(
delegate: ClassBuilderFactory
delegate: ClassBuilderFactory, val shouldGenerate: (JvmDeclarationOrigin) -> Boolean
) : DelegatingClassBuilderFactory(delegate) {
protected abstract fun handleClashingSignatures(data: ConflictingJvmDeclarationsData)
@@ -57,11 +57,17 @@ abstract class SignatureCollectingClassBuilderFactory(
override fun newField(origin: JvmDeclarationOrigin, access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor {
signatures.putValue(RawSignature(name, desc, MemberKind.FIELD), origin)
if (!shouldGenerate(origin)) {
return AbstractClassBuilder.EMPTY_FIELD_VISITOR
}
return super.newField(origin, access, name, desc, signature, value)
}
override fun newMethod(origin: JvmDeclarationOrigin, access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor {
signatures.putValue(RawSignature(name, desc, MemberKind.METHOD), origin)
if (!shouldGenerate(origin)) {
return AbstractClassBuilder.EMPTY_METHOD_VISITOR
}
return super.newMethod(origin, access, name, desc, signature, exceptions)
}

View File

@@ -34,7 +34,7 @@ data class SourceInfo(val source: String, val pathOrCleanFQN: String, val linesI
val isTopLevel = element is KtFile || (element is KtNamedFunction && element.getParent() is KtFile)
val cleanedClassFqName = if (!isTopLevel) internalClassName else internalClassName.substringBefore('$')
return SourceInfo(element.getContainingKtFile().name, cleanedClassFqName, lineNumbers!!)
return SourceInfo(element.containingKtFile.name, cleanedClassFqName, lineNumbers!!)
}
}

View File

@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
@@ -281,60 +282,29 @@ public abstract class StackValue {
}
private static void box(Type type, Type toType, InstructionAdapter v) {
if (type == Type.BYTE_TYPE || toType.getInternalName().equals(NULLABLE_BYTE_TYPE_NAME) && type == Type.INT_TYPE) {
v.cast(type, Type.BYTE_TYPE);
v.invokestatic(NULLABLE_BYTE_TYPE_NAME, "valueOf", "(B)L" + NULLABLE_BYTE_TYPE_NAME + ";", false);
}
else if (type == Type.SHORT_TYPE || toType.getInternalName().equals(NULLABLE_SHORT_TYPE_NAME) && type == Type.INT_TYPE) {
v.cast(type, Type.SHORT_TYPE);
v.invokestatic(NULLABLE_SHORT_TYPE_NAME, "valueOf", "(S)L" + NULLABLE_SHORT_TYPE_NAME + ";", false);
}
else if (type == Type.LONG_TYPE || toType.getInternalName().equals(NULLABLE_LONG_TYPE_NAME) && type == Type.INT_TYPE) {
v.cast(type, Type.LONG_TYPE);
v.invokestatic(NULLABLE_LONG_TYPE_NAME, "valueOf", "(J)L" + NULLABLE_LONG_TYPE_NAME + ";", false);
}
else if (type == Type.INT_TYPE) {
v.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
}
else if (type == Type.BOOLEAN_TYPE) {
v.invokestatic("java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
}
else if (type == Type.CHAR_TYPE) {
v.invokestatic("java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
}
else if (type == Type.FLOAT_TYPE) {
v.invokestatic("java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
}
else if (type == Type.DOUBLE_TYPE) {
v.invokestatic("java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
if (type == Type.INT_TYPE) {
if (toType.getInternalName().equals(NULLABLE_BYTE_TYPE_NAME)) {
type = Type.BYTE_TYPE;
}
else if (toType.getInternalName().equals(NULLABLE_SHORT_TYPE_NAME)) {
type = Type.SHORT_TYPE;
}
else if (toType.getInternalName().equals(NULLABLE_LONG_TYPE_NAME)) {
type = Type.LONG_TYPE;
}
v.cast(Type.INT_TYPE, type);
}
Type boxedType = AsmUtil.boxType(type);
if (boxedType == type) return;
v.invokestatic(boxedType.getInternalName(), "valueOf", Type.getMethodDescriptor(boxedType, type), false);
coerce(boxedType, toType, v);
}
private static void unbox(Type type, InstructionAdapter v) {
if (type == Type.INT_TYPE) {
v.invokevirtual("java/lang/Number", "intValue", "()I", false);
}
else if (type == Type.BOOLEAN_TYPE) {
v.invokevirtual("java/lang/Boolean", "booleanValue", "()Z", false);
}
else if (type == Type.CHAR_TYPE) {
v.invokevirtual("java/lang/Character", "charValue", "()C", false);
}
else if (type == Type.SHORT_TYPE) {
v.invokevirtual("java/lang/Number", "shortValue", "()S", false);
}
else if (type == Type.LONG_TYPE) {
v.invokevirtual("java/lang/Number", "longValue", "()J", false);
}
else if (type == Type.BYTE_TYPE) {
v.invokevirtual("java/lang/Number", "byteValue", "()B", false);
}
else if (type == Type.FLOAT_TYPE) {
v.invokevirtual("java/lang/Number", "floatValue", "()F", false);
}
else if (type == Type.DOUBLE_TYPE) {
v.invokevirtual("java/lang/Number", "doubleValue", "()D", false);
}
private static void unbox(Type methodOwner, Type type, InstructionAdapter v) {
assert isPrimitive(type) : "Unboxing should be performed to primitive type, but " + type.getClassName();
v.invokevirtual(methodOwner.getInternalName(), type.getClassName() + "Value", "()" + type.getDescriptor(), false);
}
protected void coerceTo(@NotNull Type toType, @NotNull InstructionAdapter v) {
@@ -372,23 +342,12 @@ public abstract class StackValue {
}
}
else if (toType.getSort() == Type.ARRAY) {
if (fromType.getSort() == Type.ARRAY &&
fromType.getElementType().equals(AsmTypes.JAVA_CLASS_TYPE) && toType.equals(K_CLASS_ARRAY_TYPE)) {
wrapJavaClassesIntoKClasses(v);
}
else {
v.checkcast(toType);
}
v.checkcast(toType);
}
else if (toType.getSort() == Type.OBJECT) {
if (fromType.getSort() == Type.OBJECT || fromType.getSort() == Type.ARRAY) {
if (!toType.equals(OBJECT_TYPE)) {
if (fromType.equals(AsmTypes.JAVA_CLASS_TYPE) && toType.equals(AsmTypes.K_CLASS_TYPE)) {
wrapJavaClassIntoKClass(v);
}
else {
v.checkcast(toType);
}
v.checkcast(toType);
}
}
else {
@@ -396,20 +355,29 @@ public abstract class StackValue {
}
}
else if (fromType.getSort() == Type.OBJECT) {
//toType is primitive here
Type unboxedType = unboxPrimitiveTypeOrNull(fromType);
if (unboxedType != null) {
unbox(unboxedType, v);
unbox(fromType, unboxedType, v);
coerce(unboxedType, toType, v);
}
else {
Type numberType = getType(Number.class);
if (toType.getSort() == Type.BOOLEAN || (toType.getSort() == Type.CHAR && !numberType.equals(fromType))) {
coerce(fromType, boxType(toType), v);
else if (toType.getSort() == Type.BOOLEAN) {
coerce(fromType, BOOLEAN_WRAPPER_TYPE, v);
unbox(BOOLEAN_WRAPPER_TYPE, Type.BOOLEAN_TYPE, v);
}
else if (toType.getSort() == Type.CHAR) {
if (fromType.equals(NUMBER_TYPE)) {
unbox(NUMBER_TYPE, Type.INT_TYPE, v);
v.visitInsn(Opcodes.I2C);
}
else {
coerce(fromType, numberType, v);
coerce(fromType, CHARACTER_WRAPPER_TYPE, v);
unbox(CHARACTER_WRAPPER_TYPE, Type.CHAR_TYPE, v);
}
unbox(toType, v);
}
else {
coerce(fromType, NUMBER_TYPE, v);
unbox(NUMBER_TYPE, toType, v);
}
}
else {
@@ -1211,7 +1179,20 @@ public abstract class StackValue {
else {
getter.genInvokeInstruction(v);
}
coerce(getter.getReturnType(), type, v);
Type typeOfValueOnStack = getter.getReturnType();
if (DescriptorUtils.isAnnotationClass(descriptor.getContainingDeclaration())) {
if (this.type.equals(K_CLASS_TYPE)) {
wrapJavaClassIntoKClass(v);
typeOfValueOnStack = K_CLASS_TYPE;
}
else if (this.type.equals(K_CLASS_ARRAY_TYPE)) {
wrapJavaClassesIntoKClasses(v);
typeOfValueOnStack = K_CLASS_ARRAY_TYPE;
}
}
coerce(typeOfValueOnStack, type, v);
KotlinType returnType = descriptor.getReturnType();
if (returnType != null && KotlinBuiltIns.isNothing(returnType)) {
@@ -1378,9 +1359,7 @@ public abstract class StackValue {
default:
PrimitiveType primitiveType = AsmUtil.asmPrimitiveTypeToLangPrimitiveType(type);
if (primitiveType == null) throw new UnsupportedOperationException();
String typeName = primitiveType.getTypeName().getIdentifier();
return Type.getObjectType(REF_TYPE_PREFIX + typeName + "Ref");
return sharedTypeForPrimitive(primitiveType);
}
}

View File

@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getParentCall
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.overriddenTreeAsSequence
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.singletonOrEmptyList
import java.util.*
class BridgeForBuiltinSpecial<out Signature : Any>(
@@ -64,8 +63,7 @@ object BuiltinSpecialBridgesUtil {
val specialBridgeExists = function.getSpecialBridgeSignatureIfExists(signatureByDescriptor) != null
val specialBridgesSignaturesInSuperClass = function.overriddenTreeAsSequence(useOriginal = true).mapNotNull {
if (it === function) return@mapNotNull null
it.getSpecialBridgeSignatureIfExists(signatureByDescriptor)
it.takeUnless { it === function }?.getSpecialBridgeSignatureIfExists(signatureByDescriptor)
}
val isTherePossibleClashWithSpecialBridge =
specialBridgeSignature in specialBridgesSignaturesInSuperClass
@@ -76,7 +74,7 @@ object BuiltinSpecialBridgesUtil {
else null
val commonBridges = reachableDeclarations.mapTo(LinkedHashSet<Signature>(), signatureByDescriptor)
commonBridges.removeAll(specialBridgesSignaturesInSuperClass + specialBridge?.from.singletonOrEmptyList())
commonBridges.removeAll(specialBridgesSignaturesInSuperClass + listOfNotNull(specialBridge?.from))
if (fake) {
for (overridden in function.overriddenDescriptors.map { it.original }) {

View File

@@ -42,7 +42,6 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.singletonOrEmptyList
import org.jetbrains.org.objectweb.asm.Label
import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes
@@ -289,8 +288,8 @@ class CoroutineCodegen private constructor(
}
private fun allFunctionParameters() =
originalSuspendFunctionDescriptor.extensionReceiverParameter.singletonOrEmptyList() +
originalSuspendFunctionDescriptor.valueParameters.orEmpty()
originalSuspendFunctionDescriptor.extensionReceiverParameter.let(::listOfNotNull) +
originalSuspendFunctionDescriptor.valueParameters.orEmpty()
private fun ParameterDescriptor.getFieldInfoForCoroutineLambdaParameter() =
createHiddenFieldInfo(type, COROUTINE_LAMBDA_PARAMETER_PREFIX + (this.safeAs<ValueParameterDescriptor>()?.index ?: ""))

View File

@@ -294,7 +294,7 @@ class CoroutineTransformerMethodVisitor(
get() {
assert(suspensionCallEnd.next is LabelNode) {
"Next instruction after ${this} should be a label, but " +
"${suspensionCallEnd.next.javaClass}/${suspensionCallEnd.next.opcode} was found"
"${suspensionCallEnd.next::class.java}/${suspensionCallEnd.next.opcode} was found"
}
return suspensionCallEnd.next as LabelNode
@@ -421,7 +421,7 @@ private fun InstructionAdapter.generateResumeWithExceptionCheck() {
private fun Type.fieldNameForVar(index: Int) = descriptor.first() + "$" + index
private fun withInstructionAdapter(block: InstructionAdapter.() -> Unit): InsnList {
inline fun withInstructionAdapter(block: InstructionAdapter.() -> Unit): InsnList {
val tmpMethodNode = MethodNode()
InstructionAdapter(tmpMethodNode).apply(block)

View File

@@ -137,7 +137,7 @@ fun ResolvedCall<*>.replaceSuspensionFunctionWithRealDescriptor(
newCall.recordValueArgument(newCandidateDescriptor.valueParameters[it.key.index], it.value)
}
val psiFactory = KtPsiFactory(project)
val psiFactory = KtPsiFactory(project, markGenerated = false)
val arguments = psiFactory.createCallArguments("(this)").arguments.single()
val thisExpression = arguments.getArgumentExpression()!!
newCall.recordValueArgument(

View File

@@ -217,7 +217,7 @@ private class VarExpectedTypeFrame(maxLocals: Int) : VarFrame<VarExpectedTypeFra
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
if (other == null || other::class.java != this::class.java) return false
other as VarExpectedTypeFrame

View File

@@ -66,7 +66,6 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
createClassReader().accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) {
@Override
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
InlineCodegenUtil.assertVersionNotGreaterThanGeneratedOne(version, name, inliningContext.state);
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces);
if(CoroutineCodegenUtilKt.COROUTINE_IMPL_ASM_TYPE.getInternalName().equals(superName)) {
inliningContext.setContinuation(true);
@@ -271,7 +270,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
//TODO for inline method make public class
transformationInfo.setNewConstructorDescriptor(constructorDescriptor);
MethodVisitor constructorVisitor = classBuilder.newMethod(
NO_ORIGIN, AsmUtil.NO_FLAG_PACKAGE_PRIVATE, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY
NO_ORIGIN, constructor.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY
);
final Label newBodyStartLabel = new Label();
@@ -312,7 +311,7 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
}
MethodNode intermediateMethodNode =
new MethodNode(AsmUtil.NO_FLAG_PACKAGE_PRIVATE, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
new MethodNode(constructor.access, "<init>", constructorDescriptor, null, ArrayUtil.EMPTY_STRING_ARRAY);
inlineMethodAndUpdateGlobalResult(parentRemapper, intermediateMethodNode, constructor, constructorInlineBuilder, true);
InlineCodegenUtil.removeFinallyMarkers(intermediateMethodNode);

View File

@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache;
import org.jetbrains.kotlin.name.ClassId;
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;
@@ -202,7 +203,7 @@ public class InlineCodegen extends CallGenerator {
MethodNode node = nodeAndSmap != null ? nodeAndSmap.getNode() : null;
throw new CompilationException(
"Couldn't inline method call '" + functionDescriptor.getName() + "' into\n" +
contextDescriptor + "\n" +
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
(element != null ? element.getText() : "<no source>") +
(generateNodeText ? ("\nCause: " + InlineCodegenUtil.getNodeText(node)) : ""),
e, callElement
@@ -321,7 +322,7 @@ public class InlineCodegen extends CallGenerator {
}
});
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), classId, state);
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), classId);
}
assert callableDescriptor instanceof DeserializedCallableMemberDescriptor : "Not a deserialized function or proper: " + callableDescriptor;
@@ -348,7 +349,7 @@ public class InlineCodegen extends CallGenerator {
});
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), containerId, state);
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), containerId);
}
@NotNull

View File

@@ -39,7 +39,7 @@ 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.JvmVirtualFileFinder;
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;
@@ -52,6 +52,7 @@ 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;
@@ -92,8 +93,7 @@ public class InlineCodegenUtil {
byte[] classData,
final String methodName,
final String methodDescriptor,
ClassId classId,
final @NotNull GenerationState state
ClassId classId
) {
ClassReader cr = new ClassReader(classData);
final MethodNode[] node = new MethodNode[1];
@@ -103,10 +103,6 @@ public class InlineCodegenUtil {
lines[1] = Integer.MIN_VALUE;
//noinspection PointlessBitwiseExpression
cr.accept(new ClassVisitor(API) {
@Override
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
assertVersionNotGreaterThanGeneratedOne(version, name, state);
}
@Override
public void visitSource(String source, String debug) {
@@ -151,16 +147,6 @@ public class InlineCodegenUtil {
return new SMAPAndMethodNode(node[0], smap);
}
public static void assertVersionNotGreaterThanGeneratedOne(int version, String internalName, @NotNull GenerationState state) {
// TODO: report a proper diagnostic
if (version > state.getClassFileVersion() && !"true".equals(System.getProperty("kotlin.skip.bytecode.version.check"))) {
throw new UnsupportedOperationException(
"Cannot inline bytecode of class " + internalName + " which has version " + version + ". " +
"This compiler can only inline Java 1.6 bytecode (version " + Opcodes.V1_6 + ")"
);
}
}
public static void initDefaultSourceMappingIfNeeded(
@NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state
) {
@@ -179,7 +165,7 @@ public class InlineCodegenUtil {
@Nullable
public static VirtualFile findVirtualFile(@NotNull GenerationState state, @NotNull ClassId classId) {
return JvmVirtualFileFinder.SERVICE.getInstance(state.getProject()).findVirtualFileWithHeader(classId);
return VirtualFileFinder.SERVICE.getInstance(state.getProject()).findVirtualFileWithHeader(classId);
}
@Nullable
@@ -405,6 +391,11 @@ public class InlineCodegenUtil {
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

View File

@@ -252,6 +252,7 @@ public class MethodInliner {
//TODO add skipped this and receiver
InlineResult lambdaResult = inliner.doInline(this.mv, remapper, true, info, invokeCall.finallyDepthShift);
result.mergeWithNotChangeInfo(lambdaResult);
result.getReifiedTypeParametersUsages().mergeAll(lambdaResult.getReifiedTypeParametersUsages());
//return value boxing/unboxing
Method bridge = typeMapper.mapAsmMethod(ClosureCodegen.getErasedInvokeFunction(info.getFunctionDescriptor()));
@@ -486,6 +487,11 @@ public class MethodInliner {
);
awaitClassReification = false;
}
else if (inliningContext.isInliningLambda && ReifiedTypeInliner.Companion.isOperationReifiedMarker(cur)) {
ReificationArgument reificationArgument = ReifiedTypeInlinerKt.getReificationArgument((MethodInsnNode) cur);
String parameterName = reificationArgument.getParameterName();
result.getReifiedTypeParametersUsages().addUsedReifiedParameter(parameterName);
}
}
else if (cur.getOpcode() == Opcodes.GETSTATIC) {
FieldInsnNode fieldInsnNode = (FieldInsnNode) cur;

View File

@@ -66,7 +66,6 @@ class WhenMappingTransformer(
val fieldNode = transformationInfo.fieldNode
classReader.accept(object : ClassVisitor(InlineCodegenUtil.API, classBuilder.visitor) {
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
InlineCodegenUtil.assertVersionNotGreaterThanGeneratedOne(version, name, state)
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces)
}

View File

@@ -70,7 +70,5 @@ internal class Parameters(val parameters: List<ParameterInfo>) : Iterable<Parame
}
val capturedTypes: List<Type>
get() = captured.map {
it.getType()
}
get() = captured.map(CapturedParamInfo::getType)
}

View File

@@ -70,7 +70,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
const val REIFIED_OPERATION_MARKER_METHOD_NAME = "reifiedOperationMarker"
const val NEED_CLASS_REIFICATION_MARKER_METHOD_NAME = "needClassReification"
private fun isOperationReifiedMarker(insn: AbstractInsnNode) =
fun isOperationReifiedMarker(insn: AbstractInsnNode) =
isReifiedMarker(insn) { it == REIFIED_OPERATION_MARKER_METHOD_NAME }
private fun isReifiedMarker(insn: AbstractInsnNode, namePredicate: (String) -> Boolean): Boolean {
@@ -247,7 +247,7 @@ class ReifiedTypeInliner(private val parametersMapping: TypeParameterMappings?)
}
}
private val MethodInsnNode.reificationArgument: ReificationArgument?
val MethodInsnNode.reificationArgument: ReificationArgument?
get() {
val prev = previous!!

View File

@@ -57,7 +57,7 @@ class SMAPBuilder(
private fun generateDebugStrata(realMappings: List<FileMapping>): String {
val combinedMapping = FileMapping(source, path)
realMappings.forEach { fileMapping ->
fileMapping.lineMappings.filter { it.callSiteMarker != null }.forEach { (source, dest, range, callSiteMarker) ->
fileMapping.lineMappings.filter { it.callSiteMarker != null }.forEach { (_, dest, range, callSiteMarker) ->
combinedMapping.addRangeMapping(RangeMapping(
callSiteMarker!!.lineNumber, dest, range
))

View File

@@ -28,7 +28,7 @@ internal val classId: ClassId =
ClassId.topLevel(FqName("org.jetbrains.kotlin.codegen.intrinsics.IntrinsicArrayConstructorsKt"))
internal val bytecode: ByteArray by lazy {
val stream = object {}.javaClass.classLoader.getResourceAsStream("${classId.asString()}.class")
val stream = object {}::class.java.classLoader.getResourceAsStream("${classId.asString()}.class")
stream.readBytes().apply {
stream.close()
}

View File

@@ -58,7 +58,7 @@ object JavaClassProperty : IntrinsicPropertyGetter() {
}
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val classType = codegen.getState().typeMapper.mapType(resolvedCall.call.dispatchReceiver!!.type)
val classType = codegen.state.typeMapper.mapType(resolvedCall.call.dispatchReceiver!!.type)
return object : IntrinsicCallable(getType(Class::class.java), listOf(), classType, null) {
override fun invokeIntrinsic(v: InstructionAdapter) {
if (isPrimitive(classType)) {

View File

@@ -26,7 +26,7 @@ import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
class NewArray : IntrinsicMethod() {
override fun toCallable(fd: FunctionDescriptor, isSuper: Boolean, resolvedCall: ResolvedCall<*>, codegen: ExpressionCodegen): Callable {
val jetType = resolvedCall.resultingDescriptor.returnType!!
val type = codegen.getState().typeMapper.mapType(jetType)
val type = codegen.state.typeMapper.mapType(jetType)
return object : IntrinsicCallable(type, listOf(Type.INT_TYPE), null, null) {
override fun invokeIntrinsic(v: InstructionAdapter) {
codegen.newArrayInstruction(jetType)

View File

@@ -29,9 +29,13 @@ class DeadCodeEliminationMethodTransformer : MethodTransformer() {
}
fun transformWithResult(internalClassName: String, methodNode: MethodNode): Result {
val frames = analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
return removeDeadCodeByFrames(methodNode, frames)
}
fun removeDeadCodeByFrames(methodNode: MethodNode, frames: Array<out Any?>): Result {
val removedNodes = HashSet<AbstractInsnNode>()
val frames = analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
val insnList = methodNode.instructions
val insnsArray = insnList.toArray()
@@ -51,6 +55,7 @@ class DeadCodeEliminationMethodTransformer : MethodTransformer() {
}
class Result(val removedNodes: Set<AbstractInsnNode>) {
fun hasRemovedAnything() = removedNodes.isNotEmpty()
fun isRemoved(node: AbstractInsnNode) = removedNodes.contains(node)
fun isAlive(node: AbstractInsnNode) = !isRemoved(node)
}

View File

@@ -21,8 +21,9 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor;
import org.jetbrains.kotlin.codegen.optimization.boxing.RedundantBoxingMethodTransformer;
import org.jetbrains.kotlin.codegen.optimization.boxing.RedundantCoercionToUnitTransformer;
import org.jetbrains.kotlin.codegen.optimization.boxing.RedundantNullCheckMethodTransformer;
import org.jetbrains.kotlin.codegen.optimization.captured.CapturedVarsOptimizationMethodTransformer;
import org.jetbrains.kotlin.codegen.optimization.common.UtilKt;
import org.jetbrains.kotlin.codegen.optimization.nullCheck.RedundantNullCheckV2MethodTransformer;
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer;
import org.jetbrains.org.objectweb.asm.MethodVisitor;
import org.jetbrains.org.objectweb.asm.tree.MethodNode;
@@ -33,7 +34,9 @@ public class OptimizationMethodVisitor extends TransformationMethodVisitor {
private static final MethodTransformer MANDATORY_METHOD_TRANSFORMER = new FixStackWithLabelNormalizationMethodTransformer();
private static final MethodTransformer[] OPTIMIZATION_TRANSFORMERS = new MethodTransformer[] {
new RedundantNullCheckMethodTransformer(),
//new CapturedVarsOptimizationMethodTransformer(),
new RedundantNullCheckV2MethodTransformer(),
new RedundantCheckCastEliminationMethodTransformer(),
new RedundantBoxingMethodTransformer(),
new RedundantCoercionToUnitTransformer(),
new DeadCodeEliminationMethodTransformer(),

View File

@@ -0,0 +1,63 @@
/*
* 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.optimization
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.*
class RedundantCheckCastEliminationMethodTransformer : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) {
val insns = methodNode.instructions.toArray()
if (!insns.any { it.opcode == Opcodes.CHECKCAST }) return
val redundantCheckCasts = ArrayList<TypeInsnNode>()
val frames = analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
for (i in insns.indices) {
val valueType = frames[i]?.top()?.type ?: continue
val insn = insns[i]
if (ReifiedTypeInliner.isOperationReifiedMarker(insn.previous)) continue
if (insn is TypeInsnNode) {
val insnType = Type.getObjectType(insn.desc)
if (!isTrivialSubtype(insnType, valueType)) continue
//Keep casts to multiarray types cause dex doesn't recognize ANEWARRAY [Ljava/lang/Object; as Object [][], but Object [] type
//It's not clear is it bug in dex or not and maybe best to distinguish such types from MULTINEWARRRAY ones in method analyzer
if (isMultiArrayType(insnType)) continue
if (insn.opcode == Opcodes.CHECKCAST) {
redundantCheckCasts.add(insn)
}
}
}
redundantCheckCasts.forEach {
methodNode.instructions.remove(it)
}
}
private fun isTrivialSubtype(superType: Type, subType: Type) =
superType == subType
private fun isMultiArrayType(type: Type) = type.sort == Type.ARRAY && type.dimensions != 1
}

View File

@@ -20,7 +20,6 @@ import com.intellij.openapi.util.Pair
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.utils.toReadOnlyList
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import java.util.*
@@ -66,7 +65,7 @@ class BoxedValueDescriptor(
var isSafeToRemove = true; private set
val unboxedType: Type = getUnboxedType(boxedType)
fun getAssociatedInsns() = associatedInsns.toReadOnlyList()
fun getAssociatedInsns() = associatedInsns.toList()
fun addInsn(insnNode: AbstractInsnNode) {
associatedInsns.add(insnNode)

View File

@@ -35,14 +35,12 @@ import java.util.*
open class BoxingInterpreter(private val insnList: InsnList) : OptimizationBasicInterpreter() {
private val boxingPlaces = HashMap<Int, BoxedBasicValue>()
protected open fun createNewBoxing(insn: AbstractInsnNode, type: Type, progressionIterator: ProgressionIteratorBasicValue?): BasicValue {
val index = insnList.indexOf(insn)
return boxingPlaces.getOrPut(index) {
val boxedBasicValue = CleanBoxedValue(type, insn, progressionIterator)
onNewBoxedValue(boxedBasicValue)
boxedBasicValue
}
}
protected open fun createNewBoxing(insn: AbstractInsnNode, type: Type, progressionIterator: ProgressionIteratorBasicValue?): BasicValue =
boxingPlaces.getOrPut(insnList.indexOf(insn)) {
val boxedBasicValue = CleanBoxedValue(type, insn, progressionIterator)
onNewBoxedValue(boxedBasicValue)
boxedBasicValue
}
protected fun checkUsedValue(value: BasicValue) {
if (value is TaintedBoxedValue) {
@@ -66,14 +64,17 @@ open class BoxingInterpreter(private val insnList: InsnList) : OptimizationBasic
onUnboxing(insn, firstArg, value.type)
value
}
insn.isIteratorMethodCallOfProgression(values) -> {
ProgressionIteratorBasicValue(getValuesTypeOfProgressionClass(firstArg.type.internalName))
}
insn.isIteratorMethodCallOfProgression(values) ->
ProgressionIteratorBasicValue.byProgressionClassType(firstArg.type)
insn.isNextMethodCallOfProgressionIterator(values) -> {
val progressionIterator = firstArg as? ProgressionIteratorBasicValue
?: throw AssertionError("firstArg should be progression iterator")
createNewBoxing(insn, AsmUtil.boxType(progressionIterator.valuesPrimitiveType), progressionIterator)
}
insn.isAreEqualIntrinsicForSameTypedBoxedValues(values) && canValuesBeUnboxedForAreEqual(values) -> {
onAreEqual(insn, values[0] as BoxedBasicValue, values[1] as BoxedBasicValue)
value
}
else -> {
// N-ary operation should be a method call or multinewarray.
// Arguments for multinewarray could be only numeric,
@@ -100,7 +101,7 @@ open class BoxingInterpreter(private val insnList: InsnList) : OptimizationBasic
protected open fun isExactValue(value: BasicValue) =
value is ProgressionIteratorBasicValue ||
value is CleanBoxedValue ||
value.type != null && isProgressionClass(value.type.internalName)
value.type != null && isProgressionClass(value.type)
override fun merge(v: BasicValue, w: BasicValue) =
when {
@@ -125,6 +126,7 @@ open class BoxingInterpreter(private val insnList: InsnList) : OptimizationBasic
protected open fun onNewBoxedValue(value: BoxedBasicValue) {}
protected open fun onUnboxing(insn: AbstractInsnNode, value: BoxedBasicValue, resultType: Type) {}
protected open fun onAreEqual(insn: AbstractInsnNode, value1: BoxedBasicValue, value2: BoxedBasicValue) {}
protected open fun onMethodCallWithBoxedValue(value: BoxedBasicValue) {}
protected open fun onMergeFail(value: BoxedBasicValue) {}
protected open fun onMergeSuccess(v: BoxedBasicValue, w: BoxedBasicValue) {}
@@ -190,23 +192,44 @@ private fun AbstractInsnNode.isJavaLangClassBoxing() =
desc == JLCLASS_TO_KCLASS
}
private fun AbstractInsnNode.isNextMethodCallOfProgressionIterator(values: List<BasicValue>) =
values[0] is ProgressionIteratorBasicValue &&
fun AbstractInsnNode.isNextMethodCallOfProgressionIterator(values: List<BasicValue>) =
values.firstOrNull() is ProgressionIteratorBasicValue &&
isMethodInsnWith(Opcodes.INVOKEINTERFACE) {
name == "next"
}
private fun AbstractInsnNode.isIteratorMethodCallOfProgression(values: List<BasicValue>) =
fun AbstractInsnNode.isIteratorMethodCallOfProgression(values: List<BasicValue>) =
isMethodInsnWith(Opcodes.INVOKEINTERFACE) {
val firstArgType = values[0].type
val firstArgType = values.firstOrNull()?.type
firstArgType != null &&
isProgressionClass(firstArgType.internalName) &&
isProgressionClass(firstArgType) &&
name == "iterator"
}
private fun isProgressionClass(internalClassName: String) =
RangeCodegenUtil.isRangeOrProgression(buildFqNameByInternal(internalClassName))
fun isProgressionClass(type: Type) =
RangeCodegenUtil.isRangeOrProgression(buildFqNameByInternal(type.internalName))
private fun getValuesTypeOfProgressionClass(progressionClassInternalName: String) =
RangeCodegenUtil.getPrimitiveRangeOrProgressionElementType(buildFqNameByInternal(progressionClassInternalName))
?.typeName?.asString() ?: error("type should be not null")
fun AbstractInsnNode.isAreEqualIntrinsicForSameTypedBoxedValues(values: List<BasicValue>) =
isAreEqualIntrinsic() && run {
if (values.size != 2) return false
val (v1, v2) = values
if (v1 !is BoxedBasicValue || v2 !is BoxedBasicValue) return false
val d1 = v1.descriptor
val d2 = v2.descriptor
d1.unboxedType == d2.unboxedType
}
fun AbstractInsnNode.isAreEqualIntrinsic() =
isMethodInsnWith(Opcodes.INVOKESTATIC) {
name == "areEqual" &&
owner == "kotlin/jvm/internal/Intrinsics" &&
desc == "(Ljava/lang/Object;Ljava/lang/Object;)Z"
}
fun canValuesBeUnboxedForAreEqual(values: List<BasicValue>): Boolean =
!values.any {
val unboxedType = getUnboxedType(it.type)
unboxedType == Type.DOUBLE_TYPE || unboxedType == Type.FLOAT_TYPE
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2010-2014 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.optimization.boxing
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.InsnList
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
class NullabilityInterpreter(insns: InsnList) : BoxingInterpreter(insns) {
override fun unaryOperation(insn: AbstractInsnNode, value: BasicValue) = makeNotNullIfNeeded(insn, super.unaryOperation(insn, value))
override fun newOperation(insn: AbstractInsnNode) = makeNotNullIfNeeded(insn, super.newOperation(insn))
override fun isExactValue(value: BasicValue) = super.isExactValue(value) || value is NotNullBasicValue
override fun createNewBoxing(insn: AbstractInsnNode, type: Type, progressionIterator: ProgressionIteratorBasicValue?) =
NotNullBasicValue(type)
}
private fun makeNotNullIfNeeded(insn: AbstractInsnNode, value: BasicValue?): BasicValue? =
when (insn.opcode) {
Opcodes.ANEWARRAY, Opcodes.NEWARRAY, Opcodes.LDC, Opcodes.NEW ->
if (value?.type?.sort == Type.OBJECT || value?.type?.sort == Type.ARRAY)
NotNullBasicValue(value.type)
else
value
else -> value
}
class NotNullBasicValue(type: Type?) : StrictBasicValue(type) {
override fun equals(other: Any?): Boolean = other is NotNullBasicValue
// We do not differ not-nullable values, so we should always return the same hashCode
// Actually it doesn't really matter because analyzer is not supposed to store values in hashtables
override fun hashCode() = 0
}

View File

@@ -18,17 +18,18 @@ package org.jetbrains.kotlin.codegen.optimization.boxing;
import com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.codegen.RangeCodegenUtil;
import org.jetbrains.kotlin.codegen.intrinsics.IteratorNext;
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType;
import org.jetbrains.org.objectweb.asm.Type;
public class ProgressionIteratorBasicValue extends StrictBasicValue {
private final static ImmutableMap<String, Type> VALUES_TYPENAME_TO_TYPE;
static {
ImmutableMap.Builder<String, Type> builder = ImmutableMap.builder();
for (PrimitiveType primitiveType : RangeCodegenUtil.supportedRangeTypes()) {
@@ -37,6 +38,15 @@ public class ProgressionIteratorBasicValue extends StrictBasicValue {
VALUES_TYPENAME_TO_TYPE = builder.build();
}
private static final ImmutableMap<PrimitiveType, ProgressionIteratorBasicValue> ITERATOR_VALUE_BY_ELEMENT_PRIMITIVE_TYPE;
static {
ImmutableMap.Builder<PrimitiveType, ProgressionIteratorBasicValue> builder = ImmutableMap.builder();
for (PrimitiveType elementType : RangeCodegenUtil.supportedRangeTypes()) {
builder.put(elementType, new ProgressionIteratorBasicValue(elementType.getTypeName().asString()));
}
ITERATOR_VALUE_BY_ELEMENT_PRIMITIVE_TYPE = builder.build();
}
@NotNull
private static Type getValuesType(@NotNull String valuesTypeName) {
Type type = VALUES_TYPENAME_TO_TYPE.get(valuesTypeName);
@@ -47,12 +57,20 @@ public class ProgressionIteratorBasicValue extends StrictBasicValue {
private final Type valuesPrimitiveType;
private final String valuesPrimitiveTypeName;
public ProgressionIteratorBasicValue(@NotNull String valuesPrimitiveTypeName) {
private ProgressionIteratorBasicValue(@NotNull String valuesPrimitiveTypeName) {
super(IteratorNext.Companion.getPrimitiveIteratorType(Name.identifier(valuesPrimitiveTypeName)));
this.valuesPrimitiveType = getValuesType(valuesPrimitiveTypeName);
this.valuesPrimitiveTypeName = valuesPrimitiveTypeName;
}
@Nullable
public static ProgressionIteratorBasicValue byProgressionClassType(@NotNull Type progressionClassType) {
FqName classFqName = new FqName(progressionClassType.getClassName());
PrimitiveType elementType = RangeCodegenUtil.getPrimitiveRangeOrProgressionElementType(classFqName);
return ITERATOR_VALUE_BY_ELEMENT_PRIMITIVE_TYPE.get(elementType);
}
@NotNull
public Type getValuesPrimitiveType() {
return valuesPrimitiveType;

View File

@@ -84,6 +84,13 @@ internal class RedundantBoxingInterpreter(insnList: InsnList) : BoxingInterprete
}
}
override fun onAreEqual(insn: AbstractInsnNode, value1: BoxedBasicValue, value2: BoxedBasicValue) {
val descriptor1 = value1.descriptor
val descriptor2 = value2.descriptor
candidatesBoxedValues.merge(descriptor1, descriptor2)
descriptor1.addInsn(insn)
}
override fun onMethodCallWithBoxedValue(value: BoxedBasicValue) {
markValueAsDirty(value)
}

View File

@@ -21,7 +21,9 @@ import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue;
import org.jetbrains.kotlin.codegen.optimization.common.UtilKt;
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer;
import org.jetbrains.org.objectweb.asm.Label;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
@@ -48,7 +50,7 @@ public class RedundantBoxingMethodTransformer extends MethodTransformer {
adaptLocalVariableTableForBoxedValues(node, frames);
applyVariablesRemapping(node, buildVariablesRemapping(valuesToOptimize, node));
UtilKt.remapLocalVariables(node, buildVariablesRemapping(valuesToOptimize, node));
adaptInstructionsForBoxedValues(node, valuesToOptimize);
}
@@ -221,21 +223,6 @@ public class RedundantBoxingMethodTransformer extends MethodTransformer {
return remapping;
}
private static void applyVariablesRemapping(@NotNull MethodNode node, @NotNull int[] remapping) {
for (AbstractInsnNode insn : node.instructions.toArray()) {
if (insn instanceof VarInsnNode) {
((VarInsnNode) insn).var = remapping[((VarInsnNode) insn).var];
}
if (insn instanceof IincInsnNode) {
((IincInsnNode) insn).var = remapping[((IincInsnNode) insn).var];
}
}
for (LocalVariableNode localVariableNode : node.localVariables) {
localVariableNode.index = remapping[localVariableNode.index];
}
}
private static void adaptInstructionsForBoxedValues(
@NotNull MethodNode node,
@NotNull RedundantBoxedValuesCollection values
@@ -341,9 +328,68 @@ public class RedundantBoxingMethodTransformer extends MethodTransformer {
);
node.instructions.set(insn, new InsnNode(Opcodes.ICONST_1));
break;
case Opcodes.INVOKESTATIC:
if (BoxingInterpreterKt.isAreEqualIntrinsic(insn)) {
adaptAreEqualIntrinsic(node, insn, value);
break;
}
else {
// fall-through to default
}
default:
// CHECKCAST or unboxing-method call
node.instructions.remove(insn);
}
}
private static void adaptAreEqualIntrinsic(@NotNull MethodNode node, @NotNull AbstractInsnNode insn, @NotNull BoxedValueDescriptor value) {
Type unboxedType = value.getUnboxedType();
switch (unboxedType.getSort()) {
case Type.BOOLEAN:
case Type.BYTE:
case Type.SHORT:
case Type.INT:
case Type.CHAR:
adaptAreEqualIntrinsicForInt(node, insn);
break;
case Type.LONG:
adaptAreEqualIntrinsicForLong(node, insn);
break;
case Type.OBJECT:
break;
default:
throw new AssertionError("Unexpected unboxed type kind: " + unboxedType);
}
}
private static void adaptAreEqualIntrinsicForInt(@NotNull MethodNode node, @NotNull AbstractInsnNode insn) {
LabelNode lNotEqual = new LabelNode(new Label());
LabelNode lDone = new LabelNode(new Label());
node.instructions.insertBefore(insn, new JumpInsnNode(Opcodes.IF_ICMPNE, lNotEqual));
node.instructions.insertBefore(insn, new InsnNode(Opcodes.ICONST_1));
node.instructions.insertBefore(insn, new JumpInsnNode(Opcodes.GOTO, lDone));
node.instructions.insertBefore(insn, lNotEqual);
node.instructions.insertBefore(insn, new InsnNode(Opcodes.ICONST_0));
node.instructions.insertBefore(insn, lDone);
node.instructions.remove(insn);
}
private static void adaptAreEqualIntrinsicForLong(@NotNull MethodNode node, @NotNull AbstractInsnNode insn) {
node.instructions.insertBefore(insn, new InsnNode(Opcodes.LCMP));
ifEqual1Else0(node, insn);
node.instructions.remove(insn);
}
private static void ifEqual1Else0(@NotNull MethodNode node, @NotNull AbstractInsnNode insn) {
LabelNode lNotEqual = new LabelNode(new Label());
LabelNode lDone = new LabelNode(new Label());
node.instructions.insertBefore(insn, new JumpInsnNode(Opcodes.IFNE, lNotEqual));
node.instructions.insertBefore(insn, new InsnNode(Opcodes.ICONST_1));
node.instructions.insertBefore(insn, new JumpInsnNode(Opcodes.GOTO, lDone));
node.instructions.insertBefore(insn, lNotEqual);
node.instructions.insertBefore(insn, new InsnNode(Opcodes.ICONST_0));
node.instructions.insertBefore(insn, lDone);
}
}

View File

@@ -63,7 +63,7 @@ class RedundantCoercionToUnitTransformer : MethodTransformer() {
private val frames by lazy { analyzeMethodBody() }
fun transform() {
if (!insns.any { it.isUnitOrNull() }) return
if (!insns.any { it.isUnitInstanceOrNull() }) return
computeTransformations()
for ((insn, transformation) in transformations.entries) {
@@ -158,7 +158,7 @@ class RedundantCoercionToUnitTransformer : MethodTransformer() {
transformations[insn] = replaceWithPopTransformation(boxedValueSize)
}
insn.isUnitOrNull() -> {
insn.isUnitInstanceOrNull() -> {
transformations[insn] = replaceWithNopTransformation()
}
@@ -232,7 +232,7 @@ class RedundantCoercionToUnitTransformer : MethodTransformer() {
it.isPrimitiveBoxing() && (it as MethodInsnNode).owner == resultType
private fun isTransformablePopOperand(insn: AbstractInsnNode) =
insn.opcode == Opcodes.CHECKCAST || insn.isPrimitiveBoxing() || insn.isUnitOrNull()
insn.opcode == Opcodes.CHECKCAST || insn.isPrimitiveBoxing() || insn.isUnitInstanceOrNull()
private fun isDontTouch(insn: AbstractInsnNode) =
dontTouchInsnIndices[insnList.indexOf(insn)]
@@ -240,6 +240,9 @@ class RedundantCoercionToUnitTransformer : MethodTransformer() {
}
fun AbstractInsnNode.isUnitOrNull() =
opcode == Opcodes.ACONST_NULL ||
opcode == Opcodes.GETSTATIC && this is FieldInsnNode && owner == "kotlin/Unit" && name == "INSTANCE"
fun AbstractInsnNode.isUnitInstanceOrNull() =
opcode == Opcodes.ACONST_NULL || isUnitInstance()
fun AbstractInsnNode.isUnitInstance() =
opcode == Opcodes.GETSTATIC &&
this is FieldInsnNode && owner == "kotlin/Unit" && name == "INSTANCE"

View File

@@ -1,81 +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.optimization.boxing;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.tree.*;
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue;
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame;
import java.util.ArrayList;
import java.util.List;
public class RedundantNullCheckMethodTransformer extends MethodTransformer {
@Override
public void transform(@NotNull String internalClassName, @NotNull MethodNode methodNode) {
while (removeRedundantNullCheckPass(internalClassName, methodNode)) {
//do nothing
}
}
private static boolean removeRedundantNullCheckPass(@NotNull String internalClassName, @NotNull MethodNode methodNode) {
InsnList insnList = methodNode.instructions;
Frame<BasicValue>[] frames = analyze(
internalClassName, methodNode,
new NullabilityInterpreter(insnList)
);
List<AbstractInsnNode> insnsToOptimize = new ArrayList<AbstractInsnNode>();
for (int i = 0; i < insnList.size(); i++) {
Frame<BasicValue> frame = frames[i];
AbstractInsnNode insn = insnList.get(i);
if ((insn.getOpcode() == Opcodes.IFNULL || insn.getOpcode() == Opcodes.IFNONNULL) &&
frame != null && frame.getStack(frame.getStackSize() - 1) instanceof NotNullBasicValue) {
insnsToOptimize.add(insn);
}
}
for (AbstractInsnNode insn : insnsToOptimize) {
if (insn.getPrevious() != null && insn.getPrevious().getOpcode() == Opcodes.DUP) {
insnList.remove(insn.getPrevious());
}
else {
insnList.insertBefore(insn, new InsnNode(Opcodes.POP));
}
assert insn.getOpcode() == Opcodes.IFNULL
|| insn.getOpcode() == Opcodes.IFNONNULL : "only IFNULL/IFNONNULL are supported";
if (insn.getOpcode() == Opcodes.IFNULL) {
insnList.remove(insn);
}
else {
insnList.set(
insn,
new JumpInsnNode(Opcodes.GOTO, ((JumpInsnNode) insn).label)
);
}
}
return insnsToOptimize.size() > 0;
}
}

View File

@@ -0,0 +1,295 @@
/*
* 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.optimization.captured
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.codegen.optimization.common.InsnSequence
import org.jetbrains.kotlin.codegen.optimization.common.removeEmptyCatchBlocks
import org.jetbrains.kotlin.codegen.optimization.common.removeUnusedLocalVariables
import org.jetbrains.kotlin.codegen.optimization.fixStack.peek
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.*
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) {
Transformer(internalClassName, methodNode).run()
}
// Tracks proper usages of objects corresponding to captured variables.
//
// The 'kotlin.jvm.internal.Ref.*' instance can be replaced with a local variable,
// if all of the following conditions are satisfied:
// * It is created inside a current method.
// * The only permitted operations on it are:
// - store to a local variable
// - ALOAD, ASTORE
// - DUP, POP
// - GETFIELD <owner>.element, PUTFIELD <owner>.element
// * There's a corresponding local variable definition,
// and all ALOAD/ASTORE instructions operate on that particular local variable.
// * Its 'element' field is initialized at start of local variable visibility range.
//
// Note that for code that doesn't create Ref objects explicitly these conditions are true,
// unless the Ref object escapes to a local class constructor (including local classes for lambdas).
//
private class CapturedVarDescriptor(val newInsn: TypeInsnNode, val refType: Type, val valueType: Type) : ReferenceValueDescriptor {
var hazard = false
var initCallInsn: MethodInsnNode? = null
var localVar: LocalVariableNode? = null
var localVarIndex = -1
val astoreInsns: MutableCollection<VarInsnNode> = LinkedHashSet()
val aloadInsns: MutableCollection<VarInsnNode> = LinkedHashSet()
val stackInsns: MutableCollection<AbstractInsnNode> = LinkedHashSet()
val getFieldInsns: MutableCollection<FieldInsnNode> = LinkedHashSet()
val putFieldInsns: MutableCollection<FieldInsnNode> = LinkedHashSet()
var cleanVarInstruction: VarInsnNode? = null
fun canRewrite(): Boolean =
!hazard &&
initCallInsn != null &&
localVar != null &&
localVarIndex >= 0
override fun onUseAsTainted() {
hazard = true
}
}
private class Transformer(private val internalClassName: String, private val methodNode: MethodNode) {
private val refValues = ArrayList<CapturedVarDescriptor>()
private val refValuesByNewInsn = LinkedHashMap<TypeInsnNode, CapturedVarDescriptor>()
private val insns = methodNode.instructions.toArray()
private lateinit var frames: Array<out Frame<BasicValue>?>
val hasRewritableRefValues: Boolean
get() = refValues.isNotEmpty()
fun run() {
createRefValues()
if (!hasRewritableRefValues) return
analyze()
if (!hasRewritableRefValues) return
rewrite()
}
private fun AbstractInsnNode.getIndex() = methodNode.instructions.indexOf(this)
private fun createRefValues() {
for (insn in insns) {
if (insn.opcode == Opcodes.NEW && insn is TypeInsnNode) {
val type = Type.getObjectType(insn.desc)
if (AsmTypes.isSharedVarType(type)) {
val valueType = REF_TYPE_TO_ELEMENT_TYPE[type.internalName] ?: continue
val refValue = CapturedVarDescriptor(insn, type, valueType)
refValues.add(refValue)
refValuesByNewInsn[insn] = refValue
}
}
}
}
private inner class Interpreter : ReferenceTrackingInterpreter() {
override fun newOperation(insn: AbstractInsnNode): BasicValue =
refValuesByNewInsn[insn]?.let { descriptor ->
ProperTrackedReferenceValue(descriptor.refType, descriptor)
}
?: super.newOperation(insn)
override fun processRefValueUsage(value: TrackedReferenceValue, insn: AbstractInsnNode, position: Int) {
for (descriptor in value.descriptors) {
if (descriptor !is CapturedVarDescriptor) throw AssertionError("Unexpected descriptor: $descriptor")
when {
insn.opcode == Opcodes.ALOAD ->
descriptor.aloadInsns.add(insn as VarInsnNode)
insn.opcode == Opcodes.ASTORE ->
descriptor.astoreInsns.add(insn as VarInsnNode)
insn.opcode == Opcodes.GETFIELD && insn is FieldInsnNode && insn.name == REF_ELEMENT_FIELD && position == 0 ->
descriptor.getFieldInsns.add(insn)
insn.opcode == Opcodes.PUTFIELD && insn is FieldInsnNode && insn.name == REF_ELEMENT_FIELD && position == 0 ->
descriptor.putFieldInsns.add(insn)
insn.opcode == Opcodes.INVOKESPECIAL && insn is MethodInsnNode && insn.name == INIT_METHOD_NAME && position == 0 ->
if (descriptor.initCallInsn != null && descriptor.initCallInsn != insn)
descriptor.hazard = true
else
descriptor.initCallInsn = insn
insn.opcode == Opcodes.DUP ->
descriptor.stackInsns.add(insn)
else ->
descriptor.hazard = true
}
}
}
}
private fun analyze() {
frames = MethodTransformer.analyze(internalClassName, methodNode, Interpreter())
trackPops()
assignLocalVars()
refValues.removeAll { !it.canRewrite() }
}
private fun trackPops() {
for (i in insns.indices) {
val frame = frames[i] ?: continue
val insn = insns[i]
when (insn.opcode) {
Opcodes.POP -> {
frame.top()?.getCapturedVarOrNull()?.run { stackInsns.add(insn) }
}
Opcodes.POP2 -> {
val top = frame.top()
if (top?.size == 1) {
top.getCapturedVarOrNull()?.hazard = true
frame.peek(1)?.getCapturedVarOrNull()?.hazard = true
}
}
}
}
}
private fun BasicValue.getCapturedVarOrNull() =
safeAs<ProperTrackedReferenceValue>()?.descriptor?.safeAs<CapturedVarDescriptor>()
private fun assignLocalVars() {
for (localVar in methodNode.localVariables) {
val type = Type.getType(localVar.desc)
if (!AsmTypes.isSharedVarType(type)) continue
val startFrame = frames[localVar.start.getIndex()] ?: continue
val refValue = startFrame.getLocal(localVar.index) as? ProperTrackedReferenceValue ?: continue
val descriptor = refValue.descriptor as? CapturedVarDescriptor ?: continue
if (descriptor.hazard) continue
if (descriptor.localVar == null) {
descriptor.localVar = localVar
}
else {
descriptor.hazard = true
}
}
for (refValue in refValues) {
if (refValue.hazard) continue
val localVar = refValue.localVar ?: continue
val oldVarIndex = localVar.index
if (refValue.valueType.size != 1) {
refValue.localVarIndex = methodNode.maxLocals
methodNode.maxLocals += 2
localVar.index = refValue.localVarIndex
}
else {
refValue.localVarIndex = localVar.index
}
val startIndex = localVar.start.getIndex()
val initFieldInsns = refValue.putFieldInsns.filter { it.getIndex() < startIndex }
if (initFieldInsns.size != 1) {
refValue.hazard = true
continue
}
val cleanInstructions = findCleanInstructions(refValue, oldVarIndex, methodNode.instructions)
if (cleanInstructions.size > 1 ) {
refValue.hazard = true
continue
}
refValue.cleanVarInstruction = cleanInstructions.firstOrNull()
}
}
private fun findCleanInstructions(refValue: CapturedVarDescriptor, oldVarIndex: Int, instructions: InsnList): List<VarInsnNode> {
val cleanInstructions =
InsnSequence(instructions).filterIsInstance<VarInsnNode>().filter {
it.`var` == oldVarIndex
}.filter {
it.previous?.opcode == Opcodes.ACONST_NULL
}.filter {
val operationIndex = instructions.indexOf(it)
val localVariableNode = refValue.localVar!!
instructions.indexOf(localVariableNode.start) < operationIndex && operationIndex < instructions.indexOf(localVariableNode.end)
}.toList()
return cleanInstructions
}
private fun rewrite() {
for (refValue in refValues) {
if (!refValue.canRewrite()) continue
rewriteRefValue(refValue)
}
methodNode.removeEmptyCatchBlocks()
methodNode.removeUnusedLocalVariables()
}
private fun rewriteRefValue(capturedVar: CapturedVarDescriptor) {
methodNode.instructions.run {
capturedVar.localVar!!.let {
it.signature = null
it.desc = capturedVar.valueType.descriptor
}
remove(capturedVar.newInsn)
remove(capturedVar.initCallInsn!!)
capturedVar.stackInsns.forEach { remove(it) }
capturedVar.aloadInsns.forEach { remove(it) }
capturedVar.astoreInsns.forEach { remove(it) }
capturedVar.getFieldInsns.forEach {
set(it, VarInsnNode(capturedVar.valueType.getOpcode(Opcodes.ILOAD), capturedVar.localVarIndex))
}
capturedVar.putFieldInsns.forEach {
set(it, VarInsnNode(capturedVar.valueType.getOpcode(Opcodes.ISTORE), capturedVar.localVarIndex))
}
//after visiting block codegen tries to delete all allocated references:
// see ExpressionCodegen.addLeaveTaskToRemoveLocalVariableFromFrameMap
capturedVar.cleanVarInstruction?.let {
remove(it.previous)
remove(it)
}
}
}
}
}
internal const val REF_ELEMENT_FIELD = "element"
internal const val INIT_METHOD_NAME = "<init>"
internal val REF_TYPE_TO_ELEMENT_TYPE = HashMap<String, Type>().apply {
put(AsmTypes.OBJECT_REF_TYPE.internalName, AsmTypes.OBJECT_TYPE)
PrimitiveType.values().forEach {
put(AsmTypes.sharedTypeForPrimitive(it).internalName, AsmTypes.valueTypeForPrimitive(it))
}
}

View File

@@ -0,0 +1,102 @@
/*
* 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.optimization.captured
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
abstract class ReferenceTrackingInterpreter : OptimizationBasicInterpreter() {
override fun merge(v: BasicValue, w: BasicValue): BasicValue =
when {
v is ProperTrackedReferenceValue && w is ProperTrackedReferenceValue ->
if (v.descriptor == w.descriptor)
v
else
TaintedTrackedReferenceValue(
getTaintedValueType(v.type, w.type),
setOf(v.descriptor, w.descriptor)
)
v is TrackedReferenceValue || w is TrackedReferenceValue ->
TaintedTrackedReferenceValue(
getTaintedValueType(v.type, w.type),
v.referenceValueDescriptors + w.referenceValueDescriptors
)
else ->
super.merge(v, w)
}
private val BasicValue.referenceValueDescriptors: Set<ReferenceValueDescriptor>
get() = if (this is TrackedReferenceValue) this.descriptors else emptySet()
private fun getTaintedValueType(type1: Type?, type2: Type?): Type =
when {
type1 == null || type2 == null -> AsmTypes.OBJECT_TYPE
type1 == type2 -> type1
else -> AsmTypes.OBJECT_TYPE
}
override fun copyOperation(insn: AbstractInsnNode, value: BasicValue): BasicValue? =
if (value is TrackedReferenceValue) {
checkRefValuesUsages(insn, listOf(value))
value
}
else {
super.copyOperation(insn, value)
}
override fun unaryOperation(insn: AbstractInsnNode, value: BasicValue): BasicValue? {
checkRefValuesUsages(insn, listOf(value))
return super.unaryOperation(insn, value)
}
override fun binaryOperation(insn: AbstractInsnNode, value1: BasicValue, value2: BasicValue): BasicValue? {
checkRefValuesUsages(insn, listOf(value1, value2))
return super.binaryOperation(insn, value1, value2)
}
override fun ternaryOperation(insn: AbstractInsnNode, value1: BasicValue, value2: BasicValue, value3: BasicValue): BasicValue? {
checkRefValuesUsages(insn, listOf(value1, value2, value3))
return super.ternaryOperation(insn, value1, value2, value3)
}
override fun naryOperation(insn: AbstractInsnNode, values: List<BasicValue>): BasicValue? {
checkRefValuesUsages(insn, values)
return super.naryOperation(insn, values)
}
protected open fun checkRefValuesUsages(insn: AbstractInsnNode, values: List<BasicValue>) {
values.forEach { value ->
if (value is TaintedTrackedReferenceValue) {
value.descriptors.forEach { it.onUseAsTainted() }
}
}
values.forEachIndexed { pos, value ->
if (value is TrackedReferenceValue) {
processRefValueUsage(value, insn, pos)
}
}
}
protected abstract fun processRefValueUsage(value: TrackedReferenceValue, insn: AbstractInsnNode, position: Int)
}

View File

@@ -0,0 +1,55 @@
/*
* 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.optimization.captured
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
import org.jetbrains.org.objectweb.asm.Type
interface ReferenceValueDescriptor {
fun onUseAsTainted()
}
abstract class TrackedReferenceValue(type: Type): StrictBasicValue(type) {
abstract val descriptors: Set<ReferenceValueDescriptor>
}
class ProperTrackedReferenceValue(type: Type, val descriptor: ReferenceValueDescriptor) : TrackedReferenceValue(type) {
override val descriptors: Set<ReferenceValueDescriptor>
get() = setOf(descriptor)
override fun equals(other: Any?): Boolean =
other === this ||
other is ProperTrackedReferenceValue && other.descriptor == this.descriptor
override fun hashCode(): Int =
descriptor.hashCode()
override fun toString(): String =
"[$descriptor]"
}
class TaintedTrackedReferenceValue(type: Type, override val descriptors: Set<ReferenceValueDescriptor>) : TrackedReferenceValue(type) {
override fun equals(other: Any?): Boolean =
other === this ||
other is TaintedTrackedReferenceValue && other.descriptors == this.descriptors
override fun hashCode(): Int =
descriptors.hashCode()
override fun toString(): String =
"!$descriptors"
}

View File

@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.codegen.optimization.common;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.codegen.AsmUtil;
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
import org.jetbrains.org.objectweb.asm.Handle;
import org.jetbrains.org.objectweb.asm.Opcodes;
import org.jetbrains.org.objectweb.asm.Type;
@@ -136,7 +137,7 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
case NEW:
return newValue(Type.getObjectType(((TypeInsnNode) insn).desc));
default:
throw new Error("Internal error.");
throw new IllegalArgumentException("Unexpected instruction: " + InlineCodegenUtil.getInsnOpcodeText(insn));
}
}
@@ -221,7 +222,7 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
case PUTFIELD:
return null;
default:
throw new Error("Internal error.");
throw new IllegalArgumentException("Unexpected instruction: " + InlineCodegenUtil.getInsnOpcodeText(insn));
}
}
@@ -340,7 +341,7 @@ public class OptimizationBasicInterpreter extends Interpreter<BasicValue> implem
case IFNONNULL:
return null;
default:
throw new Error("Internal error.");
throw new IllegalArgumentException("Unexpected instruction: " + InlineCodegenUtil.getInsnOpcodeText(insn));
}
}

View File

@@ -52,7 +52,7 @@ open class StrictBasicValue(type: Type?) : BasicValue(type) {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other?.javaClass != javaClass) return false
if (other == null || other::class.java != this::class.java) return false
if (!super.equals(other)) return false
other as StrictBasicValue

View File

@@ -17,8 +17,10 @@
package org.jetbrains.kotlin.codegen.optimization.common
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.*
val AbstractInsnNode.isMeaningful: Boolean get() =
@@ -50,9 +52,7 @@ fun MethodNode.prepareForEmitting() {
// local variables with live ranges starting after last meaningful instruction lead to VerifyError
localVariables = localVariables.filter { lv ->
InsnSequence(lv.start, lv.end).any { insn ->
insn.isMeaningful
}
InsnSequence(lv.start, lv.end).any(AbstractInsnNode::isMeaningful)
}
// We should remove linenumbers after last meaningful instruction
@@ -71,10 +71,64 @@ fun MethodNode.prepareForEmitting() {
fun MethodNode.removeEmptyCatchBlocks() {
tryCatchBlocks = tryCatchBlocks.filter { tcb ->
InsnSequence(tcb.start, tcb.end).any { insn ->
insn.isMeaningful
InsnSequence(tcb.start, tcb.end).any(AbstractInsnNode::isMeaningful)
}
}
fun MethodNode.removeUnusedLocalVariables() {
val used = BooleanArray(maxLocals) { false }
for (insn in instructions) {
when (insn) {
is VarInsnNode -> {
val varIndex = insn.`var`
used[varIndex] = true
if (insn.isSize2LoadStoreOperation()) {
used[varIndex + 1] = true
}
}
is IincInsnNode ->
used[insn.`var`] = true
}
}
for (localVar in localVariables) {
val varIndex = localVar.index
used[varIndex] = true
val type = Type.getType(localVar.desc)
if (type.size == 2) {
used[varIndex + 1] = true
}
}
if (used.all { it }) return
val remapping = IntArray(maxLocals) { 0 }
var lastUnused = 0
for (i in remapping.indices) {
remapping[i] = lastUnused
if (used[i]) {
lastUnused++
}
}
remapLocalVariables(remapping)
}
private fun VarInsnNode.isSize2LoadStoreOperation() =
opcode == LLOAD || opcode == DLOAD || opcode == LSTORE || opcode == DSTORE
fun MethodNode.remapLocalVariables(remapping: IntArray) {
for (insn in instructions.toArray()) {
when (insn) {
is VarInsnNode ->
insn.`var` = remapping[insn.`var`]
is IincInsnNode ->
insn.`var` = remapping[insn.`var`]
}
}
for (localVariableNode in localVariables) {
localVariableNode.index = remapping[localVariableNode.index]
}
}
inline fun AbstractInsnNode.findNextOrNull(predicate: (AbstractInsnNode) -> Boolean): AbstractInsnNode? {
@@ -119,9 +173,16 @@ val AbstractInsnNode.intConstant: Int? get() =
fun insnListOf(vararg insns: AbstractInsnNode) = InsnList().apply { insns.forEach { add(it) } }
fun AbstractInsnNode.isStoreOperation(): Boolean = getOpcode() in Opcodes.ISTORE..Opcodes.ASTORE
fun AbstractInsnNode.isLoadOperation(): Boolean = getOpcode() in Opcodes.ILOAD..Opcodes.ALOAD
fun AbstractInsnNode.isStoreOperation(): Boolean = opcode in Opcodes.ISTORE..Opcodes.ASTORE
fun AbstractInsnNode.isLoadOperation(): Boolean = opcode in Opcodes.ILOAD..Opcodes.ALOAD
val AbstractInsnNode?.insnText get() = InlineCodegenUtil.getInsnText(this)
val AbstractInsnNode?.debugText get() =
if (this == null) "<null>" else "${this.javaClass.simpleName}: $insnText"
if (this == null) "<null>" else "${this::class.java.simpleName}: $insnText"
internal inline fun <reified T : AbstractInsnNode> AbstractInsnNode.isInsn(opcode: Int, condition: T.() -> Boolean): Boolean =
takeInsnIf(opcode, condition) != null
internal inline fun <reified T : AbstractInsnNode> AbstractInsnNode.takeInsnIf(opcode: Int, condition: T.() -> Boolean): T? =
takeIf { it.opcode == opcode }?.safeAs<T>()?.takeIf { it.condition() }

View File

@@ -58,16 +58,9 @@ internal class FixStackAnalyzer(
for (marker in context.fakeAlwaysFalseIfeqMarkers) {
val next = marker.next
if (next is JumpInsnNode) {
val nop = InsnNode(Opcodes.NOP)
expectedStackNode[next.label] = nop
method.instructions.insert(next, nop)
method.instructions.remove(marker)
method.instructions.remove(next)
context.nodesToRemoveOnCleanup.add(nop)
expectedStackNode[next.label] = marker
}
}
context.fakeAlwaysFalseIfeqMarkers.clear()
}
private val analyzer = InternalAnalyzer(owner, method, context)

View File

@@ -39,8 +39,6 @@ internal class FixStackContext(val methodNode: MethodNode) {
val openingInlineMethodMarker = hashMapOf<AbstractInsnNode, AbstractInsnNode>()
var consistentInlineMarkers: Boolean = true; private set
val nodesToRemoveOnCleanup = arrayListOf<AbstractInsnNode>()
init {
saveStackMarkerForRestoreMarker = insertTryCatchBlocksMarkers(methodNode)
isThereAnyTryCatch = saveStackMarkerForRestoreMarker.isNotEmpty()

View File

@@ -39,31 +39,51 @@ class FixStackMethodTransformer : MethodTransformer() {
}
if (context.isAnalysisRequired()) {
val analyzer = FixStackAnalyzer(internalClassName, methodNode, context)
analyzer.analyze()
methodNode.maxStack = methodNode.maxStack + analyzer.maxExtraStackSize
val actions = arrayListOf<() -> Unit>()
transformBreakContinueGotos(methodNode, context, actions, analyzer)
transformSaveRestoreStackMarkers(methodNode, context, actions, analyzer)
actions.forEach { it() }
analyzeAndTransformBreakContinueGotos(context, internalClassName, methodNode)
removeAlwaysFalseIfeqMarkers(context, methodNode)
analyzeAndTransformSaveRestoreStack(context, internalClassName, methodNode)
}
context.fakeAlwaysTrueIfeqMarkers.forEach { marker ->
replaceAlwaysTrueIfeqWithGoto(methodNode, marker)
}
removeAlwaysTrueIfeqMarkers(context, methodNode)
removeAlwaysFalseIfeqMarkers(context, methodNode)
}
private fun analyzeAndTransformBreakContinueGotos(context: FixStackContext, internalClassName: String, methodNode: MethodNode) {
val analyzer = FixStackAnalyzer(internalClassName, methodNode, context)
analyzer.analyze()
methodNode.maxStack = methodNode.maxStack + analyzer.maxExtraStackSize
val actions = arrayListOf<() -> Unit>()
transformBreakContinueGotos(methodNode, context, actions, analyzer)
actions.forEach { it() }
}
private fun analyzeAndTransformSaveRestoreStack(context: FixStackContext, internalClassName: String, methodNode: MethodNode) {
val analyzer = FixStackAnalyzer(internalClassName, methodNode, context)
analyzer.analyze()
val actions = arrayListOf<() -> Unit>()
transformSaveRestoreStackMarkers(methodNode, context, actions, analyzer)
actions.forEach { it() }
}
private fun removeAlwaysFalseIfeqMarkers(context: FixStackContext, methodNode: MethodNode) {
context.fakeAlwaysFalseIfeqMarkers.forEach { marker ->
removeAlwaysFalseIfeq(methodNode, marker)
}
context.fakeAlwaysFalseIfeqMarkers.clear()
}
context.nodesToRemoveOnCleanup.forEach {
methodNode.instructions.remove(it)
private fun removeAlwaysTrueIfeqMarkers(context: FixStackContext, methodNode: MethodNode) {
context.fakeAlwaysTrueIfeqMarkers.forEach { marker ->
replaceAlwaysTrueIfeqWithGoto(methodNode, marker)
}
context.fakeAlwaysTrueIfeqMarkers.clear()
}
private fun transformBreakContinueGotos(

View File

@@ -26,7 +26,7 @@ fun <V : Value> Frame<V>.top(): V? =
peek(0)
fun <V : Value> Frame<V>.peek(offset: Int): V? =
if (stackSize >= offset) getStack(stackSize - offset - 1) else null
if (stackSize > offset) getStack(stackSize - offset - 1) else null
class SavedStackDescriptor(
val savedValues: List<BasicValue>,

View File

@@ -0,0 +1,106 @@
/*
* 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.optimization.nullCheck
import org.jetbrains.kotlin.codegen.optimization.boxing.*
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.TypeInsnNode
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
class NullabilityInterpreter : OptimizationBasicInterpreter() {
override fun newOperation(insn: AbstractInsnNode): BasicValue? {
val defaultResult = super.newOperation(insn)
val resultType = defaultResult?.type
return when {
insn.opcode == Opcodes.ACONST_NULL ->
NullBasicValue
insn.opcode == Opcodes.NEW ->
NotNullBasicValue(resultType)
insn.opcode == Opcodes.LDC && resultType.isReferenceType() ->
NotNullBasicValue(resultType)
insn.isUnitInstance() ->
NotNullBasicValue(resultType)
else ->
defaultResult
}
}
private fun Type?.isReferenceType() =
this?.sort.let { it == Type.OBJECT || it == Type.ARRAY }
override fun unaryOperation(insn: AbstractInsnNode, value: BasicValue?): BasicValue? {
val defaultResult = super.unaryOperation(insn, value)
val resultType = defaultResult?.type
return when {
insn.opcode == Opcodes.CHECKCAST ->
value
insn.opcode == Opcodes.NEWARRAY || insn.opcode == Opcodes.ANEWARRAY ->
NotNullBasicValue(resultType)
else ->
defaultResult
}
}
override fun naryOperation(insn: AbstractInsnNode, values: List<BasicValue>): BasicValue? {
val defaultResult = super.naryOperation(insn, values)
val resultType = defaultResult?.type
return when {
insn.isBoxing() ->
NotNullBasicValue(resultType)
insn.isIteratorMethodCallOfProgression(values) ->
ProgressionIteratorBasicValue.byProgressionClassType(values[0].type)
insn.isNextMethodCallOfProgressionIterator(values) ->
NotNullBasicValue(resultType)
else ->
defaultResult
}
}
override fun merge(v: BasicValue, w: BasicValue): BasicValue =
when {
v is NullBasicValue && w is NullBasicValue ->
NullBasicValue
v is NullBasicValue || w is NullBasicValue ->
StrictBasicValue.REFERENCE_VALUE
v is ProgressionIteratorBasicValue && w is ProgressionIteratorBasicValue ->
mergeNotNullValuesOfSameKind(v, w)
v is ProgressionIteratorBasicValue && w is NotNullBasicValue ->
NotNullBasicValue.NOT_NULL_REFERENCE_VALUE
w is ProgressionIteratorBasicValue && v is NotNullBasicValue ->
NotNullBasicValue.NOT_NULL_REFERENCE_VALUE
v is NotNullBasicValue && w is NotNullBasicValue ->
mergeNotNullValuesOfSameKind(v, w)
else ->
super.merge(v, w)
}
private fun mergeNotNullValuesOfSameKind(v: StrictBasicValue, w: StrictBasicValue) =
if (v.type == w.type) v else NotNullBasicValue.NOT_NULL_REFERENCE_VALUE
}
fun TypeInsnNode.getObjectType(): Type =
Type.getObjectType(desc)

View File

@@ -0,0 +1,97 @@
/*
* 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.optimization.nullCheck
import org.jetbrains.kotlin.codegen.optimization.DeadCodeEliminationMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.boxing.ProgressionIteratorBasicValue
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.tree.InsnNode
import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
class RedundantNullCheckMethodTransformer : MethodTransformer() {
private val deadCodeElimination = DeadCodeEliminationMethodTransformer()
override fun transform(internalClassName: String, methodNode: MethodNode) {
while (runSingleNullCheckEliminationPass(internalClassName, methodNode)) {
deadCodeElimination.transform(internalClassName, methodNode)
}
}
private fun isAlwaysFalse(opcode: Int, nullability: Nullability) =
(opcode == Opcodes.IFNULL && nullability == Nullability.NOT_NULL) ||
(opcode == Opcodes.IFNONNULL && nullability == Nullability.NULL)
private fun isAlwaysTrue(opcode: Int, nullability: Nullability) =
(opcode == Opcodes.IFNULL && nullability == Nullability.NULL) ||
(opcode == Opcodes.IFNONNULL && nullability == Nullability.NOT_NULL)
private fun runSingleNullCheckEliminationPass(internalClassName: String, methodNode: MethodNode): Boolean {
val insnList = methodNode.instructions
val instructions = insnList.toArray()
val nullCheckIfs = instructions.mapNotNullTo(SmartList<JumpInsnNode>()) {
it.safeAs<JumpInsnNode>()?.takeIf {
it.opcode == Opcodes.IFNULL ||
it.opcode == Opcodes.IFNONNULL
}
}
if (nullCheckIfs.isEmpty()) return false
val frames = analyze(internalClassName, methodNode, NullabilityInterpreter())
val redundantNullCheckIfs = nullCheckIfs.mapNotNull { insn ->
frames[instructions.indexOf(insn)]?.top()?.let { top ->
val nullability = top.getNullability()
if (nullability == Nullability.NULLABLE)
null
else
Pair(insn, nullability)
}
}
if (redundantNullCheckIfs.isEmpty()) return false
for ((insn, nullability) in redundantNullCheckIfs) {
val previous = insn.previous
when (previous?.opcode) {
Opcodes.ALOAD, Opcodes.DUP ->
insnList.remove(previous)
else ->
insnList.insert(previous, InsnNode(Opcodes.POP))
}
when {
isAlwaysTrue(insn.opcode, nullability) ->
insnList.set(insn, JumpInsnNode(Opcodes.GOTO, insn.label))
isAlwaysFalse(insn.opcode, nullability) ->
insnList.remove(insn)
}
}
return true
}
}

View File

@@ -0,0 +1,367 @@
/*
* 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.optimization.nullCheck
import org.jetbrains.kotlin.codegen.coroutines.withInstructionAdapter
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
import org.jetbrains.kotlin.codegen.optimization.DeadCodeEliminationMethodTransformer
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
import org.jetbrains.kotlin.codegen.optimization.common.isInsn
import org.jetbrains.kotlin.codegen.optimization.fixStack.peek
import org.jetbrains.kotlin.codegen.optimization.fixStack.top
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
import org.jetbrains.org.objectweb.asm.Label
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.tree.*
class RedundantNullCheckV2MethodTransformer : MethodTransformer() {
override fun transform(internalClassName: String, methodNode: MethodNode) {
while (TransformerPass(internalClassName, methodNode).run()) {}
}
private class TransformerPass(val internalClassName: String, val methodNode: MethodNode) {
private var changes = false
private fun AbstractInsnNode.getIndex() =
methodNode.instructions.indexOf(this)
fun run(): Boolean {
val checkedReferenceTypes = analyzeTypesAndRemoveDeadCode()
eliminateRedundantChecks(checkedReferenceTypes)
return changes
}
private fun analyzeTypesAndRemoveDeadCode(): Map<AbstractInsnNode, Type> {
val insns = methodNode.instructions.toArray()
val frames = analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
val checkedReferenceTypes = HashMap<AbstractInsnNode, Type>()
for (i in insns.indices) {
val insn = insns[i]
val frame = frames[i]
if (insn.isInstanceOfOrNullCheck()) {
checkedReferenceTypes[insn] = frame?.top()?.type ?: continue
}
else if (insn.isCheckParameterNotNull()) {
checkedReferenceTypes[insn] = frame?.peek(1)?.type ?: continue
}
}
val dceResult = DeadCodeEliminationMethodTransformer().removeDeadCodeByFrames(methodNode, frames)
if (dceResult.hasRemovedAnything()) {
changes = true
}
return checkedReferenceTypes
}
private fun eliminateRedundantChecks(checkedReferenceTypes: Map<AbstractInsnNode, Type>) {
val nullabilityAssumptions = injectNullabilityAssumptions(checkedReferenceTypes)
val nullabilityMap = analyzeNullabilities()
nullabilityAssumptions.revert()
transformTrivialChecks(nullabilityMap)
}
private fun injectNullabilityAssumptions(checkedReferenceTypes: Map<AbstractInsnNode, Type>) =
NullabilityAssumptionsBuilder(checkedReferenceTypes).injectNullabilityAssumptions()
private fun analyzeNullabilities(): Map<AbstractInsnNode, Nullability> {
val frames = analyze(internalClassName, methodNode, NullabilityInterpreter())
val insns = methodNode.instructions.toArray()
val nullabilityMap = HashMap<AbstractInsnNode, Nullability>()
for (i in insns.indices) {
val nullability = frames[i]?.top()?.getNullability() ?: continue
if (nullability == Nullability.NULLABLE) continue
val insn = insns[i]
if (insn.isInstanceOfOrNullCheck()) {
nullabilityMap[insn] = nullability
}
}
return nullabilityMap
}
private fun transformTrivialChecks(nullabilityMap: Map<AbstractInsnNode, Nullability>) {
for ((insn, nullability) in nullabilityMap) {
when (insn.opcode) {
Opcodes.IFNULL -> transformTrivialNullJump(insn as JumpInsnNode, nullability == Nullability.NULL)
Opcodes.IFNONNULL -> transformTrivialNullJump(insn as JumpInsnNode, nullability == Nullability.NOT_NULL)
Opcodes.INSTANCEOF -> transformInstanceOf(insn, nullability)
}
}
}
private fun transformTrivialNullJump(insn: JumpInsnNode, alwaysTrue: Boolean) {
changes = true
methodNode.instructions.run {
popReferenceValueBefore(insn)
if (alwaysTrue) {
set(insn, JumpInsnNode(Opcodes.GOTO, insn.label))
}
else {
remove(insn)
}
}
}
private fun transformInstanceOf(insn: AbstractInsnNode, nullability: Nullability) {
if (nullability != Nullability.NULL) return
if (ReifiedTypeInliner.isOperationReifiedMarker(insn.previous)) return
changes = true
val nextOpcode = insn.next?.opcode
if (nextOpcode == Opcodes.IFEQ || nextOpcode == Opcodes.IFNE)
transformNullInstanceOfWithJump(insn)
else
transformNullInstanceOf(insn)
}
private fun transformNullInstanceOf(insn: AbstractInsnNode) {
methodNode.instructions.run {
popReferenceValueBefore(insn)
set(insn, InsnNode(Opcodes.ICONST_0))
}
}
private fun transformNullInstanceOfWithJump(insn: AbstractInsnNode) {
methodNode.instructions.run {
popReferenceValueBefore(insn)
val jump = insn.next.assertedCast<JumpInsnNode> { "JumpInsnNode expected" }
remove(insn)
if (jump.opcode == Opcodes.IFEQ) {
set(jump, JumpInsnNode(Opcodes.GOTO, jump.label))
}
else {
remove(jump)
}
}
}
private inner class NullabilityAssumptionsBuilder(val checkedReferenceTypes: Map<AbstractInsnNode, Type>) {
private val checksDependingOnVariable = HashMap<Int, MutableList<AbstractInsnNode>>()
fun injectNullabilityAssumptions(): NullabilityAssumptions {
collectVariableDependentChecks()
return injectAssumptions()
}
private fun collectVariableDependentChecks() {
for (insn in methodNode.instructions) {
if (insn.isInstanceOfOrNullCheck()) {
val previous = insn.previous ?: continue
if (previous.opcode == Opcodes.ALOAD) {
addDependentCheck(insn, previous as VarInsnNode)
}
else if (previous.opcode == Opcodes.DUP) {
val previous2 = previous.previous ?: continue
if (previous2.opcode == Opcodes.ALOAD) {
addDependentCheck(insn, previous2 as VarInsnNode)
}
}
}
else if (insn.isCheckParameterNotNull()) {
val ldcInsn = insn.previous ?: continue
if (ldcInsn.opcode != Opcodes.LDC) continue
val aLoadInsn = ldcInsn.previous ?: continue
if (aLoadInsn.opcode != Opcodes.ALOAD) continue
addDependentCheck(insn, aLoadInsn as VarInsnNode)
}
}
}
private fun addDependentCheck(insn: AbstractInsnNode, aLoadInsn: VarInsnNode) {
checksDependingOnVariable.getOrPut(aLoadInsn.`var`) {
SmartList<AbstractInsnNode>()
}.add(insn)
}
private fun injectAssumptions(): NullabilityAssumptions {
val nullabilityAssumptions = NullabilityAssumptions()
for ((varIndex, dependentChecks) in checksDependingOnVariable) {
for (checkInsn in dependentChecks) {
val varType = checkedReferenceTypes[checkInsn]
?: throw AssertionError("No var type @${checkInsn.getIndex()}")
nullabilityAssumptions.injectAssumptionsForCheck(varIndex, checkInsn, varType)
}
}
return nullabilityAssumptions
}
private fun NullabilityAssumptions.injectAssumptionsForCheck(varIndex: Int, insn: AbstractInsnNode, varType: Type) {
when (insn.opcode) {
Opcodes.IFNULL,
Opcodes.IFNONNULL ->
injectAssumptionsForNullCheck(varIndex, insn as JumpInsnNode, varType)
Opcodes.INVOKESTATIC -> {
assert(insn.isCheckParameterNotNull()) { "Expected non-null parameter check @${insn.getIndex()}"}
injectAssumptionsForParameterNotNullCheck(varIndex, insn, varType)
}
Opcodes.INSTANCEOF ->
injectAssumptionsForInstanceOfCheck(varIndex, insn, varType)
}
}
private fun NullabilityAssumptions.injectAssumptionsForNullCheck(varIndex: Int, insn: JumpInsnNode, varType: Type) {
// ALOAD v
// IFNULL L
// <...> -- v is not null here
// L:
// <...> -- v is null here
val jumpsIfNull = insn.opcode == Opcodes.IFNULL
val originalLabel = insn.label
originalLabels[insn] = originalLabel
insn.label = synthetic(LabelNode(Label()))
val insertAfterNull = if (jumpsIfNull) insn.label else insn
val insertAfterNonNull = if (jumpsIfNull) insn else insn.label
methodNode.instructions.run {
add(insn.label)
insert(insertAfterNull, listOfSynthetics {
aconst(null)
store(varIndex, varType)
if (jumpsIfNull) {
goTo(originalLabel.label)
}
})
insert(insertAfterNonNull, listOfSynthetics {
anew(varType)
store(varIndex, varType)
if (!jumpsIfNull) {
goTo(originalLabel.label)
}
})
}
}
private fun NullabilityAssumptions.injectAssumptionsForParameterNotNullCheck(varIndex: Int, insn: AbstractInsnNode, varType: Type) {
// ALOAD v
// LDC param_name
// INVOKESTATIC checkParameterIsNotNull
// <...> -- v is not null here (otherwise an exception was thrown)
methodNode.instructions.insert(insn, listOfSynthetics {
anew(varType)
store(varIndex, varType)
})
}
private fun NullabilityAssumptions.injectAssumptionsForInstanceOfCheck(varIndex: Int, insn: AbstractInsnNode, varType: Type) {
// ALOAD v
// INSTANCEOF T
// IFEQ L
// <...> -- v is not null here (because it is an instance of T)
// L:
// <...> -- v is something else here (maybe null)
val next = insn.next ?: return
if (next.opcode != Opcodes.IFEQ && next.opcode != Opcodes.IFNE) return
if (next !is JumpInsnNode) return
val jumpsIfInstance = next.opcode == Opcodes.IFNE
val originalLabel: LabelNode?
val insertAfterNotNull: AbstractInsnNode
if (jumpsIfInstance) {
originalLabel = next.label
originalLabels[next] = next.label
val newLabel = synthetic(LabelNode(Label()))
methodNode.instructions.add(newLabel)
next.label = newLabel
insertAfterNotNull = newLabel
}
else {
originalLabel = null
insertAfterNotNull = next
}
methodNode.instructions.run {
insert(insertAfterNotNull, listOfSynthetics {
anew(varType)
store(varIndex, varType)
if (originalLabel != null) {
goTo(originalLabel.label)
}
})
}
}
}
inner class NullabilityAssumptions {
val originalLabels = HashMap<JumpInsnNode, LabelNode>()
val syntheticInstructions = ArrayList<AbstractInsnNode>()
fun <T : AbstractInsnNode> synthetic(insn: T): T {
syntheticInstructions.add(insn)
return insn
}
inline fun listOfSynthetics(block: InstructionAdapter.() -> Unit): InsnList {
val insnList = withInstructionAdapter(block)
for (insn in insnList) {
synthetic(insn)
}
return insnList
}
fun revert() {
methodNode.instructions.run {
syntheticInstructions.forEach { remove(it) }
}
for ((jumpInsn, originalLabel) in originalLabels) {
jumpInsn.label = originalLabel
}
}
}
}
}
internal fun AbstractInsnNode.isInstanceOfOrNullCheck() =
opcode == Opcodes.INSTANCEOF || opcode == Opcodes.IFNULL || opcode == Opcodes.IFNONNULL
internal fun AbstractInsnNode.isCheckParameterNotNull() =
isInsn<MethodInsnNode>(Opcodes.INVOKESTATIC) {
owner == "kotlin/jvm/internal/Intrinsics" &&
name == "checkParameterIsNotNull" &&
desc == "(Ljava/lang/Object;Ljava/lang/String;)V"
}
internal fun InsnList.popReferenceValueBefore(insn: AbstractInsnNode) {
val prev = insn.previous
when (prev?.opcode) {
Opcodes.ACONST_NULL,
Opcodes.DUP,
Opcodes.ALOAD ->
remove(prev)
else ->
insertBefore(insn, InsnNode(Opcodes.POP))
}
}

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