Compare commits

...

180 Commits

Author SHA1 Message Date
Simon Ogorodnik
31060c3352 Add module.md for kotlin-test 2017-05-19 22:51:49 +03:00
Simon Ogorodnik
0b5c285eff Suppress some unwanted kotlin.test API from docs 2017-05-19 22:13:16 +03:00
Simon Ogorodnik
6541e58902 Suppress some unwanted kotlin.test API from docs 2017-05-19 22:13:16 +03:00
Simon Ogorodnik
aac0cd68f1 Suppress some unwanted kotlin.test API from docs 2017-05-19 22:13:16 +03:00
Simon Ogorodnik
006268b4a5 Add noStdlibLink args to build-docs 2017-05-19 22:13:16 +03:00
Simon Ogorodnik
53bb95c032 Add linking to stdlib for kotlin-test 2017-05-19 22:13:16 +03:00
Simon Ogorodnik
c0e9cfbf34 Update build-docs.xml 2017-05-19 22:13:16 +03:00
Dmitry Jemerov
a61d8c0fbb Add module documentation for kotlin.test
(cherry picked from commit 927cd04)
2017-05-19 19:52:49 +02:00
Alexey Tsvetkov
72dd2e4b64 Publish javadoc.jar and sources.jar for libraries projects built with Gradle
Maven central will not publish modules without these artifacts
2017-05-19 16:39:20 +03:00
Alexey Tsvetkov
56a9086248 Update gradle wrapper permissions
It was not executable on linux
2017-05-19 15:54:59 +03:00
Sergey Igushkin
fffe2e812a Add a Gradle wrapper and a dummy buildscript to libraries/
(cherry picked from commit 9b04548)
2017-05-19 15:35:17 +03:00
Sergey Igushkin
341e9543c3 Use the Google Maven repository instead of local preview.
(cherry picked from commit 4279335)

(cherry picked from commit 0e8b850)
2017-05-19 15:35:06 +03:00
Alexey Tsvetkov
2e15fe7e19 Minor: fix 'location' nullability in MessageCollector#report
In master `location` is nullable

(cherry picked from commit 024c555)
2017-05-19 15:34:54 +03:00
Alexander Udalov
58444eb769 Support .jar archives in friend paths (for internal visibility)
(cherry picked from commit 668e53a)
2017-05-19 15:34:40 +03:00
Sergey Igushkin
3a57737379 (minor) Fix missing dependency on JUnit
(cherry picked from commit 7ad5d04)
2017-05-19 15:34:24 +03:00
Sergey Igushkin
608e17ca16 Fix friend paths configuration with the new API for compile*Test tasks
Add lazy `friendClasspathEntries` to KotlinCompile
Set `friendClasspathEntries` in the Android25Pro
Change to AGP 3.0.0-alpha1;

(cherry picked from commit 1d6dd5c)

(cherry picked from commit 6cdf501)
2017-05-19 15:34:11 +03:00
Sergey Igushkin
e4167473e9 Fix registering the non-existent Kapt3 classes directory as bytecode if
Kapt3 is disabled.

(cherry picked from commit 692e23c)

(cherry picked from commit 1cbdb6c)
2017-05-19 15:34:01 +03:00
Sergey Igushkin
776faec1e2 Change the legacy API threshold to 2.5.0
(cherry picked from commit fca2e23)

(cherry picked from commit 9394d15)
2017-05-19 15:33:46 +03:00
Sergey Igushkin
1b7f57c84e Tasks wiring improvements & Kapt3 integration through variant wrapping
(cherry picked from commit b84e1ad)

(cherry picked from commit b7784b6)
2017-05-19 15:33:35 +03:00
Sergey Igushkin
8878843a16 Task wiring
* Generalized tasks wiring
* Moved the old implementation to LegacyAndroidAndroidProjectHandler.kt
* Added an implementation with the new AGP API

(cherry picked from commit 1b4592d)

(cherry picked from commit 50a75d4)
2017-05-19 15:33:19 +03:00
Sergey Igushkin
777d81c351 Add prototype against the new AGP API
* Add a separate Gradle source set, that is compiled against the new
  versions of AGP and Gradle

* Separate the public AGP API usages from the old internal API usages
  in KotlinPlugin.kt -- see AbstractAndroidProjectHandler

* Implement Android25ProjectHandler with the new AGP API, wired it
  to KotlinAndroidPlugin through reflection

(cherry picked from commit e6dbf54)

(cherry picked from commit 88e3d4b)
2017-05-19 15:33:06 +03:00
Sergey Igushkin
48e75bf869 Fix rootDir mis-use in commonConfiguration.gradle:
replace with `kotlin_root`, that is set in the projects

(cherry picked from commit e4b6a22)

(cherry picked from commit 2ec0661)
2017-05-19 15:32:51 +03:00
Sergey Igushkin
a203e7e129 Gradle build fixes & improvements:
* Fix Java not compiled in kotlin-gradle-plugin Kotlin source set
* Fix the integration tests running under Java 6
* Fix kotlin-gradle-subplugin-example not being installed -- needed
  for a test
* Fix Android tests being always excluded
* Move versions out of `build.gradle` (x2) to a common `versions.gradle`
* Move JDK, dist and bootstrap to `commonConfiguration.gradle`
* Build `kotlin-gradle-plugin` with JDK_18

(cherry picked from commit 9a18f45)

(cherry picked from commit 1bdbbe0)
2017-05-19 15:32:40 +03:00
Sergey Igushkin
c63562e956 Gradle plugins migration to Gradle build
* Add gradle-tools subproject
* Add Gradle buildscripts to the related projects
* Remove the projects from the libraries pom.xml
* Move AndroidGradleWrapper.groovy to separate source root
* Changed artifact dependencies to project dependencies where needed
* Extract common configuration into commonConfiguration.gradle
* (convert functions to closures to be able to call them)
* Refactor DSL usage
* Replace `project.properties` with `findProperty`
* Unify Gradle wrapper between `libraries` and `gradle-tools`
(as a temporary solution, just made the wrapper files the same)

(cherry picked from commit 200b326)

(cherry picked from commit d00b3ef)
2017-05-19 15:32:24 +03:00
Ilya Gorbunov
c35d7905a0 Use JDK_16 as jdkHome when building runtime for dist
#KT-17872 Fixed
2017-05-12 21:30:10 +03:00
Vyacheslav Gerasimov
ed04194185 Update changelog for 1.1.2-2 2017-04-28 16:10:56 +03:00
Yan Zhulanow
7f8c57a2e5 Android Extensions: Fix availability in Android/JPS projects (KT-17610) 2017-04-27 21:23:34 +03:00
Denis Zharkov
7e26cc23aa Fix callable reference resolution regression
The regression appeared after
b5a8ffaddc
when we started trying both static and member methods until
first success and when there is no successful
we were just leaving the last one (e.g. private member)

But the actual problem is that we were commiting the trace
in case of single (but incorrect) result in resolution mode of
SHAPE_FUNCTION_ARGUMENTS when we couldn't yet choose the
correct static method

Also we shouldn't choose a shape for callable reference
using only the knowledge that result is single:
it may lead to the wrong inference result
(see test with Pattern::compile)

 #KT-17597 Fixed
2017-04-27 16:41:08 +03:00
Vyacheslav Gerasimov
3451bc250c Remove from changelog items about multiplatform 2017-04-26 11:27:41 +03:00
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
741 changed files with 14351 additions and 4766 deletions

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

@@ -10,8 +10,8 @@
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/guava-19.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
<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

@@ -10,8 +10,8 @@
<JAVADOC />
<SOURCES>
<root url="jar://$PROJECT_DIR$/dependencies/guava-19.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/dependencies/asm5-src.zip!/" />
<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-19.0-sources.jar!/" />
<root url="jar://$PROJECT_DIR$/ideaSDK/sources/sources.jar!/" />
</SOURCES>
</library>
</component>

File diff suppressed because it is too large Load Diff

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

