mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-15 15:51:07 +00:00
Compare commits
274 Commits
stdlib/add
...
beta2_/br1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d00b6dd1a7 | ||
|
|
3674663d30 | ||
|
|
03b688d1a1 | ||
|
|
e74282753a | ||
|
|
a7c07b8519 | ||
|
|
bbb92ead5b | ||
|
|
b320e2ed0e | ||
|
|
08e9ff602f | ||
|
|
c5e473bc50 | ||
|
|
73596f7464 | ||
|
|
0dcf34bb55 | ||
|
|
0bcdfce84b | ||
|
|
45044a77d5 | ||
|
|
e8be0962c2 | ||
|
|
8afd6421bb | ||
|
|
01b06401a2 | ||
|
|
a946126dca | ||
|
|
6147d11e1a | ||
|
|
47895c0cc2 | ||
|
|
d8593d166d | ||
|
|
bb6677620a | ||
|
|
3ecdf558ae | ||
|
|
eee1839e8e | ||
|
|
c35b8a4b58 | ||
|
|
06104521f2 | ||
|
|
63fc7110a7 | ||
|
|
f5bab93fd1 | ||
|
|
c8e9e33076 | ||
|
|
8f2c05668e | ||
|
|
737763cc67 | ||
|
|
2bd44799f8 | ||
|
|
e13fb0e7bc | ||
|
|
16df7a9d92 | ||
|
|
d5d803963f | ||
|
|
20a15dc175 | ||
|
|
26bd8600cf | ||
|
|
abb116ef9a | ||
|
|
62363c95d8 | ||
|
|
e58a45c9d8 | ||
|
|
a336888858 | ||
|
|
19501aac59 | ||
|
|
f9ac5ae737 | ||
|
|
9cb5defc43 | ||
|
|
4782077357 | ||
|
|
7906615ae9 | ||
|
|
eeeb26ddda | ||
|
|
e4905931b6 | ||
|
|
40cecdaa33 | ||
|
|
e8e9e27903 | ||
|
|
3e1cd44df8 | ||
|
|
12447eace1 | ||
|
|
a7ad17fd6d | ||
|
|
27140671db | ||
|
|
d36e01dbdd | ||
|
|
c9cb0abfad | ||
|
|
b0bb109209 | ||
|
|
d80eb5765e | ||
|
|
3c74b0fcce | ||
|
|
6f9ed63dc9 | ||
|
|
d56512fd57 | ||
|
|
b84c73eab2 | ||
|
|
1ce461dbfa | ||
|
|
39348e38ec | ||
|
|
177897e1f9 | ||
|
|
81edaa94aa | ||
|
|
fb3c9c8479 | ||
|
|
3aff0f1107 | ||
|
|
cbb5e27c14 | ||
|
|
5c294538d7 | ||
|
|
5857a02841 | ||
|
|
ddf714b93c | ||
|
|
541001fdb1 | ||
|
|
b389f1947d | ||
|
|
62dde8bf14 | ||
|
|
dfe854796b | ||
|
|
dbae0bcb59 | ||
|
|
3cab96599f | ||
|
|
b53d935e83 | ||
|
|
d6806a3307 | ||
|
|
5e3884718b | ||
|
|
1d97c742b7 | ||
|
|
a185f07ff5 | ||
|
|
8fb533f44b | ||
|
|
a186b5ee0d | ||
|
|
588812bede | ||
|
|
d20daf9766 | ||
|
|
20b1cfee0f | ||
|
|
eceae7ccda | ||
|
|
d70a7c1b66 | ||
|
|
22bce2e129 | ||
|
|
fcc0143ae1 | ||
|
|
b0b8ad2ccb | ||
|
|
9e2f16397c | ||
|
|
3066ac3d07 | ||
|
|
5faa8ca374 | ||
|
|
5671b72b5b | ||
|
|
8b9995f404 | ||
|
|
01309eb51c | ||
|
|
a2ea50a084 | ||
|
|
d8b44f405f | ||
|
|
c0eb547afe | ||
|
|
4a58a1d17d | ||
|
|
9f06becea7 | ||
|
|
933cead115 | ||
|
|
d0cbf80bee | ||
|
|
ac0a43132c | ||
|
|
936e029820 | ||
|
|
3b53a3fe3e | ||
|
|
b0e7c45168 | ||
|
|
977e61f7d1 | ||
|
|
3fd5961613 | ||
|
|
a9479b6710 | ||
|
|
2f7bb20d7f | ||
|
|
751ea6bc9f | ||
|
|
038b6beb71 | ||
|
|
15ef568dec | ||
|
|
a0d097485a | ||
|
|
4575042216 | ||
|
|
1e2c86ff43 | ||
|
|
7228710069 | ||
|
|
bccb16615d | ||
|
|
c2ba523a22 | ||
|
|
b56c71cdc2 | ||
|
|
f560590159 | ||
|
|
889460ff56 | ||
|
|
8a91ddae10 | ||
|
|
2332424696 | ||
|
|
61b32fea7c | ||
|
|
3c393282cd | ||
|
|
daa2618146 | ||
|
|
b322636064 | ||
|
|
f2c13980d1 | ||
|
|
5788d54521 | ||
|
|
9a037c1254 | ||
|
|
d69bba12e9 | ||
|
|
a2b346f6ee | ||
|
|
4203677824 | ||
|
|
0d5e7a0cfc | ||
|
|
5a15353273 | ||
|
|
012c975c61 | ||
|
|
81bf3227fa | ||
|
|
a2f06278c8 | ||
|
|
183328efe7 | ||
|
|
b1c87bab9e | ||
|
|
7a1135d715 | ||
|
|
17eead516c | ||
|
|
f0a4b4ed32 | ||
|
|
0c520c5d65 | ||
|
|
61881ea3a8 | ||
|
|
735a690c60 | ||
|
|
8389066f28 | ||
|
|
8973ed5217 | ||
|
|
645834e6f6 | ||
|
|
a8ae730c7f | ||
|
|
58fa2d3b53 | ||
|
|
a00b390282 | ||
|
|
4c9a076a8d | ||
|
|
08d42b1333 | ||
|
|
717c7b7caf | ||
|
|
eb078d5840 | ||
|
|
f3b1cd0a71 | ||
|
|
5a116129d2 | ||
|
|
cae65bdebc | ||
|
|
712c88a900 | ||
|
|
74b59aa00e | ||
|
|
155cf874df | ||
|
|
c477e1825e | ||
|
|
c4295de0c6 | ||
|
|
fd5394665b | ||
|
|
a46af42022 | ||
|
|
ad77a8c416 | ||
|
|
39e9916629 | ||
|
|
643147049e | ||
|
|
de9c143ef4 | ||
|
|
2b656af7a7 | ||
|
|
86c96b6011 | ||
|
|
e7401cdaf9 | ||
|
|
f8a5f91fb8 | ||
|
|
ce1ec60db8 | ||
|
|
722a3f722f | ||
|
|
91a43b2cb1 | ||
|
|
d10061ba70 | ||
|
|
4ed1e6cf26 | ||
|
|
e94108ef4f | ||
|
|
0b37cd6058 | ||
|
|
5fc2118915 | ||
|
|
081b4ed18c | ||
|
|
b9c55cc78e | ||
|
|
053e7c7551 | ||
|
|
49db752021 | ||
|
|
5a46e39a53 | ||
|
|
30924091e6 | ||
|
|
5d68b0eb2f | ||
|
|
2de8168a87 | ||
|
|
112d9e56f7 | ||
|
|
377aabf9d5 | ||
|
|
b18adfdd6a | ||
|
|
d16c38327b | ||
|
|
a9d9d91311 | ||
|
|
bacb0d3a51 | ||
|
|
9a82813b5c | ||
|
|
3e22c15d24 | ||
|
|
f4eeeb03c4 | ||
|
|
66a1ef5e1f | ||
|
|
d7d100e361 | ||
|
|
987028171a | ||
|
|
4413312f30 | ||
|
|
db5b197921 | ||
|
|
99b28d5c05 | ||
|
|
b5b9d3b25c | ||
|
|
8663dc7dae | ||
|
|
2b0699e5c9 | ||
|
|
d1e327adde | ||
|
|
32e907167a | ||
|
|
42a6f722c5 | ||
|
|
1100cd5f6b | ||
|
|
aa53e883a9 | ||
|
|
db74c98145 | ||
|
|
b5d9823845 | ||
|
|
57e6873e38 | ||
|
|
db104cd818 | ||
|
|
246535a43e | ||
|
|
8cf466f98b | ||
|
|
ed13cc3a4a | ||
|
|
d846189110 | ||
|
|
9afee1d2d9 | ||
|
|
17e1abeead | ||
|
|
48ac53da40 | ||
|
|
a4f80bdaa1 | ||
|
|
ab0add4c9b | ||
|
|
2ebbc432d7 | ||
|
|
c5e9e04899 | ||
|
|
1ed0d4f56a | ||
|
|
961d691656 | ||
|
|
c970c96b71 | ||
|
|
c6d3ff7936 | ||
|
|
825946f2d7 | ||
|
|
07152e250f | ||
|
|
dab7669ea4 | ||
|
|
7a7de2c70e | ||
|
|
a01c77b478 | ||
|
|
a2e131d825 | ||
|
|
6f3275e644 | ||
|
|
2187afa611 | ||
|
|
83103e83b5 | ||
|
|
8459e515dd | ||
|
|
479010a800 | ||
|
|
03e874fcb7 | ||
|
|
a6275bbe1a | ||
|
|
0c14e93f2b | ||
|
|
cd7ec5d473 | ||
|
|
134c54196f | ||
|
|
c6954c12d3 | ||
|
|
9fe570240a | ||
|
|
bf1e81cbf0 | ||
|
|
2a1a389cac | ||
|
|
f149d48791 | ||
|
|
600c567224 | ||
|
|
5556d4f77c | ||
|
|
464c4d281f | ||
|
|
8bf23ba822 | ||
|
|
d90fa2baa2 | ||
|
|
d3f62b0b51 | ||
|
|
dd4cbf1eb6 | ||
|
|
4d275967fa | ||
|
|
99ad891e8e | ||
|
|
74a717564c | ||
|
|
f6f95c2767 | ||
|
|
e21b7c336f | ||
|
|
102becd680 | ||
|
|
8c7f9dc7b3 | ||
|
|
31b43ea690 | ||
|
|
9e2474b685 | ||
|
|
5d03ade4f5 |
@@ -1,16 +1,16 @@
|
||||
<component name="libraryTable">
|
||||
<library name="junit-4.12">
|
||||
<library name="junit-4.11">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/hamcrest-core-1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/junit-4.12.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/ideaSDK/lib/junit-4.11.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/hamcrest-core-1.3-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/junit-4.12-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/dependencies/junit-4.11-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
2
.idea/runConfigurations/IDEA.xml
generated
2
.idea/runConfigurations/IDEA.xml
generated
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="IDEA" type="Application" factoryName="Application" singleton="true">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=450m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=450m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin,$PROJECT_DIR$/out/artifacts/KotlinAndroidExtensions -Dkotlin.internal.mode.enabled=true" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<configuration default="false" name="IDEA (No ProcessCanceledException)" type="Application" factoryName="Application" singleton="true">
|
||||
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
|
||||
<option name="MAIN_CLASS_NAME" value="com.intellij.idea.Main" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=250m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin -Didea.ProcessCanceledException=disabled -Dkotlin.internal.mode.enabled=true -Didea.additional.classpath=../idea-kotlin-runtime/kotlin-runtime.jar,../idea-kotlin-runtime/kotlin-reflect.jar" />
|
||||
<option name="VM_PARAMETERS" value="-Xmx800m -XX:ReservedCodeCacheSize=64m -XX:MaxPermSize=250m -XX:+HeapDumpOnOutOfMemoryError -ea -Didea.is.internal=true -Didea.debug.mode=true -Didea.system.path=../system-idea -Didea.config.path=../config-idea -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true -Dsun.io.useCanonCaches=false -Dplugin.path=$PROJECT_DIR$/out/artifacts/Kotlin,$PROJECT_DIR$/out/artifacts/KotlinAndroidExtensions -Didea.ProcessCanceledException=disabled -Dkotlin.internal.mode.enabled=true" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/ideaSDK/bin" />
|
||||
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
|
||||
|
||||
@@ -482,7 +482,7 @@
|
||||
|
||||
<zipgroupfileset dir="${basedir}/lib" includes="*.jar"/>
|
||||
<zipgroupfileset dir="${basedir}/ideaSDK/core" includes="*.jar" excludes="util.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/jna-platform.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/jna-utils.jar"/>
|
||||
<zipfileset src="${idea.sdk}/lib/oromatcher.jar"/>
|
||||
<zipfileset src="${idea.sdk}/jps/jps-model.jar"/>
|
||||
<zipfileset src="${dependencies.dir}/jline.jar"/>
|
||||
|
||||
@@ -171,7 +171,7 @@ public object TypeIntrinsics {
|
||||
*/
|
||||
private fun getFunctionTypeArity(jetType: KotlinType): Int {
|
||||
val classFqName = getClassFqName(jetType) ?: return -1
|
||||
val match = KOTLIN_FUNCTION_INTERFACE_REGEX.match(classFqName) ?: return -1
|
||||
val match = KOTLIN_FUNCTION_INTERFACE_REGEX.find(classFqName) ?: return -1
|
||||
return Integer.valueOf(match.groups[1]!!.value)
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ public class CLIConfigurationKeys {
|
||||
CompilerConfigurationKey.create("message collector");
|
||||
public static final CompilerConfigurationKey<List<CompilerPlugin>> COMPILER_PLUGINS =
|
||||
CompilerConfigurationKey.create("compiler plugins");
|
||||
public static final CompilerConfigurationKey<Boolean> REPORT_PERF =
|
||||
CompilerConfigurationKey.create("enable perf");
|
||||
|
||||
private CLIConfigurationKeys() {
|
||||
}
|
||||
|
||||
@@ -62,6 +62,7 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
|
||||
val configuration = CompilerConfiguration()
|
||||
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageSeverityCollector)
|
||||
configuration.put(CLIConfigurationKeys.REPORT_PERF, arguments.reportPerf)
|
||||
|
||||
if (IncrementalCompilation.isEnabled()) {
|
||||
val incrementalCompilationComponents = services.get(javaClass<IncrementalCompilationComponents>())
|
||||
@@ -249,8 +250,10 @@ public open class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
|
||||
}
|
||||
|
||||
public fun reportPerf(configuration: CompilerConfiguration, message: String) {
|
||||
val collector = configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY]!!
|
||||
collector.report(CompilerMessageSeverity.INFO, "PERF: " + message, CompilerMessageLocation.NO_LOCATION)
|
||||
if (configuration[CLIConfigurationKeys.REPORT_PERF] == true) {
|
||||
val collector = configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY]!!
|
||||
collector.report(CompilerMessageSeverity.INFO, "PERF: " + message, CompilerMessageLocation.NO_LOCATION)
|
||||
}
|
||||
}
|
||||
|
||||
fun reportGCTime(configuration: CompilerConfiguration) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
||||
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
|
||||
import java.io.EOFException
|
||||
|
||||
public class JvmPackagePartProvider(val env: KotlinCoreEnvironment) : PackagePartProvider {
|
||||
|
||||
@@ -47,7 +48,11 @@ public class JvmPackagePartProvider(val env: KotlinCoreEnvironment) : PackagePar
|
||||
}.filterNotNull().flatMap {
|
||||
it.children.filter { it.name.endsWith(ModuleMapping.MAPPING_FILE_EXT) }.toList<VirtualFile>()
|
||||
}.map {
|
||||
ModuleMapping.create(it.contentsToByteArray())
|
||||
try {
|
||||
ModuleMapping.create(it.contentsToByteArray())
|
||||
} catch (e: EOFException) {
|
||||
throw RuntimeException("Error on reading package parts for '$packageFqName' package in '$it', roots: $roots", e)
|
||||
}
|
||||
}
|
||||
|
||||
return mappings.map { it.findPackageParts(packageFqName) }.filterNotNull().flatMap { it.parts }.distinct()
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.extensions.*
|
||||
import com.intellij.openapi.fileTypes.ContentBasedFileSubstitutor
|
||||
import com.intellij.openapi.fileTypes.FileTypeExtensionPoint
|
||||
import com.intellij.openapi.fileTypes.PlainTextFileType
|
||||
import com.intellij.openapi.project.Project
|
||||
@@ -40,14 +41,13 @@ import com.intellij.psi.FileContextProvider
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.augment.PsiAugmentProvider
|
||||
import com.intellij.psi.compiled.ClassFileDecompilers
|
||||
import com.intellij.psi.impl.JavaClassSupersImpl
|
||||
import com.intellij.psi.impl.PsiElementFinderImpl
|
||||
import com.intellij.psi.impl.PsiTreeChangePreprocessor
|
||||
import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy
|
||||
import com.intellij.psi.impl.compiled.ClsStubBuilderFactory
|
||||
import com.intellij.psi.impl.file.impl.JavaFileManager
|
||||
import com.intellij.psi.meta.MetaDataContributor
|
||||
import com.intellij.psi.stubs.BinaryFileStubBuilders
|
||||
import com.intellij.psi.util.JavaClassSupers
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.asJava.JavaElementFinder
|
||||
import org.jetbrains.kotlin.asJava.KtLightClassForFacade
|
||||
@@ -255,7 +255,7 @@ public class KotlinCoreEnvironment private constructor(
|
||||
val appEnv = getOrCreateApplicationEnvironmentForProduction(configuration, configFilePaths)
|
||||
// Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally
|
||||
// breaks a lot of tests, therefore it is disabled for production and enabled for tests
|
||||
if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY) == null || appEnv.application.isUnitTestMode) {
|
||||
if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY) == null) {
|
||||
// JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ)
|
||||
// All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well
|
||||
Disposer.register(parentDisposable, object : Disposable {
|
||||
@@ -330,10 +330,12 @@ public class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
|
||||
private fun registerAppExtensionPoints() {
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ContentBasedFileSubstitutor.EP_NAME, javaClass<ContentBasedFileSubstitutor>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), BinaryFileStubBuilders.EP_NAME, javaClass<FileTypeExtensionPoint<Any>>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), FileContextProvider.EP_NAME, javaClass<FileContextProvider>())
|
||||
//
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaDataContributor.EP_NAME, javaClass<MetaDataContributor>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), ClsStubBuilderFactory.EP_NAME, javaClass<ClsStubBuilderFactory<*>>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), PsiAugmentProvider.EP_NAME, javaClass<PsiAugmentProvider>())
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaMainMethodProvider.EP_NAME, javaClass<JavaMainMethodProvider>())
|
||||
//
|
||||
@@ -373,7 +375,6 @@ public class KotlinCoreEnvironment private constructor(
|
||||
registerFileType(KotlinFileType.INSTANCE, KotlinParserDefinition.STD_SCRIPT_SUFFIX)
|
||||
registerParserDefinition(KotlinParserDefinition())
|
||||
getApplication().registerService(javaClass<KotlinBinaryClassCache>(), KotlinBinaryClassCache())
|
||||
getApplication().registerService(javaClass<JavaClassSupers>(), javaClass<JavaClassSupersImpl>())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +396,6 @@ public class KotlinCoreEnvironment private constructor(
|
||||
private fun registerProjectServicesForCLI(projectEnvironment: JavaCoreProjectEnvironment) {
|
||||
with (projectEnvironment.getProject()) {
|
||||
registerService(javaClass<CoreJavaFileManager>(), ServiceManager.getService(this, javaClass<JavaFileManager>()) as CoreJavaFileManager)
|
||||
|
||||
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(this)
|
||||
registerService(javaClass<LightClassGenerationSupport>(), cliLightClassGenerationSupport)
|
||||
registerService(javaClass<CliLightClassGenerationSupport>(), cliLightClassGenerationSupport)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="library" name="intellij-core" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="junit-4.12" level="project" />
|
||||
<orderEntry type="library" exported="" name="javax.inject" level="project" />
|
||||
<orderEntry type="library" name="junit-4.11" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -20,9 +20,11 @@ import com.intellij.util.containers.ContainerUtil
|
||||
import java.lang.reflect.*
|
||||
import java.util.ArrayList
|
||||
import java.util.LinkedHashSet
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
private object ClassTraversalCache {
|
||||
private val cache = ContainerUtil.createConcurrentWeakKeySoftValueMap<Class<*>, ClassInfo>()
|
||||
private val cache = ContainerUtil.createConcurrentWeakKeySoftValueMap<Class<*>, ClassInfo>(
|
||||
100, 0.75f, Runtime.getRuntime().availableProcessors(), ContainerUtil.canonicalStrategy())
|
||||
|
||||
fun getClassInfo(c: Class<*>): ClassInfo {
|
||||
val classInfo = cache.get(c)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi.stubs.elements
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.psi.stubs.StubInputStream
|
||||
import com.intellij.psi.stubs.StubOutputStream
|
||||
|
||||
@@ -33,10 +33,10 @@ class DataFlowValue(val id: Any?, val type: KotlinType, val kind: DataFlowValue.
|
||||
STABLE_VALUE("stable"),
|
||||
// Member value with open / custom getter
|
||||
// Smart casts are not safe
|
||||
MEMBER_VALUE_WITH_GETTER("custom getter", "member value that has open or custom getter"),
|
||||
PROPERTY_WITH_GETTER("custom getter", "property that has open or custom getter"),
|
||||
// Protected / public member value from another module
|
||||
// Smart casts are not safe
|
||||
ALIEN_PUBLIC_VALUE("alien public", "public API member value declared in different module"),
|
||||
ALIEN_PUBLIC_PROPERTY("alien public", "public API property declared in different module"),
|
||||
// Local variable not yet captured by a changing closure
|
||||
// Smart casts are safe but possible changes in loops / closures ahead must be taken into account
|
||||
PREDICTABLE_VARIABLE("predictable", "local variable that can be changed since the check in a loop"),
|
||||
@@ -45,7 +45,7 @@ class DataFlowValue(val id: Any?, val type: KotlinType, val kind: DataFlowValue.
|
||||
UNPREDICTABLE_VARIABLE("unpredictable", "local variable that is captured by a changing closure"),
|
||||
// Member variable regardless of its visibility
|
||||
// Smart casts are not safe
|
||||
MEMBER_VARIABLE("member", "member variable that can be changed from another thread"),
|
||||
MUTABLE_PROPERTY("member", "mutable property that could have been changed by this time"),
|
||||
// Some complex expression
|
||||
// Smart casts are not safe
|
||||
OTHER("other", "complex expression");
|
||||
|
||||
@@ -377,13 +377,13 @@ public class DataFlowValueFactory {
|
||||
}
|
||||
|
||||
private static Kind propertyKind(@NotNull PropertyDescriptor propertyDescriptor, @Nullable ModuleDescriptor usageModule) {
|
||||
if (propertyDescriptor.isVar()) return MEMBER_VARIABLE;
|
||||
if (!isFinal(propertyDescriptor)) return MEMBER_VALUE_WITH_GETTER;
|
||||
if (!hasDefaultGetter(propertyDescriptor)) return MEMBER_VALUE_WITH_GETTER;
|
||||
if (propertyDescriptor.isVar()) return MUTABLE_PROPERTY;
|
||||
if (!isFinal(propertyDescriptor)) return PROPERTY_WITH_GETTER;
|
||||
if (!hasDefaultGetter(propertyDescriptor)) return PROPERTY_WITH_GETTER;
|
||||
if (!invisibleFromOtherModules(propertyDescriptor)) {
|
||||
ModuleDescriptor declarationModule = DescriptorUtils.getContainingModule(propertyDescriptor);
|
||||
if (usageModule == null || !usageModule.equals(declarationModule)) {
|
||||
return ALIEN_PUBLIC_VALUE;
|
||||
return ALIEN_PUBLIC_PROPERTY;
|
||||
}
|
||||
}
|
||||
return STABLE_VALUE;
|
||||
@@ -400,7 +400,7 @@ public class DataFlowValueFactory {
|
||||
}
|
||||
if (!(variableDescriptor instanceof LocalVariableDescriptor) && !(variableDescriptor instanceof ParameterDescriptor)) return OTHER;
|
||||
if (!variableDescriptor.isVar()) return STABLE_VALUE;
|
||||
if (variableDescriptor instanceof SyntheticFieldDescriptor) return MEMBER_VARIABLE;
|
||||
if (variableDescriptor instanceof SyntheticFieldDescriptor) return MUTABLE_PROPERTY;
|
||||
|
||||
// Local variable classification: PREDICTABLE or UNPREDICTABLE
|
||||
PreliminaryDeclarationVisitor preliminaryVisitor =
|
||||
|
||||
@@ -254,8 +254,8 @@ public object KotlinCompilerClient {
|
||||
|
||||
|
||||
private fun String.extractPortFromRunFilename(digest: String): Int =
|
||||
makeRunFilenameString(timestamp = "[0-9TZ:\\.\\+-]+", digest = digest, port = "(\\d+)", escapeSequence = "\\").toRegex()
|
||||
.match(this)
|
||||
makeRunFilenameString(timestamp = "[0-9TZ:\\.\\+-]+", digest = digest, port = "(\\d+)", escapeSequence = "\\").toRegex()
|
||||
.find(this)
|
||||
?.groups?.get(1)
|
||||
?.value?.toInt()
|
||||
?: 0
|
||||
|
||||
10
compiler/testData/builtin-classes.txt
vendored
10
compiler/testData/builtin-classes.txt
vendored
@@ -129,7 +129,7 @@ public abstract class ByteIterator : kotlin.Iterator<kotlin.Byte> {
|
||||
}
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use IntProgression instead.", replaceWith = kotlin.ReplaceWith(expression = "IntProgression", imports = {})) public open class ByteProgression : kotlin.Progression<kotlin.Byte> {
|
||||
/*primary*/ @kotlin.Deprecated(message = "This constructor will become private soon. Use ByteProgression.fromClosedRange() instead.", replaceWith = kotlin.ReplaceWith(expression = "ByteProgression.fromClosedRange(start, end, increment)", imports = {})) public constructor ByteProgression(/*0*/ start: kotlin.Byte, /*1*/ endInclusive: kotlin.Byte, /*2*/ increment: kotlin.Int)
|
||||
/*primary*/ @kotlin.Deprecated(message = "This constructor will become private soon. Use ByteProgression.fromClosedRange() instead.", replaceWith = kotlin.ReplaceWith(expression = "ByteProgression.fromClosedRange(start, endInclusive, increment)", imports = {})) public constructor ByteProgression(/*0*/ start: kotlin.Byte, /*1*/ endInclusive: kotlin.Byte, /*2*/ increment: kotlin.Int)
|
||||
@kotlin.Deprecated(message = "Use 'last' property instead.") public open override /*1*/ val end: kotlin.Byte
|
||||
public open override /*1*/ fun <get-end>(): kotlin.Byte
|
||||
public final val first: kotlin.Byte
|
||||
@@ -231,7 +231,7 @@ public abstract class CharIterator : kotlin.Iterator<kotlin.Char> {
|
||||
}
|
||||
|
||||
public open class CharProgression : kotlin.Progression<kotlin.Char> {
|
||||
/*primary*/ @kotlin.Deprecated(message = "This constructor will become private soon. Use CharProgression.fromClosedRange() instead.", replaceWith = kotlin.ReplaceWith(expression = "CharProgression.fromClosedRange(start, end, increment)", imports = {})) public constructor CharProgression(/*0*/ start: kotlin.Char, /*1*/ endInclusive: kotlin.Char, /*2*/ increment: kotlin.Int)
|
||||
/*primary*/ @kotlin.Deprecated(message = "This constructor will become private soon. Use CharProgression.fromClosedRange() instead.", replaceWith = kotlin.ReplaceWith(expression = "CharProgression.fromClosedRange(start, endInclusive, increment)", imports = {})) public constructor CharProgression(/*0*/ start: kotlin.Char, /*1*/ endInclusive: kotlin.Char, /*2*/ increment: kotlin.Int)
|
||||
@kotlin.Deprecated(message = "Use 'last' property instead.") public open override /*1*/ val end: kotlin.Char
|
||||
public open override /*1*/ fun <get-end>(): kotlin.Char
|
||||
public final val first: kotlin.Char
|
||||
@@ -650,7 +650,7 @@ public abstract class IntIterator : kotlin.Iterator<kotlin.Int> {
|
||||
}
|
||||
|
||||
public open class IntProgression : kotlin.Progression<kotlin.Int> {
|
||||
/*primary*/ @kotlin.Deprecated(message = "This constructor will become private soon. Use IntProgression.fromClosedRange() instead.", replaceWith = kotlin.ReplaceWith(expression = "IntProgression.fromClosedRange(start, end, increment)", imports = {})) public constructor IntProgression(/*0*/ start: kotlin.Int, /*1*/ endInclusive: kotlin.Int, /*2*/ increment: kotlin.Int)
|
||||
/*primary*/ @kotlin.Deprecated(message = "This constructor will become private soon. Use IntProgression.fromClosedRange() instead.", replaceWith = kotlin.ReplaceWith(expression = "IntProgression.fromClosedRange(start, endInclusive, increment)", imports = {})) public constructor IntProgression(/*0*/ start: kotlin.Int, /*1*/ endInclusive: kotlin.Int, /*2*/ increment: kotlin.Int)
|
||||
@kotlin.Deprecated(message = "Use 'last' property instead.") public open override /*1*/ val end: kotlin.Int
|
||||
public open override /*1*/ fun <get-end>(): kotlin.Int
|
||||
public final val first: kotlin.Int
|
||||
@@ -840,7 +840,7 @@ public abstract class LongIterator : kotlin.Iterator<kotlin.Long> {
|
||||
}
|
||||
|
||||
public open class LongProgression : kotlin.Progression<kotlin.Long> {
|
||||
/*primary*/ @kotlin.Deprecated(message = "This constructor will become private soon. Use LongProgression.fromClosedRange() instead.", replaceWith = kotlin.ReplaceWith(expression = "LongProgression.fromClosedRange(start, end, increment)", imports = {})) public constructor LongProgression(/*0*/ start: kotlin.Long, /*1*/ endInclusive: kotlin.Long, /*2*/ increment: kotlin.Long)
|
||||
/*primary*/ @kotlin.Deprecated(message = "This constructor will become private soon. Use LongProgression.fromClosedRange() instead.", replaceWith = kotlin.ReplaceWith(expression = "LongProgression.fromClosedRange(start, endInclusive, increment)", imports = {})) public constructor LongProgression(/*0*/ start: kotlin.Long, /*1*/ endInclusive: kotlin.Long, /*2*/ increment: kotlin.Long)
|
||||
@kotlin.Deprecated(message = "Use 'last' property instead.") public open override /*1*/ val end: kotlin.Long
|
||||
public open override /*1*/ fun <get-end>(): kotlin.Long
|
||||
public final val first: kotlin.Long
|
||||
@@ -1165,7 +1165,7 @@ public abstract class ShortIterator : kotlin.Iterator<kotlin.Short> {
|
||||
}
|
||||
|
||||
@kotlin.Deprecated(level = DeprecationLevel.WARNING, message = "Use IntProgression instead.", replaceWith = kotlin.ReplaceWith(expression = "IntProgression", imports = {})) public open class ShortProgression : kotlin.Progression<kotlin.Short> {
|
||||
/*primary*/ @kotlin.Deprecated(message = "This constructor will become private soon. Use ShortProgression.fromClosedRange() instead.", replaceWith = kotlin.ReplaceWith(expression = "ShortProgression.fromClosedRange(start, end, increment)", imports = {})) public constructor ShortProgression(/*0*/ start: kotlin.Short, /*1*/ endInclusive: kotlin.Short, /*2*/ increment: kotlin.Int)
|
||||
/*primary*/ @kotlin.Deprecated(message = "This constructor will become private soon. Use ShortProgression.fromClosedRange() instead.", replaceWith = kotlin.ReplaceWith(expression = "ShortProgression.fromClosedRange(start, endInclusive, increment)", imports = {})) public constructor ShortProgression(/*0*/ start: kotlin.Short, /*1*/ endInclusive: kotlin.Short, /*2*/ increment: kotlin.Int)
|
||||
@kotlin.Deprecated(message = "Use 'last' property instead.") public open override /*1*/ val end: kotlin.Short
|
||||
public open override /*1*/ fun <get-end>(): kotlin.Short
|
||||
public final val first: kotlin.Short
|
||||
|
||||
@@ -10,35 +10,35 @@ fun box(): String {
|
||||
val s = J::s
|
||||
|
||||
// Check that correct reflection objects are created
|
||||
assert(i !is KMutableProperty<*>, "Fail i class: ${i.javaClass}")
|
||||
assert(s is KMutableProperty<*>, "Fail s class: ${s.javaClass}")
|
||||
assert(i !is KMutableProperty<*>) { "Fail i class: ${i.javaClass}" }
|
||||
assert(s is KMutableProperty<*>) { "Fail s class: ${s.javaClass}" }
|
||||
|
||||
// Check that no Method objects are created for such properties
|
||||
assert(i.javaGetter == null, "Fail i getter")
|
||||
assert(s.javaGetter == null, "Fail s getter")
|
||||
assert(s.javaSetter == null, "Fail s setter")
|
||||
assert(i.javaGetter == null) { "Fail i getter" }
|
||||
assert(s.javaGetter == null) { "Fail s getter" }
|
||||
assert(s.javaSetter == null) { "Fail s setter" }
|
||||
|
||||
// Check that correct Field objects are created
|
||||
val ji = i.javaField!!
|
||||
val js = s.javaField!!
|
||||
assert(Modifier.isFinal(ji.getModifiers()), "Fail i final")
|
||||
assert(!Modifier.isFinal(js.getModifiers()), "Fail s final")
|
||||
assert(Modifier.isFinal(ji.getModifiers())) { "Fail i final" }
|
||||
assert(!Modifier.isFinal(js.getModifiers())) { "Fail s final" }
|
||||
|
||||
// Check that those Field objects work as expected
|
||||
val a = J(42, "abc")
|
||||
assert(ji.get(a) == 42, "Fail ji get")
|
||||
assert(js.get(a) == "abc", "Fail js get")
|
||||
assert(ji.get(a) == 42) { "Fail ji get" }
|
||||
assert(js.get(a) == "abc") { "Fail js get" }
|
||||
js.set(a, "def")
|
||||
assert(js.get(a) == "def", "Fail js set")
|
||||
assert(a.s == "def", "Fail js access")
|
||||
assert(js.get(a) == "def") { "Fail js set" }
|
||||
assert(a.s == "def") { "Fail js access" }
|
||||
|
||||
// Check that valid Kotlin reflection objects are created by those Field objects
|
||||
val ki = ji.kotlin as KProperty1<J, Int>
|
||||
val ks = js.kotlin as KMutableProperty1<J, String>
|
||||
assert(ki.get(a) == 42, "Fail ki get")
|
||||
assert(ks.get(a) == "def", "Fail ks get")
|
||||
assert(ki.get(a) == 42) { "Fail ki get" }
|
||||
assert(ks.get(a) == "def") { "Fail ks get" }
|
||||
ks.set(a, "ghi")
|
||||
assert(ks.get(a) == "ghi", "Fail ks set")
|
||||
assert(ks.get(a) == "ghi") { "Fail ks set" }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ fun testProperLineNumber(): String {
|
||||
fail()
|
||||
}
|
||||
catch(e: AssertionError) {
|
||||
val entry = e.getStackTrace()!![1]
|
||||
val entry = e.stackTrace!![1]
|
||||
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
|
||||
if ("chainCalls.kt:21" != actual) {
|
||||
return "fail 2: ${actual}"
|
||||
@@ -34,7 +34,7 @@ fun testProperLineNumber(): String {
|
||||
fail()
|
||||
}
|
||||
catch(e: AssertionError) {
|
||||
val entry = e.getStackTrace()!![1]
|
||||
val entry = e.stackTrace!![1]
|
||||
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
|
||||
if ("chainCalls.kt:34" != actual) {
|
||||
return "fail 3: ${actual}"
|
||||
@@ -46,7 +46,7 @@ fun testProperLineNumber(): String {
|
||||
test().fail()
|
||||
}
|
||||
catch(e: AssertionError) {
|
||||
val entry = e.getStackTrace()!![1]
|
||||
val entry = e.stackTrace!![1]
|
||||
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
|
||||
if ("chainCalls.kt:46" != actual) {
|
||||
return "fail 4: ${actual}"
|
||||
|
||||
@@ -18,7 +18,7 @@ fun testProperLineNumber(): String {
|
||||
test()
|
||||
}
|
||||
catch(e: AssertionError) {
|
||||
val entry = e.getStackTrace()!![1]
|
||||
val entry = e.stackTrace!![1]
|
||||
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
|
||||
if ("infixCalls.kt:17" != actual) {
|
||||
return "fail 1: ${actual}"
|
||||
@@ -30,7 +30,7 @@ fun testProperLineNumber(): String {
|
||||
call() fail test()
|
||||
}
|
||||
catch(e: AssertionError) {
|
||||
val entry = e.getStackTrace()!![1]
|
||||
val entry = e.stackTrace!![1]
|
||||
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
|
||||
if ("infixCalls.kt:30" != actual) {
|
||||
return "fail 1: ${actual}"
|
||||
|
||||
@@ -18,7 +18,7 @@ fun testProperLineNumberAfterInline(): String {
|
||||
test())
|
||||
}
|
||||
catch(e: AssertionError) {
|
||||
val entry = e.getStackTrace()!![1]
|
||||
val entry = e.stackTrace!![1]
|
||||
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
|
||||
if ("simpleCallWithParams.kt:17" != actual) {
|
||||
return "fail 2: ${actual}"
|
||||
@@ -36,7 +36,7 @@ fun testProperLineForOtherParameters(): String {
|
||||
fail())
|
||||
}
|
||||
catch(e: AssertionError) {
|
||||
val entry = e.getStackTrace()!![1]
|
||||
val entry = e.stackTrace!![1]
|
||||
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
|
||||
if ("simpleCallWithParams.kt:35" != actual) {
|
||||
return "fail 3: ${actual}"
|
||||
@@ -50,7 +50,7 @@ fun testProperLineForOtherParameters(): String {
|
||||
test())
|
||||
}
|
||||
catch(e: AssertionError) {
|
||||
val entry = e.getStackTrace()!![1]
|
||||
val entry = e.stackTrace!![1]
|
||||
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
|
||||
if ("simpleCallWithParams.kt:49" != actual) {
|
||||
return "fail 4: ${actual}"
|
||||
@@ -62,7 +62,7 @@ fun testProperLineForOtherParameters(): String {
|
||||
checkEquals(fail(), test())
|
||||
}
|
||||
catch(e: AssertionError) {
|
||||
val entry = e.getStackTrace()!![1]
|
||||
val entry = e.stackTrace!![1]
|
||||
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
|
||||
if ("simpleCallWithParams.kt:62" != actual) {
|
||||
return "fail 5: ${actual}"
|
||||
@@ -74,7 +74,7 @@ fun testProperLineForOtherParameters(): String {
|
||||
checkEquals(fail(), test())
|
||||
}
|
||||
catch(e: AssertionError) {
|
||||
val entry = e.getStackTrace()!![1]
|
||||
val entry = e.stackTrace!![1]
|
||||
val actual = "${entry.getFileName()}:${entry.getLineNumber()}"
|
||||
if ("simpleCallWithParams.kt:74" != actual) {
|
||||
return "fail 6: ${actual}"
|
||||
|
||||
@@ -11,14 +11,14 @@ class Secondary {
|
||||
}
|
||||
|
||||
fun check(f: KFunction<Any>) {
|
||||
assert(f.javaMethod == null, "Fail f method")
|
||||
assert(f.javaConstructor != null, "Fail f constructor")
|
||||
assert(f.javaMethod == null) { "Fail f method" }
|
||||
assert(f.javaConstructor != null) { "Fail f constructor" }
|
||||
val c = f.javaConstructor!!
|
||||
|
||||
assert(c.kotlinFunction != null, "Fail m function")
|
||||
assert(c.kotlinFunction != null) { "Fail m function" }
|
||||
val ff = c.kotlinFunction!!
|
||||
|
||||
assert(f == ff, "Fail f != ff")
|
||||
assert(f == ff) { "Fail f != ff" }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
@@ -19,9 +19,9 @@ fun box(): String {
|
||||
assertEquals(setter, Class.forName("ExtensionPropertyKt").getMethod("setExt", javaClass<K>(), javaClass<Double>()))
|
||||
|
||||
val k = K(42L)
|
||||
assert(getter.invoke(null, k) == 42.0, "Fail k getter")
|
||||
assert(getter.invoke(null, k) == 42.0) { "Fail k getter" }
|
||||
setter.invoke(null, k, -239.0)
|
||||
assert(getter.invoke(null, k) == -239.0, "Fail k setter")
|
||||
assert(getter.invoke(null, k) == -239.0) { "Fail k setter" }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -8,14 +8,14 @@ fun bar(s: String): Int = s.length()
|
||||
fun String.baz(): Int = this.length()
|
||||
|
||||
fun check(f: KFunction<Int>) {
|
||||
assert(f.javaConstructor == null, "Fail f constructor")
|
||||
assert(f.javaMethod != null, "Fail f method")
|
||||
assert(f.javaConstructor == null) { "Fail f constructor" }
|
||||
assert(f.javaMethod != null) { "Fail f method" }
|
||||
val m = f.javaMethod!!
|
||||
|
||||
assert(m.kotlinFunction != null, "Fail m function")
|
||||
assert(m.kotlinFunction != null) { "Fail m function" }
|
||||
val ff = m.kotlinFunction!!
|
||||
|
||||
assert(f == ff, "Fail f != ff")
|
||||
assert(f == ff) { "Fail f != ff" }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
@@ -6,7 +6,7 @@ class K(var value: Long)
|
||||
fun box(): String {
|
||||
val p = K::value
|
||||
|
||||
assert(p.javaField != null, "Fail p field")
|
||||
assert(p.javaField != null) { "Fail p field" }
|
||||
|
||||
val getter = p.javaGetter!!
|
||||
val setter = p.javaSetter!!
|
||||
@@ -15,9 +15,9 @@ fun box(): String {
|
||||
assertEquals(setter, javaClass<K>().getMethod("setValue", javaClass<Long>()))
|
||||
|
||||
val k = K(42L)
|
||||
assert(getter.invoke(k) == 42L, "Fail k getter")
|
||||
assert(getter.invoke(k) == 42L) { "Fail k getter" }
|
||||
setter.invoke(k, -239L)
|
||||
assert(getter.invoke(k) == -239L, "Fail k setter")
|
||||
assert(getter.invoke(k) == -239L) { "Fail k setter" }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ var topLevel = "123"
|
||||
fun box(): String {
|
||||
val p = ::topLevel
|
||||
|
||||
assert(p.javaField != null, "Fail p field")
|
||||
assert(p.javaField != null) { "Fail p field" }
|
||||
val field = p.javaField!!
|
||||
val className = field.getDeclaringClass().getName()
|
||||
assertEquals("TopLevelPropertyKt", className)
|
||||
@@ -17,9 +17,9 @@ fun box(): String {
|
||||
assertEquals(getter, Class.forName("TopLevelPropertyKt").getMethod("getTopLevel"))
|
||||
assertEquals(setter, Class.forName("TopLevelPropertyKt").getMethod("setTopLevel", javaClass<String>()))
|
||||
|
||||
assert(getter.invoke(null) == "123", "Fail k getter")
|
||||
assert(getter.invoke(null) == "123") { "Fail k getter" }
|
||||
setter.invoke(null, "456")
|
||||
assert(getter.invoke(null) == "456", "Fail k setter")
|
||||
assert(getter.invoke(null) == "456") { "Fail k setter" }
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
|
||||
class test.Sub, unresolved supertypes: Super
|
||||
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInJava/source.kt:5:22: error: unresolved reference: foo
|
||||
fun bar() = SubSub().foo()
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
|
||||
class test.Sub, unresolved supertypes: Super
|
||||
|
||||
COMPILATION_ERROR
|
||||
@@ -1,7 +1,7 @@
|
||||
error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
|
||||
class test.Sub, unresolved supertypes: test.Super
|
||||
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/incompleteHierarchyInKotlin/source.kt:5:22: error: unresolved reference: foo
|
||||
fun bar() = SubSub().foo()
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
error: supertypes of the following classes cannot be resolved. Please make sure you have the required dependencies in the classpath:
|
||||
class test.Sub, unresolved supertypes: test.Super
|
||||
|
||||
COMPILATION_ERROR
|
||||
@@ -8,5 +8,5 @@ fun main(args: Array<String>) {
|
||||
val annotationClass = javaClass<AnnotationClass>()
|
||||
val annotation = klass.getAnnotation(annotationClass)!!
|
||||
val value = annotation.value
|
||||
require(value == "100 20000 2000000 2000000000000 3.14 3.14 true \u03c0 :)", "Annotation value: $value")
|
||||
require(value == "100 20000 2000000 2000000000000 3.14 3.14 true \u03c0 :)", { "Annotation value: $value" })
|
||||
}
|
||||
@@ -12,4 +12,4 @@ fun foo() {
|
||||
.bar()
|
||||
}
|
||||
|
||||
// 2 3 7 8 9 8 9 11 12 11 12 17 13
|
||||
// 2 3 7 8 9 11 12 17 13
|
||||
|
||||
@@ -12,4 +12,4 @@ fun foo() {
|
||||
.bar()
|
||||
}
|
||||
|
||||
// 2 3 7 8 9 8 9 11 12 11 17 12 17 13
|
||||
// 2 3 7 8 9 11 17 12 17 13
|
||||
|
||||
@@ -3,4 +3,4 @@ fun foo() {
|
||||
42
|
||||
}
|
||||
|
||||
// 2 3 4
|
||||
// 3 4
|
||||
|
||||
@@ -9,4 +9,4 @@ fun foo(i: Int = 1) {
|
||||
inline fun bar(i: Int = 1) {
|
||||
}
|
||||
|
||||
// 2 3 9 10 4 7 6 10 9 10
|
||||
// 2 3 9 4 7 6 10 9 10
|
||||
|
||||
@@ -13,4 +13,4 @@ inline fun foo(f: () -> Unit) {
|
||||
f()
|
||||
}
|
||||
|
||||
// 2 12 13 3 14 6 12 13 7 14 9 12 13 14
|
||||
// 2 12 3 6 12 7 9 12 13 14
|
||||
|
||||
@@ -12,4 +12,4 @@ fun foo() {
|
||||
}
|
||||
}
|
||||
|
||||
// 2 3 5 6 8 9 11 8 13
|
||||
// 2 3 5 8 9 11 8 13
|
||||
|
||||
@@ -12,4 +12,4 @@ fun foo() {
|
||||
}
|
||||
}
|
||||
|
||||
// 2 3 5 6 8 9 11 8 13
|
||||
// 2 3 5 8 9 11 8 13
|
||||
|
||||
@@ -16,4 +16,4 @@ fun foo() {
|
||||
}
|
||||
}
|
||||
|
||||
// 2 3 7 5 7 8 10 11 15 13 15 10 17
|
||||
// 2 3 7 5 7 10 11 15 13 15 10 17
|
||||
|
||||
@@ -12,4 +12,4 @@ fun foo() {
|
||||
}
|
||||
}
|
||||
|
||||
// 2 3 5 6 8 9 11 8 13
|
||||
// 2 3 5 8 9 11 8 13
|
||||
|
||||
2
compiler/testData/lineNumber/custom/when.kt
vendored
2
compiler/testData/lineNumber/custom/when.kt
vendored
@@ -12,4 +12,4 @@ fun foo(x: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
// 2 3 4 5 6 8 9 10 11 8 13
|
||||
// 3 4 5 9 10 11 8 13
|
||||
|
||||
@@ -12,4 +12,4 @@ fun foo(x: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
// 2 3 4 5 6 8 9 10 11 8 13
|
||||
// 2 3 4 5 8 9 10 11 8 13
|
||||
|
||||
@@ -42,7 +42,7 @@ internal fun Sequence<String>.ifNotContainsSequence(patternsIter: Iterator<LineP
|
||||
{ acc, line ->
|
||||
when {
|
||||
!acc.iter.isValid() -> return@fold acc
|
||||
acc.iter.value.regex.match(line)?.let { acc.iter.value.matchCheck(it) } ?: false -> acc.nextLineAndPattern()
|
||||
acc.iter.value.regex.find(line)?.let { acc.iter.value.matchCheck(it) } ?: false -> acc.nextLineAndPattern()
|
||||
else -> acc.nextLine()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ package kotlin
|
||||
* A progression of values of type `Byte`.
|
||||
*/
|
||||
public open class ByteProgression
|
||||
@Deprecated("This constructor will become private soon. Use ByteProgression.fromClosedRange() instead.", ReplaceWith("ByteProgression.fromClosedRange(start, end, increment)"))
|
||||
@Deprecated("This constructor will become private soon. Use ByteProgression.fromClosedRange() instead.", ReplaceWith("ByteProgression.fromClosedRange(start, endInclusive, increment)"))
|
||||
public constructor
|
||||
(
|
||||
start: Byte,
|
||||
@@ -81,7 +81,7 @@ public open class ByteProgression
|
||||
* A progression of values of type `Char`.
|
||||
*/
|
||||
public open class CharProgression
|
||||
@Deprecated("This constructor will become private soon. Use CharProgression.fromClosedRange() instead.", ReplaceWith("CharProgression.fromClosedRange(start, end, increment)"))
|
||||
@Deprecated("This constructor will become private soon. Use CharProgression.fromClosedRange() instead.", ReplaceWith("CharProgression.fromClosedRange(start, endInclusive, increment)"))
|
||||
public constructor
|
||||
(
|
||||
start: Char,
|
||||
@@ -140,7 +140,7 @@ public open class CharProgression
|
||||
* A progression of values of type `Short`.
|
||||
*/
|
||||
public open class ShortProgression
|
||||
@Deprecated("This constructor will become private soon. Use ShortProgression.fromClosedRange() instead.", ReplaceWith("ShortProgression.fromClosedRange(start, end, increment)"))
|
||||
@Deprecated("This constructor will become private soon. Use ShortProgression.fromClosedRange() instead.", ReplaceWith("ShortProgression.fromClosedRange(start, endInclusive, increment)"))
|
||||
public constructor
|
||||
(
|
||||
start: Short,
|
||||
@@ -198,7 +198,7 @@ public open class ShortProgression
|
||||
* A progression of values of type `Int`.
|
||||
*/
|
||||
public open class IntProgression
|
||||
@Deprecated("This constructor will become private soon. Use IntProgression.fromClosedRange() instead.", ReplaceWith("IntProgression.fromClosedRange(start, end, increment)"))
|
||||
@Deprecated("This constructor will become private soon. Use IntProgression.fromClosedRange() instead.", ReplaceWith("IntProgression.fromClosedRange(start, endInclusive, increment)"))
|
||||
public constructor
|
||||
(
|
||||
start: Int,
|
||||
@@ -256,7 +256,7 @@ public open class IntProgression
|
||||
* A progression of values of type `Long`.
|
||||
*/
|
||||
public open class LongProgression
|
||||
@Deprecated("This constructor will become private soon. Use LongProgression.fromClosedRange() instead.", ReplaceWith("LongProgression.fromClosedRange(start, end, increment)"))
|
||||
@Deprecated("This constructor will become private soon. Use LongProgression.fromClosedRange() instead.", ReplaceWith("LongProgression.fromClosedRange(start, endInclusive, increment)"))
|
||||
public constructor
|
||||
(
|
||||
start: Long,
|
||||
|
||||
@@ -19,7 +19,6 @@ package kotlin.reflect.jvm.internal
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
|
||||
import java.lang.reflect.Field
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.jvm.internal.JvmPropertySignature.JavaField
|
||||
import kotlin.reflect.jvm.internal.JvmPropertySignature.KotlinProperty
|
||||
|
||||
@@ -40,11 +39,13 @@ internal abstract class DescriptorBasedProperty<out R> protected constructor(
|
||||
descriptor
|
||||
)
|
||||
|
||||
override val descriptor: PropertyDescriptor by ReflectProperties.lazySoft<PropertyDescriptor>(descriptorInitialValue) {
|
||||
private val descriptor_ = ReflectProperties.lazySoft<PropertyDescriptor>(descriptorInitialValue) {
|
||||
container.findPropertyDescriptor(name, signature)
|
||||
}
|
||||
|
||||
val javaField: Field? by ReflectProperties.lazySoft {
|
||||
override val descriptor: PropertyDescriptor get() = descriptor_()
|
||||
|
||||
private val javaField_ = ReflectProperties.lazySoft {
|
||||
val jvmSignature = RuntimeTypeMapper.mapPropertySignature(descriptor)
|
||||
when (jvmSignature) {
|
||||
is KotlinProperty -> {
|
||||
@@ -56,6 +57,9 @@ internal abstract class DescriptorBasedProperty<out R> protected constructor(
|
||||
}
|
||||
}
|
||||
|
||||
// Used in subclasses as an implementation of an irrelevant property from KPropertyImpl
|
||||
val javaField: Field? get() = javaField_()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
val that = other.asKPropertyImpl() ?: return false
|
||||
return container == that.container && name == that.name && signature == that.signature
|
||||
|
||||
@@ -25,7 +25,9 @@ internal open class KProperty0Impl<out R> : DescriptorBasedProperty<R>, KPropert
|
||||
|
||||
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : super(container, name, signature)
|
||||
|
||||
override val getter by ReflectProperties.lazy { Getter(this) }
|
||||
private val getter_ = ReflectProperties.lazy { Getter(this) }
|
||||
|
||||
override val getter: Getter<R> get() = getter_()
|
||||
|
||||
override fun get(): R = getter.call()
|
||||
|
||||
@@ -39,7 +41,9 @@ internal open class KMutableProperty0Impl<R> : KProperty0Impl<R>, KMutableProper
|
||||
|
||||
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : super(container, name, signature)
|
||||
|
||||
override val setter by ReflectProperties.lazy { Setter(this) }
|
||||
private val setter_ = ReflectProperties.lazy { Setter(this) }
|
||||
|
||||
override val setter: Setter<R> get() = setter_()
|
||||
|
||||
override fun set(value: R) = setter.call(value)
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ internal open class KProperty1Impl<T, out R> : DescriptorBasedProperty<R>, KProp
|
||||
|
||||
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
|
||||
|
||||
override val getter by ReflectProperties.lazy { Getter(this) }
|
||||
private val getter_ = ReflectProperties.lazy { Getter(this) }
|
||||
|
||||
override val getter: Getter<T, R> get() = getter_()
|
||||
|
||||
override fun get(receiver: T): R = getter.call(receiver)
|
||||
|
||||
@@ -39,7 +41,9 @@ internal open class KMutableProperty1Impl<T, R> : KProperty1Impl<T, R>, KMutable
|
||||
|
||||
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
|
||||
|
||||
override val setter by ReflectProperties.lazy { Setter(this) }
|
||||
private val setter_ = ReflectProperties.lazy { Setter(this) }
|
||||
|
||||
override val setter: Setter<T, R> get() = setter_()
|
||||
|
||||
override fun set(receiver: T, value: R) = setter.call(receiver, value)
|
||||
|
||||
|
||||
@@ -25,7 +25,9 @@ internal open class KProperty2Impl<D, E, out R> : DescriptorBasedProperty<R>, KP
|
||||
|
||||
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
|
||||
|
||||
override val getter by ReflectProperties.lazy { Getter(this) }
|
||||
private val getter_ = ReflectProperties.lazy { Getter(this) }
|
||||
|
||||
override val getter: Getter<D, E, R> get() = getter_()
|
||||
|
||||
override fun get(receiver1: D, receiver2: E): R = getter.call(receiver1, receiver2)
|
||||
|
||||
@@ -39,7 +41,9 @@ internal open class KMutableProperty2Impl<D, E, R> : KProperty2Impl<D, E, R>, KM
|
||||
|
||||
constructor(container: KDeclarationContainerImpl, descriptor: PropertyDescriptor) : super(container, descriptor)
|
||||
|
||||
override val setter by ReflectProperties.lazy { Setter(this) }
|
||||
private val setter_ = ReflectProperties.lazy { Setter(this) }
|
||||
|
||||
override val setter: Setter<D, E, R> get() = setter_()
|
||||
|
||||
override fun set(receiver1: D, receiver2: E, value: R) = setter.call(receiver1, receiver2, value)
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="library" name="asm" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="junit-4.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="junit-4.11" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ class GenerateProgressions(out: PrintWriter) : BuiltInsSourceGenerator(out) {
|
||||
* A progression of values of type `$t`.
|
||||
*/
|
||||
public open class $progression
|
||||
@Deprecated("This constructor will become private soon. Use $progression.fromClosedRange() instead.", ReplaceWith("$progression.fromClosedRange(start, end, increment)"))
|
||||
@Deprecated("This constructor will become private soon. Use $progression.fromClosedRange() instead.", ReplaceWith("$progression.fromClosedRange(start, endInclusive, increment)"))
|
||||
public constructor
|
||||
(
|
||||
start: $t,
|
||||
|
||||
@@ -691,7 +691,6 @@ fun main(args: Array<String>) {
|
||||
model("debugger/tinyApp/src/stepping/stepIntoAndSmartStepInto", testMethod = "doSmartStepIntoTest", testClassName = "SmartStepInto")
|
||||
model("debugger/tinyApp/src/stepping/stepInto", testMethod = "doStepIntoTest", testClassName = "StepIntoOnly")
|
||||
model("debugger/tinyApp/src/stepping/stepOut", testMethod = "doStepOutTest")
|
||||
model("debugger/tinyApp/src/stepping/stepOver", testMethod = "doStepOverTest")
|
||||
model("debugger/tinyApp/src/stepping/filters", testMethod = "doStepIntoTest")
|
||||
model("debugger/tinyApp/src/stepping/custom", testMethod = "doCustomTest")
|
||||
}
|
||||
|
||||
@@ -31,7 +31,9 @@ import java.io.IOException
|
||||
public class ClsJavaStubByVirtualFileCache {
|
||||
private class CachedJavaStub(val modificationStamp: Long, val javaFileStub: PsiJavaFileStubImpl)
|
||||
|
||||
private val cache = ContainerUtil.createConcurrentWeakKeySoftValueMap<VirtualFile, CachedJavaStub>()
|
||||
private val cache = ContainerUtil.createConcurrentWeakKeySoftValueMap<VirtualFile, CachedJavaStub>(
|
||||
100, 0.75f, Runtime.getRuntime().availableProcessors(), ContainerUtil.canonicalStrategy<VirtualFile>()
|
||||
)
|
||||
|
||||
public fun get(classFile: VirtualFile): PsiJavaFileStubImpl? {
|
||||
val cached = cache.get(classFile)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.configuration
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtVisitorVoid
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import javax.swing.Icon
|
||||
|
||||
class MainFunctionGutterVisitor(val holder: AnnotationHolder, val bindingContext: BindingContext) : KtVisitorVoid() {
|
||||
override fun visitNamedFunction(function: KtNamedFunction) {
|
||||
if (MainFunctionDetector(bindingContext).isMain(function)) {
|
||||
function.nameIdentifier?.let { nameIdentifier ->
|
||||
holder.createInfoAnnotation(nameIdentifier, "Run configuration from here").gutterIconRenderer = MainGutterIconRenderer(nameIdentifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class MainGutterIconRenderer(val nameIdentifier: PsiElement) : GutterIconRenderer() {
|
||||
override fun getIcon(): Icon = KotlinIcons.LAUNCH
|
||||
override fun hashCode(): Int = nameIdentifier.hashCode()
|
||||
override fun equals(other: Any?): Boolean = other is MainGutterIconRenderer && other.nameIdentifier == nameIdentifier
|
||||
}
|
||||
@@ -16,11 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler
|
||||
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledTextFromJsMetadata
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
||||
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
|
||||
|
||||
public class KotlinJavascriptMetaFile(provider: KotlinClassFileViewProviderBase) : KtClsFileBase(provider) {
|
||||
public class KotlinJavascriptMetaFile(provider: KotlinJavascriptMetaFileViewProvider) : KtClsFileBase(provider) {
|
||||
protected override val decompiledText: LockedClearableLazyValue<DecompiledText> = LockedClearableLazyValue(Any()) {
|
||||
buildDecompiledTextFromJsMetadata(getVirtualFile())
|
||||
}
|
||||
|
||||
@@ -16,11 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler
|
||||
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
||||
import com.intellij.psi.SingleRootFileViewProvider
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.buildDecompiledText
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DecompiledText
|
||||
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
|
||||
|
||||
public class KtClsFile(provider: KotlinClassFileViewProviderBase) : KtClsFileBase(provider) {
|
||||
public class KtClsFile(provider: SingleRootFileViewProvider) : KtClsFileBase(provider) {
|
||||
protected override val decompiledText: LockedClearableLazyValue<DecompiledText> = LockedClearableLazyValue(Any()) {
|
||||
buildDecompiledText(getVirtualFile())
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.idea.decompiler
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.FileViewProvider
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
@@ -30,7 +31,7 @@ import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
|
||||
|
||||
public abstract class KtClsFileBase(val provider: KotlinClassFileViewProviderBase) : KtFile(provider, true) {
|
||||
public abstract class KtClsFileBase(val provider: FileViewProvider) : KtFile(provider, true) {
|
||||
protected abstract val decompiledText: LockedClearableLazyValue<DecompiledText>
|
||||
|
||||
public fun getDeclarationForDescriptor(descriptor: DeclarationDescriptor): KtDeclaration? {
|
||||
@@ -65,7 +66,6 @@ public abstract class KtClsFileBase(val provider: KotlinClassFileViewProviderBas
|
||||
override fun onContentReload() {
|
||||
super.onContentReload()
|
||||
|
||||
provider.content.drop()
|
||||
decompiledText.drop()
|
||||
}
|
||||
|
||||
|
||||
@@ -16,69 +16,54 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.fileTypes.FileType
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.FileIndexFacade
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.SingleRootFileViewProvider
|
||||
import com.intellij.psi.impl.source.PsiFileImpl
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.utils.concurrent.block.LockedClearableLazyValue
|
||||
|
||||
abstract class KotlinClassFileViewProviderBase(
|
||||
manager: PsiManager,
|
||||
file: VirtualFile,
|
||||
physical: Boolean) : SingleRootFileViewProvider(manager, file, physical, KotlinLanguage.INSTANCE) {
|
||||
val content : LockedClearableLazyValue<String> = LockedClearableLazyValue(Any()) {
|
||||
val psiFile = createFile(manager.getProject(), file, KotlinFileType.INSTANCE)
|
||||
val text = psiFile?.getText() ?: ""
|
||||
|
||||
(psiFile as? PsiFileImpl)?.markInvalidated()
|
||||
|
||||
text
|
||||
}
|
||||
|
||||
override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? {
|
||||
// Workaround for KT-8344
|
||||
return super.createFile(project, file, fileType)
|
||||
}
|
||||
|
||||
override fun getContents() = content.get()
|
||||
}
|
||||
|
||||
public class KotlinClassFileViewProvider(
|
||||
manager: PsiManager,
|
||||
file: VirtualFile,
|
||||
val file: VirtualFile,
|
||||
physical: Boolean,
|
||||
val isInternal: Boolean) : KotlinClassFileViewProviderBase(manager, file, physical) {
|
||||
val isInternal: Boolean) : SingleRootFileViewProvider(manager, file, physical, KotlinLanguage.INSTANCE) {
|
||||
|
||||
override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? {
|
||||
val fileIndex = ServiceManager.getService(project, javaClass<FileIndexFacade>())
|
||||
if (!fileIndex.isInLibraryClasses(file) && fileIndex.isInSource(file)) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (isInternal) return null
|
||||
|
||||
return KtClsFile(this)
|
||||
val ktClsFile by lazy() {
|
||||
//TODO: check index that file is library file, as in ClassFileViewProvider
|
||||
if (!isInternal) KtClsFile(this) else null
|
||||
}
|
||||
|
||||
override fun createCopy(copy: VirtualFile) = KotlinClassFileViewProvider(getManager(), copy, false, isInternal)
|
||||
override fun getContents(): CharSequence {
|
||||
return ktClsFile?.getText() ?: ""
|
||||
}
|
||||
|
||||
override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? = ktClsFile
|
||||
|
||||
override fun createCopy(copy: VirtualFile): SingleRootFileViewProvider {
|
||||
return KotlinClassFileViewProvider(getManager(), copy, false, isInternal)
|
||||
}
|
||||
}
|
||||
|
||||
public class KotlinJavascriptMetaFileViewProvider (
|
||||
manager: PsiManager,
|
||||
val file: VirtualFile,
|
||||
physical: Boolean,
|
||||
val isInternal: Boolean) : KotlinClassFileViewProviderBase(manager, file, physical) {
|
||||
val isInternal: Boolean) : SingleRootFileViewProvider(manager, file, physical, KotlinLanguage.INSTANCE) {
|
||||
|
||||
//TODO: check index that file is library file, as in ClassFileViewProvider
|
||||
override fun createFile(project: Project, file: VirtualFile, fileType: FileType) =
|
||||
val ktJsMetaFile by lazy(this) {
|
||||
//TODO: check index that file is library file, as in ClassFileViewProvider
|
||||
if (!isInternal) KotlinJavascriptMetaFile(this) else null
|
||||
}
|
||||
|
||||
override fun createCopy(copy: VirtualFile) = KotlinJavascriptMetaFileViewProvider(getManager(), copy, false, isInternal)
|
||||
}
|
||||
override fun getContents(): CharSequence {
|
||||
return ktJsMetaFile?.getText() ?: ""
|
||||
}
|
||||
|
||||
override fun createFile(project: Project, file: VirtualFile, fileType: FileType): PsiFile? = ktJsMetaFile
|
||||
|
||||
override fun createCopy(copy: VirtualFile): SingleRootFileViewProvider {
|
||||
return KotlinJavascriptMetaFileViewProvider(getManager(), copy, false, isInternal)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ public class JsLibraryStdDetectionUtil {
|
||||
}
|
||||
|
||||
public static boolean hasJsStdlibJar(@NotNull Library library) {
|
||||
if (!KotlinJavaScriptLibraryDetectionUtil.isKotlinJavaScriptLibrary(library)) return false;
|
||||
|
||||
List<VirtualFile> classes = Arrays.asList(library.getFiles(OrderRootType.CLASSES));
|
||||
return getJsLibraryStdVersion(classes, false) != null;
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
|
||||
import org.jetbrains.kotlin.idea.actions.internal.KotlinInternalMode
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
||||
import org.jetbrains.kotlin.idea.configuration.MainFunctionGutterVisitor
|
||||
import org.jetbrains.kotlin.idea.kdoc.KDocHighlightingVisitor
|
||||
import org.jetbrains.kotlin.idea.quickfix.QuickFixes
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
|
||||
@@ -82,7 +82,9 @@ class OverridesCompletion(
|
||||
AllIcons.Gutter.ImplementingMethod
|
||||
else
|
||||
AllIcons.Gutter.OverridingMethod
|
||||
val icon = RowIcon(baseIcon, additionalIcon)
|
||||
val icon = RowIcon(2)
|
||||
icon.setIcon(baseIcon, 0)
|
||||
icon.setIcon(additionalIcon, 1)
|
||||
|
||||
val baseClassDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(position.project, baseClass)
|
||||
val baseClassIcon = KotlinDescriptorIconProvider.getIcon(baseClass, baseClassDeclaration, 0)
|
||||
|
||||
@@ -66,5 +66,5 @@ public open class KotlinJavaScriptHandler(path: String) : ArchiveHandler(path) {
|
||||
shortName: String,
|
||||
isDirectory: Boolean,
|
||||
val content: ByteArray
|
||||
) : EntryInfo(shortName, isDirectory, ArchiveHandler.DEFAULT_LENGTH, ArchiveHandler.DEFAULT_TIMESTAMP, parent)
|
||||
) : EntryInfo(parent, shortName, isDirectory, ArchiveHandler.DEFAULT_LENGTH, ArchiveHandler.DEFAULT_TIMESTAMP)
|
||||
}
|
||||
@@ -167,7 +167,8 @@ public class KotlinConsoleRunner(
|
||||
val placeholderAttrs = TextAttributes()
|
||||
placeholderAttrs.foregroundColor = ReplColors.PLACEHOLDER_COLOR
|
||||
placeholderAttrs.fontType = Font.ITALIC
|
||||
editor.setPlaceholderAttributes(placeholderAttrs)
|
||||
|
||||
// editor.setPlaceholderAttributes(placeholderAttrs)
|
||||
}
|
||||
|
||||
private fun disableCompletion(consoleView: LanguageConsoleView) {
|
||||
@@ -180,7 +181,7 @@ public class KotlinConsoleRunner(
|
||||
fun configureEditorGutter(editor: EditorEx, color: Color, iconWithTooltip: IconWithTooltip): RangeHighlighter {
|
||||
editor.settings.isLineMarkerAreaShown = true // hack to show gutter
|
||||
editor.settings.isFoldingOutlineShown = true
|
||||
editor.gutterComponentEx.setPaintBackground(true)
|
||||
// editor.gutterComponentEx.setPaintBackground(true)
|
||||
val editorColorScheme = editor.colorsScheme
|
||||
editorColorScheme.setColor(EditorColors.GUTTER_BACKGROUND, color)
|
||||
editor.colorsScheme = editorColorScheme
|
||||
|
||||
@@ -18,20 +18,20 @@ package org.jetbrains.kotlin.idea.test
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.EditorTracker
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.Presentation
|
||||
import com.intellij.openapi.actionSystem.*
|
||||
import com.intellij.openapi.actionSystem.ex.ActionManagerEx
|
||||
import com.intellij.openapi.editor.ex.EditorEx
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.impl.PsiManagerEx
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.testFramework.LoggedErrorProcessor
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import org.apache.log4j.Logger
|
||||
import org.jetbrains.kotlin.idea.actions.internal.KotlinInternalMode
|
||||
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
@@ -58,7 +58,7 @@ public abstract class KotlinLightCodeInsightFixtureTestCase : LightCodeInsightFi
|
||||
invalidateLibraryCache(project)
|
||||
|
||||
LoggedErrorProcessor.setNewInstance(object : LoggedErrorProcessor() {
|
||||
override fun processError(message: String?, t: Throwable?, details: Array<out String>?, logger: Logger) {
|
||||
override fun processError(message: String?, t: Throwable?, details: Array<out String>?, logger: org.apache.log4j.Logger) {
|
||||
exceptions.addIfNotNull(t)
|
||||
super.processError(message, t, details, logger)
|
||||
}
|
||||
@@ -71,13 +71,16 @@ public abstract class KotlinLightCodeInsightFixtureTestCase : LightCodeInsightFi
|
||||
KotlinInternalMode.enabled = kotlinInternalModeOriginalValue
|
||||
VfsRootAccess.disallowRootAccess(KotlinTestUtils.getHomeDirectory())
|
||||
|
||||
unInvalidateBuiltinsAndStdLib(getProject()) {
|
||||
super.tearDown()
|
||||
}
|
||||
val builtInsSources = BuiltInsReferenceResolver.getInstance(getProject()).builtInsSources!!
|
||||
val fileManager = (PsiManager.getInstance(getProject()) as PsiManagerEx).getFileManager()
|
||||
|
||||
if (exceptions.isNotEmpty()) {
|
||||
exceptions.forEach { it.printStackTrace() }
|
||||
throw AssertionError("Exceptions in other threads happened")
|
||||
super.tearDown()
|
||||
|
||||
// Restore mapping between PsiFiles and VirtualFiles dropped in FileManager.cleanupForNextTest(),
|
||||
// otherwise built-ins psi elements will become invalid in next test.
|
||||
for (source in builtInsSources) {
|
||||
val provider = source.getViewProvider()
|
||||
fileManager.setViewProvider(provider.getVirtualFile(), provider)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,11 @@ package org.jetbrains.kotlin.idea.test
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.impl.PsiManagerEx
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.actions.internal.KotlinInternalMode
|
||||
import org.jetbrains.kotlin.idea.references.BuiltInsReferenceResolver
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
|
||||
public abstract class KotlinLightPlatformCodeInsightFixtureTestCase: LightPlatformCodeInsightFixtureTestCase() {
|
||||
@@ -40,8 +43,16 @@ public abstract class KotlinLightPlatformCodeInsightFixtureTestCase: LightPlatfo
|
||||
KotlinInternalMode.enabled = kotlinInternalModeOriginalValue
|
||||
VfsRootAccess.disallowRootAccess(KotlinTestUtils.getHomeDirectory())
|
||||
|
||||
unInvalidateBuiltinsAndStdLib(getProject()) {
|
||||
super.tearDown()
|
||||
val builtInsSources = BuiltInsReferenceResolver.getInstance(getProject()).builtInsSources!!
|
||||
val fileManager = (PsiManager.getInstance(getProject()) as PsiManagerEx).getFileManager()
|
||||
|
||||
super.tearDown()
|
||||
|
||||
// Restore mapping between PsiFiles and VirtualFiles dropped in FileManager.cleanupForNextTest(),
|
||||
// otherwise built-ins psi elements will become invalid in next test.
|
||||
for (source in builtInsSources) {
|
||||
val provider = source.getViewProvider()
|
||||
fileManager.setViewProvider(provider.getVirtualFile(), provider)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class KotlinLightProjectDescriptor extends LightProjectDescriptor {
|
||||
public class KotlinLightProjectDescriptor implements LightProjectDescriptor {
|
||||
protected KotlinLightProjectDescriptor() {
|
||||
}
|
||||
|
||||
|
||||
@@ -76,18 +76,23 @@ public fun Module.configureAs(kind: ModuleKind) {
|
||||
}
|
||||
|
||||
public fun KtFile.dumpTextWithErrors(): String {
|
||||
return diagnosticsHeader() + getText()
|
||||
}
|
||||
|
||||
public fun KtFile.diagnosticsHeader(): String {
|
||||
val diagnostics = analyzeFullyAndGetResult().bindingContext.getDiagnostics()
|
||||
val errors = diagnostics.filter { it.getSeverity() == Severity.ERROR }
|
||||
if (errors.isEmpty()) return getText()
|
||||
val header = errors.map { "// ERROR: " + DefaultErrorMessages.render(it).replace('\n', ' ') }.joinToString("\n", postfix = "\n")
|
||||
return header + getText()
|
||||
if (errors.isEmpty()) return ""
|
||||
return errors.map { "// ERROR: " + DefaultErrorMessages.render(it).replace('\n', ' ') }.joinToString("\n", postfix = "\n")
|
||||
}
|
||||
|
||||
public fun closeAndDeleteProject(): Unit =
|
||||
ApplicationManager.getApplication().runWriteAction() { LightPlatformTestCase.closeAndDeleteProject() }
|
||||
|
||||
public fun unInvalidateBuiltinsAndStdLib(project: Project, runnable: RunnableWithException) {
|
||||
// Doesn't work in idea 141. Shouldn't be used.
|
||||
val builtInsSources = BuiltInsReferenceResolver.getInstance(project).builtInsSources!!
|
||||
val fileManager = (PsiManager.getInstance(project) as PsiManagerEx).getFileManager()
|
||||
|
||||
val stdLibViewProviders = HashSet<KotlinClassFileViewProvider>()
|
||||
val vFileToViewProviderMap = ((PsiManager.getInstance(project) as PsiManagerEx).fileManager as FileManagerImpl).vFileToViewProviderMap
|
||||
@@ -99,11 +104,11 @@ public fun unInvalidateBuiltinsAndStdLib(project: Project, runnable: RunnableWit
|
||||
|
||||
runnable.run()
|
||||
|
||||
// Base tearDown() invalidates builtins and std-lib files. Restore them with brute force.
|
||||
// Restore mapping between PsiFiles and VirtualFiles dropped in FileManager.cleanupForNextTest(),
|
||||
// otherwise built-ins psi elements will become invalid in next test.
|
||||
fun unInvalidateFile(file: PsiFileImpl) {
|
||||
val field = javaClass<PsiFileImpl>().getDeclaredField("myInvalidated")!!
|
||||
field.setAccessible(true)
|
||||
field.set(file, false)
|
||||
val provider = file.getViewProvider();
|
||||
fileManager.setViewProvider(provider.getVirtualFile(), provider);
|
||||
}
|
||||
|
||||
builtInsSources.forEach { unInvalidateFile(it) }
|
||||
|
||||
@@ -88,7 +88,19 @@ private fun String.amendNextLinesIfNeeded(reader: OutputLineReader): String {
|
||||
nextLine = reader.readLine()
|
||||
}
|
||||
|
||||
if (nextLine != null) reader.pushBack(nextLine)
|
||||
if (nextLine != null) {
|
||||
// This code is needed for compatibility with AS 2.0 and IDEA 15.0, because of difference in android plugins
|
||||
val positionField = try {
|
||||
reader.javaClass.getDeclaredField("myPosition")
|
||||
}
|
||||
catch(e: Throwable) {
|
||||
null
|
||||
}
|
||||
if (positionField != null) {
|
||||
positionField.isAccessible = true
|
||||
positionField.setInt(reader, positionField.getInt(reader) - 1)
|
||||
}
|
||||
}
|
||||
|
||||
return builder.toString()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports any <b>import</b> statements in Kotlin code that are unused.
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,7 +6,7 @@
|
||||
<version>@snapshot@</version>
|
||||
<vendor url="http://www.jetbrains.com">JetBrains s.r.o.</vendor>
|
||||
|
||||
<idea-version since-build="143.379.11" until-build="144.9999"/>
|
||||
<idea-version since-build="141.1009.5" until-build="141.9999999"/>
|
||||
|
||||
<depends optional="true" config-file="junit.xml">JUnit</depends>
|
||||
<depends optional="true" config-file="gradle.xml">org.jetbrains.plugins.gradle</depends>
|
||||
@@ -499,16 +499,12 @@
|
||||
<debuggerClassFilterProvider implementation="org.jetbrains.kotlin.idea.debugger.filter.KotlinDebuggerInternalClassesFilterProvider"/>
|
||||
<debugger.nodeRenderer implementation="org.jetbrains.kotlin.idea.debugger.render.KotlinClassWithDelegatedPropertyRenderer"/>
|
||||
<debugger.sourcePositionProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinSourcePositionProvider"/>
|
||||
<debugger.sourcePositionHighlighter implementation="org.jetbrains.kotlin.idea.debugger.KotlinSourcePositionHighlighter"/>
|
||||
<debugger.frameExtraVarsProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinFrameExtraVariablesProvider"/>
|
||||
<debugger.extraSteppingFilter implementation="org.jetbrains.kotlin.idea.ExtraSteppingFilter"/>
|
||||
<xdebugger.settings implementation="org.jetbrains.kotlin.idea.debugger.KotlinDebuggerSettings"/>
|
||||
<xdebugger.breakpointType implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpointType"/>
|
||||
<xdebugger.breakpointType implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinLineBreakpointType" order="first"/>
|
||||
<debugger.syntheticProvider implementation="org.jetbrains.kotlin.idea.debugger.filter.KotlinSyntheticTypeComponentProvider"/>
|
||||
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpointHandlerFactory"/>
|
||||
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinLineBreakpointHandlerFactory"/>
|
||||
<debugger.jvmSteppingCommandProvider implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSteppingCommandProvider"/>
|
||||
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinBreakpointHandlerFactory"/>
|
||||
|
||||
<codeInsight.implementMethod language="kotlin" implementationClass="org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler"/>
|
||||
<codeInsight.overrideMethod language="kotlin" implementationClass="org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMembersHandler"/>
|
||||
@@ -524,10 +520,6 @@
|
||||
<callHierarchyProvider
|
||||
language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.hierarchy.calls.KotlinCallHierarchyProvider" />
|
||||
<callHierarchyProvider
|
||||
language="JAVA"
|
||||
implementationClass="org.jetbrains.kotlin.idea.hierarchy.calls.KotlinCallHierarchyProvider"
|
||||
order="first" />
|
||||
<methodHierarchyProvider
|
||||
language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.hierarchy.overrides.KotlinOverrideHierarchyProvider" />
|
||||
@@ -1094,11 +1086,6 @@
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
displayName="Convert object literal to lambda"
|
||||
groupName="Kotlin"
|
||||
@@ -1219,7 +1206,7 @@
|
||||
level="WARNING"
|
||||
/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.UnusedImportInspection"
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.KotlinUnusedImportInspection"
|
||||
displayName="Unused import directive"
|
||||
groupName="Kotlin"
|
||||
enabledByDefault="true"
|
||||
|
||||
@@ -77,7 +77,7 @@ class KotlinPluginUpdater(val propertiesComponent: PropertiesComponent) : Dispos
|
||||
|
||||
for (host in RepositoryHelper.getPluginHosts().filterNotNull()) {
|
||||
val plugins = try {
|
||||
RepositoryHelper.loadPlugins(host, null)
|
||||
RepositoryHelper.loadPlugins(host, null, null)
|
||||
}
|
||||
catch(e: Exception) {
|
||||
LOG.info("Checking custom plugin reposityory $host failed", e)
|
||||
|
||||
@@ -62,7 +62,7 @@ public class ShowExpressionTypeAction : AnAction() {
|
||||
}
|
||||
|
||||
if (type != null) {
|
||||
HintManager.getInstance().showInformationHint(editor, renderTypeHint(type))
|
||||
HintManager.getInstance().showInformationHint(editor, "<html>" + DescriptorRenderer.HTML.renderType(type) + "</html>")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,6 @@ package org.jetbrains.kotlin.idea.actions.generate
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightActionHandler
|
||||
import com.intellij.codeInsight.actions.CodeInsightAction
|
||||
import com.intellij.lang.ContextAwareActionHandler
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.actionSystem.Presentation
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
@@ -30,21 +27,6 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
|
||||
abstract class KotlinGenerateActionBase() : CodeInsightAction(), CodeInsightActionHandler {
|
||||
override fun update(
|
||||
presentation: Presentation,
|
||||
project: Project,
|
||||
editor: Editor,
|
||||
file: PsiFile,
|
||||
dataContext: DataContext,
|
||||
actionPlace: String?
|
||||
) {
|
||||
super.update(presentation, project, editor, file, dataContext, actionPlace)
|
||||
val actionHandler = handler
|
||||
if (actionHandler is ContextAwareActionHandler && presentation.isEnabled) {
|
||||
presentation.isEnabled = actionHandler.isAvailableForQuickList(editor, file, dataContext)
|
||||
}
|
||||
}
|
||||
|
||||
override fun isValidForFile(project: Project, editor: Editor, file: PsiFile): Boolean {
|
||||
if (file !is KtFile || file.isCompiled) return false
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeInsight
|
||||
|
||||
import com.intellij.lang.ExpressionTypeProvider
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.idea.actions.ShowExpressionTypeAction
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtStatementExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
|
||||
class KotlinExpressionTypeProvider : ExpressionTypeProvider<KtExpression>() {
|
||||
override fun getExpressionsAt(elementAt: PsiElement): List<KtExpression> =
|
||||
elementAt.parentsWithSelf.filterIsInstance<KtExpression>().filterNot { it.shouldSkip() }.toArrayList()
|
||||
|
||||
private fun KtExpression.shouldSkip(): Boolean {
|
||||
return this is KtStatementExpression && this !is KtFunction
|
||||
}
|
||||
|
||||
override fun getInformationHint(element: KtExpression): String {
|
||||
val type = ShowExpressionTypeAction.typeByExpression(element) ?: return "Type is unknown"
|
||||
return ShowExpressionTypeAction.renderTypeHint(type)
|
||||
}
|
||||
|
||||
override fun getErrorHint(): String = "No expression found"
|
||||
}
|
||||
@@ -21,9 +21,6 @@ import com.intellij.debugger.NoDataException
|
||||
import com.intellij.debugger.SourcePosition
|
||||
import com.intellij.debugger.engine.DebugProcess
|
||||
import com.intellij.debugger.engine.DebugProcessImpl
|
||||
import com.intellij.debugger.engine.PositionManagerEx
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContext
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
||||
import com.intellij.debugger.requests.ClassPrepareRequestor
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.roots.libraries.LibraryUtil
|
||||
@@ -33,8 +30,6 @@ import com.intellij.psi.impl.compiled.ClsFileImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.psi.util.*
|
||||
import com.intellij.util.ThreeState
|
||||
import com.intellij.xdebugger.frame.XStackFrame
|
||||
import com.sun.jdi.AbsentInformationException
|
||||
import com.sun.jdi.Location
|
||||
import com.sun.jdi.ReferenceType
|
||||
@@ -54,7 +49,6 @@ import org.jetbrains.kotlin.fileClasses.getInternalName
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeAndGetResult
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFullyAndGetResult
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.debugger.breakpoints.getLambdasAtLineIfAny
|
||||
import org.jetbrains.kotlin.idea.decompiler.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.isImportUsage
|
||||
import org.jetbrains.kotlin.idea.util.DebuggerUtils
|
||||
@@ -65,24 +59,15 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.utils.toReadOnlyList
|
||||
import java.util.*
|
||||
import com.intellij.debugger.engine.DebuggerUtils as JDebuggerUtils
|
||||
|
||||
class PositionedElement(val className: String?, val element: PsiElement?)
|
||||
|
||||
public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiRequestPositionManager, PositionManagerEx() {
|
||||
public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiRequestPositionManager {
|
||||
|
||||
private val myTypeMappers = WeakHashMap<String, CachedValue<JetTypeMapper>>()
|
||||
|
||||
override fun evaluateCondition(context: EvaluationContext, frame: StackFrameProxyImpl, location: Location, expression: String): ThreeState? {
|
||||
return ThreeState.UNSURE
|
||||
}
|
||||
|
||||
override fun createStackFrame(frame: StackFrameProxyImpl, debugProcess: DebugProcessImpl, location: Location): XStackFrame? {
|
||||
return KotlinStackFrame(frame)
|
||||
}
|
||||
|
||||
override fun getSourcePosition(location: Location?): SourcePosition? {
|
||||
if (location == null) {
|
||||
throw NoDataException.INSTANCE
|
||||
@@ -137,7 +122,10 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M
|
||||
val end = CodeInsightUtils.getEndLineOffset(file, lineNumber)
|
||||
if (start == null || end == null) return null
|
||||
|
||||
val literalsOrFunctions = getLambdasAtLineIfAny(file, lineNumber)
|
||||
val literalsOrFunctions = CodeInsightUtils.
|
||||
findElementsOfClassInRange(file, start, end, KtFunctionLiteral::class.java, KtNamedFunction::class.java).
|
||||
filter { KtPsiUtil.getParentCallIfPresent(it as KtExpression) != null }
|
||||
|
||||
if (literalsOrFunctions.isEmpty()) return null;
|
||||
|
||||
val isInLibrary = LibraryUtil.findLibraryEntry(file.virtualFile, file.project) != null
|
||||
@@ -148,16 +136,17 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M
|
||||
|
||||
val currentLocationClassName = JvmClassName.byFqNameWithoutInnerClasses(FqName(currentLocationFqName)).internalName
|
||||
for (literal in literalsOrFunctions) {
|
||||
if (isInlinedLambda(literal, typeMapper.bindingContext)) {
|
||||
if (isInsideInlineArgument(literal, location, myDebugProcess as DebugProcessImpl)) {
|
||||
return literal
|
||||
val functionLiteral = literal as KtFunction
|
||||
if (isInlinedLambda(functionLiteral, typeMapper.bindingContext)) {
|
||||
if (isInsideInlineArgument(functionLiteral, location, myDebugProcess as DebugProcessImpl)) {
|
||||
return functionLiteral
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
val internalClassName = getInternalClassNameForElement(literal.firstChild, typeMapper, file, isInLibrary).className
|
||||
if (internalClassName == currentLocationClassName) {
|
||||
return literal
|
||||
return functionLiteral
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,7 +219,7 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M
|
||||
}
|
||||
|
||||
private fun classNameForPositionAndInlinedOnes(sourcePosition: SourcePosition): List<String> {
|
||||
val result = hashSetOf<String>()
|
||||
val result = arrayListOf<String>()
|
||||
val name = classNameForPosition(sourcePosition)
|
||||
if (name != null) {
|
||||
result.add(name)
|
||||
@@ -238,22 +227,7 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M
|
||||
val list = findInlinedCalls(sourcePosition.elementAt, sourcePosition.file)
|
||||
result.addAll(list)
|
||||
|
||||
val lambdas = findLambdas(sourcePosition)
|
||||
result.addAll(lambdas)
|
||||
|
||||
return result.toReadOnlyList();
|
||||
}
|
||||
|
||||
private fun findLambdas(sourcePosition: SourcePosition): List<String> {
|
||||
return runReadAction {
|
||||
val lambdas = getLambdasAtLineIfAny(sourcePosition)
|
||||
val file = sourcePosition.file.containingFile as KtFile
|
||||
val isInLibrary = LibraryUtil.findLibraryEntry(file.virtualFile, file.project) != null
|
||||
lambdas.map {
|
||||
val typeMapper = if (!isInLibrary) prepareTypeMapper(file) else createTypeMapperForLibraryFile(it, file)
|
||||
getInternalClassNameForElement(it, typeMapper, file, isInLibrary).className
|
||||
}.filterNotNull()
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public fun classNameForPosition(sourcePosition: SourcePosition): String? {
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger
|
||||
|
||||
import com.intellij.debugger.SourcePosition
|
||||
import com.intellij.debugger.engine.SourcePositionHighlighter
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
||||
|
||||
public class KotlinSourcePositionHighlighter: SourcePositionHighlighter() {
|
||||
override fun getHighlightRange(sourcePosition: SourcePosition?): TextRange? {
|
||||
val lambda = sourcePosition?.elementAt?.parent
|
||||
if (lambda is KtFunctionLiteral) {
|
||||
return lambda.textRange
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger
|
||||
|
||||
import com.intellij.debugger.engine.JavaStackFrame
|
||||
import com.intellij.debugger.jdi.LocalVariableProxyImpl
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
||||
import com.intellij.debugger.ui.impl.watch.MethodsTracker
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl
|
||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil
|
||||
|
||||
class KotlinStackFrame(frame: StackFrameProxyImpl) : JavaStackFrame(StackFrameDescriptorImpl(frame, MethodsTracker()), true) {
|
||||
override fun getVisibleVariables(): List<LocalVariableProxyImpl>? {
|
||||
return super.getVisibleVariables().filter {
|
||||
!InlineCodegenUtil.isFakeLocalVariableForInline(it.name())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,17 +21,11 @@ import com.intellij.debugger.engine.JavaBreakpointHandler
|
||||
import com.intellij.debugger.engine.JavaBreakpointHandlerFactory
|
||||
import com.intellij.debugger.ui.breakpoints.JavaLineBreakpointType
|
||||
|
||||
public class KotlinFieldBreakpointHandlerFactory : JavaBreakpointHandlerFactory {
|
||||
public class KotlinBreakpointHandlerFactory: JavaBreakpointHandlerFactory {
|
||||
override fun createHandler(process: DebugProcessImpl): JavaBreakpointHandler? {
|
||||
return KotlinFieldBreakpointHandler(process)
|
||||
}
|
||||
}
|
||||
|
||||
public class KotlinLineBreakpointHandlerFactory: JavaBreakpointHandlerFactory {
|
||||
override fun createHandler(process: DebugProcessImpl): JavaBreakpointHandler? {
|
||||
return KotlinLineBreakpointHandler(process)
|
||||
}
|
||||
}
|
||||
|
||||
public class KotlinFieldBreakpointHandler(process: DebugProcessImpl) : JavaBreakpointHandler(javaClass<KotlinFieldBreakpointType>(), process)
|
||||
public class KotlinLineBreakpointHandler(process: DebugProcessImpl) : JavaBreakpointHandler(javaClass<KotlinLineBreakpointType>(), process)
|
||||
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger.breakpoints;
|
||||
|
||||
import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.debugger.ui.breakpoints.Breakpoint;
|
||||
import com.intellij.debugger.ui.breakpoints.BreakpointManager;
|
||||
import com.intellij.debugger.ui.breakpoints.JavaLineBreakpointType;
|
||||
import com.intellij.debugger.ui.breakpoints.LineBreakpoint;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.xdebugger.XSourcePosition;
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpoint;
|
||||
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties;
|
||||
import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties;
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons;
|
||||
import org.jetbrains.kotlin.psi.KtFunction;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
public class KotlinLineBreakpointType extends JavaLineBreakpointType {
|
||||
public KotlinLineBreakpointType() {
|
||||
super("kotlin-line", "Kotlin Line Breakpoints");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matchesPosition(@NotNull LineBreakpoint<?> breakpoint, @NotNull SourcePosition position) {
|
||||
JavaBreakpointProperties properties = getProperties(breakpoint);
|
||||
if (properties == null || properties instanceof JavaLineBreakpointProperties) {
|
||||
if (properties != null && ((JavaLineBreakpointProperties)properties).getLambdaOrdinal() == null) return true;
|
||||
|
||||
PsiElement containingMethod = getContainingMethod(breakpoint);
|
||||
if (containingMethod == null) return false;
|
||||
return inTheMethod(position, containingMethod);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiElement getContainingMethod(@NotNull LineBreakpoint<?> breakpoint) {
|
||||
SourcePosition position = breakpoint.getSourcePosition();
|
||||
if (position == null) return null;
|
||||
|
||||
JavaBreakpointProperties properties = getProperties(breakpoint);
|
||||
if (properties instanceof JavaLineBreakpointProperties) {
|
||||
Integer ordinal = ((JavaLineBreakpointProperties) properties).getLambdaOrdinal();
|
||||
PsiElement lambda = getLambdaByOrdinal(position, ordinal);
|
||||
if (lambda != null) return lambda;
|
||||
}
|
||||
|
||||
return getContainingMethod(position.getElementAt());
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static JavaBreakpointProperties getProperties(@NotNull LineBreakpoint<?> breakpoint) {
|
||||
XBreakpoint<?> xBreakpoint = breakpoint.getXBreakpoint();
|
||||
return xBreakpoint != null ? (JavaBreakpointProperties) xBreakpoint.getProperties() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static KtFunction getLambdaByOrdinal(SourcePosition position, Integer ordinal) {
|
||||
if (ordinal != null && ordinal >= 0) {
|
||||
List<KtFunction> lambdas = BreakpointTypeUtilsKt.getLambdasAtLineIfAny(position);
|
||||
if (lambdas.size() >= ordinal) {
|
||||
return lambdas.get(ordinal);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiElement getContainingMethod(@Nullable PsiElement elem) {
|
||||
//noinspection unchecked
|
||||
return PsiTreeUtil.getParentOfType(elem, KtFunction.class);
|
||||
}
|
||||
|
||||
public static boolean inTheMethod(@NotNull SourcePosition pos, @NotNull PsiElement method) {
|
||||
PsiElement elem = pos.getElementAt();
|
||||
if (elem == null) return false;
|
||||
return Comparing.equal(getContainingMethod(elem), method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canPutAt(@NotNull VirtualFile file, int line, @NotNull Project project) {
|
||||
return BreakpointTypeUtilsKt.canPutAt(file, line, project, getClass());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<JavaBreakpointVariant> computeVariants(@NotNull Project project, @NotNull XSourcePosition position) {
|
||||
return BreakpointTypeUtilsKt.computeVariants(project, position, this);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public TextRange getHighlightRange(XLineBreakpoint<JavaLineBreakpointProperties> breakpoint) {
|
||||
JavaLineBreakpointProperties properties = breakpoint.getProperties();
|
||||
if (properties != null) {
|
||||
Integer ordinal = properties.getLambdaOrdinal();
|
||||
if (ordinal != null) {
|
||||
Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint);
|
||||
if (javaBreakpoint instanceof LineBreakpoint) {
|
||||
SourcePosition position = ((LineBreakpoint) javaBreakpoint).getSourcePosition();
|
||||
if (position != null) {
|
||||
KtFunction lambda = getLambdaByOrdinal(position, ordinal);
|
||||
if (lambda != null) {
|
||||
return lambda.getTextRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public class ExactKotlinJavaBreakpointVariant extends ExactJavaBreakpointVariant {
|
||||
public ExactKotlinJavaBreakpointVariant(XSourcePosition position, KtFunction function, Integer lambdaOrdinal) {
|
||||
super(position, function, lambdaOrdinal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return KotlinIcons.LAMBDA;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,32 +16,19 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger.breakpoints
|
||||
|
||||
import com.intellij.debugger.SourcePosition
|
||||
import com.intellij.debugger.ui.breakpoints.JavaLineBreakpointType
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.xdebugger.XDebuggerUtil
|
||||
import com.intellij.xdebugger.XSourcePosition
|
||||
import com.intellij.xdebugger.impl.XSourcePositionImpl
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.getLineEndOffset
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.getLineNumber
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.getLineStartOffset
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import java.util.*
|
||||
|
||||
fun canPutAt(file: VirtualFile, line: Int, project: Project, breakpointTypeClass: Class<*>): Boolean {
|
||||
val psiFile = PsiManager.getInstance(project).findFile(file)
|
||||
@@ -74,12 +61,12 @@ fun canPutAt(file: VirtualFile, line: Int, project: Project, breakpointTypeClass
|
||||
result = KotlinFieldBreakpointType::class.java
|
||||
}
|
||||
else {
|
||||
result = KotlinLineBreakpointType::class.java
|
||||
result = null
|
||||
}
|
||||
return false
|
||||
}
|
||||
else {
|
||||
result = KotlinLineBreakpointType::class.java
|
||||
result = null
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -88,73 +75,4 @@ fun canPutAt(file: VirtualFile, line: Int, project: Project, breakpointTypeClass
|
||||
return result == breakpointTypeClass
|
||||
}
|
||||
|
||||
fun computeVariants(
|
||||
project: Project, position: XSourcePosition,
|
||||
kotlinBreakpointType: KotlinLineBreakpointType
|
||||
): List<JavaLineBreakpointType.JavaBreakpointVariant> {
|
||||
val file = PsiManager.getInstance(project).findFile(position.file) as? KtFile ?: return emptyList()
|
||||
|
||||
val pos = SourcePosition.createFromLine(file, position.line)
|
||||
val lambdas = getLambdasAtLineIfAny(pos)
|
||||
if (lambdas.isEmpty()) return emptyList()
|
||||
|
||||
val result = LinkedList<JavaLineBreakpointType.JavaBreakpointVariant>()
|
||||
|
||||
val mainMethod = KotlinLineBreakpointType.getContainingMethod(pos.elementAt)
|
||||
if (mainMethod != null) {
|
||||
result.add((kotlinBreakpointType as JavaLineBreakpointType).ExactJavaBreakpointVariant(
|
||||
XSourcePositionImpl.createByElement(mainMethod),
|
||||
mainMethod, -1))
|
||||
}
|
||||
|
||||
lambdas.forEachIndexed { ordinal, lambda ->
|
||||
result.add(kotlinBreakpointType.ExactKotlinJavaBreakpointVariant(
|
||||
XSourcePositionImpl.createByElement(lambda.bodyExpression), lambda, ordinal))
|
||||
}
|
||||
|
||||
if (result.size > 1) {
|
||||
val allBreakpoint = (kotlinBreakpointType as JavaLineBreakpointType).JavaBreakpointVariant(position)
|
||||
result.addFirst(allBreakpoint)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun getLambdasAtLineIfAny(sourcePosition: SourcePosition): List<KtFunction> {
|
||||
val file = sourcePosition.file as? KtFile ?: return emptyList()
|
||||
val lineNumber = sourcePosition.line
|
||||
return getLambdasAtLineIfAny(file, lineNumber)
|
||||
}
|
||||
|
||||
fun getLambdasAtLineIfAny(file: KtFile, line: Int): List<KtFunction> {
|
||||
var lineStartOffset = file.getLineStartOffset(line) ?: return emptyList()
|
||||
var lineEndOffset = file.getLineEndOffset(line) ?: return emptyList()
|
||||
|
||||
var topMostElement: PsiElement? = null
|
||||
var elementAt: PsiElement?
|
||||
while (topMostElement !is KtElement && lineStartOffset < lineEndOffset) {
|
||||
elementAt = file.findElementAt(lineStartOffset)
|
||||
if (elementAt != null) {
|
||||
topMostElement = CodeInsightUtils.getTopmostElementAtOffset(elementAt, lineStartOffset)
|
||||
}
|
||||
lineStartOffset++
|
||||
}
|
||||
|
||||
if (topMostElement !is KtElement) return emptyList()
|
||||
|
||||
val start = topMostElement.startOffset
|
||||
val end = topMostElement.endOffset
|
||||
|
||||
val allInlineFunctionCalls = CodeInsightUtils.
|
||||
findElementsOfClassInRange(file, start, end, KtFunction::class.java)
|
||||
.filter { KtPsiUtil.getParentCallIfPresent(it as KtExpression) != null }
|
||||
.filterIsInstance<KtFunction>()
|
||||
.toSet()
|
||||
|
||||
return allInlineFunctionCalls.filter {
|
||||
val statement = (it.bodyExpression as? KtBlockExpression)?.statements?.firstOrNull() ?: it
|
||||
statement.getLineNumber() == line && statement.getLineNumber(false) == line
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ object KotlinEvaluationBuilder: EvaluatorBuilder {
|
||||
class KotlinEvaluator(val codeFragment: KtCodeFragment, val sourcePosition: SourcePosition): Evaluator {
|
||||
override fun evaluate(context: EvaluationContextImpl): Any? {
|
||||
if (codeFragment.text.isEmpty()) {
|
||||
return context.debugProcess.virtualMachineProxy.mirrorOfVoid()
|
||||
return context.debugProcess.virtualMachineProxy.mirrorOf()
|
||||
}
|
||||
|
||||
var isCompiledDataFromCache = true
|
||||
|
||||
@@ -75,8 +75,4 @@ class DelegatedPropertyFieldDescriptor(
|
||||
|
||||
return getObject().referenceType().methodsByName(JvmAbi.getterName(fieldName))?.firstOrNull()
|
||||
}
|
||||
|
||||
override fun getDeclaredType(): String? {
|
||||
return findGetterForDelegatedProperty()?.returnType()?.name()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger.stepping;
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.SuspendContextImpl;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.xdebugger.impl.XSourcePositionImpl;
|
||||
import kotlin.IntRange;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.psi.KtFunction;
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral;
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DebuggerSteppingHelper {
|
||||
|
||||
public static DebugProcessImpl.ResumeCommand createStepOverCommand(
|
||||
final SuspendContextImpl suspendContext,
|
||||
final boolean ignoreBreakpoints,
|
||||
final KtFile file,
|
||||
final IntRange linesRange,
|
||||
final List<KtFunction> inlineArguments,
|
||||
final List<PsiElement> additionalElementsToSkip
|
||||
) {
|
||||
final DebugProcessImpl debugProcess = suspendContext.getDebugProcess();
|
||||
return debugProcess.new ResumeCommand(suspendContext) {
|
||||
@Override
|
||||
public void contextAction() {
|
||||
final StackFrameProxyImpl frameProxy = suspendContext.getFrameProxy();
|
||||
if (frameProxy != null) {
|
||||
DebugProcessImpl.ResumeCommand runToCursorCommand = ApplicationManager.getApplication().runReadAction(new Computable<DebugProcessImpl.ResumeCommand>() {
|
||||
@Override
|
||||
public DebugProcessImpl.ResumeCommand compute() {
|
||||
try {
|
||||
XSourcePositionImpl position = KotlinSteppingCommandProviderKt.getStepOverPosition(
|
||||
frameProxy.location(),
|
||||
file,
|
||||
linesRange,
|
||||
inlineArguments,
|
||||
additionalElementsToSkip
|
||||
);
|
||||
if (position != null) {
|
||||
return debugProcess.createRunToCursorCommand(suspendContext, position, ignoreBreakpoints);
|
||||
}
|
||||
}
|
||||
catch (EvaluateException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if (runToCursorCommand != null) {
|
||||
runToCursorCommand.contextAction();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
debugProcess.createStepOutCommand(suspendContext).contextAction();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static DebugProcessImpl.ResumeCommand createStepOutCommand(
|
||||
final SuspendContextImpl suspendContext,
|
||||
final boolean ignoreBreakpoints,
|
||||
final List<KtNamedFunction> inlineFunctions,
|
||||
final KtFunctionLiteral inlineArgument
|
||||
) {
|
||||
final DebugProcessImpl debugProcess = suspendContext.getDebugProcess();
|
||||
return debugProcess.new ResumeCommand(suspendContext) {
|
||||
@Override
|
||||
public void contextAction() {
|
||||
final StackFrameProxyImpl frameProxy = suspendContext.getFrameProxy();
|
||||
if (frameProxy != null) {
|
||||
DebugProcessImpl.ResumeCommand runToCursorCommand = ApplicationManager.getApplication().runReadAction(new Computable<DebugProcessImpl.ResumeCommand>() {
|
||||
@Override
|
||||
public DebugProcessImpl.ResumeCommand compute() {
|
||||
try {
|
||||
XSourcePositionImpl position = KotlinSteppingCommandProviderKt.getStepOutPosition(
|
||||
frameProxy.location(),
|
||||
suspendContext,
|
||||
inlineFunctions,
|
||||
inlineArgument
|
||||
);
|
||||
if (position != null) {
|
||||
return debugProcess.createRunToCursorCommand(suspendContext, position, ignoreBreakpoints);
|
||||
}
|
||||
}
|
||||
catch (EvaluateException ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if (runToCursorCommand != null) {
|
||||
runToCursorCommand.contextAction();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
debugProcess.createStepOverCommand(suspendContext, ignoreBreakpoints).contextAction();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -36,11 +36,11 @@ public class KotlinLambdaMethodFilter(
|
||||
private val myLastStatementLine: Int
|
||||
|
||||
init {
|
||||
val body = lambda.bodyExpression
|
||||
if (body != null && lambda.isMultiLine()) {
|
||||
if (lambda.isMultiLine()) {
|
||||
var firstStatementPosition: SourcePosition? = null
|
||||
var lastStatementPosition: SourcePosition? = null
|
||||
val statements = (body as? KtBlockExpression)?.statements ?: listOf(body)
|
||||
val body = lambda.bodyExpression as KtBlockExpression
|
||||
val statements = body.statements
|
||||
if (statements.isNotEmpty()) {
|
||||
firstStatementPosition = SourcePosition.createFromElement(statements.first())
|
||||
if (firstStatementPosition != null) {
|
||||
|
||||
@@ -30,8 +30,6 @@ public class KotlinLambdaSmartStepTarget(
|
||||
lines: Range<Int>,
|
||||
val isInline: Boolean
|
||||
): SmartStepTarget(label, highlightElement, true, lines) {
|
||||
override fun getIcon() = KotlinIcons.LAMBDA
|
||||
|
||||
fun getLambda() = getHighlightElement() as KtFunction
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -17,13 +17,6 @@ public class KotlinMethodSmartStepTarget(
|
||||
highlightElement: PsiElement,
|
||||
lines: Range<Int>
|
||||
): SmartStepTarget(label, highlightElement, false, lines) {
|
||||
override fun getIcon(): Icon? {
|
||||
return when {
|
||||
resolvedElement is KtNamedFunction && resolvedElement.getReceiverTypeReference() != null -> KotlinIcons.EXTENSION_FUNCTION
|
||||
else -> KotlinIcons.FUNCTION
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val renderer = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.withOptions {
|
||||
parameterNameRenderingPolicy = ParameterNameRenderingPolicy.NONE
|
||||
|
||||
@@ -78,7 +78,7 @@ public class KotlinSmartStepIntoHandler : JvmSmartStepIntoHandler() {
|
||||
private fun recordFunctionLiteral(function: KtFunction): Boolean {
|
||||
val context = function.analyze()
|
||||
val resolvedCall = function.getParentCall(context).getResolvedCall(context)
|
||||
if (resolvedCall != null) {
|
||||
if (resolvedCall != null && !InlineUtil.isInline(resolvedCall.getResultingDescriptor())) {
|
||||
val arguments = resolvedCall.valueArguments
|
||||
for ((param, argument) in arguments) {
|
||||
if (argument.arguments.any { getArgumentExpression(it) == function }) {
|
||||
|
||||
@@ -1,406 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger.stepping
|
||||
|
||||
import com.intellij.debugger.NoDataException
|
||||
import com.intellij.debugger.SourcePosition
|
||||
import com.intellij.debugger.engine.DebugProcessImpl
|
||||
import com.intellij.debugger.engine.SuspendContextImpl
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl
|
||||
import com.intellij.debugger.impl.JvmSteppingCommandProvider
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.xdebugger.impl.XSourcePositionImpl
|
||||
import com.sun.jdi.AbsentInformationException
|
||||
import com.sun.jdi.Location
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.getLineEndOffset
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.getLineNumber
|
||||
import org.jetbrains.kotlin.idea.core.refactoring.getLineStartOffset
|
||||
import org.jetbrains.kotlin.idea.util.DebuggerUtils
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
public class KotlinSteppingCommandProvider: JvmSteppingCommandProvider() {
|
||||
override fun getStepOverCommand(
|
||||
suspendContext: SuspendContextImpl?,
|
||||
ignoreBreakpoints: Boolean,
|
||||
stepSize: Int
|
||||
): DebugProcessImpl.ResumeCommand? {
|
||||
if (suspendContext == null || suspendContext.isResumed) return null
|
||||
|
||||
val sourcePosition = suspendContext.debugProcess.debuggerContext.sourcePosition ?: return null
|
||||
return getStepOverCommand(suspendContext, ignoreBreakpoints, sourcePosition)
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun getStepOverCommand(
|
||||
suspendContext: SuspendContextImpl,
|
||||
ignoreBreakpoints: Boolean,
|
||||
debuggerContext: DebuggerContextImpl
|
||||
): DebugProcessImpl.ResumeCommand? {
|
||||
return getStepOverCommand(suspendContext, ignoreBreakpoints, debuggerContext.sourcePosition)
|
||||
}
|
||||
|
||||
fun getStepOverCommand(suspendContext: SuspendContextImpl, ignoreBreakpoints: Boolean, sourcePosition: SourcePosition): DebugProcessImpl.ResumeCommand? {
|
||||
val file = sourcePosition.file as? KtFile ?: return null
|
||||
if (sourcePosition.line < 0) return null
|
||||
|
||||
val containingFunction = sourcePosition.elementAt.parents.firstOrNull { it is KtNamedFunction && !it.isLocal } ?: return null
|
||||
|
||||
val startLineNumber = containingFunction.getLineNumber(true)
|
||||
val endLineNumber = containingFunction.getLineNumber(false)
|
||||
if (startLineNumber > endLineNumber) return null
|
||||
|
||||
val linesRange = startLineNumber + 1..endLineNumber + 1
|
||||
|
||||
val inlineFunctionCalls = getInlineFunctionCallsIfAny(sourcePosition)
|
||||
if (inlineFunctionCalls.isEmpty()) return null
|
||||
|
||||
val inlineArguments = getInlineArgumentsIfAny(inlineFunctionCalls)
|
||||
|
||||
if (inlineArguments.any { it.shouldNotUseStepOver(sourcePosition.elementAt) }) {
|
||||
return null
|
||||
}
|
||||
|
||||
val additionalElementsToSkip = sourcePosition.elementAt.getAdditionalElementsToSkip()
|
||||
|
||||
return DebuggerSteppingHelper.createStepOverCommand(suspendContext, ignoreBreakpoints, file, linesRange, inlineArguments, additionalElementsToSkip)
|
||||
}
|
||||
|
||||
private fun PsiElement.getAdditionalElementsToSkip(): List<PsiElement> {
|
||||
val result = arrayListOf<PsiElement>()
|
||||
val ifParent = getParentOfType<KtIfExpression>(false)
|
||||
if (ifParent != null) {
|
||||
if (ifParent.then.contains(this)) {
|
||||
ifParent.elseKeyword?.let { result.add(it) }
|
||||
ifParent.`else`?.let { result.add(it) }
|
||||
}
|
||||
}
|
||||
val tryParent = getParentOfType<KtTryExpression>(false)
|
||||
if (tryParent != null) {
|
||||
val catchClause = getParentOfType<KtCatchClause>(false)
|
||||
if (catchClause != null) {
|
||||
result.addAll(tryParent.catchClauses.filter { it != catchClause })
|
||||
}
|
||||
}
|
||||
|
||||
val whenEntry = getParentOfType<KtWhenEntry>(false)
|
||||
if (whenEntry != null) {
|
||||
if (whenEntry.expression.contains(this)) {
|
||||
val whenParent = whenEntry.getParentOfType<KtWhenExpression>(false)
|
||||
if (whenParent != null) {
|
||||
result.addAll(whenParent.entries.filter { it != whenEntry })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun PsiElement.shouldNotUseStepOver(elementAt: PsiElement): Boolean {
|
||||
val ifParent = getParentOfType<KtIfExpression>(false)
|
||||
if (ifParent != null) {
|
||||
// if (inlineFunCall()) {...}
|
||||
if (ifParent.condition.contains(this)) {
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
<caret>if (...) inlineFunCall()
|
||||
else inlineFunCall()
|
||||
*/
|
||||
val ifParentElementAt = elementAt.getParentOfType<KtIfExpression>(false)
|
||||
if (ifParentElementAt == null) {
|
||||
if (ifParent.then.contains(this)) {
|
||||
return true
|
||||
}
|
||||
if (ifParent.`else`.contains(this)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val tryParent = getParentOfType<KtTryExpression>(false)
|
||||
if (tryParent != null) {
|
||||
/* try { inlineFunCall() }
|
||||
catch()...
|
||||
*/
|
||||
if (tryParent.tryBlock.contains(this)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
val whenEntry = getParentOfType<KtWhenEntry>(false)
|
||||
if (whenEntry != null) {
|
||||
// <caret>inlineFunCall -> ...
|
||||
if (whenEntry.conditions.any { it.contains(this) } ) {
|
||||
return true
|
||||
}
|
||||
|
||||
// <caret>1 == 2 -> inlineFunCall()
|
||||
if (whenEntry.expression.contains(this)) {
|
||||
val parentEntryElementAt = elementAt.getParentOfType<KtWhenEntry>(false) ?: return true
|
||||
return parentEntryElementAt == whenEntry &&
|
||||
whenEntry.conditions.any { it.contains(elementAt) }
|
||||
}
|
||||
}
|
||||
|
||||
val whileParent = getParentOfType<KtWhileExpression>(false)
|
||||
if (whileParent != null) {
|
||||
// last statement in while
|
||||
return (whileParent.body as? KtBlockExpression)?.statements?.lastOrNull()?.getLineNumber() == elementAt.getLineNumber()
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun PsiElement?.contains(element: PsiElement): Boolean {
|
||||
return this?.textRange?.contains(element.textRange) ?: false
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun getStepOutCommand(suspendContext: SuspendContextImpl, debugContext: DebuggerContextImpl): DebugProcessImpl.ResumeCommand? {
|
||||
return getStepOutCommand(suspendContext, debugContext.sourcePosition)
|
||||
}
|
||||
|
||||
override fun getStepOutCommand(suspendContext: SuspendContextImpl?, stepSize: Int): DebugProcessImpl.ResumeCommand? {
|
||||
if (suspendContext == null || suspendContext.isResumed) return null
|
||||
|
||||
val sourcePosition = suspendContext.debugProcess.debuggerContext.sourcePosition ?: return null
|
||||
return getStepOutCommand(suspendContext, sourcePosition)
|
||||
}
|
||||
|
||||
private fun getStepOutCommand(suspendContext: SuspendContextImpl, sourcePosition: SourcePosition): DebugProcessImpl.ResumeCommand? {
|
||||
val file = sourcePosition.file as? KtFile ?: return null
|
||||
if (sourcePosition.line < 0) return null
|
||||
|
||||
val lineStartOffset = file.getLineStartOffset(sourcePosition.line) ?: return null
|
||||
|
||||
val inlineFunctions = getInlineFunctionsIfAny(file, lineStartOffset)
|
||||
val inlinedArgument = getInlineArgumentIfAny(file, lineStartOffset)
|
||||
|
||||
if (inlineFunctions.isEmpty() && inlinedArgument == null) return null
|
||||
|
||||
return DebuggerSteppingHelper.createStepOutCommand(suspendContext, true, inlineFunctions, inlinedArgument)
|
||||
}
|
||||
|
||||
private fun getInlineFunctionsIfAny(file: KtFile, offset: Int): List<KtNamedFunction> {
|
||||
val elementAt = file.findElementAt(offset) ?: return emptyList()
|
||||
val containingFunction = elementAt.getParentOfType<KtNamedFunction>(false) ?: return emptyList()
|
||||
|
||||
val descriptor = containingFunction.resolveToDescriptor()
|
||||
if (!InlineUtil.isInline(descriptor)) return emptyList()
|
||||
|
||||
val inlineFunctionsCalls = DebuggerUtils.analyzeElementWithInline(
|
||||
containingFunction.getResolutionFacade(),
|
||||
containingFunction.analyzeFully(),
|
||||
containingFunction,
|
||||
false
|
||||
).filterIsInstance<KtNamedFunction>()
|
||||
|
||||
return inlineFunctionsCalls
|
||||
}
|
||||
|
||||
private fun getInlineArgumentsIfAny(inlineFunctionCalls: List<KtCallExpression>): List<KtFunction> {
|
||||
return inlineFunctionCalls.flatMap {
|
||||
it.valueArguments
|
||||
.map { getArgumentExpression(it) }
|
||||
.filterIsInstance<KtFunction>()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getArgumentExpression(it: ValueArgument) = (it.getArgumentExpression() as? KtFunctionLiteralExpression)?.functionLiteral ?: it.getArgumentExpression()
|
||||
|
||||
private fun getInlineFunctionCallsIfAny(sourcePosition: SourcePosition): List<KtCallExpression> {
|
||||
val file = sourcePosition.file as? KtFile ?: return emptyList()
|
||||
val lineNumber = sourcePosition.line
|
||||
var elementAt = sourcePosition.elementAt
|
||||
|
||||
var startOffset = file.getLineStartOffset(lineNumber) ?: elementAt.startOffset
|
||||
var endOffset = file.getLineEndOffset(lineNumber) ?: elementAt.endOffset
|
||||
|
||||
var topMostElement: PsiElement? = null
|
||||
while (topMostElement !is KtElement && startOffset < endOffset) {
|
||||
elementAt = file.findElementAt(startOffset)
|
||||
if (elementAt != null) {
|
||||
topMostElement = CodeInsightUtils.getTopmostElementAtOffset(elementAt, startOffset)
|
||||
}
|
||||
startOffset++
|
||||
}
|
||||
|
||||
if (topMostElement !is KtElement) return emptyList()
|
||||
|
||||
val start = topMostElement.startOffset
|
||||
val end = topMostElement.endOffset
|
||||
|
||||
fun isInlineCall(expr: KtExpression): Boolean {
|
||||
val context = expr.analyze(BodyResolveMode.PARTIAL)
|
||||
val resolvedCall = expr.getResolvedCall(context) ?: return false
|
||||
return InlineUtil.isInline(resolvedCall.resultingDescriptor)
|
||||
}
|
||||
|
||||
val allInlineFunctionCalls = CodeInsightUtils.
|
||||
findElementsOfClassInRange(file, start, end, KtExpression::class.java)
|
||||
.map { KtPsiUtil.getParentCallIfPresent(it as KtExpression) }
|
||||
.filterIsInstance<KtCallExpression>()
|
||||
.filter { isInlineCall(it) }
|
||||
.toSet()
|
||||
|
||||
// It is necessary to check range because of multiline assign
|
||||
var linesRange = lineNumber..lineNumber
|
||||
return allInlineFunctionCalls.filter {
|
||||
val shouldInclude = it.getLineNumber() in linesRange
|
||||
if (shouldInclude) {
|
||||
linesRange = Math.min(linesRange.start, it.getLineNumber())..Math.max(linesRange.end, it.getLineNumber(false))
|
||||
}
|
||||
shouldInclude
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getStepOverPosition(
|
||||
location: Location,
|
||||
file: KtFile,
|
||||
range: Range<Int>,
|
||||
inlinedArguments: List<KtElement>,
|
||||
elementsToSkip: List<PsiElement>
|
||||
): XSourcePositionImpl? {
|
||||
val computedReferenceType = location.declaringType() ?: return null
|
||||
|
||||
fun isLocationSuitable(nextLocation: Location): Boolean {
|
||||
if (nextLocation.method() != location.method() || nextLocation.lineNumber() !in range) {
|
||||
return false
|
||||
}
|
||||
|
||||
return try {
|
||||
nextLocation.sourceName("Kotlin") == file.name
|
||||
}
|
||||
catch(e: AbsentInformationException) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
val locations = computedReferenceType.allLineLocations()
|
||||
.dropWhile { it != location }
|
||||
.drop(1)
|
||||
.filter { isLocationSuitable(it) }
|
||||
.dropWhile { it.lineNumber() == location.lineNumber() }
|
||||
|
||||
for (locationAtLine in locations) {
|
||||
val lineNumber = locationAtLine.lineNumber()
|
||||
val lineStartOffset = file.getLineStartOffset(lineNumber - 1) ?: continue
|
||||
if (inlinedArguments.any { it.textRange.contains(lineStartOffset) }) continue
|
||||
if (elementsToSkip.any { it.textRange.contains(lineStartOffset) }) continue
|
||||
|
||||
val elementAt = file.findElementAt(lineStartOffset) ?: continue
|
||||
|
||||
return XSourcePositionImpl.createByElement(elementAt) ?: return null
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun getStepOutPosition(
|
||||
location: Location,
|
||||
suspendContext: SuspendContextImpl,
|
||||
inlineFunctions: List<KtNamedFunction>,
|
||||
inlinedArgument: KtFunctionLiteral?
|
||||
): XSourcePositionImpl? {
|
||||
val computedReferenceType = location.declaringType() ?: return null
|
||||
|
||||
val locations = computedReferenceType.allLineLocations()
|
||||
val nextLineLocations = locations.dropWhile { it.lineNumber() != location.lineNumber() }.filter { it.method() == location.method() }
|
||||
|
||||
if (inlineFunctions.isNotEmpty()) {
|
||||
return suspendContext.getXPositionForStepOutFromInlineFunction(nextLineLocations, inlineFunctions) ?: return null
|
||||
}
|
||||
|
||||
if (inlinedArgument != null) {
|
||||
return suspendContext.getXPositionForStepOutFromInlinedArgument(nextLineLocations, inlinedArgument) ?: return null
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun SuspendContextImpl.getXPositionForStepOutFromInlineFunction(
|
||||
locations: List<Location>,
|
||||
inlineFunctionsToSkip: List<KtNamedFunction>
|
||||
): XSourcePositionImpl? {
|
||||
return getNextPositionWithFilter(locations) {
|
||||
file, offset ->
|
||||
if (inlineFunctionsToSkip.any { it.textRange.contains(offset) }) {
|
||||
return@getNextPositionWithFilter true
|
||||
}
|
||||
|
||||
val inlinedArgument = getInlineArgumentIfAny(file, offset)
|
||||
inlinedArgument != null && inlinedArgument.textRange.contains(offset)
|
||||
}
|
||||
}
|
||||
|
||||
private fun SuspendContextImpl.getXPositionForStepOutFromInlinedArgument(
|
||||
locations: List<Location>,
|
||||
inlinedArgumentToSkip: KtFunctionLiteral
|
||||
): XSourcePositionImpl? {
|
||||
return getNextPositionWithFilter(locations) {
|
||||
file, offset ->
|
||||
inlinedArgumentToSkip.textRange.contains(offset)
|
||||
}
|
||||
}
|
||||
|
||||
private fun SuspendContextImpl.getNextPositionWithFilter(
|
||||
locations: List<Location>,
|
||||
skip: (KtFile, Int) -> Boolean
|
||||
): XSourcePositionImpl? {
|
||||
for (location in locations) {
|
||||
val file = try {
|
||||
this.debugProcess.positionManager.getSourcePosition(location)?.file as? KtFile
|
||||
}
|
||||
catch(e: NoDataException) {
|
||||
null
|
||||
} ?: continue
|
||||
|
||||
val currentLine = location.lineNumber() - 1
|
||||
val lineStartOffset = file.getLineStartOffset(currentLine) ?: continue
|
||||
if (skip(file, lineStartOffset)) continue
|
||||
|
||||
val elementAt = file.findElementAt(lineStartOffset) ?: continue
|
||||
return XSourcePositionImpl.createByElement(elementAt)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getInlineArgumentIfAny(file: KtFile, offset: Int): KtFunctionLiteral? {
|
||||
val elementAt = file.findElementAt(offset) ?: return null
|
||||
val functionLiteralExpression = elementAt.getParentOfType<KtFunctionLiteralExpression>(false) ?: return null
|
||||
|
||||
val context = functionLiteralExpression.analyze(BodyResolveMode.PARTIAL)
|
||||
if (!InlineUtil.isInlinedArgument(functionLiteralExpression.functionLiteral, context, false)) return null
|
||||
|
||||
return functionLiteralExpression.functionLiteral
|
||||
}
|
||||
@@ -18,18 +18,18 @@ package org.jetbrains.kotlin.idea.findUsages.handlers
|
||||
|
||||
import com.intellij.find.findUsages.AbstractFindUsagesDialog
|
||||
import com.intellij.find.findUsages.FindUsagesOptions
|
||||
import com.intellij.find.findUsages.JavaFindUsagesHelper
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.meta.PsiMetaOwner
|
||||
import com.intellij.psi.search.PsiElementProcessor
|
||||
import com.intellij.psi.search.PsiElementProcessorAdapter
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import com.intellij.psi.xml.XmlAttributeValue
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import com.intellij.util.FilteredQuery
|
||||
import com.intellij.util.Processor
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.kotlin.asJava.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
@@ -196,7 +196,7 @@ public class KotlinFindClassUsagesHandler(
|
||||
else -> null
|
||||
} ?: return Collections.emptyList()
|
||||
|
||||
return JavaFindUsagesHelper.getElementNames(psiClass)
|
||||
return getElementNames(psiClass)
|
||||
}
|
||||
|
||||
protected override fun isSearchForTextOccurencesAvailable(psiElement: PsiElement, isSingleFile: Boolean): Boolean {
|
||||
@@ -206,4 +206,58 @@ public class KotlinFindClassUsagesHandler(
|
||||
public override fun getFindUsagesOptions(dataContext: DataContext?): FindUsagesOptions {
|
||||
return factory.findClassOptions
|
||||
}
|
||||
|
||||
fun getElementNames(element: PsiElement): Set<String> {
|
||||
if (element is PsiDirectory) {
|
||||
// normalize a directory to a corresponding package
|
||||
val aPackage = runReadAction { JavaDirectoryService.getInstance().getPackage(element) }
|
||||
return if (aPackage == null) emptySet<String>() else getElementNames(aPackage)
|
||||
}
|
||||
|
||||
val result = HashSet<String>()
|
||||
|
||||
runReadAction {
|
||||
when (element) {
|
||||
is PsiPackage -> {
|
||||
ContainerUtil.addIfNotNull(result, element.qualifiedName)
|
||||
}
|
||||
is PsiClass -> {
|
||||
val qname = element.qualifiedName
|
||||
if (qname != null) {
|
||||
result.add(qname)
|
||||
val topLevelClass = PsiUtil.getTopLevelClass(element)
|
||||
if (topLevelClass != null) {
|
||||
val topName = topLevelClass.qualifiedName
|
||||
assert(topName != null)
|
||||
if (qname.length() > topName!!.length()) {
|
||||
result.add(topName + qname.substring(topName.length()).replace('.', '$'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is PsiMethod -> {
|
||||
ContainerUtil.addIfNotNull(result, element.name)
|
||||
}
|
||||
is PsiVariable -> {
|
||||
ContainerUtil.addIfNotNull(result, element.name)
|
||||
}
|
||||
is PsiMetaOwner -> {
|
||||
val metaData = element.metaData
|
||||
if (metaData != null) {
|
||||
ContainerUtil.addIfNotNull(result, metaData.name)
|
||||
}
|
||||
}
|
||||
is PsiNamedElement -> {
|
||||
ContainerUtil.addIfNotNull(result, element.name)
|
||||
}
|
||||
is XmlAttributeValue -> {
|
||||
ContainerUtil.addIfNotNull(result, element.value)
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ public class KotlinCallHierarchyNodeDescriptor extends HierarchyNodeDescriptor i
|
||||
private int usageCount = 0;
|
||||
private final Set<PsiReference> references = new HashSet<PsiReference>();
|
||||
private final CallHierarchyNodeDescriptor javaDelegate;
|
||||
private final PsiElement psiElement;
|
||||
|
||||
public KotlinCallHierarchyNodeDescriptor(@NotNull Project project,
|
||||
HierarchyNodeDescriptor parentDescriptor,
|
||||
@@ -59,6 +60,7 @@ public class KotlinCallHierarchyNodeDescriptor extends HierarchyNodeDescriptor i
|
||||
boolean isBase,
|
||||
boolean navigateToReference) {
|
||||
super(project, parentDescriptor, element, isBase);
|
||||
this.psiElement = element;
|
||||
this.javaDelegate = new CallHierarchyNodeDescriptor(myProject, null, element, isBase, navigateToReference);
|
||||
}
|
||||
|
||||
@@ -73,6 +75,10 @@ public class KotlinCallHierarchyNodeDescriptor extends HierarchyNodeDescriptor i
|
||||
javaDelegate.addReference(reference);
|
||||
}
|
||||
|
||||
private PsiElement getPsiElement() {
|
||||
return psiElement;
|
||||
}
|
||||
|
||||
public final PsiElement getTargetElement(){
|
||||
return getPsiElement();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage;
|
||||
import org.jetbrains.kotlin.idea.hierarchy.HierarchyUtils;
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
@@ -42,7 +43,7 @@ public class KotlinCallHierarchyProvider implements HierarchyProvider {
|
||||
if (element == null) return null;
|
||||
|
||||
element = HierarchyUtils.getCallHierarchyElement(element);
|
||||
if (element instanceof KtFile) return null;
|
||||
if (element instanceof KtFile || element.getLanguage() != KotlinLanguage.INSTANCE) return null;
|
||||
|
||||
return element;
|
||||
}
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.execution.lineMarker.ExecutorAction
|
||||
import com.intellij.execution.lineMarker.RunLineMarkerContributor
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.MainFunctionDetector
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
|
||||
|
||||
public class KotlinRunLineMarkerContributor : RunLineMarkerContributor() {
|
||||
override fun getInfo(element: PsiElement?): RunLineMarkerContributor.Info? {
|
||||
val function = element?.parent as? KtNamedFunction
|
||||
if (function == null) return null
|
||||
|
||||
if (function.nameIdentifier != element) return null
|
||||
|
||||
val detector = MainFunctionDetector { function ->
|
||||
function.resolveToDescriptor() as FunctionDescriptor
|
||||
}
|
||||
|
||||
if (detector.isMain(function)) {
|
||||
return RunLineMarkerContributor.Info(KotlinIcons.LAUNCH, null, ExecutorAction.getActions(0))
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter
|
||||
|
||||
import com.intellij.codeInsight.TestFrameworks
|
||||
import com.intellij.execution.TestStateStorage
|
||||
import com.intellij.execution.lineMarker.ExecutorAction
|
||||
import com.intellij.execution.lineMarker.RunLineMarkerContributor
|
||||
import com.intellij.execution.testframework.TestIconMapper
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.asJava.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import javax.swing.Icon
|
||||
|
||||
class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
|
||||
private fun getTestStateIcon(url: String, project: Project): Icon? {
|
||||
val state = TestStateStorage.getInstance(project).getState(url) ?: return null
|
||||
val magnitude = TestIconMapper.getMagnitude(state.magnitude)
|
||||
return TestIconMapper.getIcon(magnitude)
|
||||
}
|
||||
|
||||
override fun getInfo(element: PsiElement): RunLineMarkerContributor.Info? {
|
||||
val declaration = element.getStrictParentOfType<KtNamedDeclaration>() ?: return null
|
||||
if (declaration.nameIdentifier != element) return null
|
||||
|
||||
// To prevent IDEA failing on red code
|
||||
if (declaration.resolveToDescriptorIfAny() == null) return null
|
||||
|
||||
val project = element.project
|
||||
|
||||
val (url, framework) = when (declaration) {
|
||||
is KtClassOrObject -> {
|
||||
val lightClass = declaration.toLightClass() ?: return null
|
||||
val framework = TestFrameworks.detectFramework(lightClass) ?: return null
|
||||
if (!framework.isTestClass(lightClass)) return null
|
||||
|
||||
"java:suite://${lightClass.qualifiedName!!}" to framework
|
||||
}
|
||||
|
||||
is KtNamedFunction -> {
|
||||
val lightMethod = declaration.toLightMethods().firstOrNull() ?: return null
|
||||
val lightClass = lightMethod.containingClass as? KtLightClass ?: return null
|
||||
val framework = TestFrameworks.detectFramework(lightClass) ?: return null
|
||||
if (!framework.isTestMethod(lightMethod)) return null
|
||||
|
||||
"java:test://${lightClass.qualifiedName}.${lightMethod.name}" to framework
|
||||
}
|
||||
|
||||
else -> return null
|
||||
}
|
||||
|
||||
val icon = getTestStateIcon(url, project) ?: framework.icon
|
||||
return RunLineMarkerContributor.Info(icon, { "Run Test" }, ExecutorAction.getActions(1))
|
||||
}
|
||||
}
|
||||
@@ -89,6 +89,7 @@ public class KotlinCleanupInspection(): LocalInspectionTool(), CleanupLocalInspe
|
||||
Errors.USELESS_ELVIS,
|
||||
ErrorsJvm.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION,
|
||||
Errors.DEPRECATION,
|
||||
Errors.DEPRECATION_ERROR,
|
||||
Errors.NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION,
|
||||
Errors.OPERATOR_MODIFIER_REQUIRED,
|
||||
Errors.DEPRECATED_UNARY_PLUS_MINUS,
|
||||
|
||||
@@ -21,8 +21,7 @@ import com.intellij.codeInsight.actions.OptimizeImportsProcessor
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonListeners
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonProgressIndicator
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightingSessionImpl
|
||||
import com.intellij.codeInsight.daemon.impl.ProgressableTextEditorHighlightingPass
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction
|
||||
import com.intellij.codeInspection.InspectionManager
|
||||
import com.intellij.codeInspection.LocalQuickFix
|
||||
@@ -50,7 +49,7 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.ImportPath
|
||||
import java.util.*
|
||||
|
||||
class UnusedImportInspection : AbstractKotlinInspection() {
|
||||
class KotlinUnusedImportInspection : AbstractKotlinInspection() {
|
||||
override fun runForWholeFile() = true
|
||||
|
||||
override fun checkFile(file: PsiFile, manager: InspectionManager, isOnTheFly: Boolean): Array<out ProblemDescriptor>? {
|
||||
@@ -132,8 +131,8 @@ class UnusedImportInspection : AbstractKotlinInspection() {
|
||||
// unwrap progress indicator
|
||||
val progress = sequence(ProgressManager.getInstance().progressIndicator) {
|
||||
(it as? ProgressWrapper)?.originalProgressIndicator
|
||||
}.last() as DaemonProgressIndicator
|
||||
val highlightingSession = HighlightingSessionImpl.getHighlightingSession(file, progress)
|
||||
}.last()
|
||||
val highlightingSession = ProgressableTextEditorHighlightingPass.getHighlightingSession(progress)
|
||||
|
||||
val project = highlightingSession.project
|
||||
val editor = highlightingSession.editor
|
||||
@@ -150,11 +149,11 @@ class UnusedImportInspection : AbstractKotlinInspection() {
|
||||
}
|
||||
}
|
||||
|
||||
Disposer.register(progress, invokeFixLater)
|
||||
Disposer.register(highlightingSession, invokeFixLater)
|
||||
|
||||
if (progress.isCanceled) {
|
||||
Disposer.dispose(invokeFixLater)
|
||||
Disposer.dispose(progress)
|
||||
Disposer.dispose(highlightingSession)
|
||||
progress.checkCanceled()
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
|
||||
import org.jetbrains.kotlin.idea.findUsages.handlers.KotlinFindClassUsagesHandler
|
||||
import org.jetbrains.kotlin.idea.project.ProjectStructureUtil
|
||||
import org.jetbrains.kotlin.idea.search.usagesSearch.*
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
@@ -71,6 +72,10 @@ public class UnusedSymbolInspection : AbstractKotlinInspection() {
|
||||
private val javaInspection = UnusedDeclarationInspection()
|
||||
|
||||
public fun isEntryPoint(declaration: KtNamedDeclaration): Boolean {
|
||||
// TODO Workaround for EA-64030 - IOE: PsiJavaParserFacadeImpl.createAnnotationFromText
|
||||
// This should be fixed on IDEA side: ClsAnnotation should not throw exceptions when annotation class has Java keyword
|
||||
if (declaration.getAnnotationEntries().any { it.getTypeReference()?.getText()?.endsWith("native") ?: false }) return false
|
||||
|
||||
val lightElement: PsiElement? = when (declaration) {
|
||||
is KtClassOrObject -> declaration.toLightClass()
|
||||
is KtNamedFunction, is KtSecondaryConstructor -> LightClassUtil.getLightClassMethod(declaration as KtFunction)
|
||||
|
||||
@@ -95,7 +95,7 @@ public class AddForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpre
|
||||
else -> templateBuilder.setEndVariableBefore(body)
|
||||
}
|
||||
|
||||
templateBuilder.run(editor, true)
|
||||
templateBuilder.run(editor, false)
|
||||
}
|
||||
|
||||
private fun createWithIndexExpression(originalExpression: KtExpression): KtExpression {
|
||||
|
||||
@@ -23,8 +23,12 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
|
||||
public class ConvertAssertToIfWithThrowIntention : SelfTargetingIntention<KtCallExpression>(javaClass(), "Replace 'assert' with 'if' statement"), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtCallExpression, caretOffset: Int): Boolean {
|
||||
@@ -44,17 +48,21 @@ public class ConvertAssertToIfWithThrowIntention : SelfTargetingIntention<KtCall
|
||||
override fun applyTo(element: KtCallExpression, editor: Editor) {
|
||||
val args = element.getValueArguments()
|
||||
val conditionText = args[0]?.getArgumentExpression()?.getText() ?: return
|
||||
val functionLiteral = element.getFunctionLiteralArguments().singleOrNull()
|
||||
val messageIsFunction = messageIsFunction(element)
|
||||
|
||||
val functionLiteralArgument = element.functionLiteralArguments.singleOrNull()
|
||||
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
|
||||
val messageExpr = when {
|
||||
args.size() == 2 -> args[1]?.getArgumentExpression() ?: return
|
||||
functionLiteral != null -> functionLiteral!!
|
||||
else -> psiFactory.createExpression("\"Assertion failed\"")
|
||||
val messageFunctionExpr = when {
|
||||
args.size == 2 -> args[1]?.getArgumentExpression() ?: return
|
||||
functionLiteralArgument != null -> functionLiteralArgument.getFunctionLiteral()
|
||||
else -> null
|
||||
}
|
||||
|
||||
val extractedMessageSingleExpr = (messageFunctionExpr as? KtFunctionLiteralExpression)?.let { extractMessageSingleExpression(it, bindingContext) }
|
||||
|
||||
val messageIsFunction = extractedMessageSingleExpr == null && messageIsFunction(element, bindingContext)
|
||||
val messageExpr = extractedMessageSingleExpr ?: messageFunctionExpr ?: psiFactory.createExpression("\"Assertion failed\"")
|
||||
|
||||
val ifExpression = replaceWithIfThenThrowExpression(element)
|
||||
|
||||
// shorten java.lang.AssertionError
|
||||
@@ -85,8 +93,14 @@ public class ConvertAssertToIfWithThrowIntention : SelfTargetingIntention<KtCall
|
||||
simplifyConditionIfPossible(ifExpression)
|
||||
}
|
||||
|
||||
private fun messageIsFunction(callExpr: KtCallExpression): Boolean {
|
||||
val resolvedCall = callExpr.getResolvedCall(callExpr.analyze()) ?: return false
|
||||
private fun extractMessageSingleExpression(functionLiteral: KtFunctionLiteralExpression, bindingContext: BindingContext): KtExpression? {
|
||||
return functionLiteral.bodyExpression?.statements?.singleOrNull()?.let { singleStatement ->
|
||||
singleStatement.check { it.isUsedAsExpression(bindingContext) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun messageIsFunction(callExpr: KtCallExpression, bindingContext: BindingContext): Boolean {
|
||||
val resolvedCall = callExpr.getResolvedCall(bindingContext) ?: return false
|
||||
val valParameters = resolvedCall.getResultingDescriptor().getValueParameters()
|
||||
return valParameters.size() > 1 && !KotlinBuiltIns.isAny(valParameters[1].type)
|
||||
}
|
||||
|
||||
@@ -72,6 +72,6 @@ public class IterateExpressionIntention : SelfTargetingIntention<KtExpression>(j
|
||||
templateBuilder.replaceElement(bodyPlaceholder, ConstantNode(""), false)
|
||||
templateBuilder.setEndVariableAfter(bodyPlaceholder)
|
||||
|
||||
templateBuilder.run(editor, true)
|
||||
templateBuilder.run(editor, false)
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,8 @@ import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElement
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
/*
|
||||
|
||||
public object KotlinAddOrderEntryActionFactory : KotlinIntentionActionsFactory() {
|
||||
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
|
||||
val simpleExpression = diagnostic.psiElement as? KtSimpleNameExpression ?: return emptyList()
|
||||
@@ -57,3 +59,5 @@ public object KotlinAddOrderEntryActionFactory : KotlinIntentionActionsFactory()
|
||||
return OrderEntryFix.registerFixes(QuickFixActionRegistrarImpl(null), reference) as List<IntentionAction>? ?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@@ -315,6 +315,7 @@ public class QuickFixRegistrar : QuickFixContributor {
|
||||
ReplaceObsoleteLabelSyntaxFix.createWholeProjectFixFactory())
|
||||
|
||||
DEPRECATION.registerFactory(DeprecatedSymbolUsageFix, DeprecatedSymbolUsageInWholeProjectFix)
|
||||
DEPRECATION_ERROR.registerFactory(DeprecatedSymbolUsageFix, DeprecatedSymbolUsageInWholeProjectFix)
|
||||
|
||||
POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION.registerFactory(ReplaceJavaAnnotationPositionedArgumentsFix)
|
||||
|
||||
@@ -338,7 +339,7 @@ public class QuickFixRegistrar : QuickFixContributor {
|
||||
|
||||
DEPRECATED_TYPE_PARAMETER_SYNTAX.registerFactory(MigrateTypeParameterListFix)
|
||||
|
||||
UNRESOLVED_REFERENCE.registerFactory(KotlinAddOrderEntryActionFactory)
|
||||
// UNRESOLVED_REFERENCE.registerFactory(KotlinAddOrderEntryActionFactory)
|
||||
|
||||
MISPLACED_TYPE_PARAMETER_CONSTRAINTS.registerFactory(MoveTypeParameterConstraintFix)
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
val receiverTypeCandidate: TypeCandidate?
|
||||
val mandatoryTypeParametersAsCandidates: List<TypeCandidate>
|
||||
val substitutions: List<KotlinTypeSubstitution>
|
||||
var finished: Boolean = false
|
||||
var released: Boolean = false
|
||||
|
||||
init {
|
||||
// gather relevant information
|
||||
@@ -1004,7 +1004,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
}
|
||||
}
|
||||
finally {
|
||||
finished = true
|
||||
release()
|
||||
onFinish()
|
||||
}
|
||||
}
|
||||
@@ -1020,10 +1020,18 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
}
|
||||
|
||||
fun showDialogIfNeeded() {
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode() && dialogWithEditor != null && !finished) {
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode() && dialogWithEditor != null && !released) {
|
||||
dialogWithEditor.show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun release() {
|
||||
if (released) return
|
||||
dialogWithEditor?.let {
|
||||
jetFileToEdit.delete()
|
||||
released = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||
import org.jetbrains.kotlin.idea.core.*
|
||||
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
||||
import org.jetbrains.kotlin.idea.intentions.RemoveExplicitTypeArgumentsIntention
|
||||
import org.jetbrains.kotlin.idea.intentions.setType
|
||||
import org.jetbrains.kotlin.idea.util.*
|
||||
@@ -65,8 +66,14 @@ class CallableUsageReplacementStrategy(
|
||||
if (!callTypeHandler.precheckReplacementPattern(replacement)) return null
|
||||
|
||||
return {
|
||||
// copy replacement expression because it is modified by performCallReplacement
|
||||
performCallReplacement(usage, bindingContext, resolvedCall, callElement, callTypeHandler, replacement.copy())
|
||||
if (usage is KtOperationReferenceExpression && usage.getReferencedNameElementType() != KtTokens.IDENTIFIER) {
|
||||
val nameExpression = OperatorToFunctionIntention.convert(usage.parent as KtExpression).second
|
||||
createReplacer(nameExpression)!!.invoke()
|
||||
}
|
||||
else {
|
||||
// copy replacement expression because it is modified by performCallReplacement
|
||||
performCallReplacement(usage, bindingContext, resolvedCall, callElement, callTypeHandler, replacement.copy())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.idea.core.OptionalParametersHelper
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
||||
@@ -100,7 +101,7 @@ public abstract class DeprecatedSymbolUsageFixBase(
|
||||
else
|
||||
null) ?: return null
|
||||
|
||||
val descriptor = Errors.DEPRECATION.cast(deprecatedDiagnostic).a
|
||||
val descriptor = DiagnosticFactory.cast(deprecatedDiagnostic, Errors.DEPRECATION, Errors.DEPRECATION_ERROR).a
|
||||
val replacement = DeprecatedSymbolUsageFixBase.fetchReplaceWithPattern(descriptor, nameExpression.project) ?: return null
|
||||
return Data(nameExpression, replacement, descriptor)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user