mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-11 08:31:29 +00:00
Compare commits
265 Commits
rr/mitropo
...
beta3_/br1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ff00a928c | ||
|
|
22add1ee89 | ||
|
|
2ecc21b440 | ||
|
|
14bcc5a523 | ||
|
|
0113ccaad1 | ||
|
|
41141fbe23 | ||
|
|
1d076154b1 | ||
|
|
d1860c2dce | ||
|
|
39ae20b110 | ||
|
|
58b507f44d | ||
|
|
58d78011c0 | ||
|
|
1c3e5f01b4 | ||
|
|
d95b156265 | ||
|
|
b33ad0c528 | ||
|
|
323937a397 | ||
|
|
6dbec92bfe | ||
|
|
bb57825d21 | ||
|
|
ddb50031d8 | ||
|
|
c2f8386b02 | ||
|
|
aa1a99a6eb | ||
|
|
51f0cebba3 | ||
|
|
d82ef969ac | ||
|
|
50dcd08cb5 | ||
|
|
df6298de39 | ||
|
|
a9c1e57230 | ||
|
|
378a964c2f | ||
|
|
170a0393f6 | ||
|
|
95d4dd4962 | ||
|
|
288248c964 | ||
|
|
8d271d3d4d | ||
|
|
6c898b4c3e | ||
|
|
0c65310b9e | ||
|
|
1bc76d0753 | ||
|
|
0b49512ade | ||
|
|
e58a45c9d8 | ||
|
|
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" />
|
||||
|
||||
@@ -88,12 +88,5 @@
|
||||
origin.version="${relay.origin.version}"
|
||||
plugin.subdir="BareKotlin"
|
||||
substituted.version="${relay.substitute.version}"/>
|
||||
|
||||
<substitudeVersionInPlugin
|
||||
plugin.jar.name="kotlin-android-extensions"
|
||||
plugin.path="${relay.plugins.dir}/kotlin-android-extensions-plugin-${relay.origin.version}.zip"
|
||||
origin.version="${relay.origin.version}"
|
||||
plugin.subdir="KotlinAndroidExtensions"
|
||||
substituted.version="${relay.substitute.version}"/>
|
||||
</target>
|
||||
</project>
|
||||
@@ -485,7 +485,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"/>
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
@@ -59,6 +59,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>())
|
||||
|
||||
@@ -28,8 +28,8 @@ import com.intellij.mock.MockApplication
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.extensions.ExtensionsArea
|
||||
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
|
||||
@@ -41,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
|
||||
@@ -336,10 +335,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>())
|
||||
//
|
||||
@@ -379,7 +380,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>())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,7 +401,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)
|
||||
|
||||
@@ -479,7 +479,7 @@ class CompileServiceImpl(
|
||||
}
|
||||
|
||||
private fun clearJarCache() {
|
||||
ZipHandler.clearFileAccessorCache()
|
||||
// ZipHandler.clearFileAccessorCache()
|
||||
val classloader = javaClass.classLoader
|
||||
// TODO: replace the following code with direct call to CoreJarFileSystem.<clearCache> as soon as it will be available (hopefully in 15.02)
|
||||
try {
|
||||
|
||||
@@ -40,7 +40,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
import java.util.*
|
||||
|
||||
public class JvmPlatformParameters(
|
||||
public val moduleByJavaClass: (JavaClass) -> ModuleInfo
|
||||
public val moduleByJavaClass: (JavaClass) -> ModuleInfo?
|
||||
) : PlatformAnalysisParameters
|
||||
|
||||
|
||||
@@ -68,7 +68,10 @@ public object JvmAnalyzerFacade : AnalyzerFacade<JvmPlatformParameters>() {
|
||||
// We don't have full control over idea resolve api so we allow for a situation which should not happen in Kotlin.
|
||||
// For example, type in a java library can reference a class declared in a source root (is valid but rare case)
|
||||
// Providing a fallback strategy in this case can hide future problems, so we should at least log to be able to diagnose those
|
||||
val resolverForReferencedModule = resolverForProject.tryGetResolverForModule(referencedClassModule as M)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val resolverForReferencedModule = referencedClassModule?.let { resolverForProject.tryGetResolverForModule(it as M) }
|
||||
|
||||
val resolverForModule = resolverForReferencedModule ?: run {
|
||||
LOG.warn("Java referenced $referencedClassModule from $moduleInfo\nReferenced class was: $javaClass\n")
|
||||
// in case referenced class lies outside of our resolver, resolve the class as if it is inside our module
|
||||
|
||||
@@ -66,4 +66,6 @@ public interface Pseudocode {
|
||||
List<? extends Instruction> getUsages(@Nullable PseudoValue value);
|
||||
|
||||
boolean isSideEffectFree(@NotNull Instruction instruction);
|
||||
|
||||
Pseudocode copy();
|
||||
}
|
||||
|
||||
@@ -458,6 +458,41 @@ public class PseudocodeImpl implements Pseudocode {
|
||||
return mutableInstructionList.get(targetPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PseudocodeImpl copy() {
|
||||
PseudocodeImpl result = new PseudocodeImpl(correspondingElement);
|
||||
result.repeatWhole(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void repeatWhole(PseudocodeImpl originalPseudocode) {
|
||||
Map<Label, Label> originalToCopy = Maps.newLinkedHashMap();
|
||||
Multimap<Instruction, Label> originalLabelsForInstruction = HashMultimap.create();
|
||||
int labelCount = 0;
|
||||
for (PseudocodeLabel label : originalPseudocode.labels) {
|
||||
originalToCopy.put(label, label.copy(labelCount++));
|
||||
originalLabelsForInstruction.put(getJumpTarget(label), label);
|
||||
}
|
||||
for (Label label : originalToCopy.values()) {
|
||||
labels.add((PseudocodeLabel) label);
|
||||
}
|
||||
for (Instruction originalInstruction : originalPseudocode.mutableInstructionList) {
|
||||
repeatLabelsBindingForInstruction(originalInstruction, originalToCopy, originalLabelsForInstruction);
|
||||
Instruction copy = copyInstruction(originalInstruction, originalToCopy);
|
||||
addInstruction(copy);
|
||||
if (originalInstruction == originalPseudocode.errorInstruction && copy instanceof SubroutineExitInstruction) {
|
||||
errorInstruction = (SubroutineExitInstruction) copy;
|
||||
}
|
||||
if (originalInstruction == originalPseudocode.exitInstruction && copy instanceof SubroutineExitInstruction) {
|
||||
exitInstruction = (SubroutineExitInstruction) copy;
|
||||
}
|
||||
if (originalInstruction == originalPseudocode.sinkInstruction && copy instanceof SubroutineSinkInstruction) {
|
||||
sinkInstruction = (SubroutineSinkInstruction) copy;
|
||||
}
|
||||
}
|
||||
parent = originalPseudocode.parent;
|
||||
}
|
||||
|
||||
public int repeatPart(@NotNull Label startLabel, @NotNull Label finishLabel, int labelCount) {
|
||||
PseudocodeImpl originalPseudocode = ((PseudocodeLabel) startLabel).getPseudocode();
|
||||
|
||||
|
||||
@@ -57,5 +57,5 @@ public class LocalFunctionDeclarationInstruction(
|
||||
override fun toString(): String = "d(${render(element)})"
|
||||
|
||||
override fun createCopy(): InstructionImpl =
|
||||
LocalFunctionDeclarationInstruction(element, body, lexicalScope)
|
||||
LocalFunctionDeclarationInstruction(element, body.copy(), lexicalScope)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -197,7 +197,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
||||
val possibleTypes = context.dataFlowInfo.getPossibleTypes(dataFlowValue)
|
||||
if (possibleTypes.isEmpty()) return type
|
||||
|
||||
return TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, possibleTypes + type)
|
||||
return TypeIntersector.intersectTypes(KotlinTypeChecker.DEFAULT, possibleTypes)
|
||||
}
|
||||
|
||||
fun <D : CallableDescriptor> completeTypeInferenceDependentOnFunctionArgumentsForCall(context: CallCandidateResolutionContext<D>) {
|
||||
|
||||
@@ -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
|
||||
@@ -38,7 +38,7 @@ fun <T : CharSequence?> foo(x: T) {
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.length
|
||||
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
|
||||
|
||||
x.bar1()
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.bar1()
|
||||
x.bar2()
|
||||
<!DEBUG_INFO_SMARTCAST!>x<!>.bar3()
|
||||
}
|
||||
|
||||
16
compiler/testData/diagnostics/tests/regressions/kt10243.kt
vendored
Normal file
16
compiler/testData/diagnostics/tests/regressions/kt10243.kt
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
val f: Boolean = true
|
||||
private fun doUpdateRegularTasks() {
|
||||
try {
|
||||
while (f) {
|
||||
val xmlText = <!UNRESOLVED_REFERENCE!>getText<!>()
|
||||
if (<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>xmlText<!> <!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>==<!> null) {}
|
||||
else {
|
||||
<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>xmlText<!>.<!DEBUG_INFO_ELEMENT_WITH_ERROR_TYPE!>value<!> = 0 // !!!
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
finally {
|
||||
fun execute() {}
|
||||
}
|
||||
}
|
||||
4
compiler/testData/diagnostics/tests/regressions/kt10243.txt
vendored
Normal file
4
compiler/testData/diagnostics/tests/regressions/kt10243.txt
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
public val f: kotlin.Boolean = true
|
||||
private fun doUpdateRegularTasks(): kotlin.Unit
|
||||
@@ -1,15 +0,0 @@
|
||||
// Type inference failed after smart cast
|
||||
|
||||
interface A<T>
|
||||
interface B<T> : A<T>
|
||||
|
||||
fun <T> foo(b: A<T>) = b
|
||||
|
||||
fun <T> test(a: A<T>) {
|
||||
if (a is Any) {
|
||||
// Error:(9, 9) Kotlin: Type inference failed: fun <T> foo(b: A<T>): kotlin.Unit
|
||||
// cannot be applied to (A<T>)
|
||||
foo(a)
|
||||
}
|
||||
foo(a) // ok
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ T> foo(/*0*/ b: A<T>): A<T>
|
||||
public fun </*0*/ T> test(/*0*/ a: A<T>): kotlin.Unit
|
||||
|
||||
public interface A</*0*/ T> {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface B</*0*/ T> : A<T> {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -12,4 +12,4 @@ fun foo() {
|
||||
.bar()
|
||||
}
|
||||
|
||||
// 2 3 1 7 8 9 8 9 11 12 11 12 17 13
|
||||
// 2 3 1 7 8 9 11 12 16 13
|
||||
@@ -12,4 +12,4 @@ fun foo() {
|
||||
.bar()
|
||||
}
|
||||
|
||||
// 2 3 1 7 8 9 8 9 11 12 11 17 12 17 13
|
||||
// 2 3 1 7 8 9 11 16 12 16 13
|
||||
@@ -3,4 +3,4 @@ fun foo() {
|
||||
42
|
||||
}
|
||||
|
||||
// 2 3 2 4
|
||||
// 3 2 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 4 14 6 12 13 7 8 14 9 12 13 14
|
||||
// 2 12 3 4 6 12 7 8 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
|
||||
|
||||
@@ -12546,6 +12546,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt10243.kt")
|
||||
public void testKt10243() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/regressions/kt10243.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt127.kt")
|
||||
public void testKt127() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/regressions/kt127.kt");
|
||||
@@ -14742,12 +14748,6 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt10232.kt")
|
||||
public void testKt10232() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/kt10232.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt1461.kt")
|
||||
public void testKt1461() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/smartCasts/kt1461.kt");
|
||||
|
||||
@@ -33,7 +33,10 @@ public abstract class AbstractCompileKotlinAgainstInlineKotlinTest : AbstractCom
|
||||
try {
|
||||
val sourceFiles = factory1.getInputFiles() + factory2.getInputFiles()
|
||||
InlineTestUtil.checkNoCallsToInline(allGeneratedFiles.filterClassFiles(), sourceFiles)
|
||||
checkSMAP(sourceFiles, allGeneratedFiles.filterClassFiles())
|
||||
|
||||
if (getTestName(true) != "smap") {
|
||||
checkSMAP(sourceFiles, allGeneratedFiles.filterClassFiles())
|
||||
}
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
System.out.println(factory1.createText() + "\n" + factory2.createText())
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -698,7 +698,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)
|
||||
|
||||
@@ -59,7 +59,7 @@ fun createModuleResolverProvider(
|
||||
val jvmPlatformParameters = JvmPlatformParameters {
|
||||
javaClass: JavaClass ->
|
||||
val psiClass = (javaClass as JavaClassImpl).getPsi()
|
||||
psiClass.getModuleInfo()
|
||||
psiClass.getNullableModuleInfo()
|
||||
}
|
||||
|
||||
val resolverForProject = analyzerFacade.setupResolverForProject(
|
||||
|
||||
@@ -28,13 +28,20 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
|
||||
fun PsiElement.getModuleInfo(): IdeaModuleInfo {
|
||||
fun logAndReturnDefault(message: String): IdeaModuleInfo {
|
||||
LOG.error("Could not find correct module information.\nReason: $message")
|
||||
return NotUnderContentRootModuleInfo
|
||||
}
|
||||
fun PsiElement.getModuleInfo(): IdeaModuleInfo = this.getModuleInfo { reason ->
|
||||
LOG.error("Could not find correct module information.\nReason: $reason")
|
||||
NotUnderContentRootModuleInfo
|
||||
}.sure { "Defaulting to NotUnderContentRootModuleInfo so null is not possible" }
|
||||
|
||||
fun PsiElement.getNullableModuleInfo(): IdeaModuleInfo? = this.getModuleInfo { reason ->
|
||||
LOG.warn("Could not find correct module information.\nReason: $reason")
|
||||
null
|
||||
}
|
||||
|
||||
private fun PsiElement.getModuleInfo(onFailure: (String) -> IdeaModuleInfo?): IdeaModuleInfo? {
|
||||
if (this is KtLightElement<*, *>) return this.getModuleInfoForLightElement()
|
||||
|
||||
val containingJetFile = (this as? KtElement)?.getContainingFile() as? KtFile
|
||||
@@ -43,7 +50,7 @@ fun PsiElement.getModuleInfo(): IdeaModuleInfo {
|
||||
|
||||
val doNotAnalyze = containingJetFile?.doNotAnalyze
|
||||
if (doNotAnalyze != null) {
|
||||
return logAndReturnDefault(
|
||||
return onFailure(
|
||||
"Should not analyze element: ${getText()} in file ${containingJetFile?.getName() ?: " <no file>"}\n$doNotAnalyze"
|
||||
)
|
||||
}
|
||||
@@ -53,15 +60,13 @@ fun PsiElement.getModuleInfo(): IdeaModuleInfo {
|
||||
|
||||
if (containingJetFile is KtCodeFragment) {
|
||||
return containingJetFile.getContext()?.getModuleInfo()
|
||||
?: logAndReturnDefault("Analyzing code fragment of type ${containingJetFile.javaClass} with no context element\nText:\n${containingJetFile.getText()}")
|
||||
?: onFailure("Analyzing code fragment of type ${containingJetFile.javaClass} with no context element\nText:\n${containingJetFile.getText()}")
|
||||
}
|
||||
|
||||
val project = getProject()
|
||||
val containingFile = getContainingFile()
|
||||
?: return logAndReturnDefault("Analyzing element of type $javaClass with no containing file\nText:\n${getText()}")
|
||||
val containingFile = containingFile ?: return onFailure("Analyzing element of type $javaClass with no containing file\nText:\n$text")
|
||||
|
||||
val virtualFile = containingFile.getOriginalFile().getVirtualFile()
|
||||
?: return logAndReturnDefault("Analyzing non-physical file $containingFile of type ${containingFile.javaClass}")
|
||||
val virtualFile = containingFile.originalFile.virtualFile
|
||||
?: return onFailure("Analyzing element of type $javaClass in non-physical file $containingFile of type ${containingFile.javaClass}\nText:\n$text")
|
||||
|
||||
return getModuleInfoByVirtualFile(
|
||||
project,
|
||||
@@ -115,8 +120,13 @@ private fun getModuleInfoByVirtualFile(project: Project, virtualFile: VirtualFil
|
||||
}
|
||||
|
||||
private fun KtLightElement<*, *>.getModuleInfoForLightElement(): IdeaModuleInfo {
|
||||
if (this is KtLightClassForDecompiledDeclaration) {
|
||||
return getModuleInfoByVirtualFile(getProject(), getContainingFile().getVirtualFile(), false)
|
||||
val decompiledClass = this.getParentOfType<KtLightClassForDecompiledDeclaration>(strict = false)
|
||||
if (decompiledClass != null) {
|
||||
return getModuleInfoByVirtualFile(
|
||||
project,
|
||||
containingFile.virtualFile.sure { "Decompiled class should be build from physical file" },
|
||||
false
|
||||
)
|
||||
}
|
||||
val element = getOrigin() ?: when (this) {
|
||||
is FakeLightClassForFileOfPackage -> this.getContainingFile()!!
|
||||
|
||||
@@ -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,76 +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.DebugUtil
|
||||
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() ?: ""
|
||||
|
||||
DebugUtil.startPsiModification("Invalidating throw-away copy of file that was used for getting text")
|
||||
try {
|
||||
(psiFile as? PsiFileImpl)?.markInvalidated()
|
||||
}
|
||||
finally {
|
||||
DebugUtil.finishPsiModification()
|
||||
}
|
||||
|
||||
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 @@ 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)
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.js
|
||||
|
||||
import com.intellij.openapi.vfs.impl.ArchiveHandler
|
||||
import com.intellij.openapi.vfs.impl.ArchiveHandler.EntryInfo
|
||||
import com.intellij.util.ArrayUtil
|
||||
import gnu.trove.THashMap
|
||||
import org.jetbrains.kotlin.serialization.js.forEachFile
|
||||
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
|
||||
|
||||
public open class KotlinJavaScriptHandler(path: String) : ArchiveHandler(path) {
|
||||
|
||||
override fun createEntriesMap(): Map<String, EntryInfo> {
|
||||
val map = THashMap<String, EntryInfo>()
|
||||
map.put("", createRootEntry())
|
||||
|
||||
for(metadata in KotlinJavascriptMetadataUtils.loadMetadata(getFile())) {
|
||||
val moduleName = metadata.moduleName
|
||||
metadata.forEachFile {
|
||||
filePath, fileContent -> getOrCreate(moduleName + "/" + filePath, false, map, fileContent)
|
||||
}
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
private fun getOrCreate(
|
||||
entryPath: String,
|
||||
isDirectory: Boolean,
|
||||
map: MutableMap<String, EntryInfo>,
|
||||
content: ByteArray = ArrayUtil.EMPTY_BYTE_ARRAY
|
||||
): EntryInfo {
|
||||
val info = map[entryPath]
|
||||
if (info != null) return info
|
||||
|
||||
val path = splitPath(entryPath)
|
||||
val parentInfo = getOrCreate(path.first, true, map)
|
||||
val newInfo = JsMetaEntryInfo(parentInfo, path.second, isDirectory, content)
|
||||
map[entryPath] = newInfo
|
||||
|
||||
return newInfo
|
||||
}
|
||||
|
||||
override fun contentsToByteArray(relativePath: String): ByteArray {
|
||||
val entryInfo = getEntryInfo(relativePath)
|
||||
return if (entryInfo is JsMetaEntryInfo) entryInfo.content else ArrayUtil.EMPTY_BYTE_ARRAY
|
||||
}
|
||||
|
||||
private class JsMetaEntryInfo(
|
||||
parent: EntryInfo,
|
||||
shortName: String,
|
||||
isDirectory: Boolean,
|
||||
val content: ByteArray
|
||||
) : EntryInfo(shortName, isDirectory, ArchiveHandler.DEFAULT_LENGTH, ArchiveHandler.DEFAULT_TIMESTAMP, parent)
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
|
||||
@@ -74,18 +74,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
|
||||
@@ -97,11 +102,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) }
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinAndroidGradleModuleConfigurator"/>
|
||||
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleModuleConfigurator"/>
|
||||
</extensions>
|
||||
<!--
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
|
||||
</extensions>
|
||||
-->
|
||||
</idea-plugin>
|
||||
|
||||
@@ -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>
|
||||
@@ -503,16 +503,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"/>
|
||||
@@ -1095,16 +1091,11 @@
|
||||
<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"
|
||||
enabledByDefault="true"
|
||||
level="INFO"
|
||||
displayName="Convert object literal to lambda"
|
||||
groupName="Kotlin"
|
||||
enabledByDefault="true"
|
||||
level="INFO"
|
||||
/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.DeprecatedCallableAddReplaceWithInspection"
|
||||
|
||||
@@ -79,7 +79,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"
|
||||
}
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.plugins.gradle.frameworkSupport.BuildScriptDataBuilder
|
||||
import org.jetbrains.plugins.gradle.frameworkSupport.GradleFrameworkSupportProvider
|
||||
import javax.swing.Icon
|
||||
|
||||
/*
|
||||
public class GradleKotlinJavaFrameworkSupportProvider() : GradleFrameworkSupportProvider() {
|
||||
override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx("KOTLIN") {
|
||||
override fun getIcon(): Icon = KotlinIcons.FILE
|
||||
@@ -60,3 +61,4 @@ public class GradleKotlinJavaFrameworkSupportProvider() : GradleFrameworkSupport
|
||||
.addBuildscriptDependencyNotation(KotlinWithGradleConfigurator.CLASSPATH.replace("\$kotlin_version", kotlinVersion))
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -16,11 +16,14 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.configuration
|
||||
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
|
||||
import com.intellij.openapi.components.PersistentStateComponent
|
||||
import com.intellij.openapi.components.State
|
||||
import com.intellij.openapi.components.Storage
|
||||
import com.intellij.openapi.components.StoragePathMacros
|
||||
import com.intellij.openapi.module.Module
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.idea.maven.importing.MavenImporter
|
||||
import org.jetbrains.idea.maven.importing.MavenModifiableModelsProvider
|
||||
import org.jetbrains.idea.maven.importing.MavenRootModelAdapter
|
||||
import org.jetbrains.idea.maven.model.MavenPlugin
|
||||
import org.jetbrains.idea.maven.project.MavenProject
|
||||
@@ -37,10 +40,10 @@ private val KotlinPluginArtifactId = "kotlin-maven-plugin"
|
||||
private val KotlinPluginSourceDirsConfig = "sourceDirs"
|
||||
|
||||
class KotlinMavenImporter : MavenImporter(KotlinPluginGroupId, KotlinPluginArtifactId) {
|
||||
override fun preProcess(module: Module, mavenProject: MavenProject, changes: MavenProjectChanges, modifiableModelsProvider: IdeModifiableModelsProvider) {
|
||||
override fun preProcess(module: Module, mavenProject: MavenProject, changes: MavenProjectChanges, modifiableModelsProvider: MavenModifiableModelsProvider) {
|
||||
}
|
||||
|
||||
override fun process(modifiableModelsProvider: IdeModifiableModelsProvider,
|
||||
override fun process(modifiableModelsProvider: MavenModifiableModelsProvider,
|
||||
module: Module,
|
||||
rootModel: MavenRootModelAdapter,
|
||||
mavenModel: MavenProjectsTree,
|
||||
|
||||
@@ -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
|
||||
@@ -32,8 +29,6 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.impl.compiled.ClsFileImpl
|
||||
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
|
||||
@@ -53,7 +48,6 @@ import org.jetbrains.kotlin.fileClasses.internalNameWithoutInnerClasses
|
||||
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
|
||||
@@ -64,27 +58,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? {
|
||||
if (location.declaringType().containsKotlinStrata()) {
|
||||
return KotlinStackFrame(frame)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getSourcePosition(location: Location?): SourcePosition? {
|
||||
if (location == null) {
|
||||
throw NoDataException.INSTANCE
|
||||
@@ -139,7 +121,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
|
||||
@@ -150,16 +135,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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,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)
|
||||
@@ -241,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.mapNotNull {
|
||||
val typeMapper = if (!isInLibrary) prepareTypeMapper(file) else createTypeMapperForLibraryFile(it, file)
|
||||
getInternalClassNameForElement(it, typeMapper, file, isInLibrary).className
|
||||
}
|
||||
}
|
||||
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,162 +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 KotlinLambdaBreakpointVariant extends ExactJavaBreakpointVariant {
|
||||
public KotlinLambdaBreakpointVariant(XSourcePosition position, KtFunction function, Integer lambdaOrdinal) {
|
||||
super(position, function, lambdaOrdinal);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return KotlinIcons.LAMBDA;
|
||||
}
|
||||
}
|
||||
|
||||
public class KotlinLineBreakpointVariant extends ExactJavaBreakpointVariant {
|
||||
public KotlinLineBreakpointVariant(XSourcePosition position, PsiElement element) {
|
||||
super(position, element, -1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return KotlinIcons.FUNCTION;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -70,12 +70,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
|
||||
@@ -84,6 +84,7 @@ fun canPutAt(file: VirtualFile, line: Int, project: Project, breakpointTypeClass
|
||||
return result == breakpointTypeClass
|
||||
}
|
||||
|
||||
/*
|
||||
fun computeVariants(
|
||||
project: Project, position: XSourcePosition,
|
||||
kotlinBreakpointType: KotlinLineBreakpointType
|
||||
@@ -152,5 +153,5 @@ fun getLambdasAtLineIfAny(file: KtFile, line: Int): List<KtFunction> {
|
||||
statement.getLineNumber() == line && statement.getLineNumber(false) == line
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -124,7 +124,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();
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -132,8 +131,8 @@ class KotlinUnusedImportInspection : 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 KotlinUnusedImportInspection : 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 {
|
||||
|
||||
@@ -74,6 +74,6 @@ public class IterateExpressionIntention : SelfTargetingIntention<KtExpression>(j
|
||||
templateBuilder.replaceElement(bodyPlaceholder, ConstantNode(""), false)
|
||||
templateBuilder.setEndVariableAfter(bodyPlaceholder)
|
||||
|
||||
templateBuilder.run(editor, true)
|
||||
templateBuilder.run(editor, false)
|
||||
}
|
||||
}
|
||||
@@ -179,7 +179,7 @@ object KDocRenderer {
|
||||
}
|
||||
}
|
||||
MarkdownTokenTypes.TEXT,
|
||||
MarkdownTokenTypes.CODE,
|
||||
MarkdownTokenTypes.CODE_LINE,
|
||||
MarkdownTokenTypes.WHITE_SPACE,
|
||||
MarkdownTokenTypes.COLON,
|
||||
MarkdownTokenTypes.SINGLE_QUOTE,
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@@ -343,7 +343,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)
|
||||
|
||||
|
||||
@@ -228,7 +228,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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
else {
|
||||
findSAMUsages(info, result)
|
||||
//findConstructorDelegationUsages(info, result)
|
||||
findKotlinOverrides(info, result)
|
||||
//findKotlinOverrides(info, result)
|
||||
if (info is JavaChangeInfo) {
|
||||
findKotlinCallers(info, result)
|
||||
}
|
||||
@@ -418,6 +418,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
private fun findKotlinOverrides(changeInfo: ChangeInfo, result: MutableSet<UsageInfo>) {
|
||||
val method = changeInfo.method
|
||||
if (!method.isTrueJavaMethod()) return
|
||||
@@ -429,6 +430,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
findDeferredUsagesOfParameters(changeInfo, result, unwrappedElement, functionDescriptor)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
private fun findKotlinCallers(changeInfo: JavaChangeInfo, result: MutableSet<UsageInfo>) {
|
||||
val method = changeInfo.method
|
||||
@@ -492,6 +494,25 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
// Delete OverriderUsageInfo and CallerUsageInfo for Kotlin declarations since they can't be processed correctly
|
||||
// TODO (OverriderUsageInfo only): Drop when OverriderUsageInfo.getElement() gets deleted
|
||||
val usageInfos = refUsages.get()
|
||||
|
||||
for (usageInfo in usageInfos) {
|
||||
if (usageInfo !is KotlinWrapperForJavaUsageInfos) continue
|
||||
|
||||
val infos = usageInfo.javaUsageInfos
|
||||
for (i in infos.indices) {
|
||||
val javaUsageInfo = infos[i]
|
||||
if (javaUsageInfo !is OverriderUsageInfo) continue
|
||||
|
||||
val psiMethod = javaUsageInfo.overridingMethod
|
||||
if (psiMethod !is KtLightMethod) continue
|
||||
|
||||
val origin = psiMethod.getOrigin()
|
||||
if (origin != null) {
|
||||
infos[i] = UsageInfo(origin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val adjustedUsages = usageInfos.filterNot { getOverriderOrCaller(it) is KtLightMethod }
|
||||
if (adjustedUsages.size < usageInfos.size) {
|
||||
refUsages.set(adjustedUsages.toTypedArray())
|
||||
@@ -777,6 +798,26 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun hasInvalidOldIndex(it: JavaParameterInfo, usageInfo: KotlinWrapperForJavaUsageInfos): Boolean {
|
||||
return it.oldIndex >= usageInfo.javaChangeInfo.method.parameterList.parametersCount
|
||||
}
|
||||
|
||||
// TODO: Get rid of this hack
|
||||
private fun createJavaChangeInfoDelegate(javaChangeInfo: JavaChangeInfo, usageInfo: KotlinWrapperForJavaUsageInfos): JavaChangeInfo {
|
||||
if (!javaChangeInfo.newParameters.any { hasInvalidOldIndex(it, usageInfo) }) return javaChangeInfo
|
||||
|
||||
return object : JavaChangeInfo by javaChangeInfo {
|
||||
private val _newParameters = javaChangeInfo.newParameters.map {
|
||||
if (hasInvalidOldIndex(it, usageInfo)) {
|
||||
ParameterInfoImpl(-1, it.name, it.typeWrapper, it.defaultValue)
|
||||
}
|
||||
else it
|
||||
}.toTypedArray()
|
||||
|
||||
override fun getNewParameters() = _newParameters
|
||||
}
|
||||
}
|
||||
|
||||
override fun processUsage(changeInfo: ChangeInfo, usageInfo: UsageInfo, beforeMethodChange: Boolean, usages: Array<UsageInfo>): Boolean {
|
||||
val method = changeInfo.method
|
||||
val isJavaMethodUsage = isJavaMethodUsage(usageInfo)
|
||||
@@ -799,7 +840,8 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor {
|
||||
if (isOverriderOrCaller(usage)) {
|
||||
processor.processUsage(javaChangeInfo, usage, true, javaUsageInfos)
|
||||
}
|
||||
if (processor.processUsage(javaChangeInfo, usage, beforeMethodChange, javaUsageInfos)) break
|
||||
val changeInfoDelegate = createJavaChangeInfoDelegate(javaChangeInfo, usageInfo)
|
||||
if (processor.processUsage(changeInfoDelegate, usage, beforeMethodChange, javaUsageInfos)) break
|
||||
}
|
||||
if (usage is OverriderUsageInfo && usage.isOriginalOverrider) {
|
||||
val overridingMethod = usage.overridingMethod
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.intellij.openapi.command.impl.FinishMarkAction
|
||||
import com.intellij.openapi.command.impl.StartMarkAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.Messages
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.*
|
||||
@@ -32,6 +32,7 @@ import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.refactoring.HelpID
|
||||
import com.intellij.refactoring.introduce.inplace.OccurrencesChooser
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil
|
||||
import com.intellij.ui.components.JBList
|
||||
import com.intellij.util.SmartList
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
@@ -378,13 +379,29 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, message, INTRODUCE_VARIABLE, HelpID.INTRODUCE_VARIABLE)
|
||||
}
|
||||
|
||||
private fun KtExpression.chooseApplicableComponentFunctions(haveOccurrencesToReplace: Boolean): List<FunctionDescriptor>? {
|
||||
if (haveOccurrencesToReplace) return emptyList()
|
||||
private fun KtExpression.chooseApplicableComponentFunctions(
|
||||
haveOccurrencesToReplace: Boolean,
|
||||
editor: Editor?,
|
||||
callback: (List<FunctionDescriptor>) -> Unit
|
||||
) {
|
||||
if (haveOccurrencesToReplace) return callback(emptyList())
|
||||
|
||||
val functions = getApplicableComponentFunctions(this)
|
||||
if (functions.size <= 1) return emptyList()
|
||||
if (functions.size <= 1) return callback(emptyList())
|
||||
|
||||
return functions
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) return callback(functions)
|
||||
|
||||
if (editor == null) return callback(emptyList())
|
||||
|
||||
val list = JBList("Create single variable", "Create destructuring declaration")
|
||||
JBPopupFactory.getInstance()
|
||||
.createListPopupBuilder(list)
|
||||
.setMovable(true)
|
||||
.setResizable(false)
|
||||
.setRequestFocus(true)
|
||||
.setItemChoosenCallback { callback(if (list.selectedIndex == 0) emptyList() else functions) }
|
||||
.createPopup()
|
||||
.showInBestPositionFor(editor)
|
||||
}
|
||||
|
||||
private fun executeMultiDeclarationTemplate(
|
||||
@@ -517,67 +534,67 @@ object KotlinIntroduceVariableHandler : KotlinIntroduceHandlerBase() {
|
||||
commonContainer = container
|
||||
}
|
||||
|
||||
val componentFunctions = physicalExpression.chooseApplicableComponentFunctions(replaceOccurrence) ?: return@Pass
|
||||
|
||||
val validator = NewDeclarationNameValidator(
|
||||
commonContainer,
|
||||
calculateAnchor(commonParent, commonContainer, allReplaces),
|
||||
NewDeclarationNameValidator.Target.VARIABLES
|
||||
)
|
||||
val suggestedNames = if (componentFunctions.isNotEmpty()) {
|
||||
val collectingValidator = CollectingNameValidator(filter = validator)
|
||||
componentFunctions.map { suggestNamesForComponent(it, project, collectingValidator) }
|
||||
}
|
||||
else {
|
||||
KotlinNameSuggester.suggestNamesByExpressionAndType(expression,
|
||||
substringInfo?.type,
|
||||
bindingContext,
|
||||
validator,
|
||||
"value").singletonList()
|
||||
}
|
||||
val introduceVariableContext = IntroduceVariableContext(
|
||||
expression, suggestedNames, allReplaces, commonContainer, commonParent,
|
||||
replaceOccurrence, noTypeInference, expressionType, componentFunctions, bindingContext, resolutionFacade
|
||||
)
|
||||
project.executeCommand(INTRODUCE_VARIABLE, null) {
|
||||
runWriteAction { introduceVariableContext.runRefactoring() }
|
||||
|
||||
val property = introduceVariableContext.propertyRef ?: return@executeCommand
|
||||
|
||||
if (editor == null) {
|
||||
onNonInteractiveFinish?.invoke(property)
|
||||
return@executeCommand
|
||||
physicalExpression.chooseApplicableComponentFunctions(replaceOccurrence, editor) { componentFunctions ->
|
||||
val validator = NewDeclarationNameValidator(
|
||||
commonContainer,
|
||||
calculateAnchor(commonParent, commonContainer, allReplaces),
|
||||
NewDeclarationNameValidator.Target.VARIABLES
|
||||
)
|
||||
val suggestedNames = if (componentFunctions.isNotEmpty()) {
|
||||
val collectingValidator = CollectingNameValidator(filter = validator)
|
||||
componentFunctions.map { suggestNamesForComponent(it, project, collectingValidator) }
|
||||
}
|
||||
else {
|
||||
KotlinNameSuggester.suggestNamesByExpressionAndType(expression,
|
||||
substringInfo?.type,
|
||||
bindingContext,
|
||||
validator,
|
||||
"value").singletonList()
|
||||
}
|
||||
val introduceVariableContext = IntroduceVariableContext(
|
||||
expression, suggestedNames, allReplaces, commonContainer, commonParent,
|
||||
replaceOccurrence, noTypeInference, expressionType, componentFunctions, bindingContext, resolutionFacade
|
||||
)
|
||||
project.executeCommand(INTRODUCE_VARIABLE, null) {
|
||||
runWriteAction { introduceVariableContext.runRefactoring() }
|
||||
|
||||
editor.caretModel.moveToOffset(property.textOffset)
|
||||
editor.selectionModel.removeSelection()
|
||||
val property = introduceVariableContext.propertyRef ?: return@executeCommand
|
||||
|
||||
if (!isInplaceAvailable) return@executeCommand
|
||||
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.document)
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
|
||||
when (property) {
|
||||
is KtProperty -> {
|
||||
KotlinVariableInplaceIntroducer(
|
||||
property,
|
||||
introduceVariableContext.reference,
|
||||
introduceVariableContext.references.toTypedArray(),
|
||||
suggestedNames.single(),
|
||||
/*todo*/ false,
|
||||
/*todo*/ false,
|
||||
expressionType,
|
||||
noTypeInference,
|
||||
project,
|
||||
editor
|
||||
).startInplaceIntroduceTemplate()
|
||||
if (editor == null) {
|
||||
onNonInteractiveFinish?.invoke(property)
|
||||
return@executeCommand
|
||||
}
|
||||
|
||||
is KtMultiDeclaration -> {
|
||||
executeMultiDeclarationTemplate(project, editor, property, suggestedNames)
|
||||
}
|
||||
editor.caretModel.moveToOffset(property.textOffset)
|
||||
editor.selectionModel.removeSelection()
|
||||
|
||||
else -> throw AssertionError("Unexpected declaration: ${property.getElementTextWithContext()}")
|
||||
if (!isInplaceAvailable) return@executeCommand
|
||||
|
||||
PsiDocumentManager.getInstance(project).commitDocument(editor.document)
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
|
||||
when (property) {
|
||||
is KtProperty -> {
|
||||
KotlinVariableInplaceIntroducer(
|
||||
property,
|
||||
introduceVariableContext.reference,
|
||||
introduceVariableContext.references.toTypedArray(),
|
||||
suggestedNames.single(),
|
||||
/*todo*/ false,
|
||||
/*todo*/ false,
|
||||
expressionType,
|
||||
noTypeInference,
|
||||
project,
|
||||
editor
|
||||
).startInplaceIntroduceTemplate()
|
||||
}
|
||||
|
||||
is KtMultiDeclaration -> {
|
||||
executeMultiDeclarationTemplate(project, editor, property, suggestedNames)
|
||||
}
|
||||
|
||||
else -> throw AssertionError("Unexpected declaration: ${property.getElementTextWithContext()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,19 +16,37 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable
|
||||
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.analysis.analyzeInContext
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.createExpressionByPattern
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||
import org.jetbrains.kotlin.util.isValidOperator
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||
|
||||
fun getApplicableComponentFunctions(expression: KtExpression): List<FunctionDescriptor> {
|
||||
val facade = expression.getResolutionFacade()
|
||||
val scope = expression.getResolutionScope(facade.analyze(expression), facade)
|
||||
val context = facade.analyze(expression)
|
||||
val builtIns = facade.moduleDescriptor.builtIns
|
||||
|
||||
val forbiddenClasses = arrayListOf(builtIns.collection, builtIns.array)
|
||||
PrimitiveType.values().mapTo(forbiddenClasses) { builtIns.getPrimitiveArrayClassDescriptor(it) }
|
||||
|
||||
context.getType(expression)?.let {
|
||||
if ((it.singletonList() + it.supertypes()).any {
|
||||
val fqName = it.constructor.declarationDescriptor?.importableFqName
|
||||
forbiddenClasses.any { it.fqNameSafe == fqName }
|
||||
}) return emptyList()
|
||||
}
|
||||
|
||||
val scope = expression.getResolutionScope(context, facade)
|
||||
|
||||
val psiFactory = KtPsiFactory(expression)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
||||
@@ -36,11 +36,12 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import java.util.*
|
||||
|
||||
public class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUnitConfiguration>(JUnitConfigurationType.getInstance()) {
|
||||
override fun isConfigurationFromContext(configuration: JUnitConfiguration,
|
||||
context: ConfigurationContext): Boolean {
|
||||
if (RunConfigurationProducer.getInstance(javaClass<PatternConfigurationProducer>()).isMultipleElementsSelected(context)) {
|
||||
if (PatternConfigurationProducer.isMultipleElementsSelected(context)) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -112,6 +113,7 @@ public class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUni
|
||||
return false
|
||||
}
|
||||
|
||||
/*
|
||||
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
|
||||
val leaf = fromContext.sourceElement
|
||||
getTestClass(leaf)?.let { testClass ->
|
||||
@@ -131,6 +133,7 @@ public class KotlinJUnitRunConfigurationProducer : RunConfigurationProducer<JUni
|
||||
|
||||
super.onFirstRun(fromContext, context, performRunnable)
|
||||
}
|
||||
*/
|
||||
|
||||
private fun getTestMethodLocation(leaf: PsiElement): Location<PsiMethod>? {
|
||||
val function = leaf.getParentOfType<KtNamedFunction>(false) ?: return null
|
||||
|
||||
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.idea.stubindex.KotlinAnnotationsIndex
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
@@ -1,49 +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.search.ideaExtensions
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.searches.ClassesWithAnnotatedMembersSearch
|
||||
import com.intellij.psi.search.searches.ScopedQueryExecutor
|
||||
import com.intellij.util.Processor
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.search.allScope
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
|
||||
class KotlinClassesWithAnnotatedMembersSearcher : ScopedQueryExecutor<PsiClass, ClassesWithAnnotatedMembersSearch.Parameters> {
|
||||
override fun getScope(param: ClassesWithAnnotatedMembersSearch.Parameters): GlobalSearchScope {
|
||||
return GlobalSearchScope.getScopeRestrictedByFileTypes(param.annotationClass.project.allScope(), KotlinFileType.INSTANCE)
|
||||
}
|
||||
|
||||
override fun execute(queryParameters: ClassesWithAnnotatedMembersSearch.Parameters, consumer: Processor<PsiClass>): Boolean {
|
||||
val processed = hashSetOf<KtClassOrObject>()
|
||||
return KotlinAnnotatedElementsSearcher.processAnnotatedMembers(queryParameters.annotationClass,
|
||||
queryParameters.scope,
|
||||
{ it.getNonStrictParentOfType<KtClassOrObject>() !in processed}) { declaration ->
|
||||
val ktClass = declaration.getNonStrictParentOfType<KtClassOrObject>()
|
||||
if (ktClass != null && processed.add(ktClass)) {
|
||||
val lightClass = LightClassUtil.getPsiClass(ktClass)
|
||||
if (lightClass != null) consumer.process(lightClass) else true
|
||||
}
|
||||
else
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ public class KotlinOverridingMethodReferenceSearcher : MethodUsagesSearcher() {
|
||||
super.processQuery(p, consumer)
|
||||
|
||||
val method = p.method
|
||||
p.project.runReadActionInSmartMode {
|
||||
method.project.runReadActionInSmartMode {
|
||||
val containingClass = method.containingClass ?: return@runReadActionInSmartMode
|
||||
|
||||
val searchScope = p.effectiveSearchScope
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScopesCore
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.testIntegration.createTest.CreateTestAction
|
||||
import com.intellij.testIntegration.createTest.TestGenerators
|
||||
import org.jetbrains.kotlin.asJava.KtLightClass
|
||||
@@ -92,17 +93,17 @@ class KotlinCreateTestIntention : SelfTargetingRangeIntention<KtClassOrObject>(K
|
||||
val propertiesComponent = PropertiesComponent.getInstance()
|
||||
val testFolders = HashSet<VirtualFile>()
|
||||
CreateTestAction.checkForTestRoots(srcModule, testFolders)
|
||||
if (testFolders.isEmpty() && !propertiesComponent.getBoolean("create.test.in.the.same.root")) {
|
||||
if (testFolders.isEmpty() && !propertiesComponent.getBoolean("create.test.in.the.same.root", false)) {
|
||||
if (Messages.showOkCancelDialog(
|
||||
project,
|
||||
"Create test in the same source root?",
|
||||
"No Test Roots Found",
|
||||
Messages.getQuestionIcon()) != Messages.OK) return
|
||||
|
||||
propertiesComponent.setValue("create.test.in.the.same.root", true)
|
||||
propertiesComponent.setValue("create.test.in.the.same.root", java.lang.Boolean.TRUE.toString())
|
||||
}
|
||||
|
||||
val srcClass = CreateTestAction.getContainingClass(element) ?: return
|
||||
val srcClass = getContainingClass(element) ?: return
|
||||
|
||||
val srcDir = element.containingFile.containingDirectory
|
||||
val srcPackage = JavaDirectoryService.getInstance().getPackage(srcDir)
|
||||
@@ -166,4 +167,18 @@ class KotlinCreateTestIntention : SelfTargetingRangeIntention<KtClassOrObject>(K
|
||||
}
|
||||
}.invoke(element.project, editor, element.toLightClass()!!)
|
||||
}
|
||||
|
||||
private fun getContainingClass(element: PsiElement): PsiClass? {
|
||||
val psiClass = PsiTreeUtil.getParentOfType(element, PsiClass::class.java, false)
|
||||
if (psiClass == null) {
|
||||
val containingFile = element.containingFile
|
||||
if (containingFile is PsiClassOwner) {
|
||||
val classes = containingFile.classes
|
||||
if (classes.size() == 1) {
|
||||
return classes[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
return psiClass
|
||||
}
|
||||
}
|
||||
@@ -39,7 +39,7 @@ import java.util.regex.Pattern
|
||||
// TODO: We can reuse JavaTestFinder if Kotlin classes have their isPhysical() return true
|
||||
class KotlinTestFinder : JavaTestFinder() {
|
||||
override fun findSourceElement(from: PsiElement): PsiClass? {
|
||||
super.findSourceElement(from)?.let { return it }
|
||||
// super.findSourceElement(from)?.let { return it }
|
||||
|
||||
val classOrObject = from.parentsWithSelf.filterIsInstance<KtClassOrObject>().firstOrNull { !it.isLocal() } ?: return null
|
||||
if (classOrObject.resolveToDescriptorIfAny() == null) return null
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// ACTION_CLASS: org.jetbrains.kotlin.idea.actions.generate.KotlinGenerateTestSupportActionBase$Data
|
||||
// CONFIGURE_LIBRARY: JUnit@lib/junit-4.12.jar
|
||||
// CONFIGURE_LIBRARY: JUnit@lib/junit-4.11.jar
|
||||
class A {<caret>
|
||||
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import org.junit.runners.Parameterized
|
||||
|
||||
// ACTION_CLASS: org.jetbrains.kotlin.idea.actions.generate.KotlinGenerateTestSupportActionBase$Data
|
||||
// CONFIGURE_LIBRARY: JUnit@lib/junit-4.12.jar
|
||||
// CONFIGURE_LIBRARY: JUnit@lib/junit-4.11.jar
|
||||
class A {
|
||||
@Parameterized.Parameters
|
||||
fun data(): Collection<Array<Any>> {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user