@@ -9743,6 +9743,7 @@ public final class DebugProtoBuf {
*ClassKind
*isInner
*isData
*isHeader
* </pre>
*/
boolean hasFlags();
@@ -9756,6 +9757,7 @@ public final class DebugProtoBuf {
*ClassKind
*isInner
*isData
*isHeader
* </pre>
*/
int getFlags();
@@ -10463,6 +10465,7 @@ public final class DebugProtoBuf {
*ClassKind
*isInner
*isData
*isHeader
* </pre>
*/
public boolean hasFlags() {
@@ -10478,6 +10481,7 @@ public final class DebugProtoBuf {
*ClassKind
*isInner
*isData
*isHeader
* </pre>
*/
public int getFlags() {
@@ -11822,6 +11826,7 @@ public final class DebugProtoBuf {
*ClassKind
*isInner
*isData
*isHeader
* </pre>
*/
public boolean hasFlags() {
@@ -11837,6 +11842,7 @@ public final class DebugProtoBuf {
*ClassKind
*isInner
*isData
*isHeader
* </pre>
*/
public int getFlags() {
@@ -11852,6 +11858,7 @@ public final class DebugProtoBuf {
*ClassKind
*isInner
*isData
*isHeader
* </pre>
*/
public Builder setFlags(int value) {
@@ -11870,6 +11877,7 @@ public final class DebugProtoBuf {
*ClassKind
*isInner
*isData
*isHeader
* </pre>
*/
public Builder clearFlags() {
@@ -17725,6 +17733,8 @@ public final class DebugProtoBuf {
*isInline
*isTailrec
*isExternal
*isSuspend
*isHeader
* </pre>
*/
boolean hasFlags();
@@ -17741,6 +17751,8 @@ public final class DebugProtoBuf {
*isInline
*isTailrec
*isExternal
*isSuspend
*isHeader
* </pre>
*/
int getFlags();
@@ -18084,6 +18096,8 @@ public final class DebugProtoBuf {
*isInline
*isTailrec
*isExternal
*isSuspend
*isHeader
* </pre>
*/
public boolean hasFlags() {
@@ -18102,6 +18116,8 @@ public final class DebugProtoBuf {
*isInline
*isTailrec
*isExternal
*isSuspend
*isHeader
* </pre>
*/
public int getFlags() {
@@ -18913,6 +18929,8 @@ public final class DebugProtoBuf {
*isInline
*isTailrec
*isExternal
*isSuspend
*isHeader
* </pre>
*/
public boolean hasFlags() {
@@ -18931,6 +18949,8 @@ public final class DebugProtoBuf {
*isInline
*isTailrec
*isExternal
*isSuspend
*isHeader
* </pre>
*/
public int getFlags() {
@@ -18949,6 +18969,8 @@ public final class DebugProtoBuf {
*isInline
*isTailrec
*isExternal
*isSuspend
*isHeader
* </pre>
*/
public Builder setFlags(int value) {
@@ -18970,6 +18992,8 @@ public final class DebugProtoBuf {
*isInline
*isTailrec
*isExternal
*isSuspend
*isHeader
* </pre>
*/
public Builder clearFlags() {
@@ -20015,6 +20039,7 @@ public final class DebugProtoBuf {
*hasConstant
*isExternal
*isDelegated
*isHeader
* </pre>
*/
boolean hasFlags();
@@ -20034,6 +20059,7 @@ public final class DebugProtoBuf {
*hasConstant
*isExternal
*isDelegated
*isHeader
* </pre>
*/
int getFlags();
@@ -20391,6 +20417,7 @@ public final class DebugProtoBuf {
*hasConstant
*isExternal
*isDelegated
*isHeader
* </pre>
*/
public boolean hasFlags() {
@@ -20412,6 +20439,7 @@ public final class DebugProtoBuf {
*hasConstant
*isExternal
*isDelegated
*isHeader
* </pre>
*/
public int getFlags() {
@@ -21211,6 +21239,7 @@ public final class DebugProtoBuf {
*hasConstant
*isExternal
*isDelegated
*isHeader
* </pre>
*/
public boolean hasFlags() {
@@ -21232,6 +21261,7 @@ public final class DebugProtoBuf {
*hasConstant
*isExternal
*isDelegated
*isHeader
* </pre>
*/
public int getFlags() {
@@ -21253,6 +21283,7 @@ public final class DebugProtoBuf {
*hasConstant
*isExternal
*isDelegated
*isHeader
* </pre>
*/
public Builder setFlags(int value) {
@@ -21277,6 +21308,7 @@ public final class DebugProtoBuf {
*hasConstant
*isExternal
*isDelegated
*isHeader
* </pre>
*/
public Builder clearFlags() {

View File

@@ -5,7 +5,7 @@
<!-- 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"/>
@@ -584,7 +584,18 @@
</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"/>
@@ -770,41 +781,40 @@
<attribute name="Implementation-Version" value="${build.number}"/>
</manifest>
</jar>
<jar jarfile="${output}/kotlin-daemon-client-sources.jar">
<fileset dir="compiler/daemon/daemon-common/src"/>
<fileset dir="compiler/daemon/daemon-client/src"/>
<zipfileset file="${kotlin-home}/build.txt" prefix="META-INF"/>
<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-Version" value="${build.number}"/>
</manifest>
</jar>
</target>
<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="${output}/kotlin-compiler-client-embeddable-before-shrink.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"/>
<fileset dir="${output}/classes/compiler"
includes="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/**"/>
<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.compiler.client,embeddable}"/>
<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>
</jarjar>
<shrink configuration="${basedir}/compiler/compiler-client.pro"/>
</target>
<target name="android-extensions-compiler">
@@ -1021,6 +1031,8 @@
<element name="class-path"/>
<sequential>
<property environment="env"/>
<cleandir dir="@{output}"/>
<dirset dir="${basedir}" id="src.dirset">
@@ -1053,6 +1065,8 @@
<arg line="@{additionalOptions}"/>
<arg value="-classpath"/>
<arg value="${toString:classpath.path}"/>
<arg value="-jdk-home" />
<arg value="${env.JDK_16}" />
<arg value="-module-name"/>
<arg value="@{moduleName}"/>
<arg value="-Xallow-kotlin-package"/>
@@ -1384,7 +1398,7 @@
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,source-sections-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"

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

@@ -85,6 +85,7 @@ 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.*;
@@ -367,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);
}
@@ -1306,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();
@@ -1325,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

@@ -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 @@ public class OptimizationMethodVisitor extends TransformationMethodVisitor {
private static final MethodTransformer MANDATORY_METHOD_TRANSFORMER = new FixStackWithLabelNormalizationMethodTransformer();
private static final MethodTransformer[] OPTIMIZATION_TRANSFORMERS = new MethodTransformer[] {
new CapturedVarsOptimizationMethodTransformer(),
//new CapturedVarsOptimizationMethodTransformer(),
new RedundantNullCheckV2MethodTransformer(),
new RedundantCheckCastEliminationMethodTransformer(),
new RedundantBoxingMethodTransformer(),

View File

@@ -19,10 +19,7 @@ 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.nullCheck.popReferenceValueBefore
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type
import org.jetbrains.org.objectweb.asm.tree.*
@@ -44,6 +41,10 @@ class RedundantCheckCastEliminationMethodTransformer : MethodTransformer() {
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)
}
@@ -57,4 +58,6 @@ class RedundantCheckCastEliminationMethodTransformer : MethodTransformer() {
private fun isTrivialSubtype(superType: Type, subType: Type) =
superType == subType
private fun isMultiArrayType(type: Type) = type.sort == Type.ARRAY && type.dimensions != 1
}

View File

@@ -17,6 +17,7 @@
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
@@ -63,6 +64,7 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
val stackInsns: MutableCollection<AbstractInsnNode> = LinkedHashSet()
val getFieldInsns: MutableCollection<FieldInsnNode> = LinkedHashSet()
val putFieldInsns: MutableCollection<FieldInsnNode> = LinkedHashSet()
var cleanVarInstruction: VarInsnNode? = null
fun canRewrite(): Boolean =
!hazard &&
@@ -198,6 +200,7 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
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
@@ -214,9 +217,30 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
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
@@ -248,6 +272,13 @@ class CapturedVarsOptimizationMethodTransformer : MethodTransformer() {
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)
}
}
}
}

View File

@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
private val EXTERNAL_SOURCES_KINDS = arrayOf(
JvmDeclarationOriginKind.DELEGATION_TO_DEFAULT_IMPLS,
JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL,
JvmDeclarationOriginKind.DELEGATION,
JvmDeclarationOriginKind.BRIDGE
)
@@ -58,8 +58,9 @@ class BuilderFactoryForDuplicateSignatureDiagnostics(
bindingContext: BindingContext,
private val diagnostics: DiagnosticSink,
fileClassesProvider: JvmFileClassesProvider,
moduleName: String
) : SignatureCollectingClassBuilderFactory(builderFactory) {
moduleName: String,
shouldGenerate: (JvmDeclarationOrigin) -> Boolean
) : SignatureCollectingClassBuilderFactory(builderFactory, shouldGenerate) {
// Avoid errors when some classes are not loaded for some reason
private val typeMapper = KotlinTypeMapper(

View File

@@ -44,6 +44,8 @@ import org.jetbrains.kotlin.psi.KtScript
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import java.io.File
@@ -177,8 +179,10 @@ class GenerationState @JvmOverloads constructor(
{ OptimizationClassBuilderFactory(it, configuration.get(JVMConfigurationKeys.DISABLE_OPTIMIZATION, false)) },
::CoroutineTransformerClassBuilderFactory,
{ BuilderFactoryForDuplicateSignatureDiagnostics(
it, this.bindingContext, diagnostics, fileClassesProvider, this.moduleName
).apply { duplicateSignatureFactory = this } },
it, this.bindingContext, diagnostics,
fileClassesProvider, this.moduleName,
shouldGenerate = { !shouldOnlyCollectSignatures(it) }
).apply { duplicateSignatureFactory = this } },
{ BuilderFactoryForDuplicateClassNameDiagnostics(it, diagnostics) },
{ configuration.get(JVMConfigurationKeys.DECLARATIONS_JSON_PATH)
?.let { destination -> SignatureDumpingBuilderFactory(it, File(destination)) } ?: it }
@@ -209,6 +213,9 @@ class GenerationState @JvmOverloads constructor(
fun destroy() {
interceptedBuilderFactory.close()
}
private fun shouldOnlyCollectSignatures(origin: JvmDeclarationOrigin)
= classBuilderMode == ClassBuilderMode.LIGHT_CLASSES && origin.originKind == CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL
}
private class LazyJvmDiagnostics(compute: () -> Diagnostics): Diagnostics {

View File

@@ -71,6 +71,10 @@ public class K2JSCompilerArguments extends CommonCompilerArguments {
@ValueDescription("<path>")
public String outputPostfix;
@GradleOption(DefaultValues.BooleanFalseDefault.class)
@Argument(value = "Xtypedarrays", description = "Translate primitive arrays to JS typed arrays")
public boolean typedArrays;
@NotNull
public static K2JSCompilerArguments createDefaultInstance() {
K2JSCompilerArguments arguments = new K2JSCompilerArguments();

View File

@@ -111,6 +111,10 @@ public class K2JVMCompilerArguments extends CommonCompilerArguments {
@Argument(value = "Xload-builtins-from-dependencies", description = "Load definitions of built-in declarations from module dependencies, instead of from the compiler")
public boolean loadBuiltInsFromDependencies;
@Argument(value = "Xscript-resolver-environment", description = "Script resolver environment in key-value pairs (the value could be quoted and escaped)")
@ValueDescription("<key=value[,]>")
public String[] scriptResolverEnvironment;
// Paths to output directories for friend modules.
public String[] friendPaths;

View File

@@ -22,5 +22,6 @@
<orderEntry type="module" module-name="util" />
<orderEntry type="module" module-name="annotation-collector" />
<orderEntry type="module" module-name="builtins-serializer" />
<orderEntry type="module" module-name="script.runtime" />
</component>
</module>

View File

@@ -286,6 +286,10 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
ContainerUtil.addAllNotNull(libraries, arguments.libraries.split(File.pathSeparator));
}
if (arguments.typedArrays) {
configuration.put(JSConfigurationKeys.TYPED_ARRAYS_ENABLED, true);
}
configuration.put(JSConfigurationKeys.LIBRARIES, libraries);
String moduleKindName = arguments.moduleKind;

View File

@@ -215,13 +215,14 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
}
}
private fun createEnvironmentWithScriptingSupport(rootDisposable: Disposable,
configuration: CompilerConfiguration,
arguments: K2JVMCompilerArguments,
messageCollector: MessageCollector
): KotlinCoreEnvironment? {
val scriptResolverEnv = hashMapOf<String, Any?>()
val scriptResolverEnv = createScriptResolverEnvironment(arguments, messageCollector) ?: return null
configureScriptDefinitions(arguments.scriptTemplates, configuration, messageCollector, scriptResolverEnv)
if (!messageCollector.hasErrors()) {
val environment = createCoreEnvironment(rootDisposable, configuration)
@@ -416,6 +417,27 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
}
configuration.add(JVMConfigurationKeys.SCRIPT_DEFINITIONS, StandardScriptDefinition)
}
fun createScriptResolverEnvironment(arguments: K2JVMCompilerArguments, messageCollector: MessageCollector): HashMap<String, Any?>? {
val scriptResolverEnv = hashMapOf<String, Any?>()
// parses key/value pairs in the form <key>=<value>, where
// <key> - is a single word (\w+ pattern)
// <value> - optionally quoted string with allowed escaped chars (only double-quote and backslash chars are supported)
// TODO: implement generic unescaping
val envParseRe = """(\w+)=(?:"([^"\\]*(\\.[^"\\]*)*)"|([^\s]*))""".toRegex()
val unescapeRe = """\\(["\\])""".toRegex()
if (arguments.scriptResolverEnvironment != null) {
for (envParam in arguments.scriptResolverEnvironment) {
val match = envParseRe.matchEntire(envParam)
if (match == null || match.groupValues.size < 4 || match.groupValues[1].isBlank()) {
messageCollector.report(CompilerMessageSeverity.ERROR, "Unable to parse script-resolver-environment argument $envParam", CompilerMessageLocation.NO_LOCATION)
return null
}
scriptResolverEnv.put(match.groupValues[1], match.groupValues.drop(2).firstOrNull { it.isNotEmpty() }?.let { unescapeRe.replace(it, "\$1") })
}
}
return scriptResolverEnv
}
}
}

View File

@@ -20,10 +20,7 @@ import com.intellij.core.CoreJavaFileManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiClassOwner
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiPackage
import com.intellij.psi.*
import com.intellij.psi.impl.file.PsiPackageImpl
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.cli.jvm.index.JavaRoot
@@ -35,6 +32,9 @@ import org.jetbrains.kotlin.util.PerformanceCounter
import java.util.*
import kotlin.properties.Delegates
// TODO: do not inherit from CoreJavaFileManager to avoid accidental usage of its methods which do not use caches/indices
// Currently, the only relevant usage of this class as CoreJavaFileManager is at CoreJavaDirectoryService.getPackage,
// which is indirectly invoked from PsiPackage.getSubPackages
class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJavaFileManager(myPsiManager), KotlinCliJavaFileManager {
private val perfCounter = PerformanceCounter.create("Find Java class")
private var index: JvmDependenciesIndex by Delegates.notNull()
@@ -44,44 +44,64 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
this.index = packagesCache
}
override fun findClass(classId: ClassId, searchScope: GlobalSearchScope): PsiClass? {
return perfCounter.time {
val classNameWithInnerClasses = classId.relativeClassName.asString()
index.findClass(classId) { dir, type ->
findClassGivenPackage(allScope, dir, classNameWithInnerClasses, type)
}?.takeIf { it.containingFile.virtualFile in searchScope }
override fun findClass(classId: ClassId, searchScope: GlobalSearchScope): PsiClass? = perfCounter.time {
val relativeClassName = classId.relativeClassName.asString()
index.findClass(classId) { dir, type ->
findClassGivenPackage(allScope, dir, relativeClassName, type)
}?.takeIf { it.containingFile.virtualFile in searchScope }
}
// this method is called from IDEA to resolve dependencies in Java code
// which supposedly shouldn't have errors so the dependencies exist in general
override fun findClass(qName: String, scope: GlobalSearchScope): PsiClass? {
// String cannot be reliably converted to ClassId because we don't know where the package name ends and class names begin.
// For example, if qName is "a.b.c.d.e", we should either look for a top level class "e" in the package "a.b.c.d",
// or, for example, for a nested class with the relative qualified name "c.d.e" in the package "a.b".
// Below, we start by looking for the top level class "e" in the package "a.b.c.d" first, then for the class "d.e" in the package
// "a.b.c", and so on, until we find something. Most classes are top level, so most of the times the search ends quickly
forEachClassId(qName) { classId ->
findClass(classId, scope)?.let { return it }
}
return null
}
private inline fun forEachClassId(fqName: String, block: (ClassId) -> Unit) {
var classId = fqName.toSafeTopLevelClassId() ?: return
while (true) {
block(classId)
val packageFqName = classId.packageFqName
if (packageFqName.isRoot) break
classId = ClassId(
packageFqName.parent(),
FqName(packageFqName.shortName().asString() + "." + classId.relativeClassName.asString()),
false
)
}
}
override fun findClass(qName: String, scope: GlobalSearchScope): PsiClass? {
// this method is called from IDEA to resolve dependencies in Java code
// which supposedly shouldn't have errors so the dependencies exist in general
// Most classes are top level classes so we will try to find them fast
// but we must sometimes fallback to support finding inner/nested classes
return qName.toSafeTopLevelClassId()?.let { classId -> findClass(classId, scope) } ?: super.findClass(qName, scope)
}
override fun findClasses(qName: String, scope: GlobalSearchScope): Array<PsiClass> {
return perfCounter.time {
val classIdAsTopLevelClass = qName.toSafeTopLevelClassId() ?: return@time super.findClasses(qName, scope)
val result = ArrayList<PsiClass>()
val classNameWithInnerClasses = classIdAsTopLevelClass.relativeClassName.asString()
index.traverseDirectoriesInPackage(classIdAsTopLevelClass.packageFqName) { dir, rootType ->
val psiClass = findClassGivenPackage(scope, dir, classNameWithInnerClasses, rootType)
override fun findClasses(qName: String, scope: GlobalSearchScope): Array<PsiClass> = perfCounter.time {
val result = ArrayList<PsiClass>(1)
forEachClassId(qName) { classId ->
val relativeClassName = classId.relativeClassName.asString()
index.traverseDirectoriesInPackage(classId.packageFqName) { dir, rootType ->
val psiClass = findClassGivenPackage(scope, dir, relativeClassName, rootType)
if (psiClass != null) {
result.add(psiClass)
}
// traverse all
true
}
if (result.isEmpty()) {
super.findClasses(qName, scope)
}
else {
result.toTypedArray()
if (result.isNotEmpty()) {
return@time result.toTypedArray()
}
}
PsiClass.EMPTY_ARRAY
}
override fun findPackage(packageName: String): PsiPackage? {
@@ -121,7 +141,29 @@ class KotlinCliJavaFileManagerImpl(private val myPsiManager: PsiManager) : CoreJ
return findClassInPsiFile(classNameWithInnerClasses, file)
}
override fun knownClassNamesInPackage(packageFqName: FqName) = index.collectKnownClassNamesInPackage(packageFqName)
override fun knownClassNamesInPackage(packageFqName: FqName): Set<String> {
val result = hashSetOf<String>()
index.traverseDirectoriesInPackage(packageFqName, continueSearch = {
dir, _ ->
for (child in dir.children) {
if (child.extension == "class" || child.extension == "java") {
result.add(child.nameWithoutExtension)
}
}
true
})
return result
}
override fun findModules(moduleName: String, scope: GlobalSearchScope): Collection<PsiJavaModule> {
// TODO
return emptySet()
}
override fun getNonTrivialPackagePrefixes(): Collection<String> = emptyList()
companion object {
private val LOG = Logger.getInstance(KotlinCliJavaFileManagerImpl::class.java)
@@ -168,4 +210,4 @@ catch (e: AssertionError) {
}
private fun String.toSafeFqName(): FqName? = safely { FqName(this) }
private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) }
private fun String.toSafeTopLevelClassId(): ClassId? = safely { ClassId.topLevel(FqName(this)) }

View File

@@ -23,7 +23,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.read
import kotlin.concurrent.write
class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex {
class JvmDependenciesDynamicCompoundIndex : JvmDependenciesIndex {
private val indices = arrayListOf<JvmDependenciesIndex>()
private val lock = ReentrantReadWriteLock()
@@ -36,13 +36,9 @@ class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex {
fun addNewIndexForRoots(roots: Iterable<JavaRoot>): JvmDependenciesIndex? =
lock.read {
val alreadyIndexed = indexedRoots.toHashSet()
val newRoots = roots.filter { !alreadyIndexed.contains(it) }
val newRoots = roots.filter { root -> root !in alreadyIndexed }
if (newRoots.isEmpty()) null
else {
val index = JvmDependenciesIndexImpl(newRoots)
addIndex(index)
index
}
else JvmDependenciesIndexImpl(newRoots).also(this::addIndex)
}
override val indexedRoots: Sequence<JavaRoot> get() = indices.asSequence().flatMap { it.indexedRoots }
@@ -51,22 +47,15 @@ class JvmDependenciesDynamicCompoundIndex() : JvmDependenciesIndex {
classId: ClassId,
acceptedRootTypes: Set<JavaRoot.RootType>,
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
): T? =
lock.read {
indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull()
}
): T? = lock.read {
indices.asSequence().mapNotNull { it.findClass(classId, acceptedRootTypes, findClassGivenDirectory) }.firstOrNull()
}
override fun traverseDirectoriesInPackage(
packageFqName: FqName,
acceptedRootTypes: Set<JavaRoot.RootType>,
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
) {
lock.read {
indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) }
}
}
override fun collectKnownClassNamesInPackage(packageFqName: FqName): Set<String> = lock.read {
indices.flatMapTo(hashSetOf()) { it.collectKnownClassNamesInPackage(packageFqName) }
) = lock.read {
indices.forEach { it.traverseDirectoriesInPackage(packageFqName, acceptedRootTypes, continueSearch) }
}
}

View File

@@ -35,10 +35,6 @@ interface JvmDependenciesIndex {
acceptedRootTypes: Set<JavaRoot.RootType> = JavaRoot.SourceAndBinary,
continueSearch: (VirtualFile, JavaRoot.RootType) -> Boolean
)
fun collectKnownClassNamesInPackage(
packageFqName: FqName
): Set<String>
}
data class JavaRoot(val file: VirtualFile, val type: RootType, val prefixFqName: FqName? = null) {

View File

@@ -39,24 +39,21 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
private class Cache {
private val innerPackageCaches = HashMap<String, Cache>()
operator fun get(name: String) = innerPackageCaches.getOrPut(name) { Cache() }
operator fun get(name: String) = innerPackageCaches.getOrPut(name, ::Cache)
// indices of roots that are known to contain this package
// if this list contains [1, 3, 5] then roots with indices 1, 3 and 5 are known to contain this package, 2 and 4 are known not to (no information about roots 6 or higher)
// if this list contains maxIndex that means that all roots containing this package are known
val rootIndices = IntArrayList()
val rootIndices = IntArrayList(2)
}
// root "Cache" object corresponds to DefaultPackage which exists in every root. Roots with non-default fqname are also listed here but
// they will be ignored on requests with invalid fqname prefix.
private val rootCache: Cache by lazy {
with(Cache()) {
roots.indices.forEach {
rootIndices.add(it)
}
Cache().apply {
roots.indices.forEach(rootIndices::add)
rootIndices.add(maxIndex)
rootIndices.trimToSize()
this
}
}
@@ -72,7 +69,7 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
acceptedRootTypes: Set<JavaRoot.RootType>,
findClassGivenDirectory: (VirtualFile, JavaRoot.RootType) -> T?
): T? {
return search(FindClassRequest(classId, acceptedRootTypes)) { dir, rootType ->
return findClassCached(classId, acceptedRootTypes) { dir, rootType ->
val found = findClassGivenDirectory(dir, rootType)
HandleResult(found, continueSearch = found == null)
}
@@ -88,73 +85,51 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
}
}
override fun collectKnownClassNamesInPackage(
packageFqName: FqName
): Set<String> {
val result = hashSetOf<String>()
traverseDirectoriesInPackage(packageFqName, continueSearch = {
dir, _ ->
for (child in dir.children) {
if (child.extension != "class" && child.extension != "java") continue
result.add(child.nameWithoutExtension)
}
true
})
return result
}
private data class HandleResult<out T : Any>(val result: T?, val continueSearch: Boolean)
private fun <T : Any> search(
request: SearchRequest,
private fun <T : Any> findClassCached(
classId: ClassId,
acceptedRootTypes: Set<JavaRoot.RootType>,
handler: (VirtualFile, JavaRoot.RootType) -> HandleResult<T>
): T? {
// make a decision based on information saved from last class search
if (request !is FindClassRequest || lastClassSearch?.first?.classId != request.classId) {
return doSearch(request, handler)
if (lastClassSearch?.first?.classId != classId) {
return search(FindClassRequest(classId, acceptedRootTypes), handler)
}
val (cachedRequest, cachedResult) = lastClassSearch!!
return when (cachedResult) {
is SearchResult.NotFound -> {
val limitedRootTypes = request.acceptedRootTypes.toHashSet()
limitedRootTypes.removeAll(cachedRequest.acceptedRootTypes)
val limitedRootTypes = acceptedRootTypes - cachedRequest.acceptedRootTypes
if (limitedRootTypes.isEmpty()) {
null
}
else {
doSearch(FindClassRequest(request.classId, limitedRootTypes), handler)
search(FindClassRequest(classId, limitedRootTypes), handler)
}
}
is SearchResult.Found -> {
if (cachedRequest.acceptedRootTypes == request.acceptedRootTypes) {
if (cachedRequest.acceptedRootTypes == acceptedRootTypes) {
handler(cachedResult.packageDirectory, cachedResult.root.type).result
}
else {
doSearch(request, handler)
search(FindClassRequest(classId, acceptedRootTypes), handler)
}
}
}
}
private fun <T : Any> doSearch(request: SearchRequest, handler: (VirtualFile, JavaRoot.RootType) -> HandleResult<T>): T? {
val findClassRequest = request as? FindClassRequest
fun <T : Any> found(packageDirectory: VirtualFile, root: JavaRoot, result: T): T {
if (findClassRequest != null) {
lastClassSearch = Pair(findClassRequest, SearchResult.Found(packageDirectory, root))
private fun <T : Any> search(request: SearchRequest, handler: (VirtualFile, JavaRoot.RootType) -> HandleResult<T>): T? {
fun <T : Any> found(packageDirectory: VirtualFile, root: JavaRoot, result: T): T = result.also {
if (request is FindClassRequest) {
lastClassSearch = Pair(request, SearchResult.Found(packageDirectory, root))
}
return result
}
fun <T : Any> notFound(): T? {
if (findClassRequest != null) {
lastClassSearch = Pair(findClassRequest, SearchResult.NotFound)
fun <T : Any> notFound(): T? = null.also {
if (request is FindClassRequest) {
lastClassSearch = Pair(request, SearchResult.NotFound)
}
return null
}
fun handle(root: JavaRoot, targetDirInRoot: VirtualFile): T? {
@@ -197,7 +172,7 @@ class JvmDependenciesIndexImpl(_roots: List<JavaRoot>): JvmDependenciesIndex {
return notFound()
}
// try to find a target directory corresponding to package represented by packagesPath in a given root reprenting by index
// try to find a target directory corresponding to package represented by packagesPath in a given root represented by index
// possibly filling "Cache" objects with new information
private fun travelPath(rootIndex: Int, packagesPath: List<String>, fillCachesAfter: Int, cachesPath: List<Cache>): VirtualFile? {
if (rootIndex >= maxIndex) {

View File

@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.repl.messages.DiagnosticMessageHolder
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.script.KotlinScriptExternalDependencies
import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.script.dependencies.KotlinScriptExternalDependencies
class ReplCompilerStageHistory(private val state: GenericReplCompilerState) : BasicReplStageHistory<ScriptDescriptor>(state.lock) {

View File

@@ -68,10 +68,7 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
val daemonJVMOptions = configureDaemonJVMOptions(inheritMemoryLimits = true, inheritAdditionalProperties = true)
val daemonReportMessages = ArrayList<DaemonReportMessage>()
val daemonReportingTargets = when {
log.isDebugEnabled -> DaemonReportingTargets(messages = daemonReportMessages)
else -> DaemonReportingTargets(messageCollector = environment.messageCollector)
}
val daemonReportingTargets = DaemonReportingTargets(messages = daemonReportMessages)
val profiler = if (daemonOptions.reportPerf) WallAndThreadAndMemoryTotalProfiler(withGC = false) else DummyProfiler()
@@ -86,10 +83,15 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
sessionAliveFlagFile = sessionAliveFlagFile)
}
for (msg in daemonReportMessages) {
environment.messageCollector.report(CompilerMessageSeverity.INFO,
(if (msg.category == DaemonReportCategory.EXCEPTION && connection == null) "Falling back to compilation without daemon due to error: " else "") + msg.message,
CompilerMessageLocation.NO_LOCATION)
if (connection == null || log.isDebugEnabled) {
for (message in daemonReportMessages) {
val severity = when(message.category) {
DaemonReportCategory.DEBUG -> CompilerMessageSeverity.INFO
DaemonReportCategory.INFO -> CompilerMessageSeverity.INFO
DaemonReportCategory.EXCEPTION -> CompilerMessageSeverity.EXCEPTION
}
environment.messageCollector.report(severity, message.message, CompilerMessageLocation.NO_LOCATION)
}
}
fun reportTotalAndThreadPerf(message: String, daemonOptions: DaemonOptions, messageCollector: MessageCollector, profiler: Profiler) {

View File

@@ -26,7 +26,6 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompil
import org.jetbrains.kotlin.load.kotlin.incremental.components.JvmPackagePartProto
import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import org.jetbrains.kotlin.utils.rethrow
import java.rmi.server.UnicastRemoteObject
import kotlin.reflect.full.allSuperclasses

View File

@@ -16,9 +16,6 @@
package org.jetbrains.kotlin.daemon.client
import net.rubygrapefruit.platform.Native
import net.rubygrapefruit.platform.NativeException
import net.rubygrapefruit.platform.ProcessLauncher
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
@@ -26,6 +23,7 @@ import org.jetbrains.kotlin.daemon.common.*
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
import java.io.File
import java.io.IOException
import java.io.OutputStream
import java.io.PrintStream
import java.net.SocketException
@@ -98,7 +96,7 @@ object KotlinCompilerClient {
leaseSession: Boolean,
sessionAliveFlagFile: File? = null
): CompileServiceSession? = connectLoop(reportingTargets) {
setupServerHostName()
ensureServerHostnameIsSetUp()
val (service, newJVMOptions) = tryFindSuitableDaemonOrNewOpts(File(daemonOptions.runFilesPath), compilerId, daemonJVMOptions, { cat, msg -> reportingTargets.report(cat, msg) })
if (service != null) {
// the newJVMOptions could be checked here for additional parameters, if needed
@@ -373,9 +371,11 @@ object KotlinCompilerClient {
private fun startDaemon(compilerId: CompilerId, daemonJVMOptions: DaemonJVMOptions, daemonOptions: DaemonOptions, reportingTargets: DaemonReportingTargets) {
val javaExecutable = File(File(System.getProperty("java.home"), "bin"), "java")
val serverHostname = System.getProperty(JAVA_RMI_SERVER_HOSTNAME) ?: error("$JAVA_RMI_SERVER_HOSTNAME is not set!")
val platformSpecificOptions = listOf(
// hide daemon window
"-Djava.awt.headless=true")
"-Djava.awt.headless=true",
"-D$JAVA_RMI_SERVER_HOSTNAME=$serverHostname")
val args = listOf(
javaExecutable.absolutePath, "-cp", compilerId.compilerClasspath.joinToString(File.pathSeparator)) +
platformSpecificOptions +
@@ -389,13 +389,17 @@ object KotlinCompilerClient {
// assuming daemon process is deaf and (mostly) silent, so do not handle streams
val daemon =
try {
val nativeLauncher = Native.get(ProcessLauncher::class.java)
nativeLauncher.start(processBuilder)
launchWithNativePlatformLauncher(processBuilder)
}
catch (e: NativeException) {
reportingTargets.report(DaemonReportCategory.DEBUG, "Could not start daemon with native process launcher, falling back to ProcessBuilder#start")
processBuilder.start()
catch (e: IOException) {
reportingTargets.report(DaemonReportCategory.DEBUG, "Could not start daemon with native process launcher, falling back to ProcessBuilder#start (${e.cause})")
null
}
catch (e: NoClassDefFoundError) {
reportingTargets.report(DaemonReportCategory.DEBUG, "net.rubygrapefruit.platform library is not in the classpath, falling back to ProcessBuilder#start")
null
}
?: processBuilder.start()
val isEchoRead = Semaphore(1)
isEchoRead.acquire()
@@ -435,7 +439,7 @@ object KotlinCompilerClient {
if (daemonOptions.runFilesPath.isNotEmpty()) {
val succeeded = isEchoRead.tryAcquire(daemonStartupTimeout, TimeUnit.MILLISECONDS)
if (!isProcessAlive(daemon))
throw Exception("Daemon terminated unexpectedly")
throw Exception("Daemon terminated unexpectedly with error code: ${daemon.exitValue()}")
if (!succeeded)
throw Exception("Unable to get response from daemon in $daemonStartupTimeout ms")
}
@@ -449,6 +453,7 @@ object KotlinCompilerClient {
// TODO: find better method to stop the thread, but seems it will require asynchronous consuming of the stream
stdoutThread.stop()
}
reportingTargets.out?.flush()
}
}
}

View File

@@ -0,0 +1,32 @@
/*
* 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.daemon.client
import net.rubygrapefruit.platform.Native
import net.rubygrapefruit.platform.NativeException
import net.rubygrapefruit.platform.ProcessLauncher
import java.io.IOException
internal fun launchWithNativePlatformLauncher(processBuilder: ProcessBuilder): Process {
return try {
val nativeLauncher = Native.get(ProcessLauncher::class.java)
nativeLauncher.start(processBuilder)
}
catch (e: NativeException) {
throw IOException(e)
}
}

View File

@@ -31,6 +31,7 @@ import java.util.*
val SOCKET_ANY_FREE_PORT = 0
val JAVA_RMI_SERVER_HOSTNAME = "java.rmi.server.hostname"
object LoopbackNetworkInterface {
@@ -100,6 +101,8 @@ fun findPortAndCreateRegistry(attempts: Int, portRangeStart: Int, portRangeEnd:
* Needs to be set up on both client and server to prevent localhost resolution,
* which may be slow and can cause a timeout when there is a network problem/misconfiguration.
*/
fun setupServerHostName() {
System.setProperty("java.rmi.server.hostname", LoopbackNetworkInterface.loopbackInetAddressName)
fun ensureServerHostnameIsSetUp() {
if (System.getProperty(JAVA_RMI_SERVER_HOSTNAME) == null) {
System.setProperty(JAVA_RMI_SERVER_HOSTNAME, LoopbackNetworkInterface.loopbackInetAddressName)
}
}

View File

@@ -259,7 +259,7 @@ class CompileServiceImpl(
CompileService.CallResult.Ok()
}
override fun scheduleShutdown(graceful: Boolean): CompileService.CallResult<Boolean> = ifAlive(minAliveness = Aliveness.Alive) {
override fun scheduleShutdown(graceful: Boolean): CompileService.CallResult<Boolean> = ifAlive(minAliveness = Aliveness.LastSession, ignoreCompilerChanged = true) {
when {
!graceful -> {
shutdownWithDelay()

View File

@@ -89,7 +89,7 @@ object KotlinCompileDaemon {
@JvmStatic
fun main(args: Array<String>) {
setupServerHostName()
ensureServerHostnameIsSetUp()
log.info("Kotlin compiler daemon version " + (loadVersionFromResource() ?: "<unknown>"))
log.info("daemon JVM args: " + ManagementFactory.getRuntimeMXBean().inputArguments.joinToString(" "))

View File

@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.modules.Module
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import java.io.File
import java.nio.file.Paths
interface ModuleVisibilityManager {
val chunk: Collection<Module>
@@ -63,10 +64,12 @@ fun isContainedByCompiledPartOfOurModule(descriptor: DeclarationDescriptor, outD
if (binaryClass is VirtualFileKotlinClass) {
val file = binaryClass.file
if (file.fileSystem.protocol == StandardFileSystems.FILE_PROTOCOL) {
val ioFile = VfsUtilCore.virtualToIoFile(file)
return ioFile.absolutePath.startsWith(outDirectory.absolutePath + File.separator)
val ioFile = when (file.fileSystem.protocol) {
StandardFileSystems.FILE_PROTOCOL -> VfsUtilCore.virtualToIoFile(file)
StandardFileSystems.JAR_PROTOCOL -> VfsUtilCore.getVirtualFileForJar(file)?.let(VfsUtilCore::virtualToIoFile)
else -> null
}
return ioFile != null && Paths.get(ioFile.toURI()).startsWith(Paths.get(outDirectory.toURI()))
}
return false

View File

@@ -44,9 +44,9 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.idea.KotlinLanguage;
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
import org.jetbrains.kotlin.name.ClassId;
import java.util.ArrayList;
import java.util.Arrays;
@@ -112,8 +112,8 @@ public class KotlinJavaPsiFacade {
}
for (KotlinPsiElementFinderWrapper finder : finders()) {
if (finder instanceof KotlinPsiElementFinderImpl) {
PsiClass aClass = ((KotlinPsiElementFinderImpl) finder).findClass(classId, scope);
if (finder instanceof CliFinder) {
PsiClass aClass = ((CliFinder) finder).findClass(classId, scope);
if (aClass != null) return aClass;
}
else {
@@ -152,8 +152,8 @@ public class KotlinJavaPsiFacade {
public Set<String> knownClassNamesInPackage(@NotNull FqName packageFqName) {
KotlinPsiElementFinderWrapper[] finders = finders();
if (finders.length == 1) {
return ((KotlinPsiElementFinderImpl) finders[0]).knownClassNamesInPackage(packageFqName);
if (finders.length == 1 && finders[0] instanceof CliFinder) {
return ((CliFinder) finders[0]).knownClassNamesInPackage(packageFqName);
}
return null;
@@ -197,9 +197,14 @@ public class KotlinJavaPsiFacade {
}
@NotNull
protected KotlinPsiElementFinderWrapper[] calcFinders() {
private KotlinPsiElementFinderWrapper[] calcFinders() {
List<KotlinPsiElementFinderWrapper> elementFinders = new ArrayList<KotlinPsiElementFinderWrapper>();
elementFinders.add(new KotlinPsiElementFinderImpl(getProject()));
JavaFileManager javaFileManager = findJavaFileManager(project);
elementFinders.add(
javaFileManager instanceof KotlinCliJavaFileManager
? new CliFinder((KotlinCliJavaFileManager) javaFileManager)
: new NonCliFinder(project, javaFileManager)
);
List<PsiElementFinder> nonKotlinFinders = ArraysKt.filter(
getProject().getExtensions(PsiElementFinder.EP_NAME), new Function1<PsiElementFinder, Boolean>() {
@@ -220,6 +225,15 @@ public class KotlinJavaPsiFacade {
return elementFinders.toArray(new KotlinPsiElementFinderWrapper[elementFinders.size()]);
}
@NotNull
private static JavaFileManager findJavaFileManager(@NotNull Project project) {
JavaFileManager javaFileManager = ServiceManager.getService(project, JavaFileManager.class);
if (javaFileManager == null) {
throw new IllegalStateException("JavaFileManager component is not found in project");
}
return javaFileManager;
}
public PsiPackage findPackage(@NotNull String qualifiedName, GlobalSearchScope searchScope) {
PackageCache cache = SoftReference.dereference(packageCache);
if (cache == null) {
@@ -342,59 +356,56 @@ public class KotlinJavaPsiFacade {
}
}
static class KotlinPsiElementFinderImpl implements KotlinPsiElementFinderWrapper, DumbAware {
private final JavaFileManager javaFileManager;
private final boolean isCliFileManager;
private static class CliFinder implements KotlinPsiElementFinderWrapper, DumbAware {
private final KotlinCliJavaFileManager javaFileManager;
private final PsiManager psiManager;
private final PackageIndex packageIndex;
public KotlinPsiElementFinderImpl(Project project) {
this.javaFileManager = findJavaFileManager(project);
this.isCliFileManager = javaFileManager instanceof KotlinCliJavaFileManager;
this.packageIndex = PackageIndex.getInstance(project);
this.psiManager = PsiManager.getInstance(project);
public CliFinder(@NotNull KotlinCliJavaFileManager javaFileManager) {
this.javaFileManager = javaFileManager;
}
@NotNull
private static JavaFileManager findJavaFileManager(@NotNull Project project) {
JavaFileManager javaFileManager = ServiceManager.getService(project, JavaFileManager.class);
if (javaFileManager == null) {
throw new IllegalStateException("JavaFileManager component is not found in project");
}
return javaFileManager;
}
@Override
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
return javaFileManager.findClass(qualifiedName, scope);
}
public PsiClass findClass(@NotNull ClassId classId, @NotNull GlobalSearchScope scope) {
if (isCliFileManager) {
return ((KotlinCliJavaFileManager) javaFileManager).findClass(classId, scope);
}
return findClass(classId.asSingleFqName().asString(), scope);
return javaFileManager.findClass(classId, scope);
}
@Nullable
public Set<String> knownClassNamesInPackage(@NotNull FqName packageFqName) {
if (isCliFileManager) {
return ((KotlinCliJavaFileManager) javaFileManager).knownClassNamesInPackage(packageFqName);
}
return null;
return javaFileManager.knownClassNamesInPackage(packageFqName);
}
@Override
public PsiPackage findPackage(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
if (isCliFileManager) {
return javaFileManager.findPackage(qualifiedName);
}
return javaFileManager.findPackage(qualifiedName);
}
@Override
public boolean isSameResultForAnyScope() {
return false;
}
}
private static class NonCliFinder implements KotlinPsiElementFinderWrapper, DumbAware {
private final JavaFileManager javaFileManager;
private final PsiManager psiManager;
private final PackageIndex packageIndex;
public NonCliFinder(@NotNull Project project, @NotNull JavaFileManager javaFileManager) {
this.javaFileManager = javaFileManager;
this.packageIndex = PackageIndex.getInstance(project);
this.psiManager = PsiManager.getInstance(project);
}
@Override
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
return javaFileManager.findClass(qualifiedName, scope);
}
@Override
public PsiPackage findPackage(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
Query<VirtualFile> dirs = packageIndex.getDirsByPackageName(qualifiedName, true);
return hasDirectoriesInScope(dirs, scope) ? new PsiPackageImpl(psiManager, qualifiedName) : null;
}

View File

@@ -32,7 +32,8 @@ enum class JvmDeclarationOriginKind {
OTHER,
PACKAGE_PART,
INTERFACE_DEFAULT_IMPL,
DELEGATION_TO_DEFAULT_IMPLS,
CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL,
DEFAULT_IMPL_DELEGATION_TO_SUPERINTERFACE_DEFAULT_IMPL,
DELEGATION,
SAM_DELEGATION,
BRIDGE,
@@ -84,8 +85,6 @@ fun MultifileClassPart(file: KtFile, descriptor: PackageFragmentDescriptor): Jvm
JvmDeclarationOrigin(MULTIFILE_CLASS_PART, file, descriptor)
fun DefaultImpls(element: PsiElement?, descriptor: ClassDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(INTERFACE_DEFAULT_IMPL, element, descriptor)
fun DelegationToDefaultImpls(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclarationOrigin =
JvmDeclarationOrigin(DELEGATION_TO_DEFAULT_IMPLS, element, descriptor)
fun Delegation(element: PsiElement?, descriptor: FunctionDescriptor): JvmDeclarationOrigin = JvmDeclarationOrigin(DELEGATION, element, descriptor)

View File

@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.resolve.jvm.platform
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.platform.JvmBuiltIns
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -25,25 +24,28 @@ import org.jetbrains.kotlin.storage.LockBasedStorageManager
import java.util.*
object JvmPlatform : TargetPlatform("JVM") {
private val builtIns by lazy(LazyThreadSafetyMode.PUBLICATION) { JvmBuiltIns(LockBasedStorageManager()) }
private val defaultImports = LockBasedStorageManager().createMemoizedFunction<Boolean, List<ImportPath>> { includeKotlinComparisons ->
ArrayList<ImportPath>().apply {
addAll(Default.getDefaultImports(includeKotlinComparisons))
override fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath> = ArrayList<ImportPath>().apply {
addAll(Default.getDefaultImports(languageVersionSettings))
add(ImportPath.fromString("java.lang.*"))
add(ImportPath.fromString("kotlin.jvm.*"))
add(ImportPath.fromString("java.lang.*"))
add(ImportPath.fromString("kotlin.jvm.*"))
fun addAllClassifiersFromScope(scope: MemberScope) {
for (descriptor in scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, MemberScope.ALL_NAME_FILTER)) {
add(ImportPath(DescriptorUtils.getFqNameSafe(descriptor), false))
}
}
fun addAllClassifiersFromScope(scope: MemberScope) {
for (descriptor in scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS, MemberScope.ALL_NAME_FILTER)) {
add(ImportPath(DescriptorUtils.getFqNameSafe(descriptor), false))
for (builtinPackageFragment in JvmBuiltIns(LockBasedStorageManager.NO_LOCKS).builtInsPackageFragmentsImportedByDefault) {
addAllClassifiersFromScope(builtinPackageFragment.getMemberScope())
}
}
for (builtinPackageFragment in builtIns.builtInsPackageFragmentsImportedByDefault) {
addAllClassifiersFromScope(builtinPackageFragment.getMemberScope())
}
}
override fun getDefaultImports(includeKotlinComparisons: Boolean): List<ImportPath> = defaultImports(includeKotlinComparisons)
override val platformConfigurator: PlatformConfigurator = JvmPlatformConfigurator
override val multiTargetPlatform = MultiTargetPlatform.Specific(platformName)

View File

@@ -16,5 +16,6 @@
<orderEntry type="library" scope="TEST" name="kotlin-test" level="project" />
<orderEntry type="module" module-name="resolution" exported="" />
<orderEntry type="library" exported="" name="kotlin-script-runtime" level="project" />
<orderEntry type="module" module-name="script.runtime" />
</component>
</module>

View File

@@ -196,6 +196,12 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
return module.modulesWhoseInternalsAreVisible().mapTo(LinkedHashSet()) { resolverForProject.descriptorForModule(it as M) }
}
fun computeImplementingModules(module: M): Set<ModuleDescriptorImpl> =
if (modulePlatforms(module) != MultiTargetPlatform.Common) emptySet()
else modules
.filter { modulePlatforms(it) != MultiTargetPlatform.Common && module in it.dependencies() }
.mapTo(mutableSetOf(), resolverForProject::descriptorForModule)
fun setupModuleDependencies() {
modules.forEach {
module ->
@@ -203,7 +209,8 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
LazyModuleDependencies(
storageManager,
{ computeDependencyDescriptors(module) },
{ computeModulesWhoseInternalsAreVisible(module) }
{ computeModulesWhoseInternalsAreVisible(module) },
{ computeImplementingModules(module) }
)
)
}

View File

@@ -646,8 +646,8 @@ class ControlFlowInformationProvider private constructor(
}
}
is KtFunction -> {
if (owner is KtFunctionLiteral &&
!languageVersionSettings.supportsFeature(LanguageFeature.SingleUnderscoreForParameterName)) {
val anonymous = owner is KtFunctionLiteral || owner is KtNamedFunction && owner.name == null
if (anonymous && !languageVersionSettings.supportsFeature(LanguageFeature.SingleUnderscoreForParameterName)) {
return
}
val mainFunctionDetector = MainFunctionDetector(trace.bindingContext)
@@ -666,7 +666,12 @@ class ControlFlowInformationProvider private constructor(
|| OperatorNameConventions.PROVIDE_DELEGATE == functionName) {
return
}
report(UNUSED_PARAMETER.on(element, variableDescriptor), ctxt)
if (anonymous) {
report(UNUSED_ANONYMOUS_PARAMETER.on(element, variableDescriptor), ctxt)
}
else {
report(UNUSED_PARAMETER.on(element, variableDescriptor), ctxt)
}
}
}
}
@@ -1121,6 +1126,7 @@ class ControlFlowInformationProvider private constructor(
private fun mustBeReportedOnAllCopies(diagnosticFactory: DiagnosticFactory<*>) =
diagnosticFactory === UNUSED_VARIABLE
|| diagnosticFactory === UNUSED_PARAMETER
|| diagnosticFactory === UNUSED_ANONYMOUS_PARAMETER
|| diagnosticFactory === UNUSED_CHANGED_VALUE
}
}

View File

@@ -570,7 +570,8 @@ public interface Errors {
enum BadNamedArgumentsTarget {
NON_KOTLIN_FUNCTION,
INVOKE_ON_FUNCTION_TYPE
INVOKE_ON_FUNCTION_TYPE,
HEADER_CLASS_MEMBER,
}
DiagnosticFactory0<KtExpression> VARARG_OUTSIDE_PARENTHESES = DiagnosticFactory0.create(ERROR);
@@ -705,6 +706,7 @@ public interface Errors {
DiagnosticFactory1<KtSimpleNameExpression, KotlinType> COMPARE_TO_TYPE_MISMATCH = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, String> YIELD_IS_RESERVED = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> UNDERSCORE_IS_RESERVED = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> UNDERSCORE_USAGE_WITHOUT_BACKTICKS = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, String> INVALID_CHARACTERS = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<PsiElement, String> INAPPLICABLE_OPERATOR_MODIFIER = DiagnosticFactory1.create(ERROR);
@@ -742,6 +744,7 @@ public interface Errors {
DiagnosticFactory1<KtNamedDeclaration, VariableDescriptor> UNUSED_VARIABLE = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
DiagnosticFactory1<KtParameter, VariableDescriptor> UNUSED_PARAMETER = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
DiagnosticFactory1<KtParameter, VariableDescriptor> UNUSED_ANONYMOUS_PARAMETER = DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
DiagnosticFactory1<KtDestructuringDeclarationEntry, VariableDescriptor> UNUSED_DESTRUCTURED_PARAMETER_ENTRY =
DiagnosticFactory1.create(WARNING, DECLARATION_NAME);
DiagnosticFactory2<KtTypeParameter, TypeParameterDescriptor, KotlinType> UNUSED_TYPEALIAS_PARAMETER =

View File

@@ -207,6 +207,8 @@ public class DefaultErrorMessages {
return "non-Kotlin functions";
case INVOKE_ON_FUNCTION_TYPE:
return "function types";
case HEADER_CLASS_MEMBER:
return "members of header classes";
default:
throw new AssertionError(target);
}
@@ -304,6 +306,7 @@ public class DefaultErrorMessages {
MAP.put(UNINITIALIZED_ENUM_COMPANION, "Companion object of enum class ''{0}'' is uninitialized here", NAME);
MAP.put(UNUSED_VARIABLE, "Variable ''{0}'' is never used", NAME);
MAP.put(UNUSED_PARAMETER, "Parameter ''{0}'' is never used", NAME);
MAP.put(UNUSED_ANONYMOUS_PARAMETER, "Parameter ''{0}'' is never used, could be renamed to _", NAME);
MAP.put(UNUSED_DESTRUCTURED_PARAMETER_ENTRY, "Destructured parameter ''{0}'' is never used", NAME);
MAP.put(ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE, "Variable ''{0}'' is assigned but never accessed", NAME);
MAP.put(VARIABLE_WITH_REDUNDANT_INITIALIZER, "Variable ''{0}'' initializer is redundant", NAME);
@@ -463,6 +466,7 @@ public class DefaultErrorMessages {
MAP.put(COMPARE_TO_TYPE_MISMATCH, "''compareTo()'' must return Int, but returns {0}", RENDER_TYPE);
MAP.put(UNDERSCORE_IS_RESERVED, "Names _, __, ___, ..., are reserved in Kotlin");
MAP.put(UNDERSCORE_USAGE_WITHOUT_BACKTICKS, "Names _, __, ___, ... can be used only in back-ticks (`_`, `__`, `___`, ...)");
MAP.put(YIELD_IS_RESERVED, "{0}", STRING);
MAP.put(INVALID_CHARACTERS, "Name {0}", STRING);

View File

@@ -48,10 +48,14 @@ object PlatformIncompatibilityDiagnosticRenderer :
append("The following declaration")
if (descriptors.size == 1) append(" is") else append("s are")
append(" incompatible")
incompatibility.reason?.let { append(" because $it") }
incompatibility.reason?.let { appendln(" because $it:") }
for (descriptor in descriptors) {
append(indent + " ")
appendln(renderDescriptor(descriptor))
}
incompatibility.unimplemented?.let { unimplemented ->
appendln(".")
append(indent)
appendln("No implementations are found for members listed below:")
for ((descriptor, mapping) in unimplemented) {
@@ -63,12 +67,6 @@ object PlatformIncompatibilityDiagnosticRenderer :
}
render(mapping, indent + INDENTATION_UNIT, renderDescriptor)
}
} ?: run {
appendln(":")
for (descriptor in descriptors) {
append(indent + " ")
appendln(renderDescriptor(descriptor))
}
}
}
}

View File

@@ -298,4 +298,17 @@ public class KtProperty extends KtTypeParameterListOwnerStub<KotlinPropertyStub>
// Suppress Java check for out-of-block
return false;
}
public boolean hasBody() {
if (hasDelegateExpressionOrInitializer()) return true;
KtPropertyAccessor getter = getGetter();
if (getter != null && getter.hasBody()) {
return true;
}
KtPropertyAccessor setter = getSetter();
if (setter != null && setter.hasBody()) {
return true;
}
return false;
}
}

View File

@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.ImportPath
import org.jetbrains.kotlin.resolve.TargetPlatform
@JvmOverloads
fun KtPsiFactory(project: Project?, markGenerated: Boolean = true): KtPsiFactory = KtPsiFactory(project!!, markGenerated)
@@ -45,6 +46,7 @@ private val DO_NOT_ANALYZE_NOTIFICATION = "This file was created by KtPsiFactory
var KtFile.doNotAnalyze: String? by UserDataProperty(Key.create("DO_NOT_ANALYZE"))
var KtFile.analysisContext: PsiElement? by UserDataProperty(Key.create("ANALYSIS_CONTEXT"))
var PsiFile.moduleInfo: ModuleInfo? by UserDataProperty(Key.create("MODULE_INFO"))
var KtFile.targetPlatform: TargetPlatform? by UserDataProperty(Key.create("TARGET_PLATFORM"))
/**
* @param markGenerated This needs to be set to true if the `KtPsiFactory` is going to be used for creating elements that are going

View File

@@ -775,11 +775,14 @@ public class KtPsiUtil {
return (KtElement) parent;
}
}
if (current instanceof KtBlockExpression || current instanceof KtParameter) {
if (current instanceof KtBlockExpression || current instanceof KtParameter || current instanceof KtValueArgument) {
return (KtElement) current;
}
if (current instanceof KtValueArgument) {
return (KtElement) current;
if (current instanceof KtDelegatedSuperTypeEntry) {
PsiElement grandParent = current.getParent().getParent();
if (grandParent instanceof KtClassOrObject && !(grandParent.getParent() instanceof KtObjectLiteralExpression)) {
return (KtElement) grandParent;
}
}
current = parent;

View File

@@ -66,6 +66,13 @@ fun KtSimpleNameExpression.getQualifiedElement(): KtElement {
}
}
fun KtSimpleNameExpression.getQualifiedElementOrCallableRef(): KtElement {
val parent = parent
if (parent is KtCallableReferenceExpression && parent.callableReference == this) return parent
return getQualifiedElement()
}
fun KtSimpleNameExpression.getTopmostParentQualifiedExpressionForSelector(): KtQualifiedExpression? {
return generateSequence<KtExpression>(this) {
val parentQualified = it.parent as? KtQualifiedExpression
@@ -519,4 +526,10 @@ fun KtCallExpression.getOrCreateValueArgumentList(): KtValueArgumentList {
valueArgumentList?.let { return it }
return addAfter(KtPsiFactory(this).createCallArguments("()"),
typeArgumentList ?: calleeExpression) as KtValueArgumentList
}
}
fun KtDeclaration.hasBody() = when (this) {
is KtFunction -> hasBody()
is KtProperty -> hasBody()
else -> false
}

View File

@@ -78,7 +78,7 @@ interface KotlinImportDirectiveStub : StubElement<KtImportDirective> {
fun isValid(): Boolean
}
interface KotlinModifierListStub : StubElement<KtModifierList> {
interface KotlinModifierListStub : StubElement<KtDeclarationModifierList> {
fun hasModifier(modifierToken: KtModifierKeywordToken): Boolean
}

View File

@@ -31,7 +31,7 @@ class KotlinClassStubImpl(
private val qualifiedName: StringRef?,
private val name: StringRef?,
private val superNames: Array<StringRef>,
private val isTrait: Boolean,
private val isInterface: Boolean,
private val isEnumEntry: Boolean,
private val isLocal: Boolean,
private val isTopLevel: Boolean
@@ -42,7 +42,7 @@ class KotlinClassStubImpl(
return FqName(stringRef)
}
override fun isInterface() = isTrait
override fun isInterface() = isInterface
override fun isEnumEntry() = isEnumEntry
override fun isLocal() = isLocal
override fun getName() = StringRef.toString(name)

View File

@@ -18,12 +18,12 @@ package org.jetbrains.kotlin.psi.stubs.impl;
import com.intellij.psi.stubs.StubElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.psi.KtModifierList;
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
import org.jetbrains.kotlin.psi.KtDeclarationModifierList;
import org.jetbrains.kotlin.psi.stubs.KotlinModifierListStub;
import org.jetbrains.kotlin.psi.stubs.elements.KtModifierListElementType;
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
public class KotlinModifierListStubImpl extends KotlinStubBaseImpl<KtModifierList> implements KotlinModifierListStub {
public class KotlinModifierListStubImpl extends KotlinStubBaseImpl<KtDeclarationModifierList> implements KotlinModifierListStub {
private final int mask;

View File

@@ -803,10 +803,9 @@ public class DescriptorResolver {
KtModifierList modifierList = property.getModifierList();
boolean isVar = property.isVar();
boolean hasBody = hasBody(property);
Visibility visibility = resolveVisibilityFromModifiers(property, getDefaultVisibility(property, containingDeclaration));
Modality modality = containingDeclaration instanceof ClassDescriptor
? resolveMemberModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, hasBody),
? resolveMemberModalityFromModifiers(property, getDefaultModality(containingDeclaration, visibility, property.hasBody()),
trace.getBindingContext(), containingDeclaration)
: Modality.FINAL;
@@ -915,22 +914,6 @@ public class DescriptorResolver {
return propertyDescriptor;
}
public static boolean hasBody(KtProperty property) {
boolean hasBody = property.hasDelegateExpressionOrInitializer();
if (!hasBody) {
KtPropertyAccessor getter = property.getGetter();
if (getter != null && getter.hasBody()) {
hasBody = true;
}
KtPropertyAccessor setter = property.getSetter();
if (!hasBody && setter != null && setter.hasBody()) {
hasBody = true;
}
}
return hasBody;
}
@NotNull
/*package*/ static KotlinType transformAnonymousTypeIfNeeded(
@NotNull DeclarationDescriptorWithVisibility descriptor,

View File

@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
import org.jetbrains.kotlin.psi.psiUtil.getTopmostParentQualifiedExpressionForSelector
import org.jetbrains.kotlin.resolve.calls.CallExpressionElement
import org.jetbrains.kotlin.resolve.calls.checkers.UnderscoreUsageChecker
import org.jetbrains.kotlin.resolve.calls.unrollToLeftMostQualifiedExpression
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
@@ -143,7 +144,6 @@ class QualifiedExpressionResolver {
val (name, simpleName) = qualifierPartList.single()
val descriptor = scope.findClassifier(name, KotlinLookupLocation(simpleName))
storeResult(trace, simpleName, descriptor, ownerDescriptor, position = QualifierPosition.TYPE, isQualifier = true)
return TypeQualifierResolutionResult(qualifierPartList, descriptor)
}
@@ -597,6 +597,8 @@ class QualifiedExpressionResolver {
trace.record(BindingContext.REFERENCE_TARGET, referenceExpression, descriptor)
UnderscoreUsageChecker.checkSimpleNameUsage(descriptor, referenceExpression, trace)
if (descriptor is DeclarationDescriptorWithVisibility) {
val fromToCheck =
if (shouldBeVisibleFrom is PackageFragmentDescriptor && shouldBeVisibleFrom.source == SourceElement.NO_SOURCE && referenceExpression.containingFile !is DummyHolder) {

View File

@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.container.StorageComponentContainer
import org.jetbrains.kotlin.container.composeContainer
import org.jetbrains.kotlin.container.useInstance
@@ -29,6 +27,7 @@ import org.jetbrains.kotlin.resolve.checkers.*
import org.jetbrains.kotlin.resolve.lazy.DelegationFilter
import org.jetbrains.kotlin.resolve.scopes.SyntheticConstructorsProvider
import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.types.DynamicTypesSettings
import java.util.*
@@ -36,28 +35,33 @@ abstract class TargetPlatform(val platformName: String) {
override fun toString() = platformName
abstract val platformConfigurator: PlatformConfigurator
abstract fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath>
abstract fun getDefaultImports(includeKotlinComparisons: Boolean): List<ImportPath>
open val excludedImports: List<FqName> get() = emptyList()
abstract val multiTargetPlatform: MultiTargetPlatform
object Default : TargetPlatform("Default") {
override fun getDefaultImports(languageVersionSettings: LanguageVersionSettings): List<ImportPath> = ArrayList<ImportPath>().apply {
listOf(
"kotlin.*",
"kotlin.annotation.*",
"kotlin.collections.*",
"kotlin.ranges.*",
"kotlin.sequences.*",
"kotlin.text.*",
"kotlin.io.*"
).forEach { add(ImportPath.fromString(it)) }
private val defaultImports = LockBasedStorageManager().createMemoizedFunction<Boolean, List<ImportPath>> {
includeKotlinComparisons ->
ArrayList<ImportPath>().apply {
listOf(
"kotlin.*",
"kotlin.annotation.*",
"kotlin.collections.*",
"kotlin.ranges.*",
"kotlin.sequences.*",
"kotlin.text.*",
"kotlin.io.*"
).forEach { add(ImportPath.fromString(it)) }
if (languageVersionSettings.supportsFeature(LanguageFeature.DefaultImportOfPackageKotlinComparisons)) {
add(ImportPath.fromString("kotlin.comparisons.*"))
if (includeKotlinComparisons) {
add(ImportPath.fromString("kotlin.comparisons.*"))
}
}
}
override fun getDefaultImports(includeKotlinComparisons: Boolean): List<ImportPath> = defaultImports(includeKotlinComparisons)
override val platformConfigurator =
object : PlatformConfigurator(
DynamicTypesSettings(), listOf(), listOf(), listOf(), listOf(), listOf(),
@@ -95,7 +99,8 @@ private val DEFAULT_CALL_CHECKERS = listOf(
DeprecatedCallChecker, CallReturnsArrayOfNothingChecker(), InfixCallChecker(), OperatorCallChecker(),
ConstructorHeaderCallChecker, ProtectedConstructorCallChecker, ApiVersionCallChecker,
CoroutineSuspendCallChecker, BuilderFunctionsCallChecker, DslScopeViolationCallChecker, MissingDependencyClassChecker,
CallableReferenceCompatibilityChecker()
CallableReferenceCompatibilityChecker(),
UnderscoreUsageChecker
)
private val DEFAULT_TYPE_CHECKERS = emptyList<AdditionalTypeChecker>()
private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.calls;
import kotlin.Pair;
import kotlin.collections.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
@@ -265,7 +266,7 @@ public class ArgumentTypeResolver {
if (overloadResolutionResults == null) return null;
if (overloadResolutionResults.isSingleResult()) {
if (isSingleAndPossibleTransformToSuccess(overloadResolutionResults)) {
ResolvedCall<?> resolvedCall =
OverloadResolutionResultsUtil.getResultingCall(overloadResolutionResults, context.contextDependency);
if (resolvedCall == null) return null;
@@ -284,6 +285,12 @@ public class ArgumentTypeResolver {
);
}
private static boolean isSingleAndPossibleTransformToSuccess(@NotNull OverloadResolutionResults<?> overloadResolutionResults) {
if (!overloadResolutionResults.isSingleResult()) return false;
ResolvedCall<?> call = CollectionsKt.singleOrNull(overloadResolutionResults.getResultingCalls());
return call != null && call.getStatus().possibleTransformToSuccess();
}
@NotNull
public KotlinTypeInfo getFunctionLiteralTypeInfo(
@NotNull KtExpression expression,

View File

@@ -23,9 +23,7 @@ import kotlin.collections.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor;
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
@@ -42,8 +40,7 @@ import java.util.Map;
import java.util.Set;
import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.INVOKE_ON_FUNCTION_TYPE;
import static org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.NON_KOTLIN_FUNCTION;
import static org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.*;
import static org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET;
import static org.jetbrains.kotlin.resolve.calls.ValueArgumentsToParametersMapper.Status.*;
@@ -189,11 +186,19 @@ public class ValueArgumentsToParametersMapper {
KtSimpleNameExpression nameReference = argumentName.getReferenceExpression();
KtPsiUtilKt.checkReservedYield(nameReference, candidateCall.getTrace());
if (!candidate.hasStableParameterNames() && nameReference != null) {
report(NAMED_ARGUMENTS_NOT_ALLOWED.on(
nameReference,
candidate instanceof FunctionInvokeDescriptor ? INVOKE_ON_FUNCTION_TYPE : NON_KOTLIN_FUNCTION
));
if (nameReference != null) {
if (candidate instanceof MemberDescriptor && ((MemberDescriptor) candidate).isHeader() &&
candidate.getContainingDeclaration() instanceof ClassDescriptor) {
// We do not allow named arguments for members of header classes until we're able to use both
// headers and platform definitions when compiling platform code
report(NAMED_ARGUMENTS_NOT_ALLOWED.on(nameReference, HEADER_CLASS_MEMBER));
}
else if (!candidate.hasStableParameterNames()) {
report(NAMED_ARGUMENTS_NOT_ALLOWED.on(
nameReference,
candidate instanceof FunctionInvokeDescriptor ? INVOKE_ON_FUNCTION_TYPE : NON_KOTLIN_FUNCTION
));
}
}
if (candidate.hasStableParameterNames() && nameReference != null &&

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.resolve.calls.checkers
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
object UnderscoreUsageChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
if (resolvedCall is VariableAsFunctionResolvedCall) return
val descriptor = resolvedCall.resultingDescriptor
val namedDescriptor = if (descriptor is ConstructorDescriptor) descriptor.containingDeclaration else descriptor
if (!namedDescriptor.name.asString().isUnderscoreOnlyName()) return
checkCallElement(resolvedCall.call.callElement, context)
}
private fun checkCallElement(ktElement: KtElement, context: CallCheckerContext) {
when (ktElement) {
is KtSimpleNameExpression ->
checkSimpleNameUsage(ktElement, context.trace)
is KtCallExpression ->
ktElement.calleeExpression?.let { checkCallElement(it, context) }
}
}
private fun checkSimpleNameUsage(ktName: KtSimpleNameExpression, trace: BindingTrace) {
if (ktName.text.isUnderscoreOnlyName()) {
trace.report(Errors.UNDERSCORE_USAGE_WITHOUT_BACKTICKS.on(ktName))
}
}
fun checkSimpleNameUsage(descriptor: DeclarationDescriptor, ktName: KtSimpleNameExpression, trace: BindingTrace) {
if (descriptor.name.asString().isUnderscoreOnlyName()) {
checkSimpleNameUsage(ktName, trace)
}
}
fun String.isUnderscoreOnlyName() =
isNotEmpty() && all { it == '_' }
}

View File

@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.keysToMap
@@ -266,11 +267,11 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
val substitutor = Substitutor(aTypeParams, bTypeParams, parentSubstitutor)
if (aParams.map { substitutor(it.type) } != bParams.map { it.type } ||
aExtensionReceiver?.type?.let(substitutor) != bExtensionReceiver?.type) return Incompatible.ParameterTypes
if (substitutor(a.returnType) != b.returnType) return Incompatible.ReturnType
if (!areCompatibleTypeLists(aParams.map { substitutor(it.type) }, bParams.map { it.type }) ||
!areCompatibleTypes(aExtensionReceiver?.type?.let(substitutor), bExtensionReceiver?.type)) return Incompatible.ParameterTypes
if (!areCompatibleTypes(substitutor(a.returnType), b.returnType)) return Incompatible.ReturnType
if (!equalsBy(aParams, bParams, ValueParameterDescriptor::getName)) return Incompatible.ParameterNames
if (b.hasStableParameterNames() && !equalsBy(aParams, bParams, ValueParameterDescriptor::getName)) return Incompatible.ParameterNames
if (!equalsBy(aTypeParams, bTypeParams, TypeParameterDescriptor::getName)) return Incompatible.TypeParameterNames
if (a.modality != b.modality) return Incompatible.Modality
@@ -292,8 +293,19 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
return Compatible
}
private fun areCompatibleTypes(a: KotlinType?, b: KotlinType?): Boolean {
return if (a != null) b != null && TypeUtils.equalTypes(a, b) else b == null
}
private fun areCompatibleTypeLists(a: List<KotlinType?>, b: List<KotlinType?>): Boolean {
for (i in a.indices) {
if (!areCompatibleTypes(a[i], b[i])) return false
}
return true
}
private fun areCompatibleTypeParameters(a: List<TypeParameterDescriptor>, b: List<TypeParameterDescriptor>, substitutor: Substitutor): Compatibility {
if (a.map { substitutor(it.defaultType) } != b.map { it.defaultType }) return Incompatible.TypeParameterUpperBounds
if (!areCompatibleTypeLists(a.map { substitutor(it.defaultType) }, b.map { it.defaultType })) return Incompatible.TypeParameterUpperBounds
if (!equalsBy(a, b, TypeParameterDescriptor::getVariance)) return Incompatible.TypeParameterVariance
if (!equalsBy(a, b, TypeParameterDescriptor::isReified)) return Incompatible.TypeParameterReified
@@ -362,7 +374,9 @@ class HeaderImplDeclarationChecker(val moduleToCheck: ModuleDescriptor? = null)
// and not added if an explicit supertype _is_ specified
val aSupertypes = a.typeConstructor.supertypes.filterNot(KotlinBuiltIns::isAny)
val bSupertypes = b.typeConstructor.supertypes.filterNot(KotlinBuiltIns::isAny)
if (!bSupertypes.containsAll(aSupertypes.map(substitutor))) return Incompatible.Supertypes
if (aSupertypes.map(substitutor).any { aSupertype ->
bSupertypes.none { bSupertype -> areCompatibleTypes(aSupertype, bSupertype) }
}) return Incompatible.Supertypes
areCompatibleClassScopes(a, b, checkImpl && !implTypealias, substitutor).let { if (it != Compatible) return it }

View File

@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.lazy
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageFeature.DefaultImportOfPackageKotlinComparisons
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
@@ -37,8 +38,9 @@ class DefaultImportProvider(
private val targetPlatform: TargetPlatform,
private val languageVersionSettings: LanguageVersionSettings
) {
val defaultImports: List<ImportPath>
by storageManager.createLazyValue { targetPlatform.getDefaultImports(languageVersionSettings) }
val defaultImports: List<ImportPath> by storageManager.createLazyValue {
targetPlatform.getDefaultImports(languageVersionSettings.supportsFeature(DefaultImportOfPackageKotlinComparisons))
}
val excludedImports: List<FqName> by storageManager.createLazyValue {
val packagesWithAliases = listOf(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME, KotlinBuiltIns.TEXT_PACKAGE_FQ_NAME)

View File

@@ -23,9 +23,8 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.NameUtils
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.KtScript
import java.io.File
import kotlin.comparisons.compareValues
import kotlin.reflect.KClass
import kotlin.script.dependencies.KotlinScriptExternalDependencies
import kotlin.script.templates.standard.ScriptTemplateWithArgs
open class KotlinScriptDefinition(val template: KClass<out Any>) {
@@ -47,33 +46,5 @@ open class KotlinScriptDefinition(val template: KClass<out Any>) {
open fun <TF: Any> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? = null
}
interface KotlinScriptExternalDependencies : Comparable<KotlinScriptExternalDependencies> {
val javaHome: String? get() = null
val classpath: Iterable<File> get() = emptyList()
val imports: Iterable<String> get() = emptyList()
val sources: Iterable<File> get() = emptyList()
val scripts: Iterable<File> get() = emptyList()
override fun compareTo(other: KotlinScriptExternalDependencies): Int =
compareValues(javaHome, other.javaHome)
.chainCompare { compareIterables(classpath, other.classpath) }
.chainCompare { compareIterables(imports, other.imports) }
.chainCompare { compareIterables(sources, other.sources) }
.chainCompare { compareIterables(scripts, other.scripts) }
}
object StandardScriptDefinition : KotlinScriptDefinition(ScriptTemplateWithArgs::class)
private fun<T: Comparable<T>> compareIterables(a: Iterable<T>, b: Iterable<T>): Int {
val ia = a.iterator()
val ib = b.iterator()
while (true) {
if (ia.hasNext() && !ib.hasNext()) return 1
if (!ia.hasNext() && !ib.hasNext()) return 0
if (!ia.hasNext()) return -1
val compRes = compareValues(ia.next(), ib.next())
if (compRes != 0) return compRes
}
}
private inline fun Int.chainCompare(compFn: () -> Int ): Int = if (this != 0) this else compFn()

View File

@@ -34,6 +34,11 @@ import kotlin.reflect.KFunction
import kotlin.reflect.KParameter
import kotlin.reflect.full.memberFunctions
import kotlin.reflect.full.primaryConstructor
import kotlin.script.dependencies.BasicScriptDependenciesResolver
import kotlin.script.dependencies.KotlinScriptExternalDependencies
import kotlin.script.dependencies.ScriptContents
import kotlin.script.dependencies.ScriptDependenciesResolver
import kotlin.script.templates.AcceptedAnnotations
open class KotlinScriptDefinitionFromAnnotatedTemplate(
template: KClass<out Any>,
@@ -43,11 +48,15 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
) : KotlinScriptDefinition(template) {
val scriptFilePattern by lazy {
providedScriptFilePattern ?: template.annotations.firstIsInstanceOrNull<ScriptTemplateDefinition>()?.scriptFilePattern ?: DEFAULT_SCRIPT_FILE_PATTERN
providedScriptFilePattern
?: takeUnlessError { template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateDefinition>()?.scriptFilePattern }
?: takeUnlessError { template.annotations.firstIsInstanceOrNull<org.jetbrains.kotlin.script.ScriptTemplateDefinition>()?.scriptFilePattern }
?: DEFAULT_SCRIPT_FILE_PATTERN
}
val resolver: ScriptDependenciesResolver? by lazy {
val defAnn by lazy { template.annotations.firstIsInstanceOrNull<ScriptTemplateDefinition>() }
val defAnn by lazy { takeUnlessError { template.annotations.firstIsInstanceOrNull<kotlin.script.templates.ScriptTemplateDefinition>() } }
val legacyDefAnn by lazy { takeUnlessError { template.annotations.firstIsInstanceOrNull<org.jetbrains.kotlin.script.ScriptTemplateDefinition>() } }
when {
providedResolver != null -> providedResolver
// TODO: logScriptDefMessage missing or invalid constructor
@@ -61,12 +70,27 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
log.warn("[kts] Script def error ${ex.message}")
null
}
legacyDefAnn != null ->
try {
log.warn("[kts] Deprecated annotations on the script template are used, please update the provider")
legacyDefAnn.resolver.primaryConstructor?.call()?.let {
LegacyScriptDependenciesResolverWrapper(it)
}
?: null.apply {
log.warn("[kts] No default constructor found for ${legacyDefAnn.resolver.qualifiedName}")
}
}
catch (ex: ClassCastException) {
log.warn("[kts] Script def error ${ex.message}")
null
}
else -> BasicScriptDependenciesResolver()
}
}
val samWithReceiverAnnotations: List<String>? by lazy {
template.annotations.firstIsInstanceOrNull<SamWithReceiverAnnotations>()?.annotations?.toList()
takeUnlessError { template.annotations.firstIsInstanceOrNull<kotlin.script.extensions.SamWithReceiverAnnotations>()?.annotations?.toList() }
?: takeUnlessError { template.annotations.firstIsInstanceOrNull<org.jetbrains.kotlin.script.SamWithReceiverAnnotations>()?.annotations?.toList() }
}
private val acceptedAnnotations: List<KClass<out Annotation>> by lazy {
@@ -100,13 +124,9 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
override fun <TF: Any> getDependenciesFor(file: TF, project: Project, previousDependencies: KotlinScriptExternalDependencies?): KotlinScriptExternalDependencies? {
fun logClassloadingError(ex: Throwable) {
logScriptDefMessage(ScriptDependenciesResolver.ReportSeverity.WARNING, ex.message ?: "Invalid script template: ${template.qualifiedName}", null)
}
fun makeScriptContents() = BasicScriptContents(file, getAnnotations = {
val classLoader = template.java.classLoader
try {
takeUnlessError(reportError = false) {
getAnnotationEntries(file, project)
.mapNotNull { psiAnn ->
// TODO: consider advanced matching using semantic similar to actual resolving
@@ -115,21 +135,14 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
}?.let { constructAnnotation(psiAnn, classLoader.loadClass(it.qualifiedName).kotlin as KClass<out Annotation>) }
}
}
catch (ex: Throwable) {
logClassloadingError(ex)
emptyList()
}
?: emptyList()
})
try {
return takeUnlessError(reportError = false) {
val fileDeps = resolver?.resolve(makeScriptContents(), environment, ::logScriptDefMessage, previousDependencies)
// TODO: use it as a Future
return fileDeps?.get()
fileDeps?.get()
}
catch (ex: Throwable) {
logClassloadingError(ex)
}
return null
}
private fun <TF: Any> getAnnotationEntries(file: TF, project: Project): Iterable<KtAnnotationEntry> = when (file) {
@@ -164,6 +177,20 @@ open class KotlinScriptDefinitionFromAnnotatedTemplate(
override val annotationsForSamWithReceivers: List<String>
get() = samWithReceiverAnnotations ?: super.annotationsForSamWithReceivers
private inline fun<T> takeUnlessError(reportError: Boolean = true, body: () -> T?): T? =
try {
body()
}
catch (ex: Throwable) {
if (reportError) {
log.error("Invalid script template: " + template.qualifiedName, ex)
}
else {
log.warn("Invalid script template: " + template.qualifiedName, ex)
}
null
}
companion object {
internal val log = Logger.getInstance(KotlinScriptDefinitionFromAnnotatedTemplate::class.java)
}
@@ -178,3 +205,10 @@ internal fun logScriptDefMessage(reportSeverity: ScriptDependenciesResolver.Repo
ScriptDependenciesResolver.ReportSeverity.DEBUG -> KotlinScriptDefinitionFromAnnotatedTemplate.log.debug(msg)
}
}
internal fun sameSignature(left: KFunction<*>, right: KFunction<*>): Boolean =
left.parameters.size == right.parameters.size &&
left.parameters.zip(right.parameters).all {
it.first.kind == KParameter.Kind.INSTANCE ||
it.first.type == it.second.type
}

View File

@@ -24,6 +24,7 @@ import java.io.File
import java.util.concurrent.locks.ReentrantReadWriteLock
import kotlin.concurrent.read
import kotlin.concurrent.write
import kotlin.script.dependencies.KotlinScriptExternalDependencies
class KotlinScriptExternalImportsProvider(val project: Project, private val scriptDefinitionProvider: KotlinScriptDefinitionProvider) {
@@ -39,22 +40,22 @@ class KotlinScriptExternalImportsProvider(val project: Project, private val scri
private fun <TF: Any> calculateExternalDependencies(file: TF): KotlinScriptExternalDependencies? {
val path = getFilePath(file)
return cache[path]
?: if (cacheOfNulls.contains(path)) null
else scriptDefinitionProvider.findScriptDefinition(file)?.getDependenciesFor(file, project, null)
.apply {
if (this != null) {
log.info("[kts] new cached deps for $path: ${this.classpath.joinToString(File.pathSeparator)}")
}
cacheLock.write {
if (this == null) {
cacheOfNulls.add(path)
}
else {
cache.put(path, this)
}
}
val cached = cache[path]
return when {
cached != null -> cached
cacheOfNulls.contains(path) -> null
else -> scriptDefinitionProvider.findScriptDefinition(file)?.getDependenciesFor(file, project, null).apply {
cacheLock.write {
if (this != null) {
cache.put(path, this)
log.info("[kts] new cached deps for $path: ${this.classpath.joinToString(File.pathSeparator)}")
}
else {
cacheOfNulls.add(path)
}
}
}
}
}
// optimized for initial caching, additional handling of possible duplicates to save a call to distinct

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,15 +23,21 @@ import kotlin.reflect.KClass
const val DEFAULT_SCRIPT_FILE_PATTERN = ".*\\.kts"
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.templatesScriptTemplateDefinition instead",
replaceWith = ReplaceWith("kotlin.script.templates.ScriptTemplateDefinition"))
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class ScriptTemplateDefinition(val resolver: KClass<out ScriptDependenciesResolver> = BasicScriptDependenciesResolver::class,
annotation class ScriptTemplateDefinition(val resolver: KClass<out ScriptDependenciesResolver>,
val scriptFilePattern: String = DEFAULT_SCRIPT_FILE_PATTERN)
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.extensions.SamWithReceiverAnnotations instead",
replaceWith = ReplaceWith("kotlin.script.extensions.SamWithReceiverAnnotations"))
@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class SamWithReceiverAnnotations(vararg val annotations: String)
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.ScriptContents instead",
replaceWith = ReplaceWith("kotlin.script.dependencies.ScriptContents"))
interface ScriptContents {
data class Position(val line: Int, val col: Int)
@@ -41,6 +47,8 @@ interface ScriptContents {
val text: CharSequence?
}
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.PseudoFuture instead",
replaceWith = ReplaceWith("kotlin.script.dependencies.PseudoFuture"))
class PseudoFuture<T>(private val value: T): Future<T> {
override fun get(): T = value
override fun get(p0: Long, p1: TimeUnit): T = value
@@ -51,6 +59,8 @@ class PseudoFuture<T>(private val value: T): Future<T> {
fun KotlinScriptExternalDependencies?.asFuture(): PseudoFuture<KotlinScriptExternalDependencies?> = PseudoFuture(this)
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.ScriptDependenciesResolver instead",
replaceWith = ReplaceWith("kotlin.script.dependencies.ScriptDependenciesResolver"))
interface ScriptDependenciesResolver {
enum class ReportSeverity { ERROR, WARNING, INFO, DEBUG }
@@ -62,9 +72,9 @@ interface ScriptDependenciesResolver {
): Future<KotlinScriptExternalDependencies?> = PseudoFuture(null)
}
@Suppress("unused") // used in gradle-script-kotlin for a moment
@Deprecated("Use new ScriptDependenciesResolver, this one is left for temporary compatibility of new resolvers to kotlin plugin 1.1-M01",
ReplaceWith("ScriptDependenciesResolver"))
@Suppress("unused")
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.ScriptDependenciesResolver instead",
replaceWith = ReplaceWith("kotlin.script.dependencies.ScriptDependenciesResolver"))
interface ScriptDependenciesResolverEx {
fun resolve(script: ScriptContents,
environment: Map<String, Any?>?,
@@ -72,9 +82,72 @@ interface ScriptDependenciesResolverEx {
): KotlinScriptExternalDependencies? = null
}
class BasicScriptDependenciesResolver : ScriptDependenciesResolver
@Deprecated("Used only for compatibility with legacy code, use kotlin.script.dependencies.KotlinScriptExternalDependencies instead",
replaceWith = ReplaceWith("kotlin.script.dependencies.KotlinScriptExternalDependencies"))
interface KotlinScriptExternalDependencies : Comparable<KotlinScriptExternalDependencies> {
val javaHome: String? get() = null
val classpath: Iterable<File> get() = emptyList()
val imports: Iterable<String> get() = emptyList()
val sources: Iterable<File> get() = emptyList()
val scripts: Iterable<File> get() = emptyList()
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class AcceptedAnnotations(vararg val supportedAnnotationClasses: KClass<out Annotation>)
override fun compareTo(other: KotlinScriptExternalDependencies): Int =
compareValues(javaHome, other.javaHome)
.chainCompare { compareIterables(classpath, other.classpath) }
.chainCompare { compareIterables(imports, other.imports) }
.chainCompare { compareIterables(sources, other.sources) }
.chainCompare { compareIterables(scripts, other.scripts) }
}
private fun<T: Comparable<T>> compareIterables(a: Iterable<T>, b: Iterable<T>): Int {
val ia = a.iterator()
val ib = b.iterator()
while (true) {
if (ia.hasNext() && !ib.hasNext()) return 1
if (!ia.hasNext() && !ib.hasNext()) return 0
if (!ia.hasNext()) return -1
val compRes = compareValues(ia.next(), ib.next())
if (compRes != 0) return compRes
}
}
private inline fun Int.chainCompare(compFn: () -> Int ): Int = if (this != 0) this else compFn()
class LegacyScriptDependenciesResolverWrapper(val legacyResolver: ScriptDependenciesResolver) : kotlin.script.dependencies.ScriptDependenciesResolver {
override fun resolve(script: kotlin.script.dependencies.ScriptContents,
environment: Map<String, Any?>?,
report: (kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity, String, kotlin.script.dependencies.ScriptContents.Position?) -> Unit,
previousDependencies: kotlin.script.dependencies.KotlinScriptExternalDependencies?
): Future<kotlin.script.dependencies.KotlinScriptExternalDependencies?> {
val legacyDeps = legacyResolver.resolve(
object : ScriptContents {
override val file: File? get() = script.file
override val annotations: Iterable<Annotation> get() = script.annotations
override val text: CharSequence? get() = script.text
},
environment,
{ sev, msg, pos -> report(kotlin.script.dependencies.ScriptDependenciesResolver.ReportSeverity.values()[sev.ordinal],
msg,
pos?.let { kotlin.script.dependencies.ScriptContents.Position(it.line, it.col) }) },
previousDependencies?.let {
object : KotlinScriptExternalDependencies {
override val javaHome get() = it.javaHome
override val classpath get() = it.classpath
override val imports get() = it.imports
override val sources get() = it.sources
override val scripts get() = it.scripts
}
}
).get()
return kotlin.script.dependencies.PseudoFuture(legacyDeps?.let {
object : kotlin.script.dependencies.KotlinScriptExternalDependencies {
override val javaHome get() = it.javaHome
override val classpath get() = it.classpath
override val imports get() = it.imports
override val sources get() = it.sources
override val scripts get() = it.scripts
}
})
}
}

View File

@@ -22,6 +22,7 @@ import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import java.io.File
import java.net.URLClassLoader
import kotlin.script.dependencies.ScriptDependenciesResolver
interface ScriptTemplatesProvider {

View File

@@ -913,7 +913,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
return baseTypeInfo;
}
DataFlowInfo dataFlowInfo = baseTypeInfo.getDataFlowInfo();
if (isKnownToBeNotNull(baseExpression, context) && !baseType.isError()) {
if (isKnownToBeNotNull(baseExpression, baseType, context)) {
context.trace.report(UNNECESSARY_NOT_NULL_ASSERTION.on(operationSign, TypeUtils.makeNotNullable(baseType)));
}
else {
@@ -956,15 +956,20 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
return facade.getTypeInfo(baseExpression, context, isStatement);
}
private static boolean isKnownToBeNotNull(KtExpression expression, ExpressionTypingContext context) {
KotlinType type = context.trace.getType(expression);
assert type != null : "This method is only supposed to be called when the type is not null";
return isKnownToBeNotNull(expression, type, context);
}
// Returns `true` if warnings should be reported for left-hand side of elvis and not-null (!!) assertion
private static boolean isKnownToBeNotNull(
@NotNull KtExpression expression,
@Nullable KotlinType ktType,
@NotNull ExpressionTypingContext context
) {
if (ktType == null) return false;
private static boolean isKnownToBeNotNull(KtExpression expression, KotlinType jetType, ExpressionTypingContext context) {
DataFlowValue dataFlowValue = createDataFlowValue(expression, jetType, context);
return !context.dataFlowInfo.getStableNullability(dataFlowValue).canBeNull();
if (ktType.isError() && !ErrorUtils.isUninferredParameter(ktType)) return false;
if (!TypeUtils.isNullableType(ktType)) return true;
DataFlowValue dataFlowValue = createDataFlowValue(expression, ktType, context);
return context.dataFlowInfo.getStableNullability(dataFlowValue) == Nullability.NOT_NULL;
}
/**
@@ -1296,7 +1301,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
}
assert leftTypeInfo != null : "Left expression was not processed: " + expression;
KotlinType leftType = leftTypeInfo.getType();
if (leftType != null && isKnownToBeNotNull(left, leftType, context)) {
if (isKnownToBeNotNull(left, leftType, context)) {
context.trace.report(USELESS_ELVIS.on(expression, leftType));
}
else if (KtPsiUtil.isNullConstant(right) && leftType != null && !FlexibleTypesKt.isNullabilityFlexible(leftType)) {

View File

@@ -665,7 +665,7 @@ class DoubleColonExpressionResolver(
resolutionResults.isNothing -> null
else -> ResolutionResultsAndTraceCommitCallback(resolutionResults) {
checkReservedYield(reference, outerContext.trace)
if (resolutionMode != ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS || resolutionResults.isSingleResult) {
if (resolutionMode != ResolveArgumentsMode.SHAPE_FUNCTION_ARGUMENTS || resolutionResults.isSuccess) {
temporaryTrace.commit()
}
}

View File

@@ -37,21 +37,6 @@ public class ClsWrapperStubPsiFactory extends StubPsiFactory {
private ClsWrapperStubPsiFactory() { }
@Nullable
public static LightMemberOriginForDeclaration getMemberOrigin(@NotNull PsiMember member) {
if (member instanceof ClsRepositoryPsiElement<?>) {
StubElement stubElement = ((ClsRepositoryPsiElement<?>) member).getStub();
if (stubElement instanceof UserDataHolder) {
LightElementOrigin origin = ((UserDataHolder) stubElement).getUserData(ORIGIN);
if (origin instanceof LightMemberOriginForDeclaration) {
return (LightMemberOriginForDeclaration) origin;
}
}
}
return null;
}
@Override
public PsiClass createClass(@NotNull PsiClassStub stub) {
final PsiElement origin = getOriginalElement(stub);

View File

@@ -23,7 +23,6 @@ import com.intellij.psi.impl.java.stubs.PsiJavaFileStub
import com.intellij.psi.stubs.StubElement
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.LightClassUtil.findClass
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder.javaFileStub
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
import org.jetbrains.kotlin.asJava.elements.KtLightField
@@ -110,7 +109,7 @@ fun PsiJavaFileStub.findDelegate(classOrObject: KtClassOrObject): PsiClass {
fun PsiJavaFileStub.findDelegate(classFqName: FqName): PsiClass {
return findClass(this) {
classFqName.asString() == it.qualifiedName
} ?: throw IllegalStateException("Facade class $classFqName not found; classes in Java file stub: ${collectClassNames(javaFileStub)}")
} ?: throw IllegalStateException("Facade class $classFqName not found; classes in Java file stub: ${collectClassNames(this)}")
}

View File

@@ -16,12 +16,14 @@
package org.jetbrains.kotlin.asJava.classes
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.asJava.builder.LightClassData
abstract class KtLazyLightClass(manager: PsiManager) : KtLightClassBase(manager) {
abstract val lightClassData: LightClassData
override val clsDelegate: PsiClass by lazyPub { lightClassData.clsDelegate }
override fun getOwnFields() = lightClassData.getOwnFields(this)
override fun getOwnMethods() = lightClassData.getOwnMethods(this)

View File

@@ -194,12 +194,8 @@ class KtLightClassForFacade private constructor(
override fun copy() = KtLightClassForFacade(manager, facadeClassFqName, lightClassDataCache, files)
override val lightClassData by lazyPub {
lightClassDataCache.value.findDataForFacade(facadeClassFqName)
}
override val clsDelegate: PsiClass
get() = lightClassData.clsDelegate
override val lightClassData
get() = lightClassDataCache.value.findDataForFacade(facadeClassFqName)
override fun getNavigationElement() = files.iterator().next()

View File

@@ -78,9 +78,8 @@ abstract class KtLightClassForSourceDeclaration(protected val classOrObject: KtC
abstract override fun getParent(): PsiElement?
abstract override fun getQualifiedName(): String?
override val clsDelegate: PsiClass get() = lightClassData.clsDelegate
override val lightClassData: LightClassData by lazyPub { findLightClassData() }
override val lightClassData: LightClassData
get() = findLightClassData()
open protected fun findLightClassData() = getLightClassDataHolder().findDataForClassOrObject(classOrObject)

View File

@@ -16,13 +16,13 @@
package org.jetbrains.kotlin.asJava.elements
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiField
import com.intellij.psi.PsiNamedElement
import com.intellij.psi.*
import com.intellij.psi.impl.PsiVariableEx
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
interface KtLightElement<out T : KtElement, out D : PsiElement> : PsiNamedElement {
val kotlinOrigin: T?
@@ -30,8 +30,18 @@ interface KtLightElement<out T : KtElement, out D : PsiElement> : PsiNamedElemen
val clsDelegate: D
}
interface KtLightDeclaration<out T: KtDeclaration, out D: PsiElement>: KtLightElement<T, D>
interface KtLightDeclaration<out T : KtDeclaration, out D : PsiElement> : KtLightElement<T, D>
interface KtLightField : PsiField, KtLightDeclaration<KtDeclaration, PsiField>, PsiVariableEx {
interface KtLightMember<out D : PsiMember> : PsiMember, KtLightDeclaration<KtDeclaration, D>, PsiNameIdentifierOwner, PsiDocCommentOwner {
val lightMemberOrigin: LightMemberOrigin?
override fun getContainingClass(): KtLightClass
}
interface KtLightField : PsiField, KtLightMember<PsiField>, PsiVariableEx
interface KtLightMethod : PsiAnnotationMethod, KtLightMember<PsiMethod> {
val isDelegated: Boolean
get() = lightMemberOrigin?.originKind == JvmDeclarationOriginKind.DELEGATION
|| lightMemberOrigin?.originKind == JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL
}

View File

@@ -16,12 +16,8 @@
package org.jetbrains.kotlin.asJava.elements
import com.intellij.navigation.ItemPresentation
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.impl.PsiVariableEx
import com.intellij.psi.impl.light.LightElement
import com.intellij.util.IncorrectOperationException
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory
@@ -30,42 +26,24 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForEnumEntry
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtEnumEntry
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import java.lang.UnsupportedOperationException
// Copied from com.intellij.psi.impl.light.LightField
sealed class KtLightFieldImpl<T: PsiField>(
sealed class KtLightFieldImpl<D : PsiField>(
override val lightMemberOrigin: LightMemberOrigin?,
computeRealDelegate: () -> T,
private val containingClass: KtLightClass,
private val dummyDelegate: PsiField?
) : LightElement(containingClass.manager, KotlinLanguage.INSTANCE), KtLightField {
private val lightIdentifier by lazyPub { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) }
computeRealDelegate: () -> D,
containingClass: KtLightClass,
dummyDelegate: PsiField?
) : KtLightMemberImpl<PsiField>(computeRealDelegate, lightMemberOrigin, containingClass, dummyDelegate), KtLightField {
override val clsDelegate: T by lazyPub(computeRealDelegate)
override val clsDelegate: D
@Suppress("UNCHECKED_CAST")
get() = super.clsDelegate as D
@Throws(IncorrectOperationException::class)
override fun setInitializer(initializer: PsiExpression?) = throw IncorrectOperationException("Not supported")
override fun getUseScope() = kotlinOrigin?.useScope ?: super.getUseScope()
override fun getPresentation(): ItemPresentation? = (kotlinOrigin ?: this).let { ItemPresentationProviders.getItemPresentation(it) }
override fun getName() = dummyDelegate?.name ?: clsDelegate.name
override fun getNameIdentifier() = lightIdentifier
override fun getDocComment() = clsDelegate.docComment
override fun isDeprecated() = clsDelegate.isDeprecated
override fun getContainingClass() = containingClass
override fun getContainingFile() = containingClass.containingFile
override fun getType() = clsDelegate.type
override fun getTypeElement() = clsDelegate.typeElement
@@ -84,34 +62,12 @@ sealed class KtLightFieldImpl<T: PsiField>(
return this
}
private val _modifierList by lazyPub {
if (lightMemberOrigin is LightMemberOriginForDeclaration)
clsDelegate.modifierList?.let { KtLightModifierList(it, this) }
else clsDelegate.modifierList
}
override fun getModifierList() = _modifierList
override fun hasModifierProperty(@NonNls name: String) = (dummyDelegate ?: clsDelegate).hasModifierProperty(name)
override fun getText() = kotlinOrigin?.text ?: ""
override fun getTextRange() = kotlinOrigin?.textRange ?: TextRange.EMPTY_RANGE
override fun isValid() = containingClass.isValid
override fun toString(): String = "${this::class.java.simpleName}:$name"
override fun equals(other: Any?): Boolean =
other is KtLightFieldImpl<*> &&
this.name == other.name &&
this.containingClass == other.containingClass
override fun hashCode() = 31 * containingClass.hashCode() + (name?.hashCode() ?: 0)
override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin?.originalElement
override fun getNavigationElement() = kotlinOrigin ?: super.getNavigationElement()
override fun hashCode() = 31 * containingClass.hashCode() + name.hashCode()
override fun computeConstantValue(visitedVars: MutableSet<PsiVariable>?): Any? {
return (clsDelegate as PsiVariableEx).computeConstantValue(visitedVars)
@@ -124,8 +80,6 @@ sealed class KtLightFieldImpl<T: PsiField>(
return super.isEquivalentTo(another)
}
override fun isWritable() = kotlinOrigin?.isWritable ?: false
override fun copy() = Factory.create(lightMemberOrigin?.copy(), clsDelegate, containingClass)
@@ -134,7 +88,7 @@ sealed class KtLightFieldImpl<T: PsiField>(
computeDelegate: () -> PsiEnumConstant,
containingClass: KtLightClass,
dummyDelegate: PsiField?
) : KtLightFieldImpl<PsiEnumConstant>(origin, computeDelegate , containingClass, dummyDelegate), PsiEnumConstant {
) : KtLightFieldImpl<PsiEnumConstant>(origin, computeDelegate, containingClass, dummyDelegate), PsiEnumConstant {
private val initializingClass by lazyPub {
val kotlinEnumEntry = (lightMemberOrigin as? LightMemberOriginForDeclaration)?.originalElement as? KtEnumEntry
if (kotlinEnumEntry != null && kotlinEnumEntry.declarations.isNotEmpty()) {
@@ -184,8 +138,9 @@ sealed class KtLightFieldImpl<T: PsiField>(
}
fun fromClsFields(delegateClass: PsiClass, containingClass: KtLightClass) = delegateClass.fields.map {
val origin = ClsWrapperStubPsiFactory.getMemberOrigin(it)
KtLightFieldImpl.create(origin, it, containingClass)
KtLightFieldImpl.create(getOrigin(it), it, containingClass)
}
fun getOrigin(field: PsiField) = getMemberOrigin(field)
}
}

View File

@@ -0,0 +1,143 @@
/*
* 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.asJava.elements
import com.intellij.navigation.ItemPresentation
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.openapi.util.TextRange
import com.intellij.openapi.util.UserDataHolder
import com.intellij.psi.*
import com.intellij.psi.impl.compiled.ClsRepositoryPsiElement
import com.intellij.psi.impl.light.LightElement
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory.ORIGIN
import org.jetbrains.kotlin.asJava.builder.LightElementOrigin
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.builder.LightMemberOriginForDeclaration
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.psiUtil.hasBody
abstract class KtLightMemberImpl<out D : PsiMember>(
computeRealDelegate: () -> D,
override val lightMemberOrigin: LightMemberOrigin?,
private val containingClass: KtLightClass,
private val dummyDelegate: D?
) : LightElement(containingClass.manager, KotlinLanguage.INSTANCE), PsiMember, KtLightMember<D> {
override val clsDelegate by lazyPub(computeRealDelegate)
private val lightIdentifier by lazyPub { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) }
private val _modifierList by lazyPub {
if (lightMemberOrigin is LightMemberOriginForDeclaration)
KtLightModifierList(this, dummyDelegate?.modifierList)
else clsDelegate.modifierList!!
}
override fun hasModifierProperty(name: String) = _modifierList.hasModifierProperty(name)
override fun getModifierList(): PsiModifierList = _modifierList
override fun toString(): String = "${this::class.java.simpleName}:$name"
override fun getContainingClass() = containingClass
override fun getContainingFile() = containingClass.containingFile
override fun getParent(): PsiElement = containingClass
override fun isValid() = containingClass.isValid
override fun getName(): String = dummyDelegate?.name ?: clsDelegate.name!!
override fun getNameIdentifier(): PsiIdentifier = lightIdentifier
override fun getUseScope() = kotlinOrigin?.useScope ?: super.getUseScope()
override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin?.originalElement
override fun getNavigationElement() = kotlinOrigin ?: super.getNavigationElement()
override fun getPresentation(): ItemPresentation? = (kotlinOrigin ?: this).let { ItemPresentationProviders.getItemPresentation(it) }
override fun getText() = kotlinOrigin?.text ?: ""
override fun getTextRange() = kotlinOrigin?.textRange ?: TextRange.EMPTY_RANGE
override fun isWritable() = kotlinOrigin?.isWritable ?: false
override fun getDocComment() = (clsDelegate as PsiDocCommentOwner).docComment
override fun isDeprecated() = (clsDelegate as PsiDocCommentOwner).isDeprecated
}
private val visibilityModifiers = arrayOf(PsiModifier.PRIVATE, PsiModifier.PACKAGE_LOCAL, PsiModifier.PROTECTED, PsiModifier.PUBLIC)
internal fun getMemberOrigin(member: PsiMember): LightMemberOriginForDeclaration? {
if (member !is ClsRepositoryPsiElement<*>) return null
val stubElement = member.stub as? UserDataHolder ?: return null
return stubElement.getUserData<LightElementOrigin>(ORIGIN) as? LightMemberOriginForDeclaration ?: return null
}
class KtLightModifierList(
private val owner: KtLightMember<*>,
private val dummyDelegate: PsiModifierList?
) : LightElement(owner.manager, KotlinLanguage.INSTANCE), PsiModifierList {
private val clsDelegate by lazyPub { owner.clsDelegate.modifierList!! }
private val _annotations by lazyPub { computeAnnotations(this, clsDelegate) }
override fun hasModifierProperty(name: String) = when {
name == PsiModifier.ABSTRACT && isImplementationInInterface() -> false
name == PsiModifier.DEFAULT && isImplementationInInterface() -> true
dummyDelegate != null -> {
when {
name in visibilityModifiers && isMethodOverride() ->
clsDelegate.hasModifierProperty(name)
else -> dummyDelegate.hasModifierProperty(name)
}
}
else -> clsDelegate.hasModifierProperty(name)
}
private fun isMethodOverride() = owner is KtLightMethod && owner.kotlinOrigin?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false
private fun isImplementationInInterface()
= owner.containingClass.isInterface && owner is KtLightMethod && owner.kotlinOrigin?.hasBody() ?: false
override fun hasExplicitModifier(name: String) = hasModifierProperty(name)
override fun setModifierProperty(name: String, value: Boolean) = clsDelegate.setModifierProperty(name, value)
override fun checkSetModifierProperty(name: String, value: Boolean) = clsDelegate.checkSetModifierProperty(name, value)
override fun addAnnotation(qualifiedName: String) = clsDelegate.addAnnotation(qualifiedName)
override fun getApplicableAnnotations(): Array<out PsiAnnotation> = annotations
override fun getAnnotations(): Array<out PsiAnnotation> = _annotations.value
override fun findAnnotation(qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName }
override fun getParent() = owner
override fun getText(): String? = ""
override fun getTextRange() = TextRange.EMPTY_RANGE
override fun copy(): PsiElement = KtLightModifierList(owner, dummyDelegate)
override fun getReferences() = PsiReference.EMPTY_ARRAY
override fun isEquivalentTo(another: PsiElement?) =
another is KtLightModifierList && owner == another.owner
override fun toString() = "Light modifier list of $owner"
}

View File

@@ -16,13 +16,8 @@
package org.jetbrains.kotlin.asJava.elements
import com.intellij.core.JavaCoreBundle
import com.intellij.navigation.ItemPresentation
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.impl.compiled.ClsTypeElementImpl
import com.intellij.psi.impl.light.LightElement
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.scope.PsiScopeProcessor
import com.intellij.psi.util.*
import com.intellij.util.IncorrectOperationException
@@ -32,29 +27,17 @@ import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.propertyNameByAccessor
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
interface KtLightMethod : PsiAnnotationMethod, KtLightDeclaration<KtDeclaration, PsiMethod> {
val lightMethodOrigin: LightMemberOrigin?
val isDelegated: Boolean
}
class KtLightMethodImpl private constructor(
computeRealDelegate: () -> PsiMethod,
override val lightMethodOrigin: LightMemberOrigin?,
private val containingClass: KtLightClass,
lightMemberOrigin: LightMemberOrigin?,
containingClass: KtLightClass,
private val dummyDelegate: PsiMethod? = null
) : LightElement(containingClass.manager, containingClass.language), KtLightMethod {
override val kotlinOrigin: KtDeclaration? get() = lightMethodOrigin?.originalElement as? KtDeclaration
override val clsDelegate by lazyPub(computeRealDelegate)
private val lightIdentifier by lazyPub { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) }
) : KtLightMemberImpl<PsiMethod>(computeRealDelegate, lightMemberOrigin, containingClass, dummyDelegate), KtLightMethod {
private val returnTypeElem by lazyPub {
val delegateTypeElement = clsDelegate.returnTypeElement as? ClsTypeElementImpl
delegateTypeElement?.let { ClsTypeElementImpl(this, it.canonicalText, /*ClsTypeElementImpl.VARIANCE_NONE */ 0.toChar()) }
@@ -62,8 +45,6 @@ class KtLightMethodImpl private constructor(
private val calculatingReturnType = ThreadLocal<Boolean>()
override fun getContainingClass(): KtLightClass = containingClass
private val paramsList: PsiParameterList by lazyPub {
KtLightParameterList(this, dummyDelegate?.parameterList?.parametersCount ?: clsDelegate.parameterList.parametersCount) {
clsDelegate.parameterList.parameters.mapIndexed { index, clsParameter -> KtLightParameter(clsParameter, index, this@KtLightMethodImpl) }
@@ -74,7 +55,7 @@ class KtLightMethodImpl private constructor(
val cacheManager = CachedValuesManager.getManager(clsDelegate.project)
cacheManager.createCachedValue<PsiTypeParameterList>(
{
val origin = (lightMethodOrigin as? LightMemberOriginForDeclaration)?.originalElement
val origin = (lightMemberOrigin as? LightMemberOriginForDeclaration)?.originalElement
val list = if (origin != null) {
if (origin is KtClassOrObject) {
KotlinLightTypeParameterListBuilder(manager)
@@ -91,16 +72,6 @@ class KtLightMethodImpl private constructor(
)
}
override fun getNavigationElement(): PsiElement = kotlinOrigin?.navigationElement ?: super.getNavigationElement()
override fun getPresentation(): ItemPresentation? = kotlinOrigin?.presentation ?: super.getPresentation()
override fun getParent(): PsiElement = containingClass
override fun getText() = kotlinOrigin?.text ?: ""
override fun getTextRange() = kotlinOrigin?.textRange ?: TextRange.EMPTY_RANGE
override val isDelegated: Boolean
get() = lightMethodOrigin?.originKind == JvmDeclarationOriginKind.DELEGATION
|| lightMethodOrigin?.originKind == JvmDeclarationOriginKind.DELEGATION_TO_DEFAULT_IMPLS
override fun accept(visitor: PsiElementVisitor) {
if (visitor is JavaElementVisitor) {
visitor.visitMethod(this)
@@ -136,31 +107,22 @@ class KtLightMethodImpl private constructor(
} ?: throwCanNotModify()
}
private fun throwCanNotModify(): Nothing {
throw IncorrectOperationException(JavaCoreBundle.message("psi.error.attempt.to.edit.class.file"))
}
private val _modifierList by lazyPub {
if (lightMethodOrigin is LightMemberOriginForDeclaration)
KtLightModifierList(clsDelegate.modifierList, this)
else clsDelegate.modifierList
}
// TODO: add message
private fun throwCanNotModify(): Nothing = throw IncorrectOperationException()
override fun getModifierList(): PsiModifierList {
if (calculatingReturnType.get() == true) {
return KotlinJavaPsiFacade.getInstance(project).emptyModifierList
}
return _modifierList
return super.getModifierList()!!
}
override fun getNameIdentifier() = lightIdentifier
override fun getParameterList() = paramsList
override fun getTypeParameterList() = typeParamsList.value
override fun getTypeParameters(): Array<PsiTypeParameter> =
typeParameterList?.let { it.typeParameters } ?: PsiTypeParameter.EMPTY_ARRAY
typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
override fun getSignature(substitutor: PsiSubstitutor): MethodSignature {
if (substitutor == PsiSubstitutor.EMPTY) {
@@ -170,13 +132,9 @@ class KtLightMethodImpl private constructor(
}
override fun copy(): PsiElement {
return Factory.create(clsDelegate, lightMethodOrigin?.copy(), containingClass)
return Factory.create(clsDelegate, lightMemberOrigin?.copy(), containingClass)
}
override fun getUseScope() = kotlinOrigin?.useScope ?: super.getUseScope()
override fun getLanguage() = KotlinLanguage.INSTANCE
override fun processDeclarations(processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean {
return typeParameters.all { processor.execute(it, state) }
}
@@ -200,12 +158,10 @@ class KtLightMethodImpl private constructor(
other is KtLightMethodImpl &&
this.name == other.name &&
this.containingClass == other.containingClass &&
this.lightMethodOrigin == other.lightMethodOrigin &&
this.lightMemberOrigin == other.lightMemberOrigin &&
this._memberIndex == other._memberIndex
override fun hashCode(): Int = ((getName().hashCode() * 31 + (lightMethodOrigin?.hashCode() ?: 0)) * 31 + containingClass.hashCode()) * 31 + (_memberIndex?.hashCode() ?: 0)
override fun toString(): String = "${this::class.java.simpleName}:$name"
override fun hashCode(): Int = ((getName().hashCode() * 31 + (lightMemberOrigin?.hashCode() ?: 0)) * 31 + containingClass.hashCode()) * 31 + (_memberIndex?.hashCode() ?: 0)
override fun getDefaultValue() = (clsDelegate as? PsiAnnotationMethod)?.defaultValue
@@ -244,37 +200,30 @@ class KtLightMethodImpl private constructor(
origin: LightMemberOriginForDeclaration?,
computeRealDelegate: () -> PsiMethod
): KtLightMethodImpl {
return KtLightMethodImpl(computeRealDelegate, adjustMethodOrigin(origin), containingClass, dummyDelegate)
return KtLightMethodImpl(computeRealDelegate, origin, containingClass, dummyDelegate)
}
fun fromClsMethods(delegateClass: PsiClass, containingClass: KtLightClass) = delegateClass.methods.map {
val origin = ClsWrapperStubPsiFactory.getMemberOrigin(it)
KtLightMethodImpl.create(it, adjustMethodOrigin(origin), containingClass)
KtLightMethodImpl.create(it, getOrigin(it), containingClass)
}
fun getOrigin(method: PsiMethod) = adjustMethodOrigin(getMemberOrigin(method))
}
override fun getName() = dummyDelegate?.name ?: clsDelegate.name
override fun hasModifierProperty(name: String) = (dummyDelegate ?: clsDelegate).hasModifierProperty(name)
override fun getThrowsList() = clsDelegate.throwsList
override fun hasTypeParameters() = clsDelegate.hasTypeParameters()
override fun isVarArgs() = clsDelegate.isVarArgs
override fun isVarArgs() = (dummyDelegate ?: clsDelegate).isVarArgs
override fun isConstructor() = dummyDelegate?.isConstructor ?: clsDelegate.isConstructor
override fun getHierarchicalMethodSignature() = clsDelegate.hierarchicalMethodSignature
override fun getDocComment() = clsDelegate.docComment
override fun findSuperMethodSignaturesIncludingStatic(checkAccess: Boolean) = clsDelegate.findSuperMethodSignaturesIncludingStatic(checkAccess)
override fun getBody() = null
override fun isDeprecated() = clsDelegate.isDeprecated
override fun findDeepestSuperMethod() = clsDelegate.findDeepestSuperMethod()
override fun findDeepestSuperMethods() = clsDelegate.findDeepestSuperMethods()
@@ -284,10 +233,6 @@ class KtLightMethodImpl private constructor(
override fun findSuperMethods(checkAccess: Boolean) = clsDelegate.findSuperMethods(checkAccess)
override fun findSuperMethods(parentClass: PsiClass?) = clsDelegate.findSuperMethods(parentClass)
override fun getContainingFile() = parent.containingFile
override fun isValid() = containingClass.isValid
}
fun KtLightMethod.isTraitFakeOverride(): Boolean {

View File

@@ -16,14 +16,14 @@
package org.jetbrains.kotlin.asJava.elements
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiAnnotationOwner
import com.intellij.psi.PsiModifierList
import com.intellij.psi.impl.light.LightModifierList
import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValuesManager
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.util.ArrayUtil
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
import org.jetbrains.kotlin.asJava.classes.lazyPub
@@ -54,43 +54,6 @@ abstract class KtLightModifierListWithExplicitModifiers(
override fun addAnnotation(@NonNls qualifiedName: String) = delegate.addAnnotation(qualifiedName)
}
class KtLightModifierList(
private val delegate: PsiModifierList,
private val owner: PsiModifierListOwner
) : PsiModifierList by delegate {
private val _annotations by lazyPub { computeAnnotations(this, delegate) }
override fun getAnnotations(): Array<out PsiAnnotation> = _annotations.value
override fun findAnnotation(@NonNls qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName }
override fun addAnnotation(@NonNls qualifiedName: String) = delegate.addAnnotation(qualifiedName)
override fun getParent() = owner
override fun getText(): String? = ""
override fun getLanguage() = KotlinLanguage.INSTANCE
override fun getTextRange() = TextRange.EMPTY_RANGE
override fun getStartOffsetInParent() = -1
override fun getTextLength() = 0
override fun getPrevSibling(): PsiElement? = null
override fun getNextSibling(): PsiElement? = null
override fun findElementAt(offset: Int): PsiElement? = null
override fun findReferenceAt(offset: Int): PsiReference? = null
override fun getTextOffset() = -1
override fun isWritable() = false
override fun isPhysical() = false
override fun textToCharArray(): CharArray = ArrayUtil.EMPTY_CHAR_ARRAY;
override fun textMatches(text: CharSequence): Boolean = getText() == text.toString()
override fun textMatches(element: PsiElement): Boolean = text == element.text
override fun textContains(c: Char): Boolean = text?.contains(c) ?: false
override fun copy(): PsiElement = KtLightModifierList(delegate, owner)
override fun getReferences() = PsiReference.EMPTY_ARRAY
override fun isEquivalentTo(another: PsiElement?) =
another is KtLightModifierList && delegate == another.delegate && owner == another.owner
}
internal fun computeAnnotations(lightElement: PsiModifierList,
delegate: PsiAnnotationOwner): CachedValue<Array<out PsiAnnotation>> {
fun doCompute(): Array<PsiAnnotation> {

View File

@@ -53,7 +53,7 @@ public class KtLightParameter extends LightParameter implements KtLightDeclarati
this.index = index;
this.method = method;
if (method.getLightMethodOrigin() instanceof LightMemberOriginForDeclaration) {
if (method.getLightMemberOrigin() instanceof LightMemberOriginForDeclaration) {
this.modifierList = new KtLightModifierListWithExplicitModifiers(this, ArrayUtil.EMPTY_STRING_ARRAY) {
@Override
public PsiAnnotationOwner getDelegate() {

View File

@@ -58,7 +58,7 @@ fun HierarchicalScope.collectDescriptorsFiltered(
}
@Deprecated("Use getOwnProperties instead") fun LexicalScope.findLocalVariable(name: Name): VariableDescriptor? {
@Deprecated("Use getContributedProperties instead") fun LexicalScope.findLocalVariable(name: Name): VariableDescriptor? {
return findFirstFromMeAndParent {
when {
it is LexicalScopeWrapper -> it.delegate.findLocalVariable(name)

View File

@@ -65,7 +65,8 @@ class DescriptorSerializer private constructor(
val flags = Flags.getClassFlags(
hasAnnotations(classDescriptor), classDescriptor.visibility, classDescriptor.modality, classDescriptor.kind,
classDescriptor.isInner, classDescriptor.isCompanionObject, classDescriptor.isData, classDescriptor.isExternal
classDescriptor.isInner, classDescriptor.isCompanionObject, classDescriptor.isData, classDescriptor.isExternal,
classDescriptor.isHeader
)
if (flags != builder.flags) {
builder.flags = flags
@@ -150,8 +151,6 @@ class DescriptorSerializer private constructor(
var hasGetter = false
var hasSetter = false
val lateInit = descriptor.isLateInit
val isConst = descriptor.isConst
val compileTimeConstant = descriptor.compileTimeInitializer
val hasConstant = compileTimeConstant != null && compileTimeConstant !is NullValue
@@ -187,8 +186,8 @@ class DescriptorSerializer private constructor(
val flags = Flags.getPropertyFlags(
hasAnnotations, descriptor.visibility, descriptor.modality, descriptor.kind, descriptor.isVar,
hasGetter, hasSetter, hasConstant, isConst, lateInit, descriptor.isExternal,
@Suppress("DEPRECATION") descriptor.isDelegated
hasGetter, hasSetter, hasConstant, descriptor.isConst, descriptor.isLateInit, descriptor.isExternal,
@Suppress("DEPRECATION") descriptor.isDelegated, descriptor.isHeader
)
if (flags != builder.flags) {
builder.flags = flags
@@ -233,7 +232,8 @@ class DescriptorSerializer private constructor(
val flags = Flags.getFunctionFlags(
hasAnnotations(descriptor), descriptor.visibility, descriptor.modality, descriptor.kind, descriptor.isOperator,
descriptor.isInfix, descriptor.isInline, descriptor.isTailrec, descriptor.isExternal, descriptor.isSuspend
descriptor.isInfix, descriptor.isInline, descriptor.isTailrec, descriptor.isExternal, descriptor.isSuspend,
descriptor.isHeader
)
if (flags != builder.flags) {
builder.flags = flags

View File

@@ -0,0 +1,70 @@
public final class Wrapper {
public Wrapper() { /* compiled code */ }
public static final class Equals {
@org.jetbrains.annotations.NotNull
private final p.G code;
public boolean equals(@org.jetbrains.annotations.Nullable java.lang.Object other) { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public final p.G getCode() { /* compiled code */ }
public Equals(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public final p.G component1() { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public final p.Wrapper.Equals copy(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public int hashCode() { /* compiled code */ }
}
public static final class HashCode {
@org.jetbrains.annotations.NotNull
private final p.G code;
public int hashCode() { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public final p.G getCode() { /* compiled code */ }
public HashCode(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public final p.G component1() { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public final p.Wrapper.HashCode copy(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public boolean equals(java.lang.Object p) { /* compiled code */ }
}
public static final class ToString {
@org.jetbrains.annotations.NotNull
private final p.G code;
@org.jetbrains.annotations.NotNull
public java.lang.String toString() { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public final p.G getCode() { /* compiled code */ }
public ToString(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public final p.G component1() { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public final p.Wrapper.ToString copy(@org.jetbrains.annotations.NotNull p.G code) { /* compiled code */ }
public int hashCode() { /* compiled code */ }
public boolean equals(java.lang.Object p) { /* compiled code */ }
}
}

View File

@@ -0,0 +1,20 @@
// p.Wrapper
package p
class Wrapper {
data class Equals(val code: G) {
override fun equals(other: Any?): Boolean = true
}
data class HashCode(val code: G) {
override fun hashCode() = 3
}
data class ToString(val code: G) {
override fun toString() = "b"
}
}
class G
// LAZINESS:NoLaziness

View File

@@ -0,0 +1,13 @@
public final class B {
public B() { /* compiled code */ }
public static final class A implements p.I {
private final p.I f;
public A(@org.jetbrains.annotations.NotNull p.I f) { /* compiled code */ }
public void f() { /* compiled code */ }
public void g() { /* compiled code */ }
}
}

View File

@@ -0,0 +1,15 @@
// p.B
package p
class B {
class A(private val f: I) : I by f {
}
}
interface I {
fun g()
fun f()
}
// LAZINESS:NoLaziness

View File

@@ -0,0 +1,9 @@
public final class B implements p.I {
private final p.I f;
public B(@org.jetbrains.annotations.NotNull p.I f) { /* compiled code */ }
public void f() { /* compiled code */ }
public void g() { /* compiled code */ }
}

View File

@@ -0,0 +1,13 @@
// p.B
package p
class B(private val f: I) : I by f {
}
interface I {
fun g()
fun f()
}
// LAZINESS:NoLaziness

View File

@@ -0,0 +1,9 @@
public final class A {
/**
* @deprecated
*/
@kotlin.Deprecated(message = "f")
public final void f() { /* compiled code */ }
public A() { /* compiled code */ }
}

View File

@@ -0,0 +1,9 @@
// a.A
package a
class A {
@Deprecated("f")
fun f() {
}
}

View File

@@ -0,0 +1,12 @@
public interface B extends p.A {
@org.jetbrains.annotations.NotNull
java.lang.String b();
static final class DefaultImpls {
@org.jetbrains.annotations.NotNull
public static java.lang.String b(p.B $this) { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public static java.lang.String a(p.B $this) { /* compiled code */ }
}
}

View File

@@ -0,0 +1,10 @@
// p.B
package p
interface A {
fun a() = "a"
}
interface B: A {
fun b() = "b"
}

View File

@@ -0,0 +1,2 @@
public final class HiddenDeprecatedKt {
}

View File

@@ -0,0 +1,8 @@
// a.HiddenDeprecatedKt
package a
@Deprecated("f", level = DeprecationLevel.HIDDEN)
fun f() {
}
// LAZINESS:NoLaziness

View File

@@ -0,0 +1,3 @@
public final class A {
public A() { /* compiled code */ }
}

View File

@@ -0,0 +1,11 @@
// a.A
package a
class A {
@Deprecated("f", level = DeprecationLevel.HIDDEN)
fun f() {
}
}
// LAZINESS:NoLaziness

View File

@@ -0,0 +1,13 @@
public final class Inheritor implements p.I, p.I2 {
public final void f() { /* compiled code */ }
public void g() { /* compiled code */ }
public Inheritor() { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public java.lang.String foo() { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public java.lang.String bar() { /* compiled code */ }
}

View File

@@ -0,0 +1,7 @@
public final class Inheritor implements p.I, p.I2 {
public final void f() { /* compiled code */ }
public void g() { /* compiled code */ }
public Inheritor() { /* compiled code */ }
}

View File

@@ -0,0 +1,24 @@
// p.Inheritor
package p
class Inheritor: I, I2 {
fun f() {
}
override fun g() {
}
}
interface I : I1 {
fun g()
}
interface I1 {
fun foo() = "foo"
}
interface I2 {
fun bar() = "bar"
}

View File

@@ -0,0 +1,16 @@
public final class A {
private final int y;
public boolean equals(@org.jetbrains.annotations.Nullable java.lang.Object other) { /* compiled code */ }
public int hashCode() { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public java.lang.String toString() { /* compiled code */ }
public final int component1() { /* compiled code */ }
public final int getY() { /* compiled code */ }
public A(int y) { /* compiled code */ }
}

View File

@@ -0,0 +1,18 @@
// p.A
package p
class A(val y: Int) {
override fun equals(other: Any?): Boolean {
return super.equals(other)
}
override fun hashCode(): Int {
return super.hashCode()
}
override fun toString(): String {
return super.toString()
}
fun component1() = y
}

View File

@@ -0,0 +1,7 @@
public final class C {
public final void f(@org.jetbrains.annotations.NotNull int... i) { /* compiled code */ }
public final void p(int i, @org.jetbrains.annotations.NotNull java.lang.String... s) { /* compiled code */ }
public C() { /* compiled code */ }
}

View File

@@ -0,0 +1,12 @@
// C
class C {
fun f(vararg i: Int) {
}
fun p(i: Int, vararg s: String) {
}
}

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