Compare commits

...

76 Commits

Author SHA1 Message Date
Alexey Sedunov
bdc02571c7 JS: Fix detection of run configuration with preconfigured Mocha
#KT-25253 Fixed

(cherry picked from commit 2efd467c42)
2018-07-04 18:22:03 +03:00
Alexey Sedunov
acbd5e7fae Misc: Fix SOE due to wrong overloaded method call
#KT-25247 Fixed

(cherry picked from commit 5f69eebe66)
2018-07-03 22:14:02 +03:00
Yan Zhulanow
8efd490c5c as33: Remove AndroidGradleOrderEnumerationHandler (should be moved to the Android plugin) 2018-07-03 16:15:48 +03:00
Alexey Sedunov
ea32314468 Search Everywhere: Recover original behavior for non-functions
#KT-25189 Fixed

(cherry picked from commit 03ed4e39e3)
2018-07-02 22:50:42 +03:00
Alexey Sedunov
c2251e8ca9 Test Support: KT-22306
Do not show run markers in JS modules when no relevant run configurations are available

 #KT-22306 Fixed

(cherry picked from commit b52b07ec79)
2018-07-02 22:50:13 +03:00
Alexey Sedunov
bb97b70373 Rename: Fix processing of references to synthetic Java properties
Fixes for non-master-bunch plugin.xml

(cherry picked from commit 3e91346240)
2018-07-02 22:49:53 +03:00
Vyacheslav Gerasimov
2c3e02bc8c UAST: Fix possible TypeCastException when creating KotlinUNamedExpression
(cherry picked from commit a829251690)
2018-07-02 21:44:52 +03:00
Vyacheslav Gerasimov
ffd673bbda Check if module disposed when getting modules with kotlin files
(cherry picked from commit 23ee463053)
2018-07-02 21:44:44 +03:00
Vyacheslav Gerasimov
34b04d8ec4 Reformat ConfigureKotlinInProjectUtils
(cherry picked from commit 16b4d25c1d)
2018-07-02 21:44:37 +03:00
Vyacheslav Gerasimov
e1b7142454 UAST: Do not log PCE in DeclarationDescriptor.toSource
(cherry picked from commit 62c0d37d45)
2018-07-02 21:44:29 +03:00
Yan Zhulanow
70230564fb Add support for Android Studio 3.3 Canary 1 2018-07-02 21:16:09 +03:00
Yan Zhulanow
371ee9f1f7 Minor: Make plugin.xml and build files more consistent with the main bunch 2018-07-02 21:16:08 +03:00
Yan Zhulanow
20d5c78e5d Make source set empty for Android modules of deleting the resulting JAR files in 'ideaPlugin' task 2018-07-02 21:07:58 +03:00
Raluca Sauciuc
1a25aefc94 as33: Android dependency reversal
(cherry picked from commit be781f4f462f74ca0efcc91b5c07a5b3756ba5b2)
2018-07-02 21:07:58 +03:00
Alexander Udalov
b021fea545 Improve reflection error message when function/property is not found 2018-07-02 19:05:05 +02:00
Alexander Udalov
b20b34224d Load all resources in RuntimePackagePartProvider; optimize code
The issue was reproducible when the same package is present in different
modules with the same -module-name (which is a popular case of src/test
roots in simple IDEA projects). The problem was in the fact that several
resource files containing package name mapping with the same name were
present in the classpath, but RuntimePackagePartProvider only considered
the first one. The fix is to use getResources instead of
getResourceAsStream and handle each returned resource.

Also, optimize internal representation to store the mapping in the form
which is the most convenient for findPackageParts, which should be
faster than registerModule because in theory, it's called more often.

 #KT-21973 Fixed
 #KT-24651
2018-07-02 19:05:05 +02:00
Alexander Udalov
42caa688de Remove obsolete BuiltInFunction and mapIntrinsicFunctionSignature
This is now fully covered by the JVM signature mapping, introduced in
the previous commit. The change in KDeclarationContainerImpl.methodOwner
is needed because primitive classes have no methods on JVM; and when
we're looking for "Int.equals", we'll now look it up in the Class object
for java.lang.Integer, not for the primitive int.
2018-07-02 19:05:05 +02:00
Alexander Udalov
a8f31de2f5 Use manual type mapping in reflection for members from built-ins
There are cases when members deserialized from JVM classes have no JVM
signature in the proto. For example, if a member is inherited from a
built-in class (such as Map.getOrDefault in some Map implementations),
or if a member is synthesized in the compiler front-end and back-end
separately (such as enum values/valueOf). In these cases, we'll use the
naive type mapping to try to recover the signature.

 #KT-16616 Fixed
 #KT-17542 Fixed
2018-07-02 19:05:05 +02:00
Alexander Udalov
f6488f7c4a Reformat module reflection.jvm, fix inspections/warnings 2018-07-02 19:04:07 +02:00
Alexander Udalov
34677658b3 Catch SecurityException when reading system property in BitEncoding
This does not fix KT-15167 though because the exception from KT-20575 is
thrown shortly afterwards

 #KT-15167
2018-07-02 19:04:06 +02:00
Alexander Udalov
fca612bcf8 Improve diagnostic for missing BuiltInsLoader implementation
Also initialize it lazily to avoid wrapping the exception into
ExceptionInInitializerError

 #KT-20575
2018-07-02 19:04:06 +02:00
Alexander Udalov
d2908c3894 Do not serialize constructors for anonymous objects
The only client of this data is reflection, and since anonymous objects
do not have constructors in the source code, they shouldn't in
reflection as well

 #KT-20442 Fixed
2018-07-02 19:04:06 +02:00
Alexander Udalov
00c292fe77 Do not create primary constructor for enum entry synthetic class
The change in DescriptorSerializer is needed so that serialized protos
of enum entry classes which are resolved in sources
(LazyClassDescriptor) and are deserialized from binaries
(EnumEntrySyntheticClassDescriptor) are the same. There are tests on
incremental compilation in JS that check that the serialized proto is
exactly the same after rebuild and after an incremental build.

 #KT-22048 Fixed
2018-07-02 19:04:06 +02:00
Alexey Sedunov
899de0eb0f Misc: Configure stdlib in failing tests
(cherry picked from commit 22d7427)
2018-07-02 19:11:47 +03:00
Alexey Sedunov
d4c2b33c39 Misc: Fix test assertion
(cherry picked from commit 65dad5e)
2018-07-02 19:11:47 +03:00
Vyacheslav Gerasimov
60c4308186 Allow plugin installation on Android Studio 3.2 Beta 2 2018-06-29 22:13:10 +03:00
Alexey Sedunov
e3e7eaec7b Misc: Restore utility functions misplaced in a previous commit
(cherry picked from commit a63aa5b)
2018-06-29 20:29:24 +03:00
Alexey Sedunov
feeedf7c02 Configuration: Use soft references to keep library kind cache
#KT-24943 Fixed

(cherry picked from commit 76ac65f)
2018-06-29 20:29:00 +03:00
Alexey Sedunov
c08aefbf80 PSI: Do not delete package directive for file in default package
#KT-24968 Fixed

(cherry picked from commit 60583e5)
2018-06-29 20:28:43 +03:00
Alexey Sedunov
4d141fbd6c Misc: Add "refactoring exit" message
This allows executing mandatory code at the end of particular refactoring.
Also this fixes memory leak due to listener not being disposed

 #KT-17235 Fixed

(cherry picked from commit e2a632e)
2018-06-29 20:28:27 +03:00
Alexey Sedunov
2dac33d3d1 Introduce Parameter: Fix exceptions caused by write actions in dialogs
#KT-24992 Fixed

(cherry picked from commit ba2f287)
2018-06-29 20:28:06 +03:00
Alexey Sedunov
02869ab0c7 Extract Function: Make compliant with PublicApiImplicitTypeInspection
(cherry picked from commit ed597e2)
2018-06-29 20:27:45 +03:00
Alexey Sedunov
a007784439 Misc: Use KtToken to represent visibility in ExtractableCodeDescriptor
(cherry picked from commit 633c67e)
2018-06-29 20:26:42 +03:00
Alexey Sedunov
c3b3ad53b2 Search Everywhere: Update renderer to reflect changes in IDEA
#KT-24812 Fixed

(cherry picked from commit 8374501)
2018-06-29 20:24:53 +03:00
Alexey Sedunov
e1e0a61572 Search Everywhere: Use Kotlin renderer for Kotlin elements only
(cherry picked from commit 31d248c)
2018-06-29 20:24:35 +03:00
Alexey Sedunov
79681ce425 Extract Interface: Fix type import when converting parameter to property
#KT-18736 Fixed

(cherry picked from commit bede2e1)
2018-06-29 20:24:09 +03:00
Alexey Sedunov
8fa29e4857 Extract Superclass: Report private members used in abstracted members
#KT-16284 Fixed

(cherry picked from commit 9b7450c)
2018-06-29 20:23:38 +03:00
Alexey Sedunov
0e04e74d7f Extract Superclass: Fix visibility lifting when moving to interface
#KT-16281 Fixed

(cherry picked from commit bd88e02)
2018-06-29 20:23:22 +03:00
Alexey Sedunov
e1286f221f Extract Superclass: Allow extraction to existing file
#KT-15351 Fixed

(cherry picked from commit b0e0460)
2018-06-29 20:23:06 +03:00
Alexey Sedunov
7380d1e3a1 Extract Superclass: Run refactoring inside of transaction
#KT-18555 Fixed

(cherry picked from commit 5ef54a2)
2018-06-29 20:22:46 +03:00
Nicolay Mitropolsky
a620a94d7b 182: IDEA sdk set to 182.3458.5
(cherry picked from commit 80f022c3d5)
2018-06-29 16:45:43 +03:00
Mikhail Glukhikh
c4e6cb3232 Add actual: handle (incorrect) case with expect function with body
So #KT-23326 Fixed

(cherry picked from commit fdc0335b4a)
2018-06-29 15:21:07 +03:00
Mikhail Glukhikh
ef32ee409a Add actual: handle parameters with val/var as compatible with property
So #KT-23762 Fixed

(cherry picked from commit 0fb183e302)
2018-06-29 15:20:52 +03:00
Mikhail Glukhikh
68c6c79be9 Add actual: handle primary & secondary constructors as compatible
So #KT-23686 Fixed

(cherry picked from commit dd0b267531)
2018-06-29 15:20:13 +03:00
Mikhail Glukhikh
ba0f3277c5 Reformat: AddActualFix
(cherry picked from commit 082c3e6767)
2018-06-29 15:19:59 +03:00
Mikhail Glukhikh
d254acc980 Create actual: do not generate default parameter values
So #KT-23105 Fixed

(cherry picked from commit 16c6d63b10)
2018-06-29 15:19:46 +03:00
Mikhail Glukhikh
1f4d43da55 Safe delete: add dialog asking about expect / actual declarations
Related to KT-15666

(cherry picked from commit b13e4535f5)
2018-06-29 15:19:26 +03:00
Mikhail Glukhikh
e5dc807427 Safe delete: when invoking on actual, delete expect & actual neighbors
So #KT-15666 Fixed

(cherry picked from commit aac71bf904)
2018-06-29 15:19:11 +03:00
Mikhail Glukhikh
536e0583a4 Safe delete: when invoking on expect, delete also relevant actual
Partial fix of KT-15666

(cherry picked from commit 50e70e4638)
2018-06-29 15:18:57 +03:00
Mikhail Glukhikh
4830afe183 Safe delete: search for actual declarations more accurately
(cherry picked from commit 465d5c077e)
2018-06-29 15:18:43 +03:00
Mikhail Glukhikh
26e6c8ed16 Cleanup: KotlinSafeDeleteProcessor
(cherry picked from commit 5bdaef4983)
2018-06-29 15:18:28 +03:00
Nicolay Mitropolsky
b5350da727 Uast: fix for creating an UClass for invalid object-literals (EA-122644, KT-20056)
(cherry picked from commit 698096f13e)
2018-06-28 10:42:22 +03:00
Lucas Smaira
c576bc8fba Find Kotlin class with alternative resolve enabled
Kotlin run configurations are failing non-deterministically in Android
Studio due to not finding the class while in dumb mode (while AS invokes
Gradle build or in indexing after that).

Fix that by finding class in KotlinRunConfiguration with alternative
resolve enabled.

(cherry picked from commit 5820656aae)
2018-06-27 16:50:21 +03:00
Nikolay Krasko
87eb155795 as32: Minor: use full sentences for reasons
(cherry picked from commit 8ea19eda73)
2018-06-27 16:32:08 +03:00
Nikolay Krasko
80a94a7efb as32: Use full sentences for reasons
(cherry picked from commit 17d4961760)
2018-06-27 16:31:59 +03:00
Nikolay Krasko
1457cfd8a8 Move isEap and isDev utility functions to idea module
(cherry picked from commit 099f3f3ddf)
2018-06-27 16:31:49 +03:00
Nikolay Krasko
d874ed4869 Make disabled verification visible in UI
(cherry picked from commit 54bb09a5fb)
2018-06-27 16:31:39 +03:00
Sergey Igushkin
214463e6f7 Fix Android ap option providers as Kapt task nested inputs
1) Exclude the providers arguments from the kapt inputs, as the values
may contain absolute paths, may be output properties etc. The providers
should correctly annotate their inputs.

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

Issue #KT-23866 Fixed
Issue #KT-25027 Fixed

(cherry picked from commit dbd72ae53b)
2018-06-27 14:04:04 +03:00
Nicolay Mitropolsky
f8e171c9f5 Uast: proper identifiers for KotlinUBinaryExpression (KT-25092)
(cherry picked from commit bef3d4ace2)
2018-06-27 11:31:18 +03:00
Nikolay Krasko
08a544b1a2 Fobid installation for Android Studio 3.3 2018-06-26 17:51:34 +03:00
Mikhail Glukhikh
cff73d5309 Unused symbol: don't suggest actual declaration used in another platform
Related to KT-17512
Related to KT-15666

(cherry picked from commit eb92b7ed7f)
2018-06-26 15:59:13 +03:00
Mikhail Glukhikh
2c37746a28 Do not mark kotlin.test.Test annotated declarations as unused
So #KT-20523 Fixed

(cherry picked from commit 30327aa9cc)
2018-06-26 15:58:55 +03:00
Mikhail Glukhikh
e5de325629 Unused symbol: remove forced "used" from actual declarations
Now we really check whether actual declaration has usages
(in expect or actual code) or not
Related to KT-17512
Related to KT-15666

(cherry picked from commit 7e0e7dc983)
2018-06-26 15:58:40 +03:00
Mikhail Glukhikh
a2e33996a6 Implement search from expect element in KotlinReferenceSearcher
So mostly #KT-17512 Fixed

(cherry picked from commit e885e54233)
2018-06-26 15:58:25 +03:00
Mikhail Glukhikh
0ce12e4b17 Find property usages dialog: rename all check-boxes as in other dialogs
(cherry picked from commit 97d158d833)
2018-06-26 15:58:11 +03:00
Mikhail Glukhikh
01ae6515b1 Add find usages option: search expected
(cherry picked from commit abbfea357a)
2018-06-26 15:57:58 +03:00
Mikhail Glukhikh
62206740f5 KotlinFindMemberUsagesHandler: get rid of deprecation
(cherry picked from commit 69e420991a)
2018-06-26 15:57:44 +03:00
Mikhail Glukhikh
a27e2b0d1e Cleanup: KotlinReferenceSearcher
(cherry picked from commit 0a36edcf20)
2018-06-26 15:57:30 +03:00
Mikhail Glukhikh
68c5f701d5 Cleanup: findUsagesOptions
(cherry picked from commit ea7db42af6)
2018-06-26 15:57:16 +03:00
Mikhail Glukhikh
569a0a63d8 Cleanup: KotlinFindMemberUsagesHandler
(cherry picked from commit a46e4f3142)
2018-06-26 15:57:03 +03:00
Mikhail Glukhikh
67ac21fca6 Test for KT-17512 (yet with incorrect results)
(cherry picked from commit cc2869988f)
2018-06-26 15:56:49 +03:00
Mikhail Zarechenskiy
5dcd4c86e1 Fix internal compiler error on importing invisible fake reference
Note that this is not relevant for LOCAL/INHERITED visibilities:
  - for LOCAL visibility it's impossible to have a qualifier
  - INHERITED is an intermediate visibility, we enhance it later
    (see resolveUnknownVisibilityForMember)

 #KT-20356 Fixed
2018-06-26 15:39:32 +03:00
Yan Zhulanow
019e2212b8 Android Extensions, minor: Fix a compilation problem 2018-06-25 17:47:55 +03:00
Raluca Sauciuc
b135fd279d Android Extensions: make synthetic import resolution more resilient
In commit ec0abb0 (Fix EA-79206: Process only valid layout.xml...) we
started to drop layouts with invalid PsiFiles during resolution of
(synthetic) package fragments.

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

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

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

(cherry picked from commit 528d66d5840cc8f584270c516e85da1a632df8b8)
2018-06-25 14:11:58 +03:00
Yan Zhulanow
c9751c2eeb Revert "Android Extensions: Allow to access library project resources in Gradle setup (#KT-22430)"
This reverts commit a70707b
2018-06-25 14:11:58 +03:00
318 changed files with 8491 additions and 1930 deletions

3
.bunch
View File

@@ -3,4 +3,5 @@
172_173
as31_173
as32
182
182
as33_as32

View File

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

View File

@@ -16,17 +16,42 @@
package org.jetbrains.kotlin.codegen;
import kotlin.collections.CollectionsKt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.util.Base64;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.Manifest;
public class GeneratedClassLoader extends URLClassLoader {
private static final URLStreamHandler FAKE_BASE64_URL_HANDLER = new URLStreamHandler() {
@Override
protected URLConnection openConnection(URL url) {
return new URLConnection(url) {
@Override
public void connect() {
}
@Override
public InputStream getInputStream() {
return new ByteArrayInputStream(Base64.getDecoder().decode(url.getPath()));
}
};
}
};
private ClassFileFactory factory;
public GeneratedClassLoader(@NotNull ClassFileFactory factory, ClassLoader parentClassLoader, URL... urls) {
@@ -43,6 +68,39 @@ public class GeneratedClassLoader extends URLClassLoader {
return super.getResourceAsStream(name);
}
@Override
public Enumeration<URL> findResources(String name) throws IOException {
Enumeration<URL> fromParent = super.findResources(name);
URL url = createFakeURLForResource(name);
if (url == null) return fromParent;
List<URL> fromMe = Collections.singletonList(url);
List<URL> result = fromParent.hasMoreElements()
? CollectionsKt.plus(fromMe, Collections.list(fromParent))
: fromMe;
return Collections.enumeration(result);
}
@Override
public URL findResource(String name) {
URL url = createFakeURLForResource(name);
return url != null ? url : super.findResource(name);
}
@Nullable
private URL createFakeURLForResource(@NotNull String name) {
try {
OutputFile outputFile = factory.get(name);
// Encode the byte array in the URL path to prevent creating unneeded temporary files
return outputFile == null
? null
: new URL(null, "bytes:" + Base64.getEncoder().encodeToString(outputFile.asByteArray()), FAKE_BASE64_URL_HANDLER);
} catch (IOException e) {
throw ExceptionUtilsKt.rethrow(e);
}
}
@NotNull
@Override
protected Class<?> findClass(@NotNull String name) throws ClassNotFoundException {

View File

@@ -119,7 +119,10 @@ public class KtPackageDirective extends KtModifierListOwnerStub<KotlinPlaceHolde
public void setFqName(@NotNull FqName fqName) {
if (fqName.isRoot()) {
delete();
if (!getFqName().isRoot()) {
//noinspection ConstantConditions
replace(new KtPsiFactory(getProject()).createFile("").getPackageDirective());
}
return;
}

View File

@@ -23,6 +23,8 @@ import com.intellij.psi.*
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.tree.TokenSet
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.lexer.KotlinLexer
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens
@@ -33,6 +35,7 @@ import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import java.lang.IllegalArgumentException
import java.util.*
// NOTE: in this file we collect only Kotlin-specific methods working with PSI and not modifying it
@@ -430,6 +433,8 @@ val KtModifierListOwner.isPublic: Boolean
fun KtModifierListOwner.visibilityModifierType(): KtModifierKeywordToken? =
visibilityModifier()?.node?.elementType as KtModifierKeywordToken?
fun KtModifierListOwner.visibilityModifierTypeOrDefault(): KtModifierKeywordToken = visibilityModifierType() ?: KtTokens.DEFAULT_VISIBILITY_KEYWORD
fun KtDeclaration.modalityModifier() = modifierFromTokenSet(MODALITY_MODIFIERS)
fun KtStringTemplateExpression.isPlain() = entries.all { it is KtLiteralStringTemplateEntry }
@@ -591,4 +596,14 @@ fun isTopLevelInFileOrScript(element: PsiElement): Boolean {
is KtBlockExpression -> parent.parent is KtScript
else -> false
}
}
fun KtModifierKeywordToken.toVisibility(): Visibility {
return when (this) {
KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC
KtTokens.PRIVATE_KEYWORD -> Visibilities.PRIVATE
KtTokens.PROTECTED_KEYWORD -> Visibilities.PROTECTED
KtTokens.INTERNAL_KEYWORD -> Visibilities.INTERNAL
else -> throw IllegalArgumentException("Unknown visibility modifier:$this")
}
}

View File

@@ -89,8 +89,10 @@ class DescriptorSerializer private constructor(
}
}
for (descriptor in classDescriptor.constructors) {
builder.addConstructor(constructorProto(descriptor))
if (!DescriptorUtils.isAnonymousObject(classDescriptor) && classDescriptor.kind != ClassKind.ENUM_ENTRY) {
for (descriptor in classDescriptor.constructors) {
builder.addConstructor(constructorProto(descriptor))
}
}
val callableMembers =

View File

@@ -1,12 +1,11 @@
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// IGNORE_BACKEND: JVM_IR, JS_IR, JS, NATIVE
// WITH_REFLECT
// FULL_JDK
// See KT-11258 Incorrect resolution sequence for Java field
//SHOULD BE deleted after KT-16616 fix
// See KT-11258, KT-16616
import java.util.*
import kotlin.test.assertEquals
fun box(): String {
listOf(
@@ -22,5 +21,8 @@ fun box(): String {
).map {
it.members.map(Any::toString)
}
assertEquals(1, Collection<Any>::size.getter(listOf(1)))
return "OK"
}

View File

@@ -0,0 +1,13 @@
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
import kotlin.test.assertEquals
enum class E { X, Y, Z }
fun box(): String {
assertEquals(11, E::class.members.size)
assertEquals("Y", E::name.call(E.Y))
assertEquals(2, E::ordinal.call(E.Z))
return "OK"
}

View File

@@ -0,0 +1,10 @@
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
import kotlin.test.assertEquals
fun box(): String {
String::class.members
assertEquals(2, String::length.call("OK"))
return "OK"
}

View File

@@ -17,6 +17,7 @@ fun box(): String {
assertTrue(Interface::class.constructors.isEmpty())
assertTrue(Obj::class.constructors.isEmpty())
assertTrue(C.Companion::class.constructors.isEmpty())
assertTrue(object {}::class.constructors.isEmpty())
return "OK"
}

View File

@@ -0,0 +1,24 @@
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
import kotlin.test.assertEquals
enum class TestEnum(val id: String? = null) {
ENUM1(id = "enum1_id"),
ENUM2(id = "enum2_id") {
override fun test() {
ENUM1.test()
}
};
open fun test() {
}
}
fun box(): String {
assertEquals(listOf("fun <init>(kotlin.String?): TestEnum"), TestEnum.ENUM1::class.constructors.map { it.toString() })
assertEquals(listOf(), TestEnum.ENUM2::class.constructors.map { it.toString() })
return "OK"
}

View File

@@ -48,11 +48,13 @@ fun box(): String {
val p4 = TwoSecondaries::class.primaryConstructor
assertNull(p4)
assertNotNull(En::class.primaryConstructor) // TODO: maybe primaryConstructor should be null for enum classes
assertNotNull(En::class.primaryConstructor)
assertNull(I::class.primaryConstructor)
assertNull(O::class.primaryConstructor)
assertNull(C.Companion::class.primaryConstructor)
assertNull(object {}::class.primaryConstructor)
return "OK"
}

View File

@@ -0,0 +1,15 @@
// IGNORE_BACKEND: JS_IR, JS, NATIVE
// WITH_REFLECT
import kotlin.test.assertEquals
enum class E { X, Y, Z }
fun box(): String {
assertEquals("fun values(): kotlin.Array<E>", E::values.toString())
assertEquals(listOf(E.X, E.Y, E.Z), E::values.call().toList())
assertEquals("fun valueOf(kotlin.String): E", E::valueOf.toString())
assertEquals(E.Y, E::valueOf.call("Y"))
return "OK"
}

View File

@@ -0,0 +1,25 @@
// IGNORE_BACKEND: JVM_IR, JS_IR, JS, NATIVE
// FULL_JDK
// WITH_REFLECT
import kotlin.test.assertEquals
import java.util.*
fun assertToString(s: String, x: Any) {
assertEquals(s, x.toString())
}
fun box(): String {
assertToString("fun kotlin.collections.Map<K, V>.getOrDefault(K, V): V", Map<*, *>::getOrDefault)
assertToString("fun java.util.HashMap<K, V>.getOrDefault(K, V): V", HashMap<*, *>::getOrDefault)
// TODO: uncomment once KT-11754 is fixed
// assertToString("", MutableList<*>::removeAt)
assertToString("fun kotlin.collections.Collection<E>.contains(E): kotlin.Boolean", Collection<*>::contains)
assertToString("fun kotlin.collections.Set<E>.contains(E): kotlin.Boolean", Set<*>::contains)
assertToString("fun kotlin.collections.Collection<E>.isEmpty(): kotlin.Boolean", Collection<*>::isEmpty)
return "OK"
}

View File

@@ -1,29 +0,0 @@
// IGNORE_BACKEND: JS_IR
// TODO: muted automatically, investigate should it be ran for JS or not
// IGNORE_BACKEND: JS, NATIVE
// WITH_REFLECT
// FULL_JDK
// See KT-11258 Incorrect resolution sequence for Java field
// TODO: enable this test on JVM, see KT-16616
// IGNORE_BACKEND: JVM
import java.util.*
fun box(): String {
listOf(
ArrayList::class,
LinkedList::class,
AbstractList::class,
HashSet::class,
TreeSet::class,
HashMap::class,
TreeMap::class,
AbstractMap::class,
AbstractMap.SimpleEntry::class
).map {
it.members.map(Any::toString)
}
return "OK"
}

View File

@@ -0,0 +1,20 @@
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// FILE: A.kt
fun test() {
}
// FILE: B.kt
import kotlin.reflect.jvm.javaMethod
import kotlin.reflect.jvm.kotlinFunction
fun box(): String {
val r = Class.forName("AKt").methods.single { it.name == "test" }.kotlinFunction
if (r?.toString() != "fun test(): kotlin.Unit")
return "Fail: $r"
return "OK"
}

View File

@@ -0,0 +1,16 @@
// FILE: A.kt
import B.<!INVISIBLE_REFERENCE!>foo<!>
fun test() {
<!INVISIBLE_MEMBER!>foo<!>
}
// FILE: B.kt
object B : C<String>()
// FILE: C.kt
open class C<T> {
private var foo: String = "abc"
}

View File

@@ -0,0 +1,19 @@
package
public fun test(): kotlin.Unit
public object B : C<kotlin.String> {
private constructor B()
invisible_fake final override /*1*/ /*fake_override*/ var foo: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public open class C</*0*/ T> {
public constructor C</*0*/ T>()
private final var foo: kotlin.String
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}

View File

@@ -1,4 +1,3 @@
local final class `AnonymousObjectKt$main$1` : java.lang.Runnable
public constructor `AnonymousObjectKt$main$1`()
public open override /*1*/ fun run(): kotlin.Unit

View File

@@ -49,6 +49,16 @@ public class ForTestCompileRuntime {
return assertExists(new File("dist/kotlinc/lib/kotlin-test.jar"));
}
@NotNull
public static File kotlinTestJUnitJarForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-test-junit.jar"));
}
@NotNull
public static File kotlinTestJsJarForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-test-js.jar"));
}
@NotNull
public static File reflectJarForTests() {
return assertExists(new File("dist/kotlinc/lib/kotlin-reflect.jar"));

View File

@@ -16701,6 +16701,34 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/builtins")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Builtins extends AbstractIrBlackBoxCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
}
public void testAllFilesPresentInBuiltins() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/builtins"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
}
@TestMetadata("collections.kt")
public void testCollections() throws Exception {
runTest("compiler/testData/codegen/box/reflection/builtins/collections.kt");
}
@TestMetadata("enumNameOrdinal.kt")
public void testEnumNameOrdinal() throws Exception {
runTest("compiler/testData/codegen/box/reflection/builtins/enumNameOrdinal.kt");
}
@TestMetadata("stringLength.kt")
public void testStringLength() throws Exception {
runTest("compiler/testData/codegen/box/reflection/builtins/stringLength.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/call")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -17183,6 +17211,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/reflection/constructors/constructorName.kt");
}
@TestMetadata("enumEntry.kt")
public void testEnumEntry() throws Exception {
runTest("compiler/testData/codegen/box/reflection/constructors/enumEntry.kt");
}
@TestMetadata("primaryConstructor.kt")
public void testPrimaryConstructor() throws Exception {
runTest("compiler/testData/codegen/box/reflection/constructors/primaryConstructor.kt");
@@ -17417,6 +17450,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/reflection/functions/declaredVsInheritedFunctions.kt");
}
@TestMetadata("enumValuesValueOf.kt")
public void testEnumValuesValueOf() throws Exception {
runTest("compiler/testData/codegen/box/reflection/functions/enumValuesValueOf.kt");
}
@TestMetadata("functionFromStdlib.kt")
public void testFunctionFromStdlib() throws Exception {
runTest("compiler/testData/codegen/box/reflection/functions/functionFromStdlib.kt");
@@ -17869,6 +17907,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/methodsFromAny"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("builtinFunctionsToString.kt")
public void testBuiltinFunctionsToString() throws Exception {
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/builtinFunctionsToString.kt");
}
@TestMetadata("callableReferencesEqualToCallablesFromAPI.kt")
public void testCallableReferencesEqualToCallablesFromAPI() throws Exception {
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/callableReferencesEqualToCallablesFromAPI.kt");
@@ -18512,24 +18555,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class SpecialBuiltIns extends AbstractIrBlackBoxCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInSpecialBuiltIns() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/specialBuiltIns"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("getMembersOfStandardJavaClasses.kt")
public void testGetMembersOfStandardJavaClasses() throws Exception {
runTest("compiler/testData/codegen/box/reflection/specialBuiltIns/getMembersOfStandardJavaClasses.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/supertypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -8765,6 +8765,11 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/imports/InaccessiblePrivateClass.kt");
}
@TestMetadata("invisibleFakeReferenceInImport.kt")
public void testInvisibleFakeReferenceInImport() throws Exception {
runTest("compiler/testData/diagnostics/tests/imports/invisibleFakeReferenceInImport.kt");
}
@TestMetadata("JavaPackageLocalClassNotImported.kt")
public void testJavaPackageLocalClassNotImported() throws Exception {
runTest("compiler/testData/diagnostics/tests/imports/JavaPackageLocalClassNotImported.kt");

View File

@@ -8765,6 +8765,11 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/imports/InaccessiblePrivateClass.kt");
}
@TestMetadata("invisibleFakeReferenceInImport.kt")
public void testInvisibleFakeReferenceInImport() throws Exception {
runTest("compiler/testData/diagnostics/tests/imports/invisibleFakeReferenceInImport.kt");
}
@TestMetadata("JavaPackageLocalClassNotImported.kt")
public void testJavaPackageLocalClassNotImported() throws Exception {
runTest("compiler/testData/diagnostics/tests/imports/JavaPackageLocalClassNotImported.kt");

View File

@@ -16701,6 +16701,34 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/builtins")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Builtins extends AbstractBlackBoxCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInBuiltins() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/builtins"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("collections.kt")
public void testCollections() throws Exception {
runTest("compiler/testData/codegen/box/reflection/builtins/collections.kt");
}
@TestMetadata("enumNameOrdinal.kt")
public void testEnumNameOrdinal() throws Exception {
runTest("compiler/testData/codegen/box/reflection/builtins/enumNameOrdinal.kt");
}
@TestMetadata("stringLength.kt")
public void testStringLength() throws Exception {
runTest("compiler/testData/codegen/box/reflection/builtins/stringLength.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/call")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -17183,6 +17211,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/reflection/constructors/constructorName.kt");
}
@TestMetadata("enumEntry.kt")
public void testEnumEntry() throws Exception {
runTest("compiler/testData/codegen/box/reflection/constructors/enumEntry.kt");
}
@TestMetadata("primaryConstructor.kt")
public void testPrimaryConstructor() throws Exception {
runTest("compiler/testData/codegen/box/reflection/constructors/primaryConstructor.kt");
@@ -17417,6 +17450,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/reflection/functions/declaredVsInheritedFunctions.kt");
}
@TestMetadata("enumValuesValueOf.kt")
public void testEnumValuesValueOf() throws Exception {
runTest("compiler/testData/codegen/box/reflection/functions/enumValuesValueOf.kt");
}
@TestMetadata("functionFromStdlib.kt")
public void testFunctionFromStdlib() throws Exception {
runTest("compiler/testData/codegen/box/reflection/functions/functionFromStdlib.kt");
@@ -17869,6 +17907,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/methodsFromAny"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("builtinFunctionsToString.kt")
public void testBuiltinFunctionsToString() throws Exception {
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/builtinFunctionsToString.kt");
}
@TestMetadata("callableReferencesEqualToCallablesFromAPI.kt")
public void testCallableReferencesEqualToCallablesFromAPI() throws Exception {
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/callableReferencesEqualToCallablesFromAPI.kt");
@@ -18512,24 +18555,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class SpecialBuiltIns extends AbstractBlackBoxCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInSpecialBuiltIns() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/specialBuiltIns"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("getMembersOfStandardJavaClasses.kt")
public void testGetMembersOfStandardJavaClasses() throws Exception {
runTest("compiler/testData/codegen/box/reflection/specialBuiltIns/getMembersOfStandardJavaClasses.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/supertypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -221,6 +221,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
runTest("compiler/testData/compileKotlinAgainstKotlin/recursiveGeneric.kt");
}
@TestMetadata("reflectTopLevelFunctionOtherFile.kt")
public void testReflectTopLevelFunctionOtherFile() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/reflectTopLevelFunctionOtherFile.kt");
}
@TestMetadata("sealedClass.kt")
public void testSealedClass() throws Exception {
runTest("compiler/testData/compileKotlinAgainstKotlin/sealedClass.kt");

View File

@@ -16701,6 +16701,34 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/builtins")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Builtins extends AbstractLightAnalysisModeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInBuiltins() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/builtins"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("collections.kt")
public void testCollections() throws Exception {
runTest("compiler/testData/codegen/box/reflection/builtins/collections.kt");
}
@TestMetadata("enumNameOrdinal.kt")
public void testEnumNameOrdinal() throws Exception {
runTest("compiler/testData/codegen/box/reflection/builtins/enumNameOrdinal.kt");
}
@TestMetadata("stringLength.kt")
public void testStringLength() throws Exception {
runTest("compiler/testData/codegen/box/reflection/builtins/stringLength.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/call")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -17183,6 +17211,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/reflection/constructors/constructorName.kt");
}
@TestMetadata("enumEntry.kt")
public void testEnumEntry() throws Exception {
runTest("compiler/testData/codegen/box/reflection/constructors/enumEntry.kt");
}
@TestMetadata("primaryConstructor.kt")
public void testPrimaryConstructor() throws Exception {
runTest("compiler/testData/codegen/box/reflection/constructors/primaryConstructor.kt");
@@ -17417,6 +17450,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/reflection/functions/declaredVsInheritedFunctions.kt");
}
@TestMetadata("enumValuesValueOf.kt")
public void testEnumValuesValueOf() throws Exception {
runTest("compiler/testData/codegen/box/reflection/functions/enumValuesValueOf.kt");
}
@TestMetadata("functionFromStdlib.kt")
public void testFunctionFromStdlib() throws Exception {
runTest("compiler/testData/codegen/box/reflection/functions/functionFromStdlib.kt");
@@ -17869,6 +17907,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/methodsFromAny"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
@TestMetadata("builtinFunctionsToString.kt")
public void testBuiltinFunctionsToString() throws Exception {
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/builtinFunctionsToString.kt");
}
@TestMetadata("callableReferencesEqualToCallablesFromAPI.kt")
public void testCallableReferencesEqualToCallablesFromAPI() throws Exception {
runTest("compiler/testData/codegen/box/reflection/methodsFromAny/callableReferencesEqualToCallablesFromAPI.kt");
@@ -18512,24 +18555,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/specialBuiltIns")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class SpecialBuiltIns extends AbstractLightAnalysisModeTest {
@TestMetadata("getMembersOfStandardJavaClasses.kt")
public void ignoreGetMembersOfStandardJavaClasses() throws Exception {
runTest("compiler/testData/codegen/box/reflection/specialBuiltIns/getMembersOfStandardJavaClasses.kt");
}
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInSpecialBuiltIns() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/reflection/specialBuiltIns"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
}
}
@TestMetadata("compiler/testData/codegen/box/reflection/supertypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)

View File

@@ -32,7 +32,7 @@ class JsMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
companion object {
@JvmField
val INSTANCE = JsMetadataVersion(1, 2, 2)
val INSTANCE = JsMetadataVersion(1, 2, 3)
@JvmField
val INVALID_VERSION = JsMetadataVersion()

View File

@@ -18,26 +18,27 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.types.KotlinType
fun FunctionDescriptor.computeJvmDescriptor(withReturnType: Boolean = true)
= StringBuilder().apply {
append(if (this@computeJvmDescriptor is ConstructorDescriptor) "<init>" else name.asString())
append("(")
fun FunctionDescriptor.computeJvmDescriptor(withReturnType: Boolean = true, withName: Boolean = true): String = buildString {
if (withName) {
append(if (this@computeJvmDescriptor is ConstructorDescriptor) "<init>" else name.asString())
}
valueParameters.forEach {
appendErasedType(it.type)
}
append("(")
append(")")
for (parameter in valueParameters) {
appendErasedType(parameter.type)
}
if (withReturnType) {
if (hasVoidReturnType(this@computeJvmDescriptor)) {
append("V")
}
else {
appendErasedType(returnType!!)
}
}
}.toString()
append(")")
if (withReturnType) {
if (hasVoidReturnType(this@computeJvmDescriptor)) {
append("V")
} else {
appendErasedType(returnType!!)
}
}
}
// Boxing is only necessary for 'remove(E): Boolean' of a MutableCollection<Int> implementation
// Otherwise this method might clash with 'remove(I): E' defined in the java.util.List JDK interface (mapped to kotlin 'removeAt')

View File

@@ -21,27 +21,44 @@ import org.jetbrains.kotlin.load.kotlin.loadModuleMapping
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
import java.util.concurrent.ConcurrentHashMap
import java.io.IOException
import java.util.*
class RuntimePackagePartProvider(private val classLoader: ClassLoader) : PackagePartProvider {
private val module2Mapping = ConcurrentHashMap<String, ModuleMapping>()
// Names of modules which were registered with registerModule
private val visitedModules = hashSetOf<String>()
// Package FQ name -> list of JVM internal names of package parts in that package across all registered modules
private val packageParts = hashMapOf<String, LinkedHashSet<String>>()
@Synchronized
fun registerModule(moduleName: String) {
val mapping = try {
val resourcePath = "META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}"
classLoader.getResourceAsStream(resourcePath)?.use { stream ->
ModuleMapping.loadModuleMapping(stream.readBytes(), resourcePath, DeserializationConfiguration.Default)
}
} catch (e: Exception) {
// TODO: do not swallow this exception?
null
if (!visitedModules.add(moduleName)) return
val resourcePath = "META-INF/$moduleName.${ModuleMapping.MAPPING_FILE_EXT}"
val resources = try {
classLoader.getResources(resourcePath)
} catch (e: IOException) {
EmptyEnumeration
}
for (resource in resources) {
try {
resource.openStream()?.use { stream ->
val mapping = ModuleMapping.loadModuleMapping(stream.readBytes(), resourcePath, DeserializationConfiguration.Default)
for ((packageFqName, parts) in mapping.packageFqName2Parts) {
packageParts.getOrPut(packageFqName) { linkedSetOf() }.addAll(parts.parts)
}
}
} catch (e: Exception) {
// TODO: do not swallow this exception?
}
}
module2Mapping.putIfAbsent(moduleName, mapping ?: ModuleMapping.EMPTY)
}
override fun findPackageParts(packageFqName: String): List<String> {
return module2Mapping.values.mapNotNull { it.findPackageParts(packageFqName) }.flatMap { it.parts }.distinct()
}
@Synchronized
override fun findPackageParts(packageFqName: String): List<String> =
packageParts[packageFqName]?.toList().orEmpty()
// TODO
override fun findMetadataPackageParts(packageFqName: String): List<String> = TODO()
@@ -50,4 +67,9 @@ class RuntimePackagePartProvider(private val classLoader: ClassLoader) : Package
// TODO: load annotations from resource files
return emptyList()
}
private object EmptyEnumeration : Enumeration<Nothing> {
override fun hasMoreElements(): Boolean = false
override fun nextElement(): Nothing = throw NoSuchElementException()
}
}

View File

@@ -34,7 +34,12 @@ interface BuiltInsLoader {
): PackageFragmentProvider
companion object {
val Instance: BuiltInsLoader =
ServiceLoader.load(BuiltInsLoader::class.java, BuiltInsLoader::class.java.classLoader).first()
val Instance: BuiltInsLoader by lazy(LazyThreadSafetyMode.PUBLICATION) {
val implementations = ServiceLoader.load(BuiltInsLoader::class.java, BuiltInsLoader::class.java.classLoader)
implementations.firstOrNull() ?: throw IllegalStateException(
"No BuiltInsLoader implementation was found. Please ensure that the META-INF/services/ is not stripped " +
"from your application and that the Java virtual machine is not running under a security manager"
)
}
}
}

View File

@@ -263,7 +263,7 @@ public class Visibilities {
public static final Visibility INVISIBLE_FAKE = new Visibility("invisible_fake", false) {
@Override
public boolean mustCheckInImports() {
throw new IllegalStateException("This method shouldn't be invoked for INVISIBLE_FAKE visibility");
return true;
}
@Override

View File

@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.incremental.components.LookupLocation;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.DescriptorFactory;
import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy;
import org.jetbrains.kotlin.resolve.OverridingUtil;
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
@@ -32,7 +31,6 @@ import java.util.*;
public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
private final TypeConstructor typeConstructor;
private final ClassConstructorDescriptor primaryConstructor;
private final MemberScope scope;
private final NotNullLazyValue<Set<Name>> enumMemberNames;
private final Annotations annotations;
@@ -74,10 +72,6 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
this.scope = new EnumEntryScope(storageManager);
this.enumMemberNames = enumMemberNames;
ClassConstructorDescriptorImpl primaryConstructor = DescriptorFactory.createPrimaryConstructorForObject(this, source);
primaryConstructor.setReturnType(getDefaultType());
this.primaryConstructor = primaryConstructor;
}
@NotNull
@@ -95,7 +89,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
@NotNull
@Override
public Collection<ClassConstructorDescriptor> getConstructors() {
return Collections.singleton(primaryConstructor);
return Collections.emptyList();
}
@NotNull
@@ -161,7 +155,7 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
@Nullable
@Override
public ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
return primaryConstructor;
return null;
}
@NotNull

View File

@@ -152,6 +152,19 @@ public class DescriptorFactory {
Modality.FINAL, Visibilities.PUBLIC);
}
public static boolean isEnumValuesMethod(@NotNull FunctionDescriptor descriptor) {
return descriptor.getName().equals(DescriptorUtils.ENUM_VALUES) && isEnumSpecialMethod(descriptor);
}
public static boolean isEnumValueOfMethod(@NotNull FunctionDescriptor descriptor) {
return descriptor.getName().equals(DescriptorUtils.ENUM_VALUE_OF) && isEnumSpecialMethod(descriptor);
}
private static boolean isEnumSpecialMethod(@NotNull FunctionDescriptor descriptor) {
return descriptor.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED &&
DescriptorUtils.isEnumClass(descriptor.getContainingDeclaration());
}
@Nullable
public static ReceiverParameterDescriptor createExtensionReceiverParameterForCallable(
@NotNull CallableDescriptor owner,

View File

@@ -13,7 +13,19 @@ import java.util.List;
import static org.jetbrains.kotlin.metadata.jvm.deserialization.UtfEncodingKt.MAX_UTF8_INFO_LENGTH;
public class BitEncoding {
private static final boolean FORCE_8TO7_ENCODING = "true".equals(System.getProperty("kotlin.jvm.serialization.use8to7"));
private static final boolean FORCE_8TO7_ENCODING;
static {
String use8to7;
try {
use8to7 = System.getProperty("kotlin.jvm.serialization.use8to7");
}
catch (SecurityException e) {
use8to7 = null;
}
FORCE_8TO7_ENCODING = "true".equals(use8to7);
}
private static final char _8TO7_MODE_MARKER = (char) -1;

View File

@@ -18,7 +18,7 @@ class JvmMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
companion object {
@JvmField
val INSTANCE = JvmMetadataVersion(1, 1, 10)
val INSTANCE = JvmMetadataVersion(1, 1, 11)
@JvmField
val INVALID_VERSION = JvmMetadataVersion()

View File

@@ -18,7 +18,7 @@ class BuiltInsBinaryVersion(vararg numbers: Int) : BinaryVersion(*numbers) {
companion object {
@JvmField
val INSTANCE = BuiltInsBinaryVersion(1, 0, 3)
val INSTANCE = BuiltInsBinaryVersion(1, 0, 4)
@JvmField
val INVALID_VERSION = BuiltInsBinaryVersion()

View File

@@ -15,6 +15,7 @@
*/
@file:JvmName("KCallablesJvm")
package kotlin.reflect.jvm
import java.lang.reflect.AccessibleObject
@@ -40,21 +41,21 @@ var KCallable<*>.isAccessible: Boolean
return when (this) {
is KMutableProperty ->
javaField?.isAccessible ?: true &&
javaGetter?.isAccessible ?: true &&
javaSetter?.isAccessible ?: true
javaGetter?.isAccessible ?: true &&
javaSetter?.isAccessible ?: true
is KProperty ->
javaField?.isAccessible ?: true &&
javaGetter?.isAccessible ?: true
javaGetter?.isAccessible ?: true
is KProperty.Getter ->
property.javaField?.isAccessible ?: true &&
javaMethod?.isAccessible ?: true
javaMethod?.isAccessible ?: true
is KMutableProperty.Setter<*> ->
property.javaField?.isAccessible ?: true &&
javaMethod?.isAccessible ?: true
javaMethod?.isAccessible ?: true
is KFunction ->
javaMethod?.isAccessible ?: true &&
(this.asKCallableImpl()?.defaultCaller?.member as? AccessibleObject)?.isAccessible ?: true &&
this.javaConstructor?.isAccessible ?: true
(this.asKCallableImpl()?.defaultCaller?.member as? AccessibleObject)?.isAccessible ?: true &&
this.javaConstructor?.isAccessible ?: true
else -> throw UnsupportedOperationException("Unknown callable: $this ($javaClass)")
}
}

View File

@@ -15,6 +15,7 @@
*/
@file:JvmName("KClassesJvm")
package kotlin.reflect.jvm
import kotlin.reflect.KClass
@@ -26,6 +27,4 @@ import kotlin.reflect.jvm.internal.KClassImpl
* @see [java.lang.Class.getName]
*/
val KClass<*>.jvmName: String
get() {
return (this as KClassImpl).jClass.name
}
get() = (this as KClassImpl).jClass.name

View File

@@ -15,14 +15,18 @@
*/
@file:JvmName("KTypesJvm")
package kotlin.reflect.jvm
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind.ANNOTATION_CLASS
import org.jetbrains.kotlin.descriptors.ClassKind.INTERFACE
import kotlin.reflect.*
import kotlin.reflect.jvm.internal.KotlinReflectionInternalError
import kotlin.reflect.KClass
import kotlin.reflect.KClassifier
import kotlin.reflect.KType
import kotlin.reflect.KTypeParameter
import kotlin.reflect.jvm.internal.KTypeImpl
import kotlin.reflect.jvm.internal.KotlinReflectionInternalError
/**
* Returns the [KClass] instance representing the runtime class to which this type is erased to on JVM.

View File

@@ -15,11 +15,11 @@
*/
@file:JvmName("ReflectJvmMapping")
package kotlin.reflect.jvm
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import java.lang.reflect.*
import java.util.*
import kotlin.reflect.*
import kotlin.reflect.full.companionObject
import kotlin.reflect.full.functions
@@ -65,7 +65,8 @@ val KFunction<*>.javaMethod: Method?
* Returns a Java [Constructor] instance corresponding to the given Kotlin function,
* or `null` if this function is not a constructor or cannot be represented by a Java [Constructor].
*/
@Suppress("UNCHECKED_CAST") val <T> KFunction<T>.javaConstructor: Constructor<T>?
@Suppress("UNCHECKED_CAST")
val <T> KFunction<T>.javaConstructor: Constructor<T>?
get() = this.asKCallableImpl()?.caller?.member as? Constructor<T>
@@ -78,7 +79,6 @@ val KType.javaType: Type
get() = (this as KTypeImpl).javaType
// Java reflection -> Kotlin reflection
/**
@@ -102,11 +102,11 @@ val Field.kotlinProperty: KProperty<*>?
private fun Member.getKPackage(): KDeclarationContainer? =
when (ReflectKotlinClass.create(declaringClass)?.classHeader?.kind) {
KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART ->
KPackageImpl(declaringClass)
else -> null
}
when (ReflectKotlinClass.create(declaringClass)?.classHeader?.kind) {
KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART ->
KPackageImpl(declaringClass)
else -> null
}
/**
* Returns a [KFunction] instance corresponding to the given Java [Method] instance,
@@ -129,7 +129,7 @@ val Method.kotlinFunction: KFunction<*>?
companion.functions.firstOrNull {
val m = it.javaMethod
m != null && m.name == this.name &&
Arrays.equals(m.parameterTypes, this.parameterTypes) && m.returnType == this.returnType
m.parameterTypes!!.contentEquals(this.parameterTypes) && m.returnType == this.returnType
}?.let { return it }
}
}

View File

@@ -23,13 +23,13 @@ import kotlin.reflect.jvm.internal.structure.wrapperByPrimitive
import java.lang.reflect.Method as ReflectMethod
internal class AnnotationConstructorCaller(
private val jClass: Class<*>,
private val parameterNames: List<String>,
private val callMode: CallMode,
origin: Origin,
private val methods: List<ReflectMethod> = parameterNames.map { name -> jClass.getDeclaredMethod(name) }
private val jClass: Class<*>,
private val parameterNames: List<String>,
private val callMode: CallMode,
origin: Origin,
private val methods: List<ReflectMethod> = parameterNames.map { name -> jClass.getDeclaredMethod(name) }
) : FunctionCaller<Nothing?>(
null, jClass, null, methods.map { it.genericReturnType }.toTypedArray()
null, jClass, null, methods.map { it.genericReturnType }.toTypedArray()
) {
enum class CallMode { CALL_BY_NAME, POSITIONAL_CALL }
@@ -44,9 +44,9 @@ internal class AnnotationConstructorCaller(
// TODO: consider lifting this restriction once KT-8957 is implemented
if (callMode == CallMode.POSITIONAL_CALL && origin == Origin.JAVA && (parameterNames - "value").isNotEmpty()) {
throw UnsupportedOperationException(
"Positional call of a Java annotation constructor is allowed only if there are no parameters " +
"or one parameter named \"value\". This restriction exists because Java annotations (in contrast to Kotlin)" +
"do not impose any order on their arguments. Use KCallable#callBy instead."
"Positional call of a Java annotation constructor is allowed only if there are no parameters " +
"or one parameter named \"value\". This restriction exists because Java annotations (in contrast to Kotlin)" +
"do not impose any order on their arguments. Use KCallable#callBy instead."
)
}
}
@@ -56,8 +56,8 @@ internal class AnnotationConstructorCaller(
val values = args.mapIndexed { index, arg ->
val value =
if (arg == null && callMode == CallMode.CALL_BY_NAME) defaultValues[index]
else arg.transformKotlinToJvm(erasedParameterTypes[index])
if (arg == null && callMode == CallMode.CALL_BY_NAME) defaultValues[index]
else arg.transformKotlinToJvm(erasedParameterTypes[index])
value ?: throwIllegalArgumentType(index, parameterNames[index], erasedParameterTypes[index])
}
@@ -103,23 +103,23 @@ private fun throwIllegalArgumentType(index: Int, name: String, expectedJvmType:
private fun createAnnotationInstance(annotationClass: Class<*>, methods: List<ReflectMethod>, values: Map<String, Any>): Any {
fun equals(other: Any?): Boolean =
(other as? Annotation)?.annotationClass?.java == annotationClass &&
methods.all { method ->
val ours = values[method.name]
val theirs = method(other)
when (ours) {
is BooleanArray -> Arrays.equals(ours, theirs as BooleanArray)
is CharArray -> Arrays.equals(ours, theirs as CharArray)
is ByteArray -> Arrays.equals(ours, theirs as ByteArray)
is ShortArray -> Arrays.equals(ours, theirs as ShortArray)
is IntArray -> Arrays.equals(ours, theirs as IntArray)
is FloatArray -> Arrays.equals(ours, theirs as FloatArray)
is LongArray -> Arrays.equals(ours, theirs as LongArray)
is DoubleArray -> Arrays.equals(ours, theirs as DoubleArray)
is Array<*> -> Arrays.equals(ours, theirs as Array<*>)
else -> ours == theirs
(other as? Annotation)?.annotationClass?.java == annotationClass &&
methods.all { method ->
val ours = values[method.name]
val theirs = method(other)
when (ours) {
is BooleanArray -> Arrays.equals(ours, theirs as BooleanArray)
is CharArray -> Arrays.equals(ours, theirs as CharArray)
is ByteArray -> Arrays.equals(ours, theirs as ByteArray)
is ShortArray -> Arrays.equals(ours, theirs as ShortArray)
is IntArray -> Arrays.equals(ours, theirs as IntArray)
is FloatArray -> Arrays.equals(ours, theirs as FloatArray)
is LongArray -> Arrays.equals(ours, theirs as LongArray)
is DoubleArray -> Arrays.equals(ours, theirs as DoubleArray)
is Array<*> -> Arrays.equals(ours, theirs as Array<*>)
else -> ours == theirs
}
}
}
val hashCode by lazy {
values.entries.sumBy { entry ->
@@ -163,7 +163,7 @@ private fun createAnnotationInstance(annotationClass: Class<*>, methods: List<Re
}
}
return Proxy.newProxyInstance(annotationClass.classLoader, arrayOf(annotationClass)) { proxy, method, args ->
return Proxy.newProxyInstance(annotationClass.classLoader, arrayOf(annotationClass)) { _, method, args ->
val name = method.name
when (name) {
"annotationType" -> annotationClass

View File

@@ -39,7 +39,6 @@ internal object EmptyContainerForLocal : KDeclarationContainerImpl() {
override fun getLocalProperty(index: Int): PropertyDescriptor? = null
private fun fail(): Nothing = throw KotlinReflectionInternalError(
"Introspecting local functions, lambdas, anonymous functions and local variables " +
"is not yet fully supported in Kotlin reflection"
"Introspecting local functions, lambdas, anonymous functions and local variables is not yet fully supported in Kotlin reflection"
)
}

View File

@@ -24,14 +24,13 @@ import java.lang.reflect.Field as ReflectField
import java.lang.reflect.Method as ReflectMethod
internal abstract class FunctionCaller<out M : Member?>(
internal val member: M,
internal val returnType: Type,
internal val instanceClass: Class<*>?,
valueParameterTypes: Array<Type>
internal val member: M,
internal val returnType: Type,
internal val instanceClass: Class<*>?,
valueParameterTypes: Array<Type>
) {
val parameterTypes: List<Type> =
instanceClass?.let { listOf(it, *valueParameterTypes) } ?:
valueParameterTypes.toList()
instanceClass?.let { listOf(it, *valueParameterTypes) } ?: valueParameterTypes.toList()
val arity: Int
get() = parameterTypes.size
@@ -53,13 +52,13 @@ internal abstract class FunctionCaller<out M : Member?>(
// Constructors
class Constructor(constructor: ReflectConstructor<*>) : FunctionCaller<ReflectConstructor<*>>(
constructor,
constructor.declaringClass,
constructor.declaringClass.let { klass ->
val outerClass = klass.declaringClass
if (outerClass != null && !Modifier.isStatic(klass.modifiers)) outerClass else null
},
constructor.genericParameterTypes
constructor,
constructor.declaringClass,
constructor.declaringClass.let { klass ->
val outerClass = klass.declaringClass
if (outerClass != null && !Modifier.isStatic(klass.modifiers)) outerClass else null
},
constructor.genericParameterTypes
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
@@ -70,10 +69,10 @@ internal abstract class FunctionCaller<out M : Member?>(
// TODO fix 'callBy' for bound (and non-bound) inner class constructor references
// See https://youtrack.jetbrains.com/issue/KT-14990
class BoundConstructor(constructor: ReflectConstructor<*>, private val boundReceiver: Any?) :
FunctionCaller<ReflectConstructor<*>>(
constructor, constructor.declaringClass, null,
constructor.genericParameterTypes
) {
FunctionCaller<ReflectConstructor<*>>(
constructor, constructor.declaringClass, null,
constructor.genericParameterTypes
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.newInstance(*argsWithReceiver(boundReceiver, args))
@@ -83,14 +82,14 @@ internal abstract class FunctionCaller<out M : Member?>(
// Methods
abstract class Method(
method: ReflectMethod,
requiresInstance: Boolean = !Modifier.isStatic(method.modifiers),
parameterTypes: Array<Type> = method.genericParameterTypes
method: ReflectMethod,
requiresInstance: Boolean = !Modifier.isStatic(method.modifiers),
parameterTypes: Array<Type> = method.genericParameterTypes
) : FunctionCaller<ReflectMethod>(
method,
method.genericReturnType,
if (requiresInstance) method.declaringClass else null,
parameterTypes
method,
method.genericReturnType,
if (requiresInstance) method.declaringClass else null,
parameterTypes
) {
private val isVoidMethod = returnType == Void.TYPE
@@ -124,24 +123,23 @@ internal abstract class FunctionCaller<out M : Member?>(
}
}
class BoundStaticMethod(method: ReflectMethod, private val boundReceiver: Any?) :
Method(method, requiresInstance = false, parameterTypes = method.genericParameterTypes.dropFirst()) {
class BoundStaticMethod(method: ReflectMethod, private val boundReceiver: Any?) : Method(
method, requiresInstance = false, parameterTypes = method.genericParameterTypes.dropFirst()
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return callMethod(null, argsWithReceiver(boundReceiver, args))
}
}
class BoundInstanceMethod(method: ReflectMethod, private val boundReceiver: Any?) :
Method(method, requiresInstance = false) {
class BoundInstanceMethod(method: ReflectMethod, private val boundReceiver: Any?) : Method(method, requiresInstance = false) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return callMethod(boundReceiver, args)
}
}
class BoundJvmStaticInObject(method: ReflectMethod) :
Method(method, requiresInstance = false) {
class BoundJvmStaticInObject(method: ReflectMethod) : Method(method, requiresInstance = false) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return callMethod(null, args)
@@ -151,13 +149,13 @@ internal abstract class FunctionCaller<out M : Member?>(
// Field accessors
abstract class FieldGetter(
field: ReflectField,
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
field: ReflectField,
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
) : FunctionCaller<ReflectField>(
field,
field.genericType,
if (requiresInstance) field.declaringClass else null,
emptyArray()
field,
field.genericType,
if (requiresInstance) field.declaringClass else null,
emptyArray()
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
@@ -166,14 +164,14 @@ internal abstract class FunctionCaller<out M : Member?>(
}
abstract class FieldSetter(
field: ReflectField,
private val notNull: Boolean,
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
field: ReflectField,
private val notNull: Boolean,
requiresInstance: Boolean = !Modifier.isStatic(field.modifiers)
) : FunctionCaller<ReflectField>(
field,
Void.TYPE,
if (requiresInstance) field.declaringClass else null,
arrayOf(field.genericType)
field,
Void.TYPE,
if (requiresInstance) field.declaringClass else null,
arrayOf(field.genericType)
) {
override fun checkArguments(args: Array<*>) {
super.checkArguments(args)
@@ -199,16 +197,18 @@ internal abstract class FunctionCaller<out M : Member?>(
}
}
class ClassCompanionFieldGetter(field: ReflectField, klass: Class<*>) :
FunctionCaller<ReflectField>(field, field.genericType, klass, emptyArray()) {
class ClassCompanionFieldGetter(field: ReflectField, klass: Class<*>) : FunctionCaller<ReflectField>(
field, field.genericType, klass, emptyArray()
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.get(args.first())
}
}
class BoundInstanceFieldGetter(field: ReflectField, private val boundReceiver: Any?) :
FieldGetter(field, requiresInstance = false) {
class BoundInstanceFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(
field, requiresInstance = false
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.get(boundReceiver)
@@ -217,8 +217,9 @@ internal abstract class FunctionCaller<out M : Member?>(
class BoundJvmStaticInObjectFieldGetter(field: ReflectField) : FieldGetter(field, requiresInstance = false)
class BoundClassCompanionFieldGetter(field: ReflectField, private val boundReceiver: Any?) :
FieldGetter(field, requiresInstance = false) {
class BoundClassCompanionFieldGetter(field: ReflectField, private val boundReceiver: Any?) : FieldGetter(
field, requiresInstance = false
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.get(boundReceiver)
@@ -236,32 +237,36 @@ internal abstract class FunctionCaller<out M : Member?>(
}
}
class ClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) :
FunctionCaller<ReflectField>(field, Void.TYPE, klass, arrayOf(field.genericType)) {
class ClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) : FunctionCaller<ReflectField>(
field, Void.TYPE, klass, arrayOf(field.genericType)
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.set(null, args.last())
}
}
class BoundInstanceFieldSetter(field: ReflectField, notNull: Boolean, private val boundReceiver: Any?) :
FieldSetter(field, notNull, false) {
class BoundInstanceFieldSetter(field: ReflectField, notNull: Boolean, private val boundReceiver: Any?) : FieldSetter(
field, notNull, false
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.set(boundReceiver, args.first())
}
}
class BoundJvmStaticInObjectFieldSetter(field: ReflectField, notNull: Boolean) :
FieldSetter(field, notNull, requiresInstance = false) {
class BoundJvmStaticInObjectFieldSetter(field: ReflectField, notNull: Boolean) : FieldSetter(
field, notNull, requiresInstance = false
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.set(null, args.last())
}
}
class BoundClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) :
FunctionCaller<ReflectField>(field, Void.TYPE, klass, arrayOf(field.genericType)) {
class BoundClassCompanionFieldSetter(field: ReflectField, klass: Class<*>) : FunctionCaller<ReflectField>(
field, Void.TYPE, klass, arrayOf(field.genericType)
) {
override fun call(args: Array<*>): Any? {
checkArguments(args)
return member.set(null, args.last())
@@ -277,17 +282,17 @@ internal abstract class FunctionCaller<out M : Member?>(
companion object {
// TODO lazily allocate array at bound callers?
fun argsWithReceiver(receiver: Any?, args: Array<out Any?>): Array<out Any?> =
arrayOfNulls<Any?>(args.size + 1).apply {
this[0] = receiver
System.arraycopy(args, 0, this, 1, args.size)
}
arrayOfNulls<Any?>(args.size + 1).apply {
this[0] = receiver
System.arraycopy(args, 0, this, 1, args.size)
}
@Suppress("UNCHECKED_CAST")
inline fun <reified T> Array<out T>.dropFirst(): Array<T> =
if (size <= 1) emptyArray<T>() else copyOfRange(1, size) as Array<T>
if (size <= 1) emptyArray() else copyOfRange(1, size) as Array<T>
@Suppress("UNCHECKED_CAST")
fun Array<*>.dropFirstArg(): Array<Any?> =
(this as Array<Any?>).dropFirst()
(this as Array<Any?>).dropFirst()
}
}

View File

@@ -19,31 +19,31 @@ package kotlin.reflect.jvm.internal
import kotlin.reflect.KCallable
internal interface FunctionWithAllInvokes :
// (0..22).forEach { n -> println("Function$n<" + (0..n).joinToString { "Any?" } + ">,") }
Function0<Any?>,
Function1<Any?, Any?>,
Function2<Any?, Any?, Any?>,
Function3<Any?, Any?, Any?, Any?>,
Function4<Any?, Any?, Any?, Any?, Any?>,
Function5<Any?, Any?, Any?, Any?, Any?, Any?>,
Function6<Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function7<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function8<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function9<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function10<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function11<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function12<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function13<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function14<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function15<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function16<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function17<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function18<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function19<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function20<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function21<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function22<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
KCallable<Any?>
// (0..22).forEach { n -> println("Function$n<" + (0..n).joinToString { "Any?" } + ">,") }
Function0<Any?>,
Function1<Any?, Any?>,
Function2<Any?, Any?, Any?>,
Function3<Any?, Any?, Any?, Any?>,
Function4<Any?, Any?, Any?, Any?, Any?>,
Function5<Any?, Any?, Any?, Any?, Any?, Any?>,
Function6<Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function7<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function8<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function9<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function10<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function11<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function12<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function13<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function14<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function15<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function16<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function17<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function18<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function19<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function20<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function21<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
Function22<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
KCallable<Any?>
{
// (0..22).forEach { n -> println("override fun invoke(" + (1..n).joinToString { "p$it: Any?" } + "): Any? = call(" + (1..n).joinToString { "p$it" } + ")") }
override fun invoke(): Any? = call()

View File

@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import java.lang.reflect.Type
import java.util.*
import kotlin.reflect.*
import kotlin.reflect.jvm.internal.KotlinReflectionInternalError
import kotlin.reflect.jvm.javaType
internal abstract class KCallableImpl<out R> : KCallable<R> {
@@ -38,11 +37,11 @@ internal abstract class KCallableImpl<out R> : KCallable<R> {
abstract val isBound: Boolean
private val annotations_ = ReflectProperties.lazySoft { descriptor.computeAnnotations() }
private val _annotations = ReflectProperties.lazySoft { descriptor.computeAnnotations() }
override val annotations: List<Annotation> get() = annotations_()
override val annotations: List<Annotation> get() = _annotations()
private val parameters_ = ReflectProperties.lazySoft {
private val _parameters = ReflectProperties.lazySoft {
val descriptor = descriptor
val result = ArrayList<KParameter>()
var index = 0
@@ -71,21 +70,21 @@ internal abstract class KCallableImpl<out R> : KCallable<R> {
}
override val parameters: List<KParameter>
get() = parameters_()
get() = _parameters()
private val returnType_ = ReflectProperties.lazySoft {
private val _returnType = ReflectProperties.lazySoft {
KTypeImpl(descriptor.returnType!!) { caller.returnType }
}
override val returnType: KType
get() = returnType_()
get() = _returnType()
private val typeParameters_ = ReflectProperties.lazySoft {
private val _typeParameters = ReflectProperties.lazySoft {
descriptor.typeParameters.map(::KTypeParameterImpl)
}
override val typeParameters: List<KTypeParameter>
get() = typeParameters_()
get() = _typeParameters()
override val visibility: KVisibility?
get() = descriptor.visibility.toKVisibility()
@@ -184,19 +183,18 @@ internal abstract class KCallableImpl<out R> : KCallable<R> {
}
private fun defaultPrimitiveValue(type: Type): Any? =
if (type is Class<*> && type.isPrimitive) {
when (type) {
Boolean::class.java -> false
Char::class.java -> 0.toChar()
Byte::class.java -> 0.toByte()
Short::class.java -> 0.toShort()
Int::class.java -> 0
Float::class.java -> 0f
Long::class.java -> 0L
Double::class.java -> 0.0
Void.TYPE -> throw IllegalStateException("Parameter with void type is illegal")
else -> throw UnsupportedOperationException("Unknown primitive: $type")
}
if (type is Class<*> && type.isPrimitive) {
when (type) {
Boolean::class.java -> false
Char::class.java -> 0.toChar()
Byte::class.java -> 0.toByte()
Short::class.java -> 0.toShort()
Int::class.java -> 0
Float::class.java -> 0f
Long::class.java -> 0L
Double::class.java -> 0.0
Void.TYPE -> throw IllegalStateException("Parameter with void type is illegal")
else -> throw UnsupportedOperationException("Unknown primitive: $type")
}
else null
} else null
}

View File

@@ -47,8 +47,8 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
val moduleData = data().moduleData
val descriptor =
if (classId.isLocal) moduleData.deserialization.deserializeClass(classId)
else moduleData.module.findClassAcrossModuleDependencies(classId)
if (classId.isLocal) moduleData.deserialization.deserializeClass(classId)
else moduleData.module.findClassAcrossModuleDependencies(classId)
descriptor ?: reportUnresolvedClass()
}
@@ -94,11 +94,11 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
}
val nestedClasses: Collection<KClass<*>> by ReflectProperties.lazySoft {
descriptor.unsubstitutedInnerClassesScope.getContributedDescriptors().filterNot(DescriptorUtils::isEnumEntry).mapNotNull {
nestedClass ->
val jClass = (nestedClass as ClassDescriptor).toJavaClass()
jClass?.let { KClassImpl(it) }
}
descriptor.unsubstitutedInnerClassesScope.getContributedDescriptors().filterNot(DescriptorUtils::isEnumEntry)
.mapNotNull { nestedClass ->
val jClass = (nestedClass as ClassDescriptor).toJavaClass()
jClass?.let { KClassImpl(it) }
}
}
@Suppress("UNCHECKED_CAST")
@@ -108,8 +108,7 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
val field = if (descriptor.isCompanionObject && !CompanionObjectMapping.isMappedIntrinsicCompanionObject(descriptor)) {
jClass.enclosingClass.getDeclaredField(descriptor.name.asString())
}
else {
} else {
jClass.getDeclaredField(JvmAbi.INSTANCE_FIELD)
}
field.get(null) as T
@@ -128,12 +127,11 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
if (superClass !is ClassDescriptor) throw KotlinReflectionInternalError("Supertype not a class: $superClass")
val superJavaClass = superClass.toJavaClass()
?: throw KotlinReflectionInternalError("Unsupported superclass of $this: $superClass")
?: throw KotlinReflectionInternalError("Unsupported superclass of $this: $superClass")
if (jClass.superclass == superJavaClass) {
jClass.genericSuperclass
}
else {
} else {
val index = jClass.interfaces.indexOf(superJavaClass)
if (index < 0) throw KotlinReflectionInternalError("No superclass of $this in Java reflection for $superClass")
jClass.genericInterfaces[index]
@@ -151,11 +149,11 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
val declaredNonStaticMembers: Collection<KCallableImpl<*>>
by ReflectProperties.lazySoft { getMembers(memberScope, DECLARED) }
val declaredStaticMembers: Collection<KCallableImpl<*>>
private val declaredStaticMembers: Collection<KCallableImpl<*>>
by ReflectProperties.lazySoft { getMembers(staticScope, DECLARED) }
val inheritedNonStaticMembers: Collection<KCallableImpl<*>>
private val inheritedNonStaticMembers: Collection<KCallableImpl<*>>
by ReflectProperties.lazySoft { getMembers(memberScope, INHERITED) }
val inheritedStaticMembers: Collection<KCallableImpl<*>>
private val inheritedStaticMembers: Collection<KCallableImpl<*>>
by ReflectProperties.lazySoft { getMembers(staticScope, INHERITED) }
val allNonStaticMembers: Collection<KCallableImpl<*>>
@@ -192,12 +190,12 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
}
override fun getProperties(name: Name): Collection<PropertyDescriptor> =
(memberScope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION) +
staticScope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION))
(memberScope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION) +
staticScope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION))
override fun getFunctions(name: Name): Collection<FunctionDescriptor> =
memberScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION) +
staticScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
memberScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION) +
staticScope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
override fun getLocalProperty(index: Int): PropertyDescriptor? {
// TODO: also check that this is a synthetic class (Metadata.k == 3)
@@ -263,10 +261,10 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
get() = descriptor.isCompanionObject
override fun equals(other: Any?): Boolean =
other is KClassImpl<*> && javaObjectType == other.javaObjectType
other is KClassImpl<*> && javaObjectType == other.javaObjectType
override fun hashCode(): Int =
javaObjectType.hashCode()
javaObjectType.hashCode()
override fun toString(): String {
return "class " + classId.let { classId ->
@@ -282,15 +280,15 @@ internal class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclaration
when (kind) {
KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
throw UnsupportedOperationException(
"Packages and file facades are not yet supported in Kotlin reflection. " +
"Meanwhile please use Java reflection to inspect this class: $jClass"
"Packages and file facades are not yet supported in Kotlin reflection. " +
"Meanwhile please use Java reflection to inspect this class: $jClass"
)
}
KotlinClassHeader.Kind.SYNTHETIC_CLASS -> {
throw UnsupportedOperationException(
"This class is an internal synthetic class generated by the Kotlin compiler, such as an anonymous class " +
"for a lambda, a SAM wrapper, a callable reference, etc. It's not a Kotlin class or interface, so the reflection " +
"library has no idea what declarations does it have. Please use Java reflection to inspect this class: $jClass"
"This class is an internal synthetic class generated by the Kotlin compiler, such as an anonymous class " +
"for a lambda, a SAM wrapper, a callable reference, etc. It's not a Kotlin class or interface, so the reflection " +
"library has no idea what declarations does it have. Please use Java reflection to inspect this class: $jClass"
)
}
KotlinClassHeader.Kind.UNKNOWN -> {

View File

@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.DeclarationDescriptorVisitorEmptyBodies
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import java.lang.reflect.Constructor
import java.lang.reflect.Method
@@ -27,6 +28,7 @@ import kotlin.jvm.internal.ClassBasedDeclarationContainer
import kotlin.reflect.jvm.internal.components.RuntimeModuleData
import kotlin.reflect.jvm.internal.structure.createArrayType
import kotlin.reflect.jvm.internal.structure.safeClassLoader
import kotlin.reflect.jvm.internal.structure.wrapperByPrimitive
internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContainer {
abstract inner class Data {
@@ -37,7 +39,7 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
}
protected open val methodOwner: Class<*>
get() = jClass
get() = jClass.wrapperByPrimitive ?: jClass
abstract val constructorDescriptors: Collection<ConstructorDescriptor>
@@ -50,21 +52,20 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
protected fun getMembers(scope: MemberScope, belonginess: MemberBelonginess): Collection<KCallableImpl<*>> {
val visitor = object : DeclarationDescriptorVisitorEmptyBodies<KCallableImpl<*>, Unit>() {
override fun visitPropertyDescriptor(descriptor: PropertyDescriptor, data: Unit): KCallableImpl<*> =
createProperty(descriptor)
createProperty(descriptor)
override fun visitFunctionDescriptor(descriptor: FunctionDescriptor, data: Unit): KCallableImpl<*> =
KFunctionImpl(this@KDeclarationContainerImpl, descriptor)
KFunctionImpl(this@KDeclarationContainerImpl, descriptor)
override fun visitConstructorDescriptor(descriptor: ConstructorDescriptor, data: Unit): KCallableImpl<*> =
throw IllegalStateException("No constructors should appear in this scope: $descriptor")
throw IllegalStateException("No constructors should appear in this scope: $descriptor")
}
return scope.getContributedDescriptors().mapNotNull { descriptor ->
if (descriptor is CallableMemberDescriptor &&
descriptor.visibility != Visibilities.INVISIBLE_FAKE &&
belonginess.accept(descriptor))
descriptor.accept(visitor, Unit)
else null
belonginess.accept(descriptor)
) descriptor.accept(visitor, Unit) else null
}.toList()
}
@@ -73,12 +74,12 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
INHERITED;
fun accept(member: CallableMemberDescriptor): Boolean =
member.kind.isReal == (this == DECLARED)
member.kind.isReal == (this == DECLARED)
}
private fun createProperty(descriptor: PropertyDescriptor): KPropertyImpl<*> {
val receiverCount = (descriptor.dispatchReceiverParameter?.let { 1 } ?: 0) +
(descriptor.extensionReceiverParameter?.let { 1 } ?: 0)
(descriptor.extensionReceiverParameter?.let { 1 } ?: 0)
when {
descriptor.isVar -> when (receiverCount) {
@@ -101,13 +102,13 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
if (match != null) {
val (number) = match.destructured
return getLocalProperty(number.toInt())
?: throw KotlinReflectionInternalError("Local property #$number not found in $jClass")
?: throw KotlinReflectionInternalError("Local property #$number not found in $jClass")
}
val properties = getProperties(Name.identifier(name))
.filter { descriptor ->
RuntimeTypeMapper.mapPropertySignature(descriptor).asString() == signature
}
.filter { descriptor ->
RuntimeTypeMapper.mapPropertySignature(descriptor).asString() == signature
}
if (properties.isEmpty()) {
throw KotlinReflectionInternalError("Property '$name' (JVM signature: $signature) not resolved in $this")
@@ -125,16 +126,20 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
// TODO: consider writing additional info (besides signature) to property reference objects to distinguish them in this case
val mostVisibleProperties = properties
.groupBy { it.visibility }
.toSortedMap(Comparator { first, second ->
Visibilities.compare(first, second) ?: 0
}).values.last()
.groupBy { it.visibility }
.toSortedMap(Comparator { first, second ->
Visibilities.compare(first, second) ?: 0
}).values.last()
if (mostVisibleProperties.size == 1) {
return mostVisibleProperties.first()
}
val allMembers = getProperties(Name.identifier(name)).joinToString("\n") { descriptor ->
DescriptorRenderer.DEBUG_TEXT.render(descriptor) + " | " + RuntimeTypeMapper.mapPropertySignature(descriptor)
}
throw KotlinReflectionInternalError(
"${properties.size} properties '$name' (JVM signature: $signature) resolved in $this: $properties"
"Property '$name' (JVM signature: $signature) not resolved in $this:" +
if (allMembers.isEmpty()) " no members found" else "\n$allMembers"
)
}
@@ -142,16 +147,18 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
}
fun findFunctionDescriptor(name: String, signature: String): FunctionDescriptor {
val functions = (if (name == "<init>") constructorDescriptors.toList() else getFunctions(Name.identifier(name)))
.filter { descriptor ->
RuntimeTypeMapper.mapSignature(descriptor).asString() == signature
}
val members = if (name == "<init>") constructorDescriptors.toList() else getFunctions(Name.identifier(name))
val functions = members.filter { descriptor ->
RuntimeTypeMapper.mapSignature(descriptor).asString() == signature
}
if (functions.size != 1) {
val debugText = "'$name' (JVM signature: $signature)"
val allMembers = members.joinToString("\n") { descriptor ->
DescriptorRenderer.DEBUG_TEXT.render(descriptor) + " | " + RuntimeTypeMapper.mapSignature(descriptor)
}
throw KotlinReflectionInternalError(
if (functions.isEmpty()) "Function $debugText not resolved in $this"
else "${functions.size} functions $debugText resolved in $this: $functions"
"Function '$name' (JVM signature: $signature) not resolved in $this:" +
if (allMembers.isEmpty()) " no members found" else "\n$allMembers"
)
}
@@ -178,35 +185,33 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
}
private fun Class<*>.tryGetMethod(name: String, parameterTypes: Array<Class<*>>, returnType: Class<*>, declared: Boolean): Method? =
try {
val result = if (declared) getDeclaredMethod(name, *parameterTypes) else getMethod(name, *parameterTypes)
try {
val result = if (declared) getDeclaredMethod(name, *parameterTypes) else getMethod(name, *parameterTypes)
if (result.returnType == returnType) result
else {
// If we've found a method with an unexpected return type, it's likely that there are several methods in this class
// with the given parameter types and Java reflection API has returned not the one we're looking for.
// Falling back to enumerating all methods in the class in this (rather rare) case.
// Example: class A(val x: Int) { fun getX(): String = ... }
val allMethods = if (declared) declaredMethods else methods
allMethods.firstOrNull { method ->
method.name == name &&
method.returnType == returnType &&
method.parameterTypes.contentEquals(parameterTypes)
}
if (result.returnType == returnType) result
else {
// If we've found a method with an unexpected return type, it's likely that there are several methods in this class
// with the given parameter types and Java reflection API has returned not the one we're looking for.
// Falling back to enumerating all methods in the class in this (rather rare) case.
// Example: class A(val x: Int) { fun getX(): String = ... }
val allMethods = if (declared) declaredMethods else methods
allMethods.firstOrNull { method ->
method.name == name &&
method.returnType == returnType &&
method.parameterTypes!!.contentEquals(parameterTypes)
}
}
catch (e: NoSuchMethodException) {
null
}
} catch (e: NoSuchMethodException) {
null
}
private fun Class<*>.tryGetConstructor(parameterTypes: List<Class<*>>, declared: Boolean): Constructor<*>? =
try {
if (declared) getDeclaredConstructor(*parameterTypes.toTypedArray())
else getConstructor(*parameterTypes.toTypedArray())
}
catch (e: NoSuchMethodException) {
null
}
try {
if (declared) getDeclaredConstructor(*parameterTypes.toTypedArray())
else getConstructor(*parameterTypes.toTypedArray())
} catch (e: NoSuchMethodException) {
null
}
fun findMethodBySignature(name: String, desc: String, isPublic: Boolean): Method? {
if (name == "<init>") return null
@@ -267,23 +272,23 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain
}
private fun parseType(desc: String, begin: Int, end: Int): Class<*> =
when (desc[begin]) {
'L' -> jClass.safeClassLoader.loadClass(desc.substring(begin + 1, end - 1).replace('/', '.'))
'[' -> parseType(desc, begin + 1, end).createArrayType()
'V' -> Void.TYPE
'Z' -> Boolean::class.java
'C' -> Char::class.java
'B' -> Byte::class.java
'S' -> Short::class.java
'I' -> Int::class.java
'F' -> Float::class.java
'J' -> Long::class.java
'D' -> Double::class.java
else -> throw KotlinReflectionInternalError("Unknown type prefix in the method signature: $desc")
}
when (desc[begin]) {
'L' -> jClass.safeClassLoader.loadClass(desc.substring(begin + 1, end - 1).replace('/', '.'))
'[' -> parseType(desc, begin + 1, end).createArrayType()
'V' -> Void.TYPE
'Z' -> Boolean::class.java
'C' -> Char::class.java
'B' -> Byte::class.java
'S' -> Short::class.java
'I' -> Int::class.java
'F' -> Float::class.java
'J' -> Long::class.java
'D' -> Double::class.java
else -> throw KotlinReflectionInternalError("Unknown type prefix in the method signature: $desc")
}
private fun loadReturnType(desc: String): Class<*> =
parseType(desc, desc.indexOf(')') + 1, desc.length)
parseType(desc, desc.indexOf(')') + 1, desc.length)
companion object {
private val DEFAULT_CONSTRUCTOR_MARKER = Class.forName("kotlin.jvm.internal.DefaultConstructorMarker")

View File

@@ -32,20 +32,20 @@ import kotlin.reflect.jvm.internal.AnnotationConstructorCaller.Origin.KOTLIN
import kotlin.reflect.jvm.internal.JvmFunctionSignature.*
internal class KFunctionImpl private constructor(
override val container: KDeclarationContainerImpl,
name: String,
private val signature: String,
descriptorInitialValue: FunctionDescriptor?,
private val boundReceiver: Any? = CallableReference.NO_RECEIVER
override val container: KDeclarationContainerImpl,
name: String,
private val signature: String,
descriptorInitialValue: FunctionDescriptor?,
private val boundReceiver: Any? = CallableReference.NO_RECEIVER
) : KCallableImpl<Any?>(), KFunction<Any?>, FunctionBase, FunctionWithAllInvokes {
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?)
: this(container, name, signature, null, boundReceiver)
constructor(container: KDeclarationContainerImpl, descriptor: FunctionDescriptor) : this(
container,
descriptor.name.asString(),
RuntimeTypeMapper.mapSignature(descriptor).asString(),
descriptor
container,
descriptor.name.asString(),
RuntimeTypeMapper.mapSignature(descriptor).asString(),
descriptor
)
override val isBound: Boolean get() = boundReceiver != CallableReference.NO_RECEIVER
@@ -56,7 +56,7 @@ internal class KFunctionImpl private constructor(
override val name: String get() = descriptor.name.asString()
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft caller@ {
override val caller: FunctionCaller<*> by ReflectProperties.lazySoft caller@{
val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
val member: Member? = when (jvmSignature) {
is KotlinConstructor -> {
@@ -72,7 +72,6 @@ internal class KFunctionImpl private constructor(
val methods = jvmSignature.methods
return@caller AnnotationConstructorCaller(container.jClass, methods.map { it.name }, POSITIONAL_CALL, JAVA, methods)
}
is BuiltInFunction -> jvmSignature.getMember(container)
}
when (member) {
@@ -90,12 +89,14 @@ internal class KFunctionImpl private constructor(
}
}
override val defaultCaller: FunctionCaller<*>? by ReflectProperties.lazySoft defaultCaller@ {
override val defaultCaller: FunctionCaller<*>? by ReflectProperties.lazySoft defaultCaller@{
val jvmSignature = RuntimeTypeMapper.mapSignature(descriptor)
val member: Member? = when (jvmSignature) {
is KotlinFunction -> {
container.findDefaultMethod(jvmSignature.methodName, jvmSignature.methodDesc,
!Modifier.isStatic(caller.member!!.modifiers), descriptor.isPublicInBytecode)
container.findDefaultMethod(
jvmSignature.methodName, jvmSignature.methodDesc,
!Modifier.isStatic(caller.member!!.modifiers), descriptor.isPublicInBytecode
)
}
is KotlinConstructor -> {
if (isAnnotationConstructor)
@@ -120,7 +121,7 @@ internal class KFunctionImpl private constructor(
// In objects, $default's signature does _not_ contain the additional object instance parameter,
// as opposed to companion objects where the first parameter is the companion object instance.
descriptor.annotations.findAnnotation(JVM_STATIC) != null &&
!(descriptor.containingDeclaration as ClassDescriptor).isCompanionObject ->
!(descriptor.containingDeclaration as ClassDescriptor).isCompanionObject ->
createJvmStaticInObjectCaller(member)
else ->
@@ -131,16 +132,16 @@ internal class KFunctionImpl private constructor(
}
private fun createStaticMethodCaller(member: Method) =
if (isBound) FunctionCaller.BoundStaticMethod(member, boundReceiver) else FunctionCaller.StaticMethod(member)
if (isBound) FunctionCaller.BoundStaticMethod(member, boundReceiver) else FunctionCaller.StaticMethod(member)
private fun createJvmStaticInObjectCaller(member: Method) =
if (isBound) FunctionCaller.BoundJvmStaticInObject(member) else FunctionCaller.JvmStaticInObject(member)
if (isBound) FunctionCaller.BoundJvmStaticInObject(member) else FunctionCaller.JvmStaticInObject(member)
private fun createInstanceMethodCaller(member: Method) =
if (isBound) FunctionCaller.BoundInstanceMethod(member, boundReceiver) else FunctionCaller.InstanceMethod(member)
if (isBound) FunctionCaller.BoundInstanceMethod(member, boundReceiver) else FunctionCaller.InstanceMethod(member)
private fun createConstructorCaller(member: Constructor<*>) =
if (isBound) FunctionCaller.BoundConstructor(member, boundReceiver) else FunctionCaller.Constructor(member)
if (isBound) FunctionCaller.BoundConstructor(member, boundReceiver) else FunctionCaller.Constructor(member)
override fun getArity() = caller.arity
@@ -165,8 +166,8 @@ internal class KFunctionImpl private constructor(
}
override fun hashCode(): Int =
(container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode()
(container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode()
override fun toString(): String =
ReflectionObjectRenderer.renderFunction(descriptor)
ReflectionObjectRenderer.renderFunction(descriptor)
}

View File

@@ -36,8 +36,8 @@ import kotlin.reflect.jvm.internal.components.ReflectKotlinClass
import kotlin.reflect.jvm.internal.structure.classId
internal class KPackageImpl(
override val jClass: Class<*>,
@Suppress("unused") val usageModuleName: String? = null // may be useful for debug
override val jClass: Class<*>,
@Suppress("unused") val usageModuleName: String? = null // may be useful for debug
) : KDeclarationContainerImpl() {
private inner class Data : KDeclarationContainerImpl.Data() {
private val kotlinClass: ReflectKotlinClass? by ReflectProperties.lazySoft {
@@ -58,8 +58,7 @@ internal class KPackageImpl(
// The default value for 'xs' is empty string, as declared in kotlin.Metadata
if (facadeName != null && facadeName.isNotEmpty()) {
jClass.classLoader.loadClass(facadeName.replace('/', '.'))
}
else {
} else {
jClass
}
}
@@ -70,8 +69,7 @@ internal class KPackageImpl(
val strings = header.strings
if (data != null && strings != null) {
JvmProtoBufUtil.readPackageDataFrom(data, strings)
}
else null
} else null
}
}
@@ -97,10 +95,10 @@ internal class KPackageImpl(
get() = emptyList()
override fun getProperties(name: Name): Collection<PropertyDescriptor> =
scope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION)
scope.getContributedVariables(name, NoLookupLocation.FROM_REFLECTION)
override fun getFunctions(name: Name): Collection<FunctionDescriptor> =
scope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
scope.getContributedFunctions(name, NoLookupLocation.FROM_REFLECTION)
override fun getLocalProperty(index: Int): PropertyDescriptor? {
return data().metadata?.let { (nameResolver, packageProto) ->
@@ -111,10 +109,10 @@ internal class KPackageImpl(
}
override fun equals(other: Any?): Boolean =
other is KPackageImpl && jClass == other.jClass
other is KPackageImpl && jClass == other.jClass
override fun hashCode(): Int =
jClass.hashCode()
jClass.hashCode()
override fun toString(): String {
val fqName = jClass.classId.packageFqName

View File

@@ -23,21 +23,22 @@ import kotlin.reflect.KParameter
import kotlin.reflect.KType
internal class KParameterImpl(
val callable: KCallableImpl<*>,
override val index: Int,
override val kind: KParameter.Kind,
computeDescriptor: () -> ParameterDescriptor
val callable: KCallableImpl<*>,
override val index: Int,
override val kind: KParameter.Kind,
computeDescriptor: () -> ParameterDescriptor
) : KParameter {
private val descriptor: ParameterDescriptor by ReflectProperties.lazySoft(computeDescriptor)
override val annotations: List<Annotation> by ReflectProperties.lazySoft { descriptor.computeAnnotations() }
override val name: String? get() {
val valueParameter = descriptor as? ValueParameterDescriptor ?: return null
if (valueParameter.containingDeclaration.hasSynthesizedParameterNames()) return null
val name = valueParameter.name
return if (name.isSpecial) null else name.asString()
}
override val name: String?
get() {
val valueParameter = descriptor as? ValueParameterDescriptor ?: return null
if (valueParameter.containingDeclaration.hasSynthesizedParameterNames()) return null
val name = valueParameter.name
return if (name.isSpecial) null else name.asString()
}
override val type: KType
get() = KTypeImpl(descriptor.type) { callable.caller.parameterTypes[index] }
@@ -49,11 +50,11 @@ internal class KParameterImpl(
get() = descriptor.let { it is ValueParameterDescriptor && it.varargElementType != null }
override fun equals(other: Any?) =
other is KParameterImpl && callable == other.callable && descriptor == other.descriptor
other is KParameterImpl && callable == other.callable && descriptor == other.descriptor
override fun hashCode() =
(callable.hashCode() * 31) + descriptor.hashCode()
(callable.hashCode() * 31) + descriptor.hashCode()
override fun toString() =
ReflectionObjectRenderer.renderParameter(this)
ReflectionObjectRenderer.renderParameter(this)
}

View File

@@ -24,11 +24,13 @@ import kotlin.reflect.KProperty0
internal open class KProperty0Impl<out R> : KProperty0<R>, KPropertyImpl<R> {
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(container, name, signature, boundReceiver)
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(
container, name, signature, boundReceiver
)
private val getter_ = ReflectProperties.lazy { Getter(this) }
private val _getter = ReflectProperties.lazy { Getter(this) }
override val getter: Getter<R> get() = getter_()
override val getter: Getter<R> get() = _getter()
override fun get(): R = getter.call()
@@ -46,11 +48,13 @@ internal open class KProperty0Impl<out R> : KProperty0<R>, KPropertyImpl<R> {
internal class KMutableProperty0Impl<R> : KProperty0Impl<R>, KMutableProperty0<R> {
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(container, name, signature, boundReceiver)
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(
container, name, signature, boundReceiver
)
private val setter_ = ReflectProperties.lazy { Setter(this) }
private val _setter = ReflectProperties.lazy { Setter(this) }
override val setter: Setter<R> get() = setter_()
override val setter: Setter<R> get() = _setter()
override fun set(value: R) = setter.call(value)

View File

@@ -22,13 +22,15 @@ import kotlin.reflect.KMutableProperty1
import kotlin.reflect.KProperty1
internal open class KProperty1Impl<T, out R> : KProperty1<T, R>, KPropertyImpl<R> {
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(container, name, signature, boundReceiver)
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(
container, name, signature, boundReceiver
)
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
private val getter_ = ReflectProperties.lazy { Getter(this) }
private val _getter = ReflectProperties.lazy { Getter(this) }
override val getter: Getter<T, R> get() = getter_()
override val getter: Getter<T, R> get() = _getter()
override fun get(receiver: T): R = getter.call(receiver)
@@ -44,13 +46,15 @@ internal open class KProperty1Impl<T, out R> : KProperty1<T, R>, KPropertyImpl<R
}
internal class KMutableProperty1Impl<T, R> : KProperty1Impl<T, R>, KMutableProperty1<T, R> {
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(container, name, signature, boundReceiver)
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : super(
container, name, signature, boundReceiver
)
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
private val setter_ = ReflectProperties.lazy { Setter(this) }
private val _setter = ReflectProperties.lazy { Setter(this) }
override val setter: Setter<T, R> get() = setter_()
override val setter: Setter<T, R> get() = _setter()
override fun set(receiver: T, value: R) = setter.call(receiver, value)

View File

@@ -23,13 +23,15 @@ import kotlin.reflect.KMutableProperty2
import kotlin.reflect.KProperty2
internal open class KProperty2Impl<D, E, out R> : KProperty2<D, E, R>, KPropertyImpl<R> {
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : super(container, name, signature, CallableReference.NO_RECEIVER)
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : super(
container, name, signature, CallableReference.NO_RECEIVER
)
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
private val getter_ = ReflectProperties.lazy { Getter(this) }
private val _getter = ReflectProperties.lazy { Getter(this) }
override val getter: Getter<D, E, R> get() = getter_()
override val getter: Getter<D, E, R> get() = _getter()
override fun get(receiver1: D, receiver2: E): R = getter.call(receiver1, receiver2)
@@ -49,13 +51,14 @@ internal class KMutableProperty2Impl<D, E, R> : KProperty2Impl<D, E, R>, KMutabl
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
private val setter_ = ReflectProperties.lazy { Setter(this) }
private val _setter = ReflectProperties.lazy { Setter(this) }
override val setter: Setter<D, E, R> get() = setter_()
override val setter: Setter<D, E, R> get() = _setter()
override fun set(receiver1: D, receiver2: E, value: R) = setter.call(receiver1, receiver2, value)
class Setter<D, E, R>(override val property: KMutableProperty2Impl<D, E, R>) : KPropertyImpl.Setter<R>(), KMutableProperty2.Setter<D, E, R> {
class Setter<D, E, R>(override val property: KMutableProperty2Impl<D, E, R>) : KPropertyImpl.Setter<R>(),
KMutableProperty2.Setter<D, E, R> {
override fun invoke(receiver1: D, receiver2: E, value: R): Unit = property.set(receiver1, receiver2, value)
}
}

View File

@@ -33,27 +33,27 @@ import kotlin.reflect.full.IllegalPropertyDelegateAccessException
import kotlin.reflect.jvm.internal.JvmPropertySignature.*
internal abstract class KPropertyImpl<out R> private constructor(
override val container: KDeclarationContainerImpl,
override val name: String,
val signature: String,
descriptorInitialValue: PropertyDescriptor?,
val boundReceiver: Any?
override val container: KDeclarationContainerImpl,
override val name: String,
val signature: String,
descriptorInitialValue: PropertyDescriptor?,
val boundReceiver: Any?
) : KCallableImpl<R>(), KProperty<R> {
constructor(container: KDeclarationContainerImpl, name: String, signature: String, boundReceiver: Any?) : this(
container, name, signature, null, boundReceiver
container, name, signature, null, boundReceiver
)
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : this(
container,
descriptor.name.asString(),
RuntimeTypeMapper.mapPropertySignature(descriptor).asString(),
descriptor,
CallableReference.NO_RECEIVER
container,
descriptor.name.asString(),
RuntimeTypeMapper.mapPropertySignature(descriptor).asString(),
descriptor,
CallableReference.NO_RECEIVER
)
override val isBound: Boolean get() = boundReceiver != CallableReference.NO_RECEIVER
private val javaField_ = ReflectProperties.lazySoft {
private val _javaField = ReflectProperties.lazySoft {
val jvmSignature = RuntimeTypeMapper.mapPropertySignature(descriptor)
when (jvmSignature) {
is KotlinProperty -> {
@@ -61,51 +61,51 @@ internal abstract class KPropertyImpl<out R> private constructor(
JvmProtoBufUtil.getJvmFieldSignature(jvmSignature.proto, jvmSignature.nameResolver, jvmSignature.typeTable)?.let {
val owner = if (JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor.containingDeclaration)) {
container.jClass.enclosingClass
}
else descriptor.containingDeclaration.let { containingDeclaration ->
} else descriptor.containingDeclaration.let { containingDeclaration ->
if (containingDeclaration is ClassDescriptor) containingDeclaration.toJavaClass()
else container.jClass
}
try {
owner?.getDeclaredField(it.name)
}
catch (e: NoSuchFieldException) {
} catch (e: NoSuchFieldException) {
null
}
}
}
is JavaField -> jvmSignature.field
is JavaMethodProperty -> null
is MappedKotlinProperty -> null
}
}
val javaField: Field? get() = javaField_()
val javaField: Field? get() = _javaField()
protected fun computeDelegateField(): Field? =
if (@Suppress("DEPRECATION") descriptor.isDelegated) javaField else null
if (@Suppress("DEPRECATION") descriptor.isDelegated) javaField else null
protected fun getDelegate(field: Field?, receiver: Any?): Any? =
try {
if (receiver === EXTENSION_PROPERTY_DELEGATE) {
if (descriptor.extensionReceiverParameter == null) {
throw RuntimeException("'$this' is not an extension property and thus getExtensionDelegate() " +
"is not going to work, use getDelegate() instead")
}
try {
if (receiver === EXTENSION_PROPERTY_DELEGATE) {
if (descriptor.extensionReceiverParameter == null) {
throw RuntimeException(
"'$this' is not an extension property and thus getExtensionDelegate() " +
"is not going to work, use getDelegate() instead"
)
}
field?.get(receiver)
}
catch (e: IllegalAccessException) {
throw IllegalPropertyDelegateAccessException(e)
}
field?.get(receiver)
} catch (e: IllegalAccessException) {
throw IllegalPropertyDelegateAccessException(e)
}
override abstract val getter: Getter<R>
abstract override val getter: Getter<R>
private val descriptor_ = ReflectProperties.lazySoft(descriptorInitialValue) {
private val _descriptor = ReflectProperties.lazySoft(descriptorInitialValue) {
container.findPropertyDescriptor(name, signature)
}
override val descriptor: PropertyDescriptor get() = descriptor_()
override val descriptor: PropertyDescriptor get() = _descriptor()
override val caller: FunctionCaller<*> get() = getter.caller
@@ -121,13 +121,13 @@ internal abstract class KPropertyImpl<out R> private constructor(
}
override fun hashCode(): Int =
(container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode()
(container.hashCode() * 31 + name.hashCode()) * 31 + signature.hashCode()
override fun toString(): String =
ReflectionObjectRenderer.renderProperty(descriptor)
ReflectionObjectRenderer.renderProperty(descriptor)
abstract class Accessor<out PropertyType, out ReturnType> :
KCallableImpl<ReturnType>(), KProperty.Accessor<PropertyType>, KFunction<ReturnType> {
KCallableImpl<ReturnType>(), KProperty.Accessor<PropertyType>, KFunction<ReturnType> {
abstract override val property: KPropertyImpl<PropertyType>
abstract override val descriptor: PropertyAccessorDescriptor
@@ -185,14 +185,14 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
fun isInsideClassCompanionObject(): Boolean {
val possibleCompanionObject = property.descriptor.containingDeclaration
return DescriptorUtils.isCompanionObject(possibleCompanionObject) &&
!DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)
!DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)
}
fun isJvmStaticProperty() =
property.descriptor.annotations.findAnnotation(JVM_STATIC) != null
property.descriptor.annotations.findAnnotation(JVM_STATIC) != null
fun isNotNullProperty() =
!TypeUtils.isNullableType(property.descriptor.type)
!TypeUtils.isNullableType(property.descriptor.type)
fun computeFieldCaller(field: Field): FunctionCaller<Field> = when {
isInsideClassCompanionObject() -> {
@@ -235,16 +235,16 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
val accessor = accessorSignature?.let { signature ->
property.container.findMethodBySignature(
jvmSignature.nameResolver.getString(signature.name),
jvmSignature.nameResolver.getString(signature.desc),
descriptor.isPublicInBytecode
jvmSignature.nameResolver.getString(signature.name),
jvmSignature.nameResolver.getString(signature.desc),
descriptor.isPublicInBytecode
)
}
when {
accessor == null -> computeFieldCaller(
property.javaField
?: throw KotlinReflectionInternalError("No accessors or field is found for property $property")
property.javaField
?: throw KotlinReflectionInternalError("No accessors or field is found for property $property")
)
!Modifier.isStatic(accessor.modifiers) ->
if (isBound) FunctionCaller.BoundInstanceMethod(accessor, property.boundReceiver)
@@ -262,12 +262,26 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
}
is JavaMethodProperty -> {
val method =
if (isGetter) jvmSignature.getterMethod
else jvmSignature.setterMethod ?: throw KotlinReflectionInternalError(
"No source found for setter of Java method property: ${jvmSignature.getterMethod}"
)
if (isGetter) jvmSignature.getterMethod
else jvmSignature.setterMethod ?: throw KotlinReflectionInternalError(
"No source found for setter of Java method property: ${jvmSignature.getterMethod}"
)
if (isBound) FunctionCaller.BoundInstanceMethod(method, property.boundReceiver)
else FunctionCaller.InstanceMethod(method)
}
is MappedKotlinProperty -> {
val signature =
if (isGetter) jvmSignature.getterSignature
else (jvmSignature.setterSignature
?: throw KotlinReflectionInternalError("No setter found for property $property"))
val accessor = property.container.findMethodBySignature(
signature.methodName, signature.methodDesc, descriptor.isPublicInBytecode
) ?: throw KotlinReflectionInternalError("No accessor found for property $property")
assert(!Modifier.isStatic(accessor.modifiers)) { "Mapped property cannot have a static accessor: $property" }
return if (isBound) FunctionCaller.BoundInstanceMethod(accessor, property.boundReceiver)
else FunctionCaller.InstanceMethod(accessor)
}
}
}

View File

@@ -36,8 +36,8 @@ import kotlin.reflect.jvm.internal.structure.primitiveByWrapper
import kotlin.reflect.jvm.jvmErasure
internal class KTypeImpl(
val type: KotlinType,
computeJavaType: () -> Type
val type: KotlinType,
computeJavaType: () -> Type
) : KType {
internal val javaType: Type by ReflectProperties.lazySoft(computeJavaType)
@@ -52,8 +52,8 @@ internal class KTypeImpl(
// There may be no argument if it's a primitive array (such as IntArray)
val argument = type.arguments.singleOrNull()?.type ?: return KClassImpl(jClass)
val elementClassifier =
convert(argument)
?: throw KotlinReflectionInternalError("Cannot determine classifier for array element type: $this")
convert(argument)
?: throw KotlinReflectionInternalError("Cannot determine classifier for array element type: $this")
return KClassImpl(elementClassifier.jvmErasure.java.createArrayType())
}
@@ -69,7 +69,7 @@ internal class KTypeImpl(
}
}
override val arguments: List<KTypeProjection> by ReflectProperties.lazySoft arguments@ {
override val arguments: List<KTypeProjection> by ReflectProperties.lazySoft arguments@{
val typeArguments = type.arguments
if (typeArguments.isEmpty()) return@arguments emptyList<KTypeProjection>()
@@ -78,8 +78,7 @@ internal class KTypeImpl(
typeArguments.mapIndexed { i, typeProjection ->
if (typeProjection.isStarProjection) {
KTypeProjection.STAR
}
else {
} else {
val type = KTypeImpl(typeProjection.type) {
val javaType = javaType
when (javaType) {
@@ -114,11 +113,11 @@ internal class KTypeImpl(
get() = type.isMarkedNullable
override fun equals(other: Any?) =
other is KTypeImpl && type == other.type
other is KTypeImpl && type == other.type
override fun hashCode() =
type.hashCode()
type.hashCode()
override fun toString() =
ReflectionObjectRenderer.renderType(type)
ReflectionObjectRenderer.renderType(type)
}

View File

@@ -45,11 +45,11 @@ internal class KTypeParameterImpl(override val descriptor: TypeParameterDescript
get() = descriptor.isReified
override fun equals(other: Any?) =
other is KTypeParameterImpl && descriptor == other.descriptor
other is KTypeParameterImpl && descriptor == other.descriptor
override fun hashCode() =
descriptor.hashCode()
descriptor.hashCode()
override fun toString() =
ReflectionObjectRenderer.renderTypeParameter(descriptor)
ReflectionObjectRenderer.renderTypeParameter(descriptor)
}

View File

@@ -21,7 +21,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;
public class ReflectProperties {
public static abstract class Val<T> {
@@ -97,33 +96,6 @@ public class ReflectProperties {
}
}
// A delegate for a lazy property on a weak reference, whose initializer may be invoked multiple times
// including simultaneously from different threads
public static class LazyWeakVal<T> extends Val<T> {
private final Function0<T> initializer;
private WeakReference<Object> value = null;
public LazyWeakVal(@NotNull Function0<T> initializer) {
this.initializer = initializer;
}
@Override
public T invoke() {
WeakReference<Object> cached = value;
if (cached != null) {
Object result = cached.get();
if (result != null) {
return unescape(result);
}
}
T result = initializer.invoke();
value = new WeakReference<Object>(escape(result));
return result;
}
}
@NotNull
public static <T> LazyVal<T> lazy(@NotNull Function0<T> initializer) {
return new LazyVal<T>(initializer);
@@ -138,9 +110,4 @@ public class ReflectProperties {
public static <T> LazySoftVal<T> lazySoft(@NotNull Function0<T> initializer) {
return lazySoft(null, initializer);
}
@NotNull
public static <T> LazyWeakVal<T> lazyWeak(@NotNull Function0<T> initializer) {
return new LazyWeakVal<T>(initializer);
}
}

View File

@@ -44,7 +44,7 @@ internal object ReflectionObjectRenderer {
if (addParentheses) append(")")
}
fun renderCallable(descriptor: CallableDescriptor): String {
private fun renderCallable(descriptor: CallableDescriptor): String {
return when (descriptor) {
is PropertyDescriptor -> renderProperty(descriptor)
is FunctionDescriptor -> renderFunction(descriptor)
@@ -108,7 +108,8 @@ internal object ReflectionObjectRenderer {
fun renderTypeParameter(typeParameter: TypeParameterDescriptor): String {
return buildString {
when (typeParameter.variance) {
Variance.INVARIANT -> {}
Variance.INVARIANT -> {
}
Variance.IN_VARIANCE -> append("in ")
Variance.OUT_VARIANCE -> append("out ")
}

View File

@@ -18,16 +18,15 @@ package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.descriptors.JavaClassConstructorDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.load.java.getJvmMethodNameIfSpecial
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.metadata.deserialization.TypeTable
@@ -39,14 +38,15 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.NameUtils
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.propertyIfAccessor
import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
import java.lang.reflect.Constructor
import java.lang.reflect.Field
import java.lang.reflect.Member
import java.lang.reflect.Method
import kotlin.reflect.jvm.internal.structure.*
@@ -76,7 +76,7 @@ internal sealed class JvmFunctionSignature {
class JavaConstructor(val constructor: Constructor<*>) : JvmFunctionSignature() {
override fun asString(): String =
constructor.parameterTypes.joinToString(separator = "", prefix = "<init>(", postfix = ")V") { it.desc }
constructor.parameterTypes.joinToString(separator = "", prefix = "<init>(", postfix = ")V") { it.desc }
}
class FakeJavaAnnotationConstructor(val jClass: Class<*>) : JvmFunctionSignature() {
@@ -84,17 +84,7 @@ internal sealed class JvmFunctionSignature {
val methods = jClass.declaredMethods.sortedBy { it.name }
override fun asString(): String =
methods.joinToString(separator = "", prefix = "<init>(", postfix = ")V") { it.returnType.desc }
}
open class BuiltInFunction(private val signature: String) : JvmFunctionSignature() {
open fun getMember(container: KDeclarationContainerImpl): Member? = null
override fun asString(): String = signature
class Predefined(signature: String, private val member: Member): BuiltInFunction(signature) {
override fun getMember(container: KDeclarationContainerImpl): Member = member
}
methods.joinToString(separator = "", prefix = "<init>(", postfix = ")V") { it.returnType.desc }
}
}
@@ -106,19 +96,18 @@ internal sealed class JvmPropertySignature {
abstract fun asString(): String
class KotlinProperty(
val descriptor: PropertyDescriptor,
val proto: ProtoBuf.Property,
val signature: JvmProtoBuf.JvmPropertySignature,
val nameResolver: NameResolver,
val typeTable: TypeTable
val descriptor: PropertyDescriptor,
val proto: ProtoBuf.Property,
val signature: JvmProtoBuf.JvmPropertySignature,
val nameResolver: NameResolver,
val typeTable: TypeTable
) : JvmPropertySignature() {
private val string: String = if (signature.hasGetter()) {
nameResolver.getString(signature.getter.name) + nameResolver.getString(signature.getter.desc)
}
else {
} else {
val (name, desc) =
JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable) ?:
throw KotlinReflectionInternalError("No field signature for property: $descriptor")
JvmProtoBufUtil.getJvmFieldSignature(proto, nameResolver, typeTable)
?: throw KotlinReflectionInternalError("No field signature for property: $descriptor")
JvmAbi.getterName(name) + getManglingSuffix() + "()" + desc
}
@@ -149,9 +138,14 @@ internal sealed class JvmPropertySignature {
class JavaField(val field: Field) : JvmPropertySignature() {
override fun asString(): String =
JvmAbi.getterName(field.name) +
"()" +
field.type.desc
JvmAbi.getterName(field.name) + "()" + field.type.desc
}
class MappedKotlinProperty(
val getterSignature: JvmFunctionSignature.KotlinFunction,
val setterSignature: JvmFunctionSignature.KotlinFunction?
) : JvmPropertySignature() {
override fun asString(): String = getterSignature.asString()
}
}
@@ -170,10 +164,6 @@ internal object RuntimeTypeMapper {
when (function) {
is DeserializedCallableMemberDescriptor -> {
mapIntrinsicFunctionSignature(function)?.let {
return it
}
val proto = function.proto
if (proto is ProtoBuf.Function) {
JvmProtoBufUtil.getJvmMethodSignature(proto, function.nameResolver, function.typeTable)?.let { signature ->
@@ -185,13 +175,11 @@ internal object RuntimeTypeMapper {
return JvmFunctionSignature.KotlinConstructor(signature)
}
}
// If it's a deserialized function but has no JVM signature, it must be from built-ins
throw KotlinReflectionInternalError("Reflection on built-in Kotlin types is not yet fully supported. " +
"No metadata found for $function")
return mapJvmFunctionSignature(function)
}
is JavaMethodDescriptor -> {
val method = ((function.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member ?:
throw KotlinReflectionInternalError("Incorrect resolution sequence for Java method $function")
val method = ((function.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member
?: throw KotlinReflectionInternalError("Incorrect resolution sequence for Java method $function")
return JvmFunctionSignature.JavaMethod(method)
}
@@ -205,61 +193,56 @@ internal object RuntimeTypeMapper {
else -> throw KotlinReflectionInternalError("Incorrect resolution sequence for Java constructor $function ($element)")
}
}
else -> throw KotlinReflectionInternalError("Unknown origin of $function (${function.javaClass})")
}
if (DescriptorFactory.isEnumValueOfMethod(function) || DescriptorFactory.isEnumValuesMethod(function)) {
return mapJvmFunctionSignature(function)
}
throw KotlinReflectionInternalError("Unknown origin of $function (${function.javaClass})")
}
fun mapPropertySignature(possiblyOverriddenProperty: PropertyDescriptor): JvmPropertySignature {
val property = DescriptorUtils.unwrapFakeOverride(possiblyOverriddenProperty).original
return when (property) {
when (property) {
is DeserializedPropertyDescriptor -> {
val proto = property.proto
val signature = proto.getExtensionOrNull(JvmProtoBuf.propertySignature)
?: // If this property has no JVM signature, it must be from built-ins
throw KotlinReflectionInternalError(
"Reflection on built-in Kotlin types is not yet fully supported. No metadata found for $property"
)
JvmPropertySignature.KotlinProperty(property, proto, signature, property.nameResolver, property.typeTable)
if (signature != null) {
return JvmPropertySignature.KotlinProperty(property, proto, signature, property.nameResolver, property.typeTable)
}
}
is JavaPropertyDescriptor -> {
val element = (property.source as? JavaSourceElement)?.javaElement
when (element) {
return when (element) {
is ReflectJavaField -> JvmPropertySignature.JavaField(element.member)
is ReflectJavaMethod -> JvmPropertySignature.JavaMethodProperty(
element.member,
((property.setter?.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member
element.member,
((property.setter?.source as? JavaSourceElement)?.javaElement as? ReflectJavaMethod)?.member
)
else -> throw KotlinReflectionInternalError("Incorrect resolution sequence for Java field $property (source = $element)")
}
}
else -> {
throw KotlinReflectionInternalError("Unknown origin of $property (${property.javaClass})")
}
}
}
private fun mapIntrinsicFunctionSignature(function: FunctionDescriptor): JvmFunctionSignature? {
val parameters = function.valueParameters
when (function.name.asString()) {
"equals" -> if (parameters.size == 1 && KotlinBuiltIns.isNullableAny(parameters.single().type)) {
return JvmFunctionSignature.BuiltInFunction.Predefined("equals(Ljava/lang/Object;)Z",
Any::class.java.getDeclaredMethod("equals", Any::class.java))
}
"hashCode" -> if (parameters.isEmpty()) {
return JvmFunctionSignature.BuiltInFunction.Predefined("hashCode()I",
Any::class.java.getDeclaredMethod("hashCode"))
}
"toString" -> if (parameters.isEmpty()) {
return JvmFunctionSignature.BuiltInFunction.Predefined("toString()Ljava/lang/String;",
Any::class.java.getDeclaredMethod("toString"))
}
// TODO: generalize and support other functions from built-ins
}
return null
return JvmPropertySignature.MappedKotlinProperty(
property.getter!!.let(this::mapJvmFunctionSignature),
property.setter?.let(this::mapJvmFunctionSignature)
)
}
private fun mapJvmFunctionSignature(descriptor: FunctionDescriptor): JvmFunctionSignature.KotlinFunction =
JvmFunctionSignature.KotlinFunction(
JvmMemberSignature.Method(mapName(descriptor), descriptor.computeJvmDescriptor(withName = false))
)
private fun mapName(descriptor: CallableMemberDescriptor): String =
getJvmMethodNameIfSpecial(descriptor) ?: when (descriptor) {
is PropertyGetterDescriptor -> JvmAbi.getterName(descriptor.propertyIfAccessor.name.asString())
is PropertySetterDescriptor -> JvmAbi.setterName(descriptor.propertyIfAccessor.name.asString())
else -> descriptor.name.asString()
}
fun mapJvmClassToKotlinClassId(klass: Class<*>): ClassId {
if (klass.isArray) {
klass.componentType.primitiveType?.let {

View File

@@ -36,8 +36,7 @@ internal fun <T : Any> getOrCreateKotlinClass(jClass: Class<T>): KClassImpl<T> {
if (kClass?.jClass == jClass) {
return kClass
}
}
else if (cached != null) {
} else if (cached != null) {
// If the cached value is not a weak reference, it's an array of weak references
@Suppress("UNCHECKED_CAST")
(cached as Array<WeakReference<KClassImpl<T>>>)

View File

@@ -35,13 +35,13 @@ private class WeakClassLoaderBox(classLoader: ClassLoader) {
var temporaryStrongRef: ClassLoader? = classLoader
override fun equals(other: Any?) =
other is WeakClassLoaderBox && ref.get() === other.ref.get()
other is WeakClassLoaderBox && ref.get() === other.ref.get()
override fun hashCode() =
identityHashCode
identityHashCode
override fun toString() =
ref.get()?.toString() ?: "<null>"
ref.get()?.toString() ?: "<null>"
}
internal fun Class<*>.getOrCreateModule(): RuntimeModuleData {
@@ -58,15 +58,13 @@ internal fun Class<*>.getOrCreateModule(): RuntimeModuleData {
val module = RuntimeModuleData.create(classLoader)
try {
while (true) {
val ref = moduleByClassLoader.putIfAbsent(key, WeakReference(module))
if (ref == null) return module
val ref = moduleByClassLoader.putIfAbsent(key, WeakReference(module)) ?: return module
val result = ref.get()
if (result != null) return result
moduleByClassLoader.remove(key, ref)
}
}
finally {
} finally {
key.temporaryStrongRef = null
}
}

View File

@@ -91,43 +91,40 @@ internal fun loadClass(classLoader: ClassLoader, packageName: String, className:
}
internal fun Visibility.toKVisibility(): KVisibility? =
when (this) {
Visibilities.PUBLIC -> KVisibility.PUBLIC
Visibilities.PROTECTED -> KVisibility.PROTECTED
Visibilities.INTERNAL -> KVisibility.INTERNAL
Visibilities.PRIVATE, Visibilities.PRIVATE_TO_THIS -> KVisibility.PRIVATE
else -> null
}
when (this) {
Visibilities.PUBLIC -> KVisibility.PUBLIC
Visibilities.PROTECTED -> KVisibility.PROTECTED
Visibilities.INTERNAL -> KVisibility.INTERNAL
Visibilities.PRIVATE, Visibilities.PRIVATE_TO_THIS -> KVisibility.PRIVATE
else -> null
}
internal fun Annotated.computeAnnotations(): List<Annotation> =
annotations.mapNotNull {
val source = it.source
when (source) {
is ReflectAnnotationSource -> source.annotation
is RuntimeSourceElementFactory.RuntimeSourceElement -> (source.javaElement as? ReflectJavaAnnotation)?.annotation
else -> null
}
annotations.mapNotNull {
val source = it.source
when (source) {
is ReflectAnnotationSource -> source.annotation
is RuntimeSourceElementFactory.RuntimeSourceElement -> (source.javaElement as? ReflectJavaAnnotation)?.annotation
else -> null
}
}
// TODO: wrap other exceptions
internal inline fun <R> reflectionCall(block: () -> R): R =
try {
block()
}
catch (e: IllegalAccessException) {
throw IllegalCallableAccessException(e)
}
try {
block()
} catch (e: IllegalAccessException) {
throw IllegalCallableAccessException(e)
}
internal fun Any?.asKFunctionImpl(): KFunctionImpl? =
this as? KFunctionImpl ?:
(this as? FunctionReference)?.compute() as? KFunctionImpl
this as? KFunctionImpl ?: (this as? FunctionReference)?.compute() as? KFunctionImpl
internal fun Any?.asKPropertyImpl(): KPropertyImpl<*>? =
this as? KPropertyImpl<*> ?:
(this as? PropertyReference)?.compute() as? KPropertyImpl
this as? KPropertyImpl<*> ?: (this as? PropertyReference)?.compute() as? KPropertyImpl
internal fun Any?.asKCallableImpl(): KCallableImpl<*>? =
this as? KCallableImpl<*> ?: asKFunctionImpl() ?: asKPropertyImpl()
this as? KCallableImpl<*> ?: asKFunctionImpl() ?: asKPropertyImpl()
internal val ReflectKotlinClass.packageModuleName: String?
get() {
@@ -157,11 +154,11 @@ internal val CallableMemberDescriptor.isPublicInBytecode: Boolean
}
internal fun <M : MessageLite, D : CallableDescriptor> deserializeToDescriptor(
moduleAnchor: Class<*>,
proto: M,
nameResolver: NameResolver,
typeTable: TypeTable,
createDescriptor: MemberDeserializer.(M) -> D
moduleAnchor: Class<*>,
proto: M,
nameResolver: NameResolver,
typeTable: TypeTable,
createDescriptor: MemberDeserializer.(M) -> D
): D? {
val moduleData = moduleAnchor.getOrCreateModule()
@@ -172,8 +169,8 @@ internal fun <M : MessageLite, D : CallableDescriptor> deserializeToDescriptor(
}
val context = DeserializationContext(
moduleData.deserialization, nameResolver, moduleData.module, typeTable, VersionRequirementTable.EMPTY,
containerSource = null, parentTypeDeserializer = null, typeParameters = typeParameters
moduleData.deserialization, nameResolver, moduleData.module, typeTable, VersionRequirementTable.EMPTY,
containerSource = null, parentTypeDeserializer = null, typeParameters = typeParameters
)
return MemberDeserializer(context).createDescriptor(proto)
}

View File

@@ -37,7 +37,7 @@ fun <R> Function<R>.reflect(): KFunction<R>? {
val (nameResolver, proto) = JvmProtoBufUtil.readFunctionDataFrom(data, annotation.d2)
val descriptor = deserializeToDescriptor(javaClass, proto, nameResolver, TypeTable(proto.typeTable), MemberDeserializer::loadFunction)
?: return null
?: return null
@Suppress("UNCHECKED_CAST")
return KFunctionImpl(EmptyContainerForLocal, descriptor) as KFunction<R>

View File

@@ -677,8 +677,8 @@ fun main(args: Array<String>) {
model("refactoring/introduceJavaParameter", extension = "java", testMethod = "doIntroduceJavaParameterTest")
model("refactoring/introduceTypeParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeParameterTest")
model("refactoring/introduceTypeAlias", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeAliasTest")
model("refactoring/extractSuperclass", pattern = KT_OR_KTS, testMethod = "doExtractSuperclassTest")
model("refactoring/extractInterface", pattern = KT_OR_KTS, testMethod = "doExtractInterfaceTest")
model("refactoring/extractSuperclass", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractSuperclassTest")
model("refactoring/extractInterface", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractInterfaceTest")
}
testClass<AbstractPullUpTest> {

View File

@@ -675,8 +675,8 @@ fun main(args: Array<String>) {
model("refactoring/introduceJavaParameter", extension = "java", testMethod = "doIntroduceJavaParameterTest")
model("refactoring/introduceTypeParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeParameterTest")
model("refactoring/introduceTypeAlias", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeAliasTest")
model("refactoring/extractSuperclass", pattern = KT_OR_KTS, testMethod = "doExtractSuperclassTest")
model("refactoring/extractInterface", pattern = KT_OR_KTS, testMethod = "doExtractInterfaceTest")
model("refactoring/extractSuperclass", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractSuperclassTest")
model("refactoring/extractInterface", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractInterfaceTest")
}
testClass<AbstractPullUpTest> {

View File

@@ -673,8 +673,8 @@ fun main(args: Array<String>) {
model("refactoring/introduceJavaParameter", extension = "java", testMethod = "doIntroduceJavaParameterTest")
model("refactoring/introduceTypeParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeParameterTest")
model("refactoring/introduceTypeAlias", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeAliasTest")
model("refactoring/extractSuperclass", pattern = KT_OR_KTS, testMethod = "doExtractSuperclassTest")
model("refactoring/extractInterface", pattern = KT_OR_KTS, testMethod = "doExtractInterfaceTest")
model("refactoring/extractSuperclass", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractSuperclassTest")
model("refactoring/extractInterface", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractInterfaceTest")
}
testClass<AbstractPullUpTest> {

View File

@@ -673,8 +673,8 @@ fun main(args: Array<String>) {
model("refactoring/introduceJavaParameter", extension = "java", testMethod = "doIntroduceJavaParameterTest")
model("refactoring/introduceTypeParameter", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeParameterTest")
model("refactoring/introduceTypeAlias", pattern = KT_OR_KTS, testMethod = "doIntroduceTypeAliasTest")
model("refactoring/extractSuperclass", pattern = KT_OR_KTS, testMethod = "doExtractSuperclassTest")
model("refactoring/extractInterface", pattern = KT_OR_KTS, testMethod = "doExtractInterfaceTest")
model("refactoring/extractSuperclass", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractSuperclassTest")
model("refactoring/extractInterface", pattern = KT_OR_KTS_WITHOUT_DOTS_IN_NAME, testMethod = "doExtractInterfaceTest")
}
testClass<AbstractPullUpTest> {

File diff suppressed because it is too large Load Diff

View File

@@ -24,6 +24,7 @@ import com.intellij.psi.search.SearchRequestCollector
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.UsageSearchContext
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.util.containers.nullize
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.elements.KtLightField
import org.jetbrains.kotlin.asJava.elements.KtLightMember
@@ -36,23 +37,30 @@ import org.jetbrains.kotlin.compatibility.ExecutorProcessor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
import org.jetbrains.kotlin.idea.search.*
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions.Companion.Empty
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
import org.jetbrains.kotlin.idea.search.usagesSearch.getClassNameForCompanionObject
import org.jetbrains.kotlin.idea.search.usagesSearch.operators.OperatorReferenceSearcher
import org.jetbrains.kotlin.idea.stubindex.KotlinSourceFilterScope
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.idea.util.expectedDeclarationIfAny
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier
import org.jetbrains.kotlin.psi.psiUtil.parents
import java.util.*
data class KotlinReferencesSearchOptions(val acceptCallableOverrides: Boolean = false,
val acceptOverloads: Boolean = false,
val acceptExtensionsOfDeclarationClass: Boolean = false,
val acceptCompanionObjectMembers: Boolean = false,
val searchForComponentConventions: Boolean = true,
val searchForOperatorConventions: Boolean = true,
val searchNamedArguments: Boolean = true) {
data class KotlinReferencesSearchOptions(
val acceptCallableOverrides: Boolean = false,
val acceptOverloads: Boolean = false,
val acceptExtensionsOfDeclarationClass: Boolean = false,
val acceptCompanionObjectMembers: Boolean = false,
val searchForComponentConventions: Boolean = true,
val searchForOperatorConventions: Boolean = true,
val searchNamedArguments: Boolean = true,
val searchForExpectedUsages: Boolean = true
) {
fun anyEnabled(): Boolean = acceptCallableOverrides || acceptOverloads || acceptExtensionsOfDeclarationClass
companion object {
@@ -61,12 +69,12 @@ data class KotlinReferencesSearchOptions(val acceptCallableOverrides: Boolean =
}
class KotlinReferencesSearchParameters(
elementToSearch: PsiElement,
scope: SearchScope = runReadAction { elementToSearch.project.allScope() },
ignoreAccessScope: Boolean = false,
optimizer: SearchRequestCollector? = null,
val kotlinOptions: KotlinReferencesSearchOptions = KotlinReferencesSearchOptions.Empty)
: ReferencesSearch.SearchParameters(elementToSearch, scope, ignoreAccessScope, optimizer)
elementToSearch: PsiElement,
scope: SearchScope = runReadAction { elementToSearch.project.allScope() },
ignoreAccessScope: Boolean = false,
optimizer: SearchRequestCollector? = null,
val kotlinOptions: KotlinReferencesSearchOptions = Empty
) : ReferencesSearch.SearchParameters(elementToSearch, scope, ignoreAccessScope, optimizer)
class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters>() {
override fun processQuery(queryParameters: ReferencesSearch.SearchParameters, consumer: ExecutorProcessor<PsiReference>) {
@@ -77,8 +85,7 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
private class QueryProcessor(val queryParameters: ReferencesSearch.SearchParameters, val consumer: ExecutorProcessor<PsiReference>) {
private val kotlinOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions
?: KotlinReferencesSearchOptions.Empty
private val kotlinOptions = (queryParameters as? KotlinReferencesSearchParameters)?.kotlinOptions ?: Empty
private val longTasks = ArrayList<() -> Unit>()
@@ -92,52 +99,62 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
val unwrappedElement = element.namedUnwrappedElement ?: return
val elementToSearch =
if (kotlinOptions.searchForExpectedUsages && unwrappedElement is KtDeclaration && unwrappedElement.hasActualModifier()) {
unwrappedElement.expectedDeclarationIfAny() as? PsiNamedElement
} else {
null
} ?: unwrappedElement
val effectiveSearchScope = run {
val elements = if (unwrappedElement is KtDeclaration && !isOnlyKotlinSearch(queryParameters.scopeDeterminedByUser)) {
unwrappedElement.toLightElements()
}
else {
listOf(unwrappedElement)
}
val elements = if (elementToSearch is KtDeclaration && !isOnlyKotlinSearch(queryParameters.scopeDeterminedByUser)) {
elementToSearch.toLightElements().nullize()
} else {
null
} ?: listOf(elementToSearch)
elements.fold(queryParameters.effectiveSearchScope) { scope, e ->
scope.unionSafe(queryParameters.effectiveSearchScope(e))
}
}
val refFilter: (PsiReference) -> Boolean = when (unwrappedElement) {
val refFilter: (PsiReference) -> Boolean = when (elementToSearch) {
is KtParameter -> ({ ref: PsiReference -> !ref.isNamedArgumentReference()/* they are processed later*/ })
else -> ({ true })
}
val resultProcessor = KotlinRequestResultProcessor(unwrappedElement, filter = refFilter, options = kotlinOptions)
val resultProcessor = KotlinRequestResultProcessor(elementToSearch, filter = refFilter, options = kotlinOptions)
val name = unwrappedElement.name
if (kotlinOptions.anyEnabled()) {
val name = elementToSearch.name
if (kotlinOptions.anyEnabled() || elementToSearch is KtNamedDeclaration && elementToSearch.isExpectDeclaration()) {
if (name != null) {
// Check difference with default scope
queryParameters.optimizer.searchWord(
name, effectiveSearchScope, UsageSearchContext.IN_CODE, true, unwrappedElement, resultProcessor)
name, effectiveSearchScope, UsageSearchContext.IN_CODE, true, elementToSearch, resultProcessor
)
}
}
val classNameForCompanionObject = unwrappedElement.getClassNameForCompanionObject()
val classNameForCompanionObject = elementToSearch.getClassNameForCompanionObject()
if (classNameForCompanionObject != null) {
queryParameters.optimizer.searchWord(
classNameForCompanionObject, effectiveSearchScope, UsageSearchContext.ANY, true, unwrappedElement, resultProcessor)
classNameForCompanionObject, effectiveSearchScope, UsageSearchContext.ANY, true, elementToSearch, resultProcessor
)
}
if (unwrappedElement is KtParameter && kotlinOptions.searchNamedArguments) {
searchNamedArguments(unwrappedElement)
if (elementToSearch is KtParameter && kotlinOptions.searchNamedArguments) {
searchNamedArguments(elementToSearch)
}
if (!(unwrappedElement is KtElement && isOnlyKotlinSearch(effectiveSearchScope))) {
if (!(elementToSearch is KtElement && isOnlyKotlinSearch(effectiveSearchScope))) {
searchLightElements(element)
}
if (element is KtFunction || element is PsiMethod) {
val referenceSearcher = OperatorReferenceSearcher.create(
element, effectiveSearchScope, consumer, queryParameters.optimizer, kotlinOptions)
element, effectiveSearchScope, consumer, queryParameters.optimizer, kotlinOptions
)
if (referenceSearcher != null) {
longTasks.add { referenceSearcher.run() }
}
@@ -174,17 +191,20 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
namedArgsScope = KotlinSourceFilterScope.sourcesAndLibraries(namedArgsScope, project)
val filesWithFunctionName = CacheManager.SERVICE.getInstance(project).getVirtualFilesWithWord(
function.name!!, UsageSearchContext.IN_CODE, namedArgsScope, true)
function.name!!, UsageSearchContext.IN_CODE, namedArgsScope, true
)
namedArgsScope = GlobalSearchScope.filesScope(project, filesWithFunctionName.asList())
}
val processor = KotlinRequestResultProcessor(parameter, filter = { it.isNamedArgumentReference() })
queryParameters.optimizer.searchWord(parameterName,
namedArgsScope,
KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT,
true,
parameter,
processor)
queryParameters.optimizer.searchWord(
parameterName,
namedArgsScope,
KOTLIN_NAMED_ARGUMENT_SEARCH_CONTEXT,
true,
parameter,
processor
)
}
private fun searchLightElements(element: PsiElement) {
@@ -220,12 +240,10 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
if (declaration is KtProperty || (declaration is KtParameter && declaration.hasValOrVar())) {
searchNamedElement(declaration as PsiNamedElement)
processStaticsFromCompanionObject(declaration)
}
else if (declaration is KtPropertyAccessor) {
} else if (declaration is KtPropertyAccessor) {
val property = declaration.getStrictParentOfType<KtProperty>()
searchNamedElement(property)
}
else if (declaration is KtFunction) {
} else if (declaration is KtFunction) {
processStaticsFromCompanionObject(declaration)
if (element.isMangled) {
searchNamedElement(declaration) { it.restrictToKotlinSources() }
@@ -256,22 +274,22 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
val originLightClass = element.getStrictParentOfType<KtClass>()?.toLightClass()
if (originLightClass != null) {
val lightDeclarations: List<KtLightMember<*>?> =
originLightClass.methods.map { it as? KtLightMethod } +
originLightClass.fields.map { it as? KtLightField }
originLightClass.methods.map { it as? KtLightMethod } + originLightClass.fields.map { it as? KtLightField }
for (declaration in element.declarations) {
lightDeclarations
.firstOrNull { it?.kotlinOrigin == declaration }
?.let { searchNamedElement(it) }
.firstOrNull { it?.kotlinOrigin == declaration }
?.let { searchNamedElement(it) }
}
}
}
}
}
private fun searchDataClassComponentUsages(containingClass: PsiClass?,
componentFunctionDescriptor: FunctionDescriptor,
kotlinOptions: KotlinReferencesSearchOptions
private fun searchDataClassComponentUsages(
containingClass: PsiClass?,
componentFunctionDescriptor: FunctionDescriptor,
kotlinOptions: KotlinReferencesSearchOptions
) {
val componentFunction = containingClass?.methods?.firstOrNull {
it.name == componentFunctionDescriptor.name.asString() && it.parameterList.parametersCount == 0
@@ -280,7 +298,8 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
searchNamedElement(componentFunction)
val searcher = OperatorReferenceSearcher.create(
componentFunction, queryParameters.effectiveSearchScope, consumer, queryParameters.optimizer, kotlinOptions)
componentFunction, queryParameters.effectiveSearchScope, consumer, queryParameters.optimizer, kotlinOptions
)
longTasks.add { searcher!!.run() }
}
}
@@ -291,8 +310,8 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
private fun findStaticMethodsFromCompanionObject(declaration: KtDeclaration): List<PsiMethod> {
val originObject = declaration.parents
.dropWhile { it is KtClassBody }
.firstOrNull() as? KtObjectDeclaration ?: return emptyList()
.dropWhile { it is KtClassBody }
.firstOrNull() as? KtObjectDeclaration ?: return emptyList()
if (!originObject.isCompanion()) return emptyList()
val originClass = originObject.getStrictParentOfType<KtClass>()
val originLightClass = originClass?.toLightClass() ?: return emptyList()
@@ -309,9 +328,11 @@ class KotlinReferencesSearcher : QueryExecutorBase<PsiReference, ReferencesSearc
val baseScope = queryParameters.effectiveSearchScope(element)
val scope = if (modifyScope != null) modifyScope(baseScope) else baseScope
val context = UsageSearchContext.IN_CODE + UsageSearchContext.IN_FOREIGN_LANGUAGES + UsageSearchContext.IN_COMMENTS
val resultProcessor = KotlinRequestResultProcessor(element,
queryParameters.elementToSearch.namedUnwrappedElement ?: element,
options = kotlinOptions)
val resultProcessor = KotlinRequestResultProcessor(
element,
queryParameters.elementToSearch.namedUnwrappedElement ?: element,
options = kotlinOptions
)
queryParameters.optimizer.searchWord(name, scope, context.toShort(), true, element, resultProcessor)
}
}

View File

@@ -0,0 +1,80 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
kotlin("jvm")
id("jps-compatible")
}
dependencies {
testRuntime(intellijDep())
compileOnly(project(":kotlin-reflect-api"))
compile(project(":compiler:util"))
compile(project(":compiler:light-classes"))
compile(project(":compiler:frontend"))
compile(project(":compiler:frontend.java"))
compile(project(":idea"))
compile(project(":idea:idea-jvm"))
compile(project(":idea:idea-core"))
compile(project(":idea:ide-common"))
compile(project(":idea:idea-gradle"))
compile(androidDxJar())
compileOnly(project(":kotlin-android-extensions-runtime"))
compileOnly(intellijDep())
compileOnly(intellijPluginDep("android"))
testCompile(projectDist(":kotlin-test:kotlin-test-jvm"))
testCompile(projectTests(":idea:idea-test-framework")) { isTransitive = false }
testCompile(project(":plugins:lint")) { isTransitive = false }
testCompile(project(":idea:idea-jvm"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(projectTests(":idea"))
testCompile(projectTests(":idea:idea-gradle"))
testCompile(commonDep("junit:junit"))
testCompile(intellijDep())
testCompile(intellijPluginDep("properties"))
testCompileOnly(intellijPluginDep("android"))
testRuntime(projectDist(":kotlin-reflect"))
testRuntime(project(":plugins:android-extensions-ide"))
testRuntime(project(":plugins:kapt3-idea"))
testRuntime(project(":sam-with-receiver-ide-plugin"))
testRuntime(project(":noarg-ide-plugin"))
testRuntime(project(":allopen-ide-plugin"))
testRuntime(project(":kotlin-scripting-idea"))
testRuntime(intellijPluginDep("android"))
testRuntime(intellijPluginDep("smali"))
testRuntime(intellijPluginDep("copyright"))
testRuntime(intellijPluginDep("coverage"))
testRuntime(intellijPluginDep("gradle"))
testRuntime(intellijPluginDep("Groovy"))
testRuntime(intellijPluginDep("IntelliLang"))
testRuntime(intellijPluginDep("java-decompiler"))
testRuntime(intellijPluginDep("java-i18n"))
testRuntime(intellijPluginDep("junit"))
//testRuntime(intellijPluginDep("maven"))
testRuntime(intellijPluginDep("testng"))
}
sourceSets {
"main" {}
"test" {}
}
projectTest {
workingDir = rootDir
useAndroidSdk()
}
testsJar {}
runtimeJar {
archiveName = "android-ide.jar"
}
ideaPlugin()

View File

@@ -0,0 +1,25 @@
plugins {
kotlin("jvm")
}
apply { plugin("jps-compatible") }
dependencies {
compile(project(":compiler:util"))
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
compileOnly(intellijDep())
compileOnly(intellijPluginDep("gradle"))
compileOnly(intellijPluginDep("android"))
}
sourceSets {
"main" {}
"test" {}
}
runtimeJar {
archiveName = "android-output-parser-ide.jar"
}
ideaPlugin()

View File

@@ -791,13 +791,13 @@ class MultiplatformProjectImportingTest : GradleImportingTestCase() {
importProject()
assertModuleModuleDepScope("app", "cmn", DependencyScope.COMPILE)
TestCase.assertEquals(listOf("cmn"), facetSettings("app").implementedModuleNames)
TestCase.assertEquals(listOf("cmn"), facetSettings("jvm").implementedModuleNames)
currentExternalProjectSettings.isResolveModulePerSourceSet = false
importProject()
assertModuleModuleDepScope("app", "cmn", DependencyScope.COMPILE)
TestCase.assertEquals(listOf("cmn"), facetSettings("app").implementedModuleNames)
TestCase.assertEquals(listOf("cmn"), facetSettings("jvm").implementedModuleNames)
} finally {
currentExternalProjectSettings.isResolveModulePerSourceSet = isResolveModulePerSourceSet
}

View File

@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.idea.framework.effectiveKind
import org.jetbrains.kotlin.idea.quickfix.KotlinAddRequiredModuleFix
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.idea.util.findFirstPsiJavaModule
import org.jetbrains.kotlin.idea.util.isDev
import org.jetbrains.kotlin.idea.util.isEap
import org.jetbrains.kotlin.idea.util.projectStructure.allModules
import org.jetbrains.kotlin.idea.util.projectStructure.sdk
import org.jetbrains.kotlin.idea.util.projectStructure.version
@@ -47,33 +49,35 @@ data class RepositoryDescription(val id: String, val name: String, val url: Stri
const val LAST_SNAPSHOT_VERSION = "1.2-SNAPSHOT"
val SNAPSHOT_REPOSITORY = RepositoryDescription(
"sonatype.oss.snapshots",
"Sonatype OSS Snapshot Repository",
"http://oss.sonatype.org/content/repositories/snapshots",
null,
isSnapshot = true)
"sonatype.oss.snapshots",
"Sonatype OSS Snapshot Repository",
"http://oss.sonatype.org/content/repositories/snapshots",
null,
isSnapshot = true
)
val EAP_REPOSITORY = RepositoryDescription(
"bintray.kotlin.eap",
"Bintray Kotlin EAP Repository",
"http://dl.bintray.com/kotlin/kotlin-eap",
"https://bintray.com/kotlin/kotlin-eap/kotlin/",
isSnapshot = false)
"bintray.kotlin.eap",
"Bintray Kotlin EAP Repository",
"http://dl.bintray.com/kotlin/kotlin-eap",
"https://bintray.com/kotlin/kotlin-eap/kotlin/",
isSnapshot = false
)
val DEFAULT_GRADLE_PLUGIN_REPOSITORY = RepositoryDescription(
"default.gradle.plugins",
"Default Gradle Plugin Repository",
"https://plugins.gradle.org/m2/",
null,
isSnapshot = false
"default.gradle.plugins",
"Default Gradle Plugin Repository",
"https://plugins.gradle.org/m2/",
null,
isSnapshot = false
)
fun devRepository(version: String) = RepositoryDescription(
"teamcity.kotlin.dev",
"Teamcity Repository of Kotlin Development Builds",
"https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:$version,branch:default:any/artifacts/content/maven/",
null,
isSnapshot = false
"teamcity.kotlin.dev",
"Teamcity Repository of Kotlin Development Builds",
"https://teamcity.jetbrains.com/guestAuth/app/rest/builds/buildType:(id:Kotlin_dev_Compiler),number:$version,branch:default:any/artifacts/content/maven/",
null,
isSnapshot = false
)
val MAVEN_CENTRAL = "mavenCentral()"
@@ -83,7 +87,7 @@ val JCENTER = "jcenter()"
val KOTLIN_GROUP_ID = "org.jetbrains.kotlin"
fun isRepositoryConfigured(repositoriesBlockText: String): Boolean =
repositoriesBlockText.contains(MAVEN_CENTRAL) || repositoriesBlockText.contains(JCENTER)
repositoriesBlockText.contains(MAVEN_CENTRAL) || repositoriesBlockText.contains(JCENTER)
fun DependencyScope.toGradleCompileScope(isAndroidModule: Boolean) = when (this) {
DependencyScope.COMPILE -> "compile"
@@ -117,17 +121,19 @@ fun isModuleConfigured(moduleSourceRootGroup: ModuleSourceRootGroup): Boolean {
*/
fun getModulesWithKotlinFiles(project: Project): Collection<Module> {
if (!runReadAction {
!project.isDisposed && FileTypeIndex.containsFileOfType (KotlinFileType.INSTANCE, GlobalSearchScope.projectScope(project))
}) {
!project.isDisposed &&
FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, GlobalSearchScope.projectScope(project))
}) {
return emptyList()
}
return project.allModules()
.filter { module ->
runReadAction {
!project.isDisposed && FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, module.getModuleScope(true))
}
.filter { module ->
runReadAction {
!project.isDisposed && !module.isDisposed
FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, module.getModuleScope(true))
}
}
}
/**
@@ -193,13 +199,13 @@ fun allConfigurators() = Extensions.getExtensions(KotlinProjectConfigurator.EP_N
fun getCanBeConfiguredModules(project: Project, configurator: KotlinProjectConfigurator): List<Module> {
return ModuleSourceRootMap(project).groupByBaseModules(project.allModules())
.filter { configurator.canConfigure(it) }
.map { it.baseModule }
.filter { configurator.canConfigure(it) }
.map { it.baseModule }
}
private fun KotlinProjectConfigurator.canConfigure(moduleSourceRootGroup: ModuleSourceRootGroup) =
getStatus(moduleSourceRootGroup) == ConfigureKotlinStatus.CAN_BE_CONFIGURED &&
(allConfigurators().toList() - this).none { it.getStatus(moduleSourceRootGroup) == ConfigureKotlinStatus.CONFIGURED }
getStatus(moduleSourceRootGroup) == ConfigureKotlinStatus.CAN_BE_CONFIGURED &&
(allConfigurators().toList() - this).none { it.getStatus(moduleSourceRootGroup) == ConfigureKotlinStatus.CONFIGURED }
/**
* Returns a list of modules which contain sources in Kotlin and for which it's possible to run the given configurator.
@@ -236,7 +242,10 @@ fun getConfigurationPossibilitiesForConfigureNotification(
ConfigureKotlinStatus.CONFIGURED -> moduleAlreadyConfigured = true
}
}
if (moduleCanBeConfigured && !moduleAlreadyConfigured && !SuppressNotificationState.isKotlinNotConfiguredSuppressed(moduleSourceRootGroup))
if (moduleCanBeConfigured && !moduleAlreadyConfigured && !SuppressNotificationState.isKotlinNotConfiguredSuppressed(
moduleSourceRootGroup
)
)
configurableModules.add(moduleSourceRootGroup)
}
@@ -246,15 +255,15 @@ fun getConfigurationPossibilitiesForConfigureNotification(
fun findApplicableConfigurator(module: Module): KotlinProjectConfigurator {
val moduleGroup = module.toModuleGroup()
return allConfigurators().find { it.getStatus(moduleGroup) != ConfigureKotlinStatus.NON_APPLICABLE }
?: KotlinJavaModuleConfigurator.instance
?: KotlinJavaModuleConfigurator.instance
}
fun hasAnyKotlinRuntimeInScope(module: Module): Boolean {
return runReadAction {
val scope = module.getModuleWithDependenciesAndLibrariesScope(hasKotlinFilesOnlyInTests(module))
getKotlinJvmRuntimeMarkerClass(module.project, scope) != null ||
hasKotlinJsKjsmFile(module.project, LibraryKindSearchScope(module, scope, JSLibraryKind) ) ||
hasKotlinCommonRuntimeInScope(scope)
hasKotlinJsKjsmFile(module.project, LibraryKindSearchScope(module, scope, JSLibraryKind)) ||
hasKotlinCommonRuntimeInScope(scope)
}
}
@@ -284,17 +293,10 @@ fun hasKotlinFilesInSources(module: Module): Boolean {
return FileTypeIndex.containsFileOfType(KotlinFileType.INSTANCE, module.getModuleScope(false))
}
fun isEap(version: String): Boolean {
return version.contains("rc") || version.contains("eap") || version.contains("-M")
}
fun isDev(version: String): Boolean {
return version.contains("dev")
}
private class LibraryKindSearchScope(val module: Module,
val baseScope: GlobalSearchScope,
val libraryKind: PersistentLibraryKind<*>
private class LibraryKindSearchScope(
val module: Module,
val baseScope: GlobalSearchScope,
val libraryKind: PersistentLibraryKind<*>
) : DelegatingGlobalSearchScope(baseScope) {
override fun contains(file: VirtualFile): Boolean {
if (!super.contains(file)) return false

View File

@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.idea.KotlinPluginUtil;
import org.jetbrains.kotlin.idea.configuration.ConfigureKotlinInProjectUtilsKt;
import org.jetbrains.kotlin.idea.configuration.KotlinProjectConfigurator;
import org.jetbrains.kotlin.idea.configuration.RepositoryDescription;
import org.jetbrains.kotlin.idea.util.VersioningKt;
import org.jetbrains.kotlin.idea.versions.KotlinRuntimeLibraryUtilKt;
import javax.swing.*;
@@ -222,7 +223,7 @@ public class ConfigureDialogWithModulesAndVersion extends DialogWrapper {
Collections.sort(versions, VersionComparatorUtil.COMPARATOR.reversed());
// Handle the case when the new version has just been released and the Maven search index hasn't been updated yet
if (!ConfigureKotlinInProjectUtilsKt.isEap(bundledRuntimeVersion) && !KotlinPluginUtil.isSnapshotVersion() &&
if (!VersioningKt.isEap(bundledRuntimeVersion) && !KotlinPluginUtil.isSnapshotVersion() &&
!bundledRuntimeVersion.contains("dev") && !versions.contains(bundledRuntimeVersion)) {
versions.add(0, bundledRuntimeVersion);
}

View File

@@ -335,7 +335,8 @@ public class KotlinRunConfiguration extends JetRunConfiguration {
JavaParameters params = new JavaParameters();
JavaRunConfigurationModule module = myConfiguration.getConfigurationModule();
int classPathType = getClasspathType(module);
int classPathType = DumbService.getInstance(module.getProject()).computeWithAlternativeResolveEnabled(
() -> getClasspathType(module));
String jreHome = myConfiguration.ALTERNATIVE_JRE_PATH_ENABLED ? myConfiguration.ALTERNATIVE_JRE_PATH : null;
JavaParametersUtil.configureModule(module, params, classPathType, jreHome);

View File

@@ -0,0 +1,59 @@
<idea-plugin>
<extensionPoints>
<extensionPoint qualifiedName="org.jetbrains.kotlin.updater" beanClass="com.intellij.openapi.fileTypes.FileTypeExtensionPoint"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.projectConfigurator" interface="org.jetbrains.kotlin.idea.configuration.KotlinProjectConfigurator"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.declarationAttributeAltererExtension"
interface="org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension"
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.idePlatformSupport"
interface="org.jetbrains.kotlin.caches.resolve.IdePlatformSupport"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.highlighterExtension"
interface="org.jetbrains.kotlin.idea.highlighter.HighlighterExtension"/>
<extensionPoint name="scratchFileLanguageProvider" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="org.jetbrains.kotlin.idea.scratch.ScratchFileLanguageProvider"/>
</extensionPoint>
<extensionPoint qualifiedName="org.jetbrains.kotlin.binaryExtension"
interface="org.jetbrains.kotlin.idea.util.KotlinBinaryExtension"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.facetValidatorCreator"
interface="org.jetbrains.kotlin.idea.facet.KotlinFacetValidatorCreator"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.clearBuildState"
interface="org.jetbrains.kotlin.idea.compiler.configuration.ClearBuildStateExtension"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.newFileHook"
interface="org.jetbrains.kotlin.idea.actions.NewKotlinFileHook"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.completionExtension"
interface="org.jetbrains.kotlin.idea.completion.KotlinCompletionExtension"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.buildSystemTypeDetector"
interface="org.jetbrains.kotlin.idea.configuration.BuildSystemTypeDetector"/>
</extensionPoints>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinJavaModuleConfigurator"/>
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinJsModuleConfigurator"/>
<scriptDefinitionContributor
id="ScriptTemplatesFromCompilerSettingsProvider"
implementation="org.jetbrains.kotlin.idea.script.ScriptTemplatesFromCompilerSettingsProvider"/>
<scriptDefinitionContributor
id="ScriptTemplatesFromDependenciesProvider"
implementation="org.jetbrains.kotlin.idea.script.ScriptTemplatesFromDependenciesProvider"/>
<scriptDefinitionContributor id="StandardScriptDefinitionContributor"
order="last"
implementation="org.jetbrains.kotlin.idea.core.script.StandardScriptDefinitionContributor"/>
<scriptDefinitionContributor id="ConsoleScriptDefinitionContributor"
implementation="org.jetbrains.kotlin.console.ConsoleScriptDefinitionContributor"/>
<idePlatformSupport implementation="org.jetbrains.kotlin.caches.resolve.JvmPlatformSupport"/>
<idePlatformSupport implementation="org.jetbrains.kotlin.caches.resolve.JsPlatformSupport"/>
<idePlatformSupport implementation="org.jetbrains.kotlin.caches.resolve.CommonPlatformSupport"/>
<scratchFileLanguageProvider language="kotlin" implementationClass="org.jetbrains.kotlin.idea.scratch.KtScratchFileLanguageProvider"/>
</extensions>
</idea-plugin>

View File

@@ -0,0 +1,79 @@
<idea-plugin>
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSFrameworkSupportProvider"/>
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJavaFrameworkSupportProvider"/>
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSFrameworkSupportProvider"/>
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPCommonFrameworkSupportProvider"/>
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPJavaFrameworkSupportProvider"/>
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPJSFrameworkSupportProvider"/>
<pluginDescriptions implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradlePluginDescription"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectResolverExtension" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.kapt.idea.KaptProjectResolverExtension" order="last"/>
<projectResolve implementation="org.jetbrains.kotlin.allopen.ide.AllOpenProjectResolverExtension" order="last"/>
<projectResolve implementation="org.jetbrains.kotlin.noarg.ide.NoArgProjectResolverExtension" order="last"/>
<projectResolve implementation="org.jetbrains.kotlin.samWithReceiver.ide.SamWithReceiverProjectResolverExtension" order="last"/>
</extensions>
<extensionPoints>
<extensionPoint qualifiedName="org.jetbrains.kotlin.gradleProjectImportHandler" area="IDEA_PROJECT"
interface="org.jetbrains.kotlin.idea.configuration.GradleProjectImportHandler"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.gradleModelFacade"
interface="org.jetbrains.kotlin.idea.inspections.gradle.KotlinGradleModelFacade"/>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleLibraryDataService"/>
<externalSystemTaskNotificationListener implementation="org.jetbrains.kotlin.idea.core.script.ReloadGradleTemplatesOnSync"/>
<localInspection
implementationClass="org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection"
displayName="Kotlin Gradle and IDE plugins versions are different"
groupName="Kotlin"
enabledByDefault="true"
language="Groovy"
hasStaticDescription="true"
level="WARNING"/>
<localInspection
implementationClass="org.jetbrains.kotlin.idea.inspections.gradle.DifferentStdlibGradleVersionInspection"
displayName="Kotlin library and Gradle plugin versions are different"
groupName="Kotlin"
enabledByDefault="true"
language="Groovy"
hasStaticDescription="true"
level="WARNING"/>
<localInspection
implementationClass="org.jetbrains.kotlin.idea.inspections.gradle.DeprecatedGradleDependencyInspection"
displayName="Deprecated library is used in Gradle"
groupName="Kotlin"
enabledByDefault="true"
language="Groovy"
hasStaticDescription="true"
level="WARNING"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.allopen.ide.AllOpenGradleProjectImportHandler"/>
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.scripting.idea.plugin.ScriptingGradleProjectImportHandler"/>
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.noarg.ide.NoArgGradleProjectImportHandler"/>
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.samWithReceiver.ide.SamWithReceiverGradleProjectImportHandler"/>
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleModuleConfigurator"/>
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinJsGradleModuleConfigurator"/>
<gradleModelFacade implementation="org.jetbrains.kotlin.idea.inspections.gradle.DefaultGradleModelFacade"/>
<scriptDefinitionContributor implementation="org.jetbrains.kotlin.idea.core.script.GradleScriptDefinitionsContributor" order="first"/>
<moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleMultiplatformModuleBuilder"/>
<buildSystemTypeDetector implementation="org.jetbrains.kotlin.idea.configuration.GradleDetector"/>
</extensions>
</idea-plugin>

View File

@@ -517,6 +517,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<psi.treeChangePreprocessor implementation="org.jetbrains.kotlin.idea.caches.KotlinPackageStatementPsiTreeChangePreprocessor"/>
<renamePsiElementProcessor id="KotlinAwareJavaGetter"
implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinAwareJavaGetterRenameProcessor"
order="first"/>
<renamePsiElementProcessor id="KotlinClass"
implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinClassifierProcessor"
order="first"/>

View File

@@ -518,6 +518,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<psi.treeChangePreprocessor implementation="org.jetbrains.kotlin.idea.caches.KotlinPackageStatementPsiTreeChangePreprocessor"/>
<renamePsiElementProcessor id="KotlinAwareJavaGetter"
implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinAwareJavaGetterRenameProcessor"
order="first"/>
<renamePsiElementProcessor id="KotlinClass"
implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinClassifierProcessor"
order="first"/>

View File

@@ -517,6 +517,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<psi.treeChangePreprocessor implementation="org.jetbrains.kotlin.idea.caches.KotlinPackageStatementPsiTreeChangePreprocessor"/>
<renamePsiElementProcessor id="KotlinAwareJavaGetter"
implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinAwareJavaGetterRenameProcessor"
order="first"/>
<renamePsiElementProcessor id="KotlinClass"
implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinClassifierProcessor"
order="first"/>

View File

@@ -13,7 +13,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<version>@snapshot@</version>
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
<idea-version since-build="181.4668.68.32.4763614" until-build="181.*"/>
<idea-version since-build="181.4668.68.32.4763614" until-build="181.5281.24.32.*"/>
<depends>com.intellij.modules.platform</depends>
<depends>com.intellij.modules.androidstudio</depends>
@@ -517,6 +517,9 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<psi.treeChangePreprocessor implementation="org.jetbrains.kotlin.idea.caches.KotlinPackageStatementPsiTreeChangePreprocessor"/>
<renamePsiElementProcessor id="KotlinAwareJavaGetter"
implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinAwareJavaGetterRenameProcessor"
order="first"/>
<renamePsiElementProcessor id="KotlinClass"
implementation="org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinClassifierProcessor"
order="first"/>

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.kotlin.idea.configuration.ui.ConfigurePluginUpdatesForm">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="5" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
@@ -19,7 +19,7 @@
</component>
<vspacer id="42b13">
<constraints>
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<grid id="2505b" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="0" vgap="-1">
@@ -100,6 +100,30 @@
</component>
</children>
</grid>
<grid id="6a5b2" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="290b2" class="javax.swing.JLabel" binding="verifierDisabledText">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<foreground color="-65536"/>
<text value="(status)"/>
</properties>
</component>
<hspacer id="edb4">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
</hspacer>
</children>
</grid>
</children>
</grid>
</form>

View File

@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.idea.configuration.ui;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.ui.AsyncProcessIcon;
import javax.swing.*;
@@ -17,6 +18,7 @@ public class ConfigurePluginUpdatesForm {
public JLabel updateStatusLabel;
public JButton installButton;
public JLabel installStatusLabel;
private JLabel verifierDisabledText;
public ConfigurePluginUpdatesForm() {
int size = channelCombo.getModel().getSize();
@@ -28,6 +30,7 @@ public class ConfigurePluginUpdatesForm {
}
}
channelCombo.setPrototypeDisplayValue(maxLengthItem + " ");
showVerifierDisabledStatus();
}
private void createUIComponents() {
@@ -59,4 +62,14 @@ public class ConfigurePluginUpdatesForm {
installButton.setEnabled(false);
installButton.setVisible(false);
}
private void showVerifierDisabledStatus() {
//noinspection UnresolvedPropertyKey
if (!Registry.is("kotlin.plugin.update.verifier.enabled", true)) {
verifierDisabledText.setText("(verifier disabled)");
}
else {
verifierDisabledText.setText("");
}
}
}

View File

@@ -30,6 +30,7 @@ import com.intellij.psi.PsiModifier;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.StateRestoringCheckBox;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.asJava.LightClassUtilsKt;
import org.jetbrains.kotlin.idea.KotlinBundle;
import org.jetbrains.kotlin.idea.core.PsiModificationUtilsKt;
@@ -37,6 +38,8 @@ import org.jetbrains.kotlin.idea.findUsages.KotlinClassFindUsagesOptions;
import org.jetbrains.kotlin.idea.refactoring.RenderingUtilsKt;
import org.jetbrains.kotlin.psi.KtClass;
import org.jetbrains.kotlin.psi.KtClassOrObject;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import javax.swing.*;
import static org.jetbrains.kotlin.asJava.LightClassUtilsKt.toLightClass;
@@ -45,6 +48,7 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
private StateRestoringCheckBox constructorUsages;
private StateRestoringCheckBox derivedClasses;
private StateRestoringCheckBox derivedTraits;
private StateRestoringCheckBox expectedUsages;
public KotlinFindClassUsagesDialog(
KtClassOrObject classOrObject,
@@ -144,14 +148,36 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
return (KotlinClassFindUsagesOptions) super.getFindUsagesOptions();
}
@Override
public void configureLabelComponent(@NotNull SimpleColoredComponent coloredComponent) {
@Nullable
private KtClassOrObject getOriginalClass() {
PsiElement klass = LightClassUtilsKt.getUnwrapped(getPsiElement());
//noinspection ConstantConditions
KtClassOrObject originalClass = klass instanceof KtClassOrObject
? (KtClassOrObject) klass
: klass.getUserData(ORIGINAL_CLASS);
return klass instanceof KtClassOrObject
? (KtClassOrObject) klass
: klass.getUserData(ORIGINAL_CLASS);
}
@Override
protected void addUsagesOptions(JPanel optionsPanel) {
super.addUsagesOptions(optionsPanel);
KtClassOrObject klass = getOriginalClass();
boolean isActual = klass != null && PsiUtilsKt.hasActualModifier(klass);
KotlinClassFindUsagesOptions options = getFindUsagesOptions();
if (isActual) {
expectedUsages = addCheckboxToPanel(
"Expected classes",
options.getSearchExpected(),
optionsPanel,
false
);
}
}
@Override
public void configureLabelComponent(@NotNull SimpleColoredComponent coloredComponent) {
KtClassOrObject originalClass = getOriginalClass();
if (originalClass != null) {
coloredComponent.append(RenderingUtilsKt.formatClass(originalClass));
}
@@ -173,5 +199,6 @@ public class KotlinFindClassUsagesDialog extends FindClassUsagesDialog {
kotlinOptions.setSearchConstructorUsages(constructorUsages.isSelected());
kotlinOptions.isDerivedClasses = derivedClasses.isSelected();
kotlinOptions.isDerivedInterfaces = derivedTraits.isSelected();
kotlinOptions.setSearchExpected(isSelected(expectedUsages));
}
}

View File

@@ -20,17 +20,27 @@ import com.intellij.find.FindBundle;
import com.intellij.find.FindSettings;
import com.intellij.find.findUsages.FindMethodUsagesDialog;
import com.intellij.find.findUsages.FindUsagesHandler;
import com.intellij.find.findUsages.JavaMethodFindUsagesOptions;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.StateRestoringCheckBox;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.asJava.LightClassUtilsKt;
import org.jetbrains.kotlin.asJava.elements.KtLightMethod;
import org.jetbrains.kotlin.idea.KotlinBundle;
import org.jetbrains.kotlin.idea.findUsages.KotlinFunctionFindUsagesOptions;
import org.jetbrains.kotlin.idea.refactoring.RenderingUtilsKt;
import org.jetbrains.kotlin.psi.KtDeclaration;
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import javax.swing.*;
public class KotlinFindFunctionUsagesDialog extends FindMethodUsagesDialog {
private StateRestoringCheckBox expectedUsages;
public KotlinFindFunctionUsagesDialog(
PsiMethod method,
Project project,
@@ -43,6 +53,7 @@ public class KotlinFindFunctionUsagesDialog extends FindMethodUsagesDialog {
super(method, project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, handler);
}
@NotNull
@Override
protected KotlinFunctionFindUsagesOptions getFindUsagesOptions() {
return (KotlinFunctionFindUsagesOptions) myFindUsagesOptions;
@@ -89,5 +100,29 @@ public class KotlinFindFunctionUsagesDialog extends FindMethodUsagesDialog {
false
);
}
PsiElement element = LightClassUtilsKt.getUnwrapped(getPsiElement());
//noinspection ConstantConditions
KtDeclaration function = element instanceof KtNamedDeclaration
? (KtNamedDeclaration) element
: ((KtLightMethod) element).getKotlinOrigin();
boolean isActual = function != null && PsiUtilsKt.hasActualModifier(function);
KotlinFunctionFindUsagesOptions options = getFindUsagesOptions();
if (isActual) {
expectedUsages = addCheckboxToPanel(
"Expected functions",
options.getSearchExpected(),
optionsPanel,
false
);
}
}
@Override
public void calcFindUsagesOptions(JavaMethodFindUsagesOptions options) {
super.calcFindUsagesOptions(options);
KotlinFunctionFindUsagesOptions kotlinOptions = (KotlinFunctionFindUsagesOptions) options;
kotlinOptions.setSearchExpected(isSelected(expectedUsages));
}
}

View File

@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.idea.KotlinBundle;
import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions;
import org.jetbrains.kotlin.lexer.KtTokens;
import org.jetbrains.kotlin.psi.KtNamedDeclaration;
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
import javax.swing.*;
@@ -46,10 +47,12 @@ public class KotlinFindPropertyUsagesDialog extends JavaFindUsagesDialog<KotlinP
super(element, project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, handler);
}
private StateRestoringCheckBox cbReaders;
private StateRestoringCheckBox cbWriters;
private StateRestoringCheckBox cbOverrides;
private StateRestoringCheckBox readAccesses;
private StateRestoringCheckBox writeAccesses;
private StateRestoringCheckBox overrideUsages;
private StateRestoringCheckBox expectedUsages;
@NotNull
@Override
protected KotlinPropertyFindUsagesOptions getFindUsagesOptions() {
return (KotlinPropertyFindUsagesOptions) myFindUsagesOptions;
@@ -64,9 +67,10 @@ public class KotlinFindPropertyUsagesDialog extends JavaFindUsagesDialog<KotlinP
public void calcFindUsagesOptions(KotlinPropertyFindUsagesOptions options) {
super.calcFindUsagesOptions(options);
options.isReadAccess = isSelected(cbReaders);
options.isWriteAccess = isSelected(cbWriters);
options.setSearchOverrides(isSelected(cbOverrides));
options.isReadAccess = isSelected(readAccesses);
options.isWriteAccess = isSelected(writeAccesses);
options.setSearchOverrides(isSelected(overrideUsages));
options.setSearchExpected(isSelected(expectedUsages));
}
@Override
@@ -77,13 +81,13 @@ public class KotlinFindPropertyUsagesDialog extends JavaFindUsagesDialog<KotlinP
KotlinPropertyFindUsagesOptions options = getFindUsagesOptions();
cbReaders = addCheckboxToPanel(
readAccesses = addCheckboxToPanel(
KotlinBundle.message("find.what.property.readers.checkbox"),
options.isReadAccess,
findWhatPanel,
true
);
cbWriters = addCheckboxToPanel(
writeAccesses = addCheckboxToPanel(
KotlinBundle.message("find.what.property.writers.checkbox"),
options.isWriteAccess,
findWhatPanel,
@@ -107,7 +111,7 @@ public class KotlinFindPropertyUsagesDialog extends JavaFindUsagesDialog<KotlinP
boolean isAbstract = property.hasModifier(KtTokens.ABSTRACT_KEYWORD);
boolean isOpen = property.hasModifier(KtTokens.OPEN_KEYWORD);
if (isOpen || isAbstract) {
cbOverrides = addCheckboxToPanel(
overrideUsages = addCheckboxToPanel(
isAbstract
? KotlinBundle.message("find.what.implementing.properties.checkbox")
: KotlinBundle.message("find.what.overriding.properties.checkbox"),
@@ -116,10 +120,20 @@ public class KotlinFindPropertyUsagesDialog extends JavaFindUsagesDialog<KotlinP
false
);
}
boolean isActual = PsiUtilsKt.hasActualModifier(property);
KotlinPropertyFindUsagesOptions options = getFindUsagesOptions();
if (isActual) {
expectedUsages = addCheckboxToPanel(
"Expected properties",
options.getSearchExpected(),
optionsPanel,
false
);
}
}
@Override
protected void update() {
setOKActionEnabled(isSelected(cbReaders) || isSelected(cbWriters));
setOKActionEnabled(isSelected(readAccesses) || isSelected(writeAccesses));
}
}

View File

@@ -22,11 +22,17 @@ import com.intellij.find.findUsages.JavaMethodFindUsagesOptions
import com.intellij.find.findUsages.JavaVariableFindUsagesOptions
import com.intellij.openapi.project.Project
class KotlinClassFindUsagesOptions(project: Project) : JavaClassFindUsagesOptions(project) {
interface KotlinMemberFindUsagesOptions {
var searchExpected: Boolean
}
class KotlinClassFindUsagesOptions(project: Project) : KotlinMemberFindUsagesOptions, JavaClassFindUsagesOptions(project) {
override var searchExpected: Boolean = true
var searchConstructorUsages: Boolean = true
override fun equals(o: Any?): Boolean {
return super.equals(o) && o is KotlinClassFindUsagesOptions && o.searchConstructorUsages == searchConstructorUsages
override fun equals(other: Any?): Boolean {
return super.equals(other) && other is KotlinClassFindUsagesOptions && other.searchConstructorUsages == searchConstructorUsages
}
override fun hashCode(): Int {
@@ -34,16 +40,18 @@ class KotlinClassFindUsagesOptions(project: Project) : JavaClassFindUsagesOption
}
}
interface KotlinCallableFindUsagesOptions {
interface KotlinCallableFindUsagesOptions : KotlinMemberFindUsagesOptions {
var searchOverrides: Boolean
fun toJavaOptions(project: Project): FindUsagesOptions?
}
class KotlinFunctionFindUsagesOptions(project: Project): KotlinCallableFindUsagesOptions, JavaMethodFindUsagesOptions(project) {
class KotlinFunctionFindUsagesOptions(project: Project) : KotlinCallableFindUsagesOptions, JavaMethodFindUsagesOptions(project) {
override var searchExpected: Boolean = true
override var searchOverrides: Boolean
get() = isOverridingMethods
set(value: Boolean) {
set(value) {
isOverridingMethods = value
}
@@ -64,7 +72,10 @@ class KotlinFunctionFindUsagesOptions(project: Project): KotlinCallableFindUsage
}
}
class KotlinPropertyFindUsagesOptions(project: Project): KotlinCallableFindUsagesOptions, JavaVariableFindUsagesOptions(project) {
class KotlinPropertyFindUsagesOptions(
project: Project
) : KotlinCallableFindUsagesOptions, JavaVariableFindUsagesOptions(project) {
override var searchExpected: Boolean = true
var isReadWriteAccess: Boolean = true
override var searchOverrides: Boolean = false

View File

@@ -135,9 +135,14 @@ class KotlinFindClassUsagesHandler(
}
private fun processClassReferencesLater(classOrObject: KtClassOrObject) {
val searchParameters = KotlinReferencesSearchParameters(classOrObject,
scope = options.searchScope,
kotlinOptions = KotlinReferencesSearchOptions(acceptCompanionObjectMembers = true))
val searchParameters = KotlinReferencesSearchParameters(
classOrObject,
scope = options.searchScope,
kotlinOptions = KotlinReferencesSearchOptions(
acceptCompanionObjectMembers = true,
searchForExpectedUsages = kotlinOptions.searchExpected
)
)
var usagesQuery = ReferencesSearch.search(searchParameters)
if (kotlinOptions.isSkipImportStatements) {
@@ -146,8 +151,7 @@ class KotlinFindClassUsagesHandler(
if (!kotlinOptions.searchConstructorUsages) {
usagesQuery = FilteredQuery(usagesQuery) { !it.isConstructorUsage(classOrObject) }
}
else if (!options.isUsages) {
} else if (!options.isUsages) {
usagesQuery = FilteredQuery(usagesQuery) { it.isConstructorUsage(classOrObject) }
}
addTask { usagesQuery.forEach(referenceProcessor) }

View File

@@ -53,17 +53,25 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.findOriginalTopMostOverriddenDescriptors
import org.jetbrains.kotlin.resolve.source.getPsi
abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
protected constructor(declaration: T, elementsToSearch: Collection<PsiElement>, factory: KotlinFindUsagesHandlerFactory)
: KotlinFindUsagesHandler<T>(declaration, elementsToSearch, factory) {
abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration> protected constructor(
declaration: T,
elementsToSearch: Collection<PsiElement>,
factory: KotlinFindUsagesHandlerFactory
) : KotlinFindUsagesHandler<T>(declaration, elementsToSearch, factory) {
private class Function(declaration: KtFunction,
elementsToSearch: Collection<PsiElement>,
factory: KotlinFindUsagesHandlerFactory) : KotlinFindMemberUsagesHandler<KtFunction>(declaration, elementsToSearch, factory) {
private class Function(
declaration: KtFunction,
elementsToSearch: Collection<PsiElement>,
factory: KotlinFindUsagesHandlerFactory
) : KotlinFindMemberUsagesHandler<KtFunction>(declaration, elementsToSearch, factory) {
override fun getFindUsagesOptions(dataContext: DataContext?): FindUsagesOptions = factory.findFunctionOptions
override fun getFindUsagesDialog(isSingleFile: Boolean, toShowInNewTab: Boolean, mustOpenInNewTab: Boolean): AbstractFindUsagesDialog {
override fun getFindUsagesDialog(
isSingleFile: Boolean,
toShowInNewTab: Boolean,
mustOpenInNewTab: Boolean
): AbstractFindUsagesDialog {
val options = factory.findFunctionOptions
val lightMethod = getElement().toLightMethods().firstOrNull()
if (lightMethod != null) {
@@ -75,9 +83,12 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
override fun createKotlinReferencesSearchOptions(options: FindUsagesOptions): KotlinReferencesSearchOptions {
val kotlinOptions = options as KotlinFunctionFindUsagesOptions
return KotlinReferencesSearchOptions(true,
kotlinOptions.isIncludeOverloadUsages,
kotlinOptions.isIncludeOverloadUsages)
return KotlinReferencesSearchOptions(
acceptCallableOverrides = true,
acceptOverloads = kotlinOptions.isIncludeOverloadUsages,
acceptExtensionsOfDeclarationClass = kotlinOptions.isIncludeOverloadUsages,
searchForExpectedUsages = kotlinOptions.searchExpected
)
}
override fun applyQueryFilters(element: PsiElement, options: FindUsagesOptions, query: Query<PsiReference>): Query<PsiReference> {
@@ -87,12 +98,28 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
}
}
private class Property(declaration: KtNamedDeclaration, elementsToSearch: Collection<PsiElement>, factory: KotlinFindUsagesHandlerFactory) : KotlinFindMemberUsagesHandler<KtNamedDeclaration>(declaration, elementsToSearch, factory) {
private class Property(
declaration: KtNamedDeclaration,
elementsToSearch: Collection<PsiElement>,
factory: KotlinFindUsagesHandlerFactory
) : KotlinFindMemberUsagesHandler<KtNamedDeclaration>(declaration, elementsToSearch, factory) {
override fun getFindUsagesOptions(dataContext: DataContext?): FindUsagesOptions = factory.findPropertyOptions
override fun getFindUsagesDialog(isSingleFile: Boolean, toShowInNewTab: Boolean, mustOpenInNewTab: Boolean): AbstractFindUsagesDialog {
return KotlinFindPropertyUsagesDialog(getElement(), project, factory.findPropertyOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, this)
override fun getFindUsagesDialog(
isSingleFile: Boolean,
toShowInNewTab: Boolean,
mustOpenInNewTab: Boolean
): AbstractFindUsagesDialog {
return KotlinFindPropertyUsagesDialog(
getElement(),
project,
factory.findPropertyOptions,
toShowInNewTab,
mustOpenInNewTab,
isSingleFile,
this
)
}
override fun applyQueryFilters(element: PsiElement, options: FindUsagesOptions, query: Query<PsiReference>): Query<PsiReference> {
@@ -102,8 +129,7 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
return EmptyQuery()
}
val result = query
.applyFilter(kotlinOptions.isSkipImportStatements) { !it.isImportUsage() }
val result = query.applyFilter(kotlinOptions.isSkipImportStatements) { !it.isImportUsage() }
if (!kotlinOptions.isReadAccess || !kotlinOptions.isWriteAccess) {
val detector = KotlinReadWriteAccessDetector()
@@ -121,7 +147,13 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
}
override fun createKotlinReferencesSearchOptions(options: FindUsagesOptions): KotlinReferencesSearchOptions {
return KotlinReferencesSearchOptions(true, false, false)
val kotlinOptions = options as KotlinPropertyFindUsagesOptions
return KotlinReferencesSearchOptions(
acceptCallableOverrides = true,
acceptOverloads = false,
acceptExtensionsOfDeclarationClass = false,
searchForExpectedUsages = kotlinOptions.searchExpected
)
}
}
@@ -130,7 +162,7 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
}
private inner class MySearcher(
element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions
element: PsiElement, processor: Processor<UsageInfo>, options: FindUsagesOptions
) : Searcher(element, processor, options) {
private val kotlinOptions = options as KotlinCallableFindUsagesOptions
@@ -143,9 +175,7 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
val kotlinSearchOptions = createKotlinReferencesSearchOptions(options)
val searchParameters = KotlinReferencesSearchParameters(element, options.searchScope, kotlinOptions = kotlinSearchOptions)
applyQueryFilters(element, options, ReferencesSearch.search(searchParameters)).let { query ->
addTask { query.forEach(referenceProcessor) }
}
addTask { applyQueryFilters(element, options, ReferencesSearch.search(searchParameters)).forEach(referenceProcessor) }
if (element is KtElement && !isOnlyKotlinSearch(options.searchScope)) {
// TODO: very bad code!! ReferencesSearch does not work correctly for constructors and annotation parameters
@@ -156,8 +186,12 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
}
for (psiMethod in element.toLightMethods()) {
applyQueryFilters(element, options, MethodReferencesSearch.search(psiMethod, psiMethodScopeSearch, true)).let { query ->
addTask { query.forEach(referenceProcessor) }
addTask {
applyQueryFilters(
element,
options,
MethodReferencesSearch.search(psiMethod, psiMethodScopeSearch, true)
).forEach(referenceProcessor)
}
}
}
@@ -179,18 +213,21 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
protected abstract fun createKotlinReferencesSearchOptions(options: FindUsagesOptions): KotlinReferencesSearchOptions
protected abstract fun applyQueryFilters(element: PsiElement,
options: FindUsagesOptions,
query: Query<PsiReference>): Query<PsiReference>
protected abstract fun applyQueryFilters(
element: PsiElement,
options: FindUsagesOptions,
query: Query<PsiReference>
): Query<PsiReference>
override fun isSearchForTextOccurencesAvailable(psiElement: PsiElement, isSingleFile: Boolean): Boolean = !isSingleFile && psiElement !is KtParameter
override fun isSearchForTextOccurrencesAvailable(psiElement: PsiElement, isSingleFile: Boolean): Boolean =
!isSingleFile && psiElement !is KtParameter
override fun findReferencesToHighlight(target: PsiElement, searchScope: SearchScope): Collection<PsiReference> {
val callableDescriptor = (target as? KtCallableDeclaration)?.resolveToDescriptorIfAny() as? CallableDescriptor
val descriptorsToHighlight = if (callableDescriptor is ParameterDescriptor)
listOf(callableDescriptor)
else
callableDescriptor?.findOriginalTopMostOverriddenDescriptors() ?: emptyList<CallableDescriptor>()
callableDescriptor?.findOriginalTopMostOverriddenDescriptors() ?: emptyList()
val baseDeclarations = descriptorsToHighlight.map { it.source.getPsi() }.filter { it != null && it != target }
@@ -199,17 +236,18 @@ abstract class KotlinFindMemberUsagesHandler<T : KtNamedDeclaration>
val handler = (FindManager.getInstance(project) as FindManagerImpl).findUsagesManager.getFindUsagesHandler(it!!, true)
handler?.findReferencesToHighlight(it, searchScope) ?: emptyList()
}
}
else {
} else {
super.findReferencesToHighlight(target, searchScope)
}
}
companion object {
fun getInstance(declaration: KtNamedDeclaration,
elementsToSearch: Collection<PsiElement> = emptyList(),
factory: KotlinFindUsagesHandlerFactory): KotlinFindMemberUsagesHandler<out KtNamedDeclaration> {
fun getInstance(
declaration: KtNamedDeclaration,
elementsToSearch: Collection<PsiElement> = emptyList(),
factory: KotlinFindUsagesHandlerFactory
): KotlinFindMemberUsagesHandler<out KtNamedDeclaration> {
return if (declaration is KtFunction)
Function(declaration, elementsToSearch, factory)
else

View File

@@ -12,11 +12,13 @@ import com.intellij.openapi.roots.ModuleRootListener
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.impl.libraries.LibraryEx
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
import java.util.*
import com.intellij.util.containers.SoftFactoryMap
class LibraryEffectiveKindProviderImpl(project: Project) : LibraryEffectiveKindProvider {
companion object {
private val effectiveKindMap = HashMap<LibraryEx, PersistentLibraryKind<*>?>()
private val effectiveKindMap = object : SoftFactoryMap<LibraryEx, PersistentLibraryKind<*>?>() {
override fun create(key: LibraryEx) = detectLibraryKind(key.getFiles(OrderRootType.CLASSES))
}
}
init {
@@ -36,10 +38,8 @@ class LibraryEffectiveKindProviderImpl(project: Project) : LibraryEffectiveKindP
val kind = library.kind
return when (kind) {
is KotlinLibraryKind -> kind
else -> {
synchronized(effectiveKindMap) {
effectiveKindMap.getOrPut(library) { detectLibraryKind(library.getFiles(OrderRootType.CLASSES)) }
}
else -> synchronized(effectiveKindMap) {
effectiveKindMap.get(library)
}
}
}

View File

@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.goto
import com.intellij.ide.actions.SearchEverywhereClassifier
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import java.awt.Component
@@ -31,7 +32,7 @@ class KotlinSearchEverywhereClassifier : SearchEverywhereClassifier {
override fun getVirtualFile(o: Any) = (o as? PsiElement)?.containingFile?.virtualFile
override fun getListCellRendererComponent(list: JList<*>, value: Any?, index: Int, isSelected: Boolean, cellHasFocus: Boolean): Component? {
if (value !is PsiElement) return null
return KotlinSearchEverywherePsiRenderer(list).getListCellRendererComponent(list, value, index, isSelected, isSelected)
val declaration = (value as? PsiElement)?.unwrapped as? KtNamedDeclaration ?: return null
return KotlinSearchEverywherePsiRenderer(list).getListCellRendererComponent(list, declaration, index, isSelected, isSelected)
}
}

View File

@@ -16,66 +16,166 @@
package org.jetbrains.kotlin.idea.goto
import com.intellij.ide.util.DefaultPsiElementCellRenderer
import com.intellij.ide.util.PlatformModuleRendererFactory
import com.intellij.ide.util.PsiElementListCellRenderer
import com.intellij.ide.util.gotoByName.GotoFileCellRenderer
import com.intellij.navigation.NavigationItem
import com.intellij.openapi.util.Iconable
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFileSystemItem
import com.intellij.psi.presentation.java.SymbolPresentationUtil
import com.intellij.ui.ColoredListCellRenderer
import com.intellij.ui.JBColor
import com.intellij.ui.SimpleTextAttributes
import com.intellij.util.ui.FilePathSplittingPolicy
import com.intellij.ide.util.DefaultPsiElementCellRenderer
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.renderer.ParameterNameRenderingPolicy
import java.awt.BorderLayout
import java.awt.Container
import java.io.File
import java.util.*
import javax.swing.DefaultListCellRenderer
import javax.swing.JList
class KotlinSearchEverywherePsiRenderer(private val list: JList<*>) : DefaultPsiElementCellRenderer() {
private val RENDERER = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.withOptions {
parameterNameRenderingPolicy = ParameterNameRenderingPolicy.NONE
modifiers = emptySet()
startFromName = false
// Mostly copied from com.intellij.ide.actions.SearchEverywherePsiRenderer
// TODO: Drop copied code when SearchEverywherePsiRenderer becomes public
internal class KotlinSearchEverywherePsiRenderer(private val myList: JList<*>) : DefaultPsiElementCellRenderer() {
companion object {
private val RENDERER = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.withOptions {
parameterNameRenderingPolicy = ParameterNameRenderingPolicy.NONE
modifiers = emptySet()
startFromName = false
}
}
override fun getElementText(element: PsiElement?): String {
if (element is KtNamedFunction) {
val descriptor = element.resolveToDescriptorIfAny()
if (descriptor != null) {
return buildString {
descriptor.extensionReceiverParameter?.let { append(RENDERER.renderType(it.type)).append('.') }
append(element.name)
descriptor.valueParameters.joinTo(this, prefix = "(", postfix = ")") { RENDERER.renderType(it.type) }
init {
setFocusBorderEnabled(false)
layout = object : BorderLayout() {
override fun layoutContainer(target: Container) {
super.layoutContainer(target)
val right = getLayoutComponent(BorderLayout.EAST)
val left = getLayoutComponent(BorderLayout.WEST)
//IDEA-140824
if (right != null && left != null && left.bounds.x + left.bounds.width > right.bounds.x) {
val bounds = right.bounds
val newX = left.bounds.x + left.bounds.width
right.setBounds(newX, bounds.y, bounds.width - (newX - bounds.x), bounds.height)
}
}
}
return super.getElementText(element)
}
// Mostly copied from SearchEverywherePsiRenderer
override fun getContainerText(element: PsiElement?, name: String?): String? {
var text = SymbolPresentationUtil.getSymbolContainerText(element) ?: return null
if (list.width == 0) return text
override fun getElementText(element: PsiElement?): String {
if (element !is KtNamedFunction) return super.getElementText(element)
val descriptor = element.resolveToDescriptorIfAny() ?: return ""
return buildString {
descriptor.extensionReceiverParameter?.let { append(RENDERER.renderType(it.type)).append('.') }
append(element.name)
descriptor.valueParameters.joinTo(this, prefix = "(", postfix = ")") { RENDERER.renderType(it.type) }
}
}
override fun getContainerText(element: PsiElement, name: String): String? {
if (element is PsiFileSystemItem) {
val file = element.virtualFile
val parent = file?.parent
if (parent == null) {
if (file != null) { // use fallback from Switcher
val presentableUrl = file.presentableUrl
return FileUtil.getLocationRelativeToUserHome(presentableUrl)
}
return null
}
val relativePath = GotoFileCellRenderer.getRelativePath(parent, element.getProject()) ?: return "( " + File.separator + " )"
var width = myList.width
if (width == 0) width += 800
val path = FilePathSplittingPolicy.SPLIT_BY_SEPARATOR.getOptimalTextForComponent(
name,
File(relativePath),
this,
width - myRightComponentWidth - 16 - 10
)
return "($path)"
}
return getSymbolContainerText(name, element)
}
private fun getSymbolContainerText(name: String, element: PsiElement): String? {
var text = SymbolPresentationUtil.getSymbolContainerText(element)
if (myList.width == 0) return text
if (text == null) return null
if (text.startsWith("(") && text.endsWith(")")) {
text = text.substring(1, text.length - 1)
}
val inIndex = text.indexOf("in ")
if (inIndex >= 0) text = text.substring(inIndex + 3)
val fm = list.getFontMetrics(list.font)
val maxWidth = list.width - fm.stringWidth(name) - 16 - myRightComponentWidth - 20
val left = if (inIndex >= 0) "(in " else "("
val `in` = text.startsWith("in ")
if (`in`) text = text.substring(3)
val fm = myList.getFontMetrics(myList.font)
val maxWidth = myList.width - fm.stringWidth(name) - 16 - myRightComponentWidth - 20
val left = if (`in`) "(in " else "("
val right = ")"
if (fm.stringWidth(left + text + right) < maxWidth) return left + text + right
val parts = LinkedList(StringUtil.split(text, "."))
val separator = if (text.contains(File.separator)) File.separator else "."
val parts = LinkedList(StringUtil.split(text, separator))
var index: Int
while (parts.size > 1) {
index = parts.size / 2 - 1
parts.removeAt(index)
if (fm.stringWidth(StringUtil.join(parts, ".") + "...") < maxWidth) {
parts.add(index, if (index == 0) "..." else ".")
return left + StringUtil.join(parts, ".") + right
if (fm.stringWidth(StringUtil.join(parts, separator) + "...") < maxWidth) {
parts.add(index, "...")
return left + StringUtil.join(parts, separator) + right
}
}
return left + "..." + right
//todo
return "$left...$right"
}
}
override fun customizeNonPsiElementLeftRenderer(
renderer: ColoredListCellRenderer<*>?,
list: JList<*>?,
value: Any?,
index: Int,
selected: Boolean,
hasFocus: Boolean
): Boolean {
if (value !is NavigationItem) return false
val item = value as NavigationItem?
val attributes = getNavigationItemAttributes(item)
var nameAttributes: SimpleTextAttributes? = if (attributes != null) SimpleTextAttributes.fromTextAttributes(attributes) else null
val color = list!!.foreground
if (nameAttributes == null) nameAttributes = SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, color)
renderer!!.append(item!!.toString() + " ", nameAttributes)
val itemPresentation = item.presentation!!
renderer.icon = itemPresentation.getIcon(true)
val locationString = itemPresentation.locationString
if (!StringUtil.isEmpty(locationString)) {
renderer.append(locationString!!, SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, JBColor.GRAY))
}
return true
}
override fun getRightCellRenderer(value: Any): DefaultListCellRenderer? {
val rightRenderer = super.getRightCellRenderer(value)
return if (rightRenderer is PlatformModuleRendererFactory.PlatformModuleRenderer) {
// that renderer will display file path, but we're showing it ourselves - no need to show twice
null
} else rightRenderer
}
override fun getIconFlags() = Iconable.ICON_FLAG_READ_STATUS
}

View File

@@ -16,14 +16,19 @@
package org.jetbrains.kotlin.idea.highlighter
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.execution.lineMarker.ExecutorAction
import com.intellij.execution.lineMarker.RunLineMarkerContributor
import com.intellij.icons.AllIcons
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
class KotlinRunLineMarkerContributor : RunLineMarkerContributor() {
override fun getInfo(element: PsiElement): Info? {
@@ -36,6 +41,22 @@ class KotlinRunLineMarkerContributor : RunLineMarkerContributor() {
}
if (detector.isMain(function)) {
val platform = TargetPlatformDetector.getPlatform(function.containingKtFile)
val isAvailable = when (platform) {
is JvmPlatform -> true
is JsPlatform, is TargetPlatform.Common -> {
RunConfigurationProducer
.getProducers(function.project)
.asSequence()
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
.filter { !it.isForTests }
.mapNotNull { it.getConfigurationData(function) }
.firstOrNull() != null
}
else -> false
}
if (!isAvailable) return null
return RunLineMarkerContributor.Info(AllIcons.RunConfigurations.TestState.Run, null, ExecutorAction.getActions(0))
}

View File

@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.highlighter
import com.intellij.codeInsight.TestFrameworks
import com.intellij.execution.TestStateStorage
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.execution.lineMarker.ExecutorAction
import com.intellij.execution.lineMarker.RunLineMarkerContributor
import com.intellij.execution.testframework.TestIconMapper
@@ -33,10 +34,8 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.js.jsOrJsImpl
import org.jetbrains.kotlin.idea.js.jsTestOutputFilePath
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.idea.util.string.joinWithEscape
import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.kotlin.name.FqName
@@ -110,12 +109,17 @@ class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
private fun getJavaScriptTestIcon(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor): Icon? {
if (!descriptor.isTest()) return null
val module = declaration.module?.jsOrJsImpl() ?: return null
val testFilePath = module.jsTestOutputFilePath ?: return null
val runConfigData = RunConfigurationProducer
.getProducers(declaration.project)
.asSequence()
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
.filter { it.isForTests }
.mapNotNull { it.getConfigurationData(declaration) }
.firstOrNull() ?: return null
val locations = ArrayList<String>()
locations += FileUtil.toSystemDependentName(testFilePath)
locations += FileUtil.toSystemDependentName(runConfigData.jsOutputFilePath)
val klass = when (declaration) {
is KtClassOrObject -> declaration

View File

@@ -50,7 +50,10 @@ import org.jetbrains.kotlin.idea.imports.importableFqName
import org.jetbrains.kotlin.idea.quickfix.RemoveUnusedFunctionParameterFix
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
import org.jetbrains.kotlin.idea.search.isCheapEnoughToSearchConsideringOperators
import org.jetbrains.kotlin.idea.search.projectScope
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
import org.jetbrains.kotlin.idea.search.usagesSearch.getAccessorNames
import org.jetbrains.kotlin.idea.search.usagesSearch.getClassNameForCompanionObject
@@ -74,7 +77,14 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
companion object {
private val javaInspection = UnusedDeclarationInspection()
private val KOTLIN_ADDITIONAL_ANNOTATIONS = listOf("kotlin.test.*")
private fun KtDeclaration.hasKotlinAdditionalAnnotation() =
this is KtNamedDeclaration && checkAnnotatedUsingPatterns(this, KOTLIN_ADDITIONAL_ANNOTATIONS)
fun isEntryPoint(declaration: KtNamedDeclaration): Boolean {
if (declaration.hasKotlinAdditionalAnnotation()) return true
if (declaration is KtClass && declaration.declarations.any { it.hasKotlinAdditionalAnnotation() }) return true
val lightElement: PsiElement? = when (declaration) {
is KtClassOrObject -> declaration.toLightClass()
is KtNamedFunction, is KtSecondaryConstructor -> LightClassUtil.getLightClassMethod(declaration as KtFunction)
@@ -109,6 +119,7 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
declaration: KtNamedDeclaration,
annotationPatterns: Collection<String>
): Boolean {
if (declaration.annotationEntries.isEmpty()) return false
val context = declaration.analyze()
val annotationsPresent = declaration.annotationEntries.mapNotNull {
context[BindingContext.ANNOTATION, it]?.fqName?.asString()
@@ -190,7 +201,8 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
}
private fun hasNonTrivialUsages(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor? = null): Boolean {
val psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(declaration.project)
val project = declaration.project
val psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(project)
val useScope = declaration.useScope
val restrictedScope = if (useScope is GlobalSearchScope) {
@@ -206,14 +218,18 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
}
}
if (zeroOccurrences) {
if (zeroOccurrences && !declaration.hasActualModifier()) {
if (declaration is KtObjectDeclaration && declaration.isCompanion()) {
// go on: companion object can be used only in containing class
} else {
return false
}
}
KotlinSourceFilterScope.projectSources(useScope, declaration.project)
if (declaration.hasActualModifier()) {
KotlinSourceFilterScope.projectSources(project.projectScope(), project)
} else {
KotlinSourceFilterScope.projectSources(useScope, project)
}
} else useScope
return (declaration is KtObjectDeclaration && declaration.isCompanion() &&
@@ -221,7 +237,6 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
hasReferences(declaration, descriptor, restrictedScope) ||
hasOverrides(declaration, restrictedScope) ||
hasFakeOverrides(declaration, restrictedScope) ||
isPlatformImplementation(declaration) ||
hasPlatformImplementations(declaration, descriptor)
}
@@ -267,7 +282,12 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
return false
}
val referenceUsed: Boolean by lazy { !ReferencesSearch.search(declaration, useScope).forEach(::checkReference) }
val searchParameters = KotlinReferencesSearchParameters(
declaration,
useScope,
kotlinOptions = KotlinReferencesSearchOptions(acceptCallableOverrides = declaration.hasActualModifier())
)
val referenceUsed: Boolean by lazy { !ReferencesSearch.search(searchParameters).forEach(::checkReference) }
if (descriptor is FunctionDescriptor &&
DescriptorUtils.getAnnotationByFqName(descriptor.annotations, JvmFileClassUtil.JVM_NAME) != null
@@ -278,9 +298,11 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
if (declaration is KtCallableDeclaration && !declaration.hasModifier(KtTokens.INTERNAL_KEYWORD)) {
val lightMethods = declaration.toLightMethods()
if (lightMethods.isNotEmpty()) {
return lightMethods.any { method ->
val lightMethodsUsed = lightMethods.any { method ->
!MethodReferencesSearch.search(method).forEach(::checkReference)
}
if (lightMethodsUsed) return true
if (!declaration.hasActualModifier()) return false
}
}
@@ -319,9 +341,6 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
}
}
private fun isPlatformImplementation(declaration: KtNamedDeclaration) =
declaration.hasActualModifier()
private fun hasPlatformImplementations(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor?): Boolean {
if (!declaration.hasExpectModifier()) return false

View File

@@ -22,7 +22,6 @@ import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.idea.core.canBePrivate
import org.jetbrains.kotlin.idea.core.canBeProtected
import org.jetbrains.kotlin.idea.core.setVisibility
@@ -31,9 +30,9 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi.psiUtil.toVisibility
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifier
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
import java.lang.IllegalArgumentException
open class ChangeVisibilityModifierIntention protected constructor(
val modifier: KtModifierKeywordToken
@@ -88,16 +87,6 @@ open class ChangeVisibilityModifierIntention protected constructor(
if (element is KtPropertyAccessor) element.modifierList?.nextSibling?.replace(KtPsiFactory(element).createWhiteSpace())
}
private fun KtModifierKeywordToken.toVisibility(): Visibility {
return when (this) {
KtTokens.PUBLIC_KEYWORD -> Visibilities.PUBLIC
KtTokens.PRIVATE_KEYWORD -> Visibilities.PRIVATE
KtTokens.PROTECTED_KEYWORD -> Visibilities.PROTECTED
KtTokens.INTERNAL_KEYWORD -> Visibilities.INTERNAL
else -> throw IllegalArgumentException("Unknown visibility modifier:$this")
}
}
private fun noModifierYetApplicabilityRange(declaration: KtDeclaration): TextRange? {
return when (declaration) {
is KtNamedFunction -> declaration.funKeyword?.textRange

View File

@@ -19,9 +19,9 @@ package org.jetbrains.kotlin.idea.intentions
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiElement
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.idea.refactoring.CompositeRefactoringRunner
import org.jetbrains.kotlin.idea.refactoring.checkConflictsInteractively
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.*
import org.jetbrains.kotlin.idea.refactoring.runRefactoringWithPostprocessing
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtElement
@@ -54,12 +54,10 @@ abstract class MoveMemberOutOfObjectIntention(text: String) : SelfTargetingRange
KotlinMoveTargetForExistingElement(destination),
MoveDeclarationsDelegate.NestedClass()
)
val refactoring = { MoveKotlinDeclarationsProcessor(moveDescriptor).run() }
refactoring.runRefactoringWithPostprocessing(project, MoveKotlinDeclarationsProcessor.REFACTORING_ID) {
runWriteAction {
deleteClassOrObjectIfEmpty()
}
}
object : CompositeRefactoringRunner(project, MoveKotlinDeclarationsProcessor.REFACTORING_ID) {
override fun runRefactoring() = MoveKotlinDeclarationsProcessor(moveDescriptor).run()
override fun onRefactoringDone() = runWriteAction { deleteClassOrObjectIfEmpty() }
}.run()
return
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.js
import com.intellij.openapi.module.Module
import com.intellij.psi.PsiElement
interface KotlinJSRunConfigurationData {
val element: PsiElement
val module: Module
val jsOutputFilePath: String
}
interface KotlinJSRunConfigurationDataProvider<out T : KotlinJSRunConfigurationData> {
val isForTests: Boolean
fun getConfigurationData(element: PsiElement): T?
}

View File

@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.idea.core.CollectingNameValidator
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
import org.jetbrains.kotlin.idea.core.appendElement
import org.jetbrains.kotlin.idea.core.getOrCreateBody
import org.jetbrains.kotlin.idea.refactoring.runRefactoringWithPostprocessing
import org.jetbrains.kotlin.idea.refactoring.CompositeRefactoringRunner
import org.jetbrains.kotlin.idea.refactoring.changeSignature.*
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.psi.*
@@ -112,12 +112,17 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
val contextElement = constructorDescriptor.source.getPsi() ?: return
val constructorPointer = contextElement.createSmartPointer()
val config = configureChangeSignature(element, propertyDescriptor)
val changeSignature = { runChangeSignature(project, constructorDescriptor, config, contextElement, text) }
changeSignature.runRefactoringWithPostprocessing(project, "refactoring.changeSignature") {
val constructorOrClass = constructorPointer.element
val constructor = constructorOrClass as? KtConstructor<*> ?: (constructorOrClass as? KtClass)?.primaryConstructor
constructor?.getValueParameters()?.lastOrNull()?.replace(parameterToInsert)
}
object : CompositeRefactoringRunner(project, "refactoring.changeSignature") {
override fun runRefactoring() {
runChangeSignature(project, constructorDescriptor, config, contextElement, text)
}
override fun onRefactoringDone() {
val constructorOrClass = constructorPointer.element
val constructor = constructorOrClass as? KtConstructor<*> ?: (constructorOrClass as? KtClass)?.primaryConstructor
constructor?.getValueParameters()?.lastOrNull()?.replace(parameterToInsert)
}
}.run()
}
finally {
FinishMarkAction.finish(project, editor, startMarkAction)
@@ -170,20 +175,26 @@ object InitializePropertyQuickFixFactory : KotlinIntentionActionsFactory() {
val descriptor = descriptorsToProcess.next()
val constructorPointer = descriptor.source.getPsi()?.createSmartPointer()
val config = configureChangeSignature(propertyDescriptor)
val changeSignature = { runChangeSignature(project, descriptor, config, element.containingClassOrObject!!, text) }
val changeSignature = { }
changeSignature.runRefactoringWithPostprocessing(project, "refactoring.changeSignature") {
val constructorOrClass = constructorPointer?.element
val constructor = constructorOrClass as? KtConstructor<*> ?: (constructorOrClass as? KtClass)?.primaryConstructor
if (constructor == null || !visitedElements.add(constructor)) return@runRefactoringWithPostprocessing
constructor.getValueParameters().lastOrNull()?.let { newParam ->
val psiFactory = KtPsiFactory(project)
(constructor as? KtSecondaryConstructor)?.getOrCreateBody()?.appendElement(
psiFactory.createExpression("this.${element.name} = ${newParam.name!!}")
) ?: element.setInitializer(psiFactory.createExpression(newParam.name!!))
object : CompositeRefactoringRunner(project, "refactoring.changeSignature") {
override fun runRefactoring() {
runChangeSignature(project, descriptor, config, element.containingClassOrObject!!, text)
}
processConstructors(project, propertyDescriptor, descriptorsToProcess)
}
override fun onRefactoringDone() {
val constructorOrClass = constructorPointer?.element
val constructor = constructorOrClass as? KtConstructor<*> ?: (constructorOrClass as? KtClass)?.primaryConstructor
if (constructor == null || !visitedElements.add(constructor)) return
constructor.getValueParameters().lastOrNull()?.let { newParam ->
val psiFactory = KtPsiFactory(project)
(constructor as? KtSecondaryConstructor)?.getOrCreateBody()?.appendElement(
psiFactory.createExpression("this.${element.name} = ${newParam.name!!}")
) ?: element.setInitializer(psiFactory.createExpression(newParam.name!!))
}
processConstructors(project, propertyDescriptor, descriptorsToProcess)
}
}.run()
}
override fun invoke(project: Project, editor: Editor?, file: KtFile) {

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