Switch to 191 platform

This commit is contained in:
Vyacheslav Gerasimov
2019-04-22 21:52:19 +03:00
parent 21232d202e
commit 8723ad4f46
128 changed files with 1025 additions and 1025 deletions
+8 -8
View File
@@ -1,9 +1,9 @@
183
182
181_182
as32_181_182
as33_182
as34
as35_191
191
192_191
192
183
182_183
181_182_183
as32_181_182_183
as33_182_183
as34_183
as35
@@ -51,7 +51,11 @@ class MockExternalAnnotationsManager : ExternalAnnotationsManager() {
throw UnsupportedOperationException("not implemented")
}
override fun hasAnnotationRootsForFile(file: VirtualFile): Boolean {
throw UnsupportedOperationException("not implemented")
}
override fun hasAnnotationRootsForFile(file: VirtualFile): Boolean = false
override fun findDefaultConstructorExternalAnnotations(aClass: PsiClass, annotationFQN: String): List<PsiAnnotation> = emptyList()
override fun findDefaultConstructorExternalAnnotations(aClass: PsiClass): List<PsiAnnotation> = emptyList()
override fun findExternalAnnotations(listOwner: PsiModifierListOwner, annotationFQN: String): List<PsiAnnotation> = emptyList()
}
@@ -51,11 +51,7 @@ class MockExternalAnnotationsManager : ExternalAnnotationsManager() {
throw UnsupportedOperationException("not implemented")
}
override fun hasAnnotationRootsForFile(file: VirtualFile): Boolean = false
override fun findDefaultConstructorExternalAnnotations(aClass: PsiClass, annotationFQN: String): List<PsiAnnotation> = emptyList()
override fun findDefaultConstructorExternalAnnotations(aClass: PsiClass): List<PsiAnnotation> = emptyList()
override fun findExternalAnnotations(listOwner: PsiModifierListOwner, annotationFQN: String): List<PsiAnnotation> = emptyList()
override fun hasAnnotationRootsForFile(file: VirtualFile): Boolean {
throw UnsupportedOperationException("not implemented")
}
}
+1 -1
View File
@@ -16,6 +16,7 @@ messages/**)
-dontnote **
-dontwarn com.intellij.util.ui.IsRetina*
-dontwarn com.intellij.util.ui.UIUtilities
-dontwarn com.intellij.util.RetinaImage*
-dontwarn apple.awt.*
-dontwarn dk.brics.automaton.*
@@ -201,7 +202,6 @@ messages/**)
-keep class org.jetbrains.org.objectweb.asm.tree.FieldNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.ParameterNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.TypeAnnotationNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.InsnList { *; }
-keep class org.jetbrains.org.objectweb.asm.signature.SignatureReader { *; }
-keep class org.jetbrains.org.objectweb.asm.signature.SignatureVisitor { *; }
@@ -16,7 +16,6 @@ messages/**)
-dontnote **
-dontwarn com.intellij.util.ui.IsRetina*
-dontwarn com.intellij.util.ui.UIUtilities
-dontwarn com.intellij.util.RetinaImage*
-dontwarn apple.awt.*
-dontwarn dk.brics.automaton.*
@@ -202,6 +201,7 @@ messages/**)
-keep class org.jetbrains.org.objectweb.asm.tree.FieldNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.ParameterNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.TypeAnnotationNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.InsnList { *; }
-keep class org.jetbrains.org.objectweb.asm.signature.SignatureReader { *; }
-keep class org.jetbrains.org.objectweb.asm.signature.SignatureVisitor { *; }
+5 -25
View File
@@ -19,16 +19,7 @@ package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.AbstractDataFlowValueRenderingTest
import org.jetbrains.kotlin.addImport.AbstractAddImportTest
import org.jetbrains.kotlin.allopen.AbstractBytecodeListingTestForAllOpen
import org.jetbrains.kotlin.android.*
import org.jetbrains.kotlin.android.annotator.AbstractAndroidGutterIconTest
import org.jetbrains.kotlin.android.configure.AbstractConfigureProjectTest
import org.jetbrains.kotlin.android.folding.AbstractAndroidResourceFoldingTest
import org.jetbrains.kotlin.android.intention.AbstractAndroidIntentionTest
import org.jetbrains.kotlin.android.intention.AbstractAndroidResourceIntentionTest
import org.jetbrains.kotlin.android.lint.AbstractKotlinLintTest
import org.jetbrains.kotlin.android.parcel.AbstractParcelBytecodeListingTest
import org.jetbrains.kotlin.android.quickfix.AbstractAndroidLintQuickfixTest
import org.jetbrains.kotlin.android.quickfix.AbstractAndroidQuickFixMultiFileTest
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidBoxTest
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidBytecodeShapeTest
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidSyntheticPropertyDescriptorTest
@@ -150,15 +141,13 @@ import org.jetbrains.kotlin.jps.build.*
import org.jetbrains.kotlin.jps.build.dependeciestxt.actualizeMppJpsIncTestCaseDirs
import org.jetbrains.kotlin.jps.incremental.AbstractJsProtoComparisonTest
import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractArgumentParsingTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractKaptToolIntegrationTest
import org.jetbrains.kotlin.jvm.abi.AbstractCompareJvmAbiTest
import org.jetbrains.kotlin.jvm.abi.AbstractCompileAgainstJvmAbiTest
import org.jetbrains.kotlin.jvm.abi.AbstractJvmAbiContentTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractArgumentParsingTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractKaptToolIntegrationTest
import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest
import org.jetbrains.kotlin.kapt3.test.AbstractKotlinKaptContextTest
import org.jetbrains.kotlin.nj2k.AbstractNewJavaToKotlinConverterSingleFileTest
import org.jetbrains.kotlin.nj2k.AbstractNullabilityAnalysisTest
import org.jetbrains.kotlin.noarg.AbstractBlackBoxCodegenTestForNoArg
import org.jetbrains.kotlin.noarg.AbstractBytecodeListingTestForNoArg
import org.jetbrains.kotlin.psi.patternMatching.AbstractPsiUnifierTest
@@ -654,10 +643,6 @@ fun main(args: Array<String>) {
model("debugger/tinyApp/src/evaluate/multipleBreakpoints", testMethod = "doMultipleBreakpointsTest")
}
testClass<AbstractAsyncStackTraceTest> {
model("debugger/tinyApp/src/asyncStackTrace")
}
testClass<AbstractFileRankingTest> {
model("debugger/fileRanking")
}
@@ -967,14 +952,8 @@ fun main(args: Array<String>) {
}
}
testGroup("nj2k/tests", "nj2k/testData/") {
testClass<AbstractNullabilityAnalysisTest> {
model("nullabilityAnalysis")
}
}
testGroup("jps-plugin/jps-tests/test", "jps-plugin/testData") {
testClass<AbstractIncrementalJvmJpsTest> {
testClass<AbstractIncrementalJpsTest> {
model("incremental/multiModule/common", extension = null, excludeParentDirs = true)
model("incremental/multiModule/jvm", extension = null, excludeParentDirs = true)
model("incremental/multiModule/multiplatform/custom", extension = null, excludeParentDirs = true)
@@ -1142,7 +1121,7 @@ fun main(args: Array<String>) {
model("script", extension = "kts")
}
}
/*
testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") {
testClass<AbstractAndroidCompletionTest> {
model("android/completion", recursive = false, extension = null)
@@ -1215,4 +1194,5 @@ fun main(args: Array<String>) {
model("android/gutterIcon")
}
}
*/
}
@@ -19,7 +19,16 @@ package org.jetbrains.kotlin.generators.tests
import org.jetbrains.kotlin.AbstractDataFlowValueRenderingTest
import org.jetbrains.kotlin.addImport.AbstractAddImportTest
import org.jetbrains.kotlin.allopen.AbstractBytecodeListingTestForAllOpen
import org.jetbrains.kotlin.android.*
import org.jetbrains.kotlin.android.annotator.AbstractAndroidGutterIconTest
import org.jetbrains.kotlin.android.configure.AbstractConfigureProjectTest
import org.jetbrains.kotlin.android.folding.AbstractAndroidResourceFoldingTest
import org.jetbrains.kotlin.android.intention.AbstractAndroidIntentionTest
import org.jetbrains.kotlin.android.intention.AbstractAndroidResourceIntentionTest
import org.jetbrains.kotlin.android.lint.AbstractKotlinLintTest
import org.jetbrains.kotlin.android.parcel.AbstractParcelBytecodeListingTest
import org.jetbrains.kotlin.android.quickfix.AbstractAndroidLintQuickfixTest
import org.jetbrains.kotlin.android.quickfix.AbstractAndroidQuickFixMultiFileTest
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidBoxTest
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidBytecodeShapeTest
import org.jetbrains.kotlin.android.synthetic.test.AbstractAndroidSyntheticPropertyDescriptorTest
@@ -141,13 +150,15 @@ import org.jetbrains.kotlin.jps.build.*
import org.jetbrains.kotlin.jps.build.dependeciestxt.actualizeMppJpsIncTestCaseDirs
import org.jetbrains.kotlin.jps.incremental.AbstractJsProtoComparisonTest
import org.jetbrains.kotlin.jps.incremental.AbstractJvmProtoComparisonTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractArgumentParsingTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractKaptToolIntegrationTest
import org.jetbrains.kotlin.jvm.abi.AbstractCompareJvmAbiTest
import org.jetbrains.kotlin.jvm.abi.AbstractCompileAgainstJvmAbiTest
import org.jetbrains.kotlin.jvm.abi.AbstractJvmAbiContentTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractArgumentParsingTest
import org.jetbrains.kotlin.kapt.cli.test.AbstractKaptToolIntegrationTest
import org.jetbrains.kotlin.kapt3.test.AbstractClassFileToSourceStubConverterTest
import org.jetbrains.kotlin.kapt3.test.AbstractKotlinKaptContextTest
import org.jetbrains.kotlin.nj2k.AbstractNewJavaToKotlinConverterSingleFileTest
import org.jetbrains.kotlin.nj2k.AbstractNullabilityAnalysisTest
import org.jetbrains.kotlin.noarg.AbstractBlackBoxCodegenTestForNoArg
import org.jetbrains.kotlin.noarg.AbstractBytecodeListingTestForNoArg
import org.jetbrains.kotlin.psi.patternMatching.AbstractPsiUnifierTest
@@ -643,6 +654,10 @@ fun main(args: Array<String>) {
model("debugger/tinyApp/src/evaluate/multipleBreakpoints", testMethod = "doMultipleBreakpointsTest")
}
testClass<AbstractAsyncStackTraceTest> {
model("debugger/tinyApp/src/asyncStackTrace")
}
testClass<AbstractFileRankingTest> {
model("debugger/fileRanking")
}
@@ -952,8 +967,14 @@ fun main(args: Array<String>) {
}
}
testGroup("nj2k/tests", "nj2k/testData/") {
testClass<AbstractNullabilityAnalysisTest> {
model("nullabilityAnalysis")
}
}
testGroup("jps-plugin/jps-tests/test", "jps-plugin/testData") {
testClass<AbstractIncrementalJpsTest> {
testClass<AbstractIncrementalJvmJpsTest> {
model("incremental/multiModule/common", extension = null, excludeParentDirs = true)
model("incremental/multiModule/jvm", extension = null, excludeParentDirs = true)
model("incremental/multiModule/multiplatform/custom", extension = null, excludeParentDirs = true)
@@ -1121,7 +1142,7 @@ fun main(args: Array<String>) {
model("script", extension = "kts")
}
}
/*
testGroup("plugins/android-extensions/android-extensions-idea/tests", "plugins/android-extensions/android-extensions-idea/testData") {
testClass<AbstractAndroidCompletionTest> {
model("android/completion", recursive = false, extension = null)
@@ -1194,5 +1215,4 @@ fun main(args: Array<String>) {
model("android/gutterIcon")
}
}
*/
}
+2 -2
View File
@@ -1,6 +1,7 @@
versions.intellijSdk=183.5153.4
versions.intellijSdk=191.6707.61
versions.androidBuildTools=r23.0.1
versions.idea.NodeJS=181.3494.12
versions.jar.asm-all=7.0.1
versions.jar.guava=25.1-jre
versions.jar.groovy-all=2.4.15
versions.jar.lombok-ast=0.2.3
@@ -10,6 +11,5 @@ versions.jar.streamex=0.6.7
versions.jar.gson=2.8.5
versions.jar.oro=2.0.8
versions.jar.picocontainer=1.2
versions.jar.asm-all=7.0
ignore.jar.snappy-in-java=true
versions.gradle-api=4.5.1
@@ -1,7 +1,6 @@
versions.intellijSdk=191.6707.61
versions.intellijSdk=183.5153.4
versions.androidBuildTools=r23.0.1
versions.idea.NodeJS=181.3494.12
versions.jar.asm-all=7.0.1
versions.jar.guava=25.1-jre
versions.jar.groovy-all=2.4.15
versions.jar.lombok-ast=0.2.3
@@ -11,5 +10,6 @@ versions.jar.streamex=0.6.7
versions.jar.gson=2.8.5
versions.jar.oro=2.0.8
versions.jar.picocontainer=1.2
versions.jar.asm-all=7.0
ignore.jar.snappy-in-java=true
versions.gradle-api=4.5.1
@@ -1,17 +1,90 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.caches.project
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.LIBRARY_KEY
import org.jetbrains.kotlin.idea.MODULE_ROOT_TYPE_KEY
import org.jetbrains.kotlin.idea.SDK_KEY
import org.jetbrains.kotlin.idea.caches.project.UserDataModuleContainer.ForPsiElement
import org.jetbrains.kotlin.idea.caches.project.UserDataModuleContainer.ForVirtualFile
import org.jetbrains.kotlin.idea.core.getSourceType
import org.jetbrains.kotlin.utils.addIfNotNull
// This file declares non-exported API for overriding module info with user-data
// NO-OP implementation, full implementation only for AS3.3, AS3.4
private sealed class UserDataModuleContainer {
abstract fun <T> getUserData(key: Key<T>): T?
abstract fun getModule(): Module?
data class ForVirtualFile(val virtualFile: VirtualFile, val project: Project) : UserDataModuleContainer() {
override fun <T> getUserData(key: Key<T>): T? = virtualFile.getUserData(key)
override fun getModule(): Module? = ModuleUtilCore.findModuleForFile(virtualFile, project)
}
data class ForPsiElement(val psiElement: PsiElement) : UserDataModuleContainer() {
override fun <T> getUserData(key: Key<T>): T? {
return psiElement.getUserData(key)
?: psiElement.containingFile?.getUserData(key)
?: psiElement.containingFile?.originalFile?.virtualFile?.getUserData(key)
}
override fun getModule(): Module? = ModuleUtilCore.findModuleForPsiElement(psiElement)
}
}
private fun collectModuleInfoByUserData(
project: Project,
container: UserDataModuleContainer
): List<IdeaModuleInfo> {
fun forModule(): ModuleSourceInfo? {
val rootType = container.getUserData(MODULE_ROOT_TYPE_KEY) ?: return null
val module = container.getModule() ?: return null
return when (rootType.getSourceType()) {
null -> null
SourceType.PRODUCTION -> module.productionSourceInfo()
SourceType.TEST -> module.testSourceInfo()
}
}
val result = mutableListOf<IdeaModuleInfo>()
result.addIfNotNull(forModule())
val library = container.getUserData(LIBRARY_KEY)
if (library != null) {
result.addAll(createLibraryInfo(project, library))
}
val sdk = container.getUserData(SDK_KEY)
if (sdk != null) {
result.add(SdkInfo(project, sdk))
}
return result
}
fun collectModuleInfoByUserData(
project: Project,
virtualFile: VirtualFile
): List<IdeaModuleInfo> = emptyList()
): List<IdeaModuleInfo> = collectModuleInfoByUserData(project, ForVirtualFile(virtualFile, project))
fun collectModuleInfoByUserData(
psiElement: PsiElement
): List<IdeaModuleInfo> = emptyList()
): List<IdeaModuleInfo> = collectModuleInfoByUserData(psiElement.project, ForPsiElement(psiElement))
@@ -0,0 +1,17 @@
package org.jetbrains.kotlin.idea.caches.project
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
// NO-OP implementation, full implementation only for AS3.3, AS3.4
fun collectModuleInfoByUserData(
project: Project,
virtualFile: VirtualFile
): List<IdeaModuleInfo> = emptyList()
fun collectModuleInfoByUserData(
psiElement: PsiElement
): List<IdeaModuleInfo> = emptyList()
@@ -1,90 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.caches.project
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleUtilCore
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.idea.LIBRARY_KEY
import org.jetbrains.kotlin.idea.MODULE_ROOT_TYPE_KEY
import org.jetbrains.kotlin.idea.SDK_KEY
import org.jetbrains.kotlin.idea.caches.project.UserDataModuleContainer.ForPsiElement
import org.jetbrains.kotlin.idea.caches.project.UserDataModuleContainer.ForVirtualFile
import org.jetbrains.kotlin.idea.core.getSourceType
import org.jetbrains.kotlin.utils.addIfNotNull
// This file declares non-exported API for overriding module info with user-data
private sealed class UserDataModuleContainer {
abstract fun <T> getUserData(key: Key<T>): T?
abstract fun getModule(): Module?
data class ForVirtualFile(val virtualFile: VirtualFile, val project: Project) : UserDataModuleContainer() {
override fun <T> getUserData(key: Key<T>): T? = virtualFile.getUserData(key)
override fun getModule(): Module? = ModuleUtilCore.findModuleForFile(virtualFile, project)
}
data class ForPsiElement(val psiElement: PsiElement) : UserDataModuleContainer() {
override fun <T> getUserData(key: Key<T>): T? {
return psiElement.getUserData(key)
?: psiElement.containingFile?.getUserData(key)
?: psiElement.containingFile?.originalFile?.virtualFile?.getUserData(key)
}
override fun getModule(): Module? = ModuleUtilCore.findModuleForPsiElement(psiElement)
}
}
private fun collectModuleInfoByUserData(
project: Project,
container: UserDataModuleContainer
): List<IdeaModuleInfo> {
fun forModule(): ModuleSourceInfo? {
val rootType = container.getUserData(MODULE_ROOT_TYPE_KEY) ?: return null
val module = container.getModule() ?: return null
return when (rootType.getSourceType()) {
null -> null
SourceType.PRODUCTION -> module.productionSourceInfo()
SourceType.TEST -> module.testSourceInfo()
}
}
val result = mutableListOf<IdeaModuleInfo>()
result.addIfNotNull(forModule())
val library = container.getUserData(LIBRARY_KEY)
if (library != null) {
result.addAll(createLibraryInfo(project, library))
}
val sdk = container.getUserData(SDK_KEY)
if (sdk != null) {
result.add(SdkInfo(project, sdk))
}
return result
}
fun collectModuleInfoByUserData(
project: Project,
virtualFile: VirtualFile
): List<IdeaModuleInfo> = collectModuleInfoByUserData(project, ForVirtualFile(virtualFile, project))
fun collectModuleInfoByUserData(
psiElement: PsiElement
): List<IdeaModuleInfo> = collectModuleInfoByUserData(psiElement.project, ForPsiElement(psiElement))
@@ -15,22 +15,21 @@
*/
package org.jetbrains.kotlin.idea.run
import com.intellij.execution.Location
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.execution.junit.PatternConfigurationProducer
import com.intellij.execution.actions.ConfigurationFromContext
import com.intellij.ide.plugins.PluginManager
import com.intellij.openapi.extensions.PluginId.getId
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.component1
import com.intellij.openapi.util.component2
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.idea.caches.project.isMPPModule
import org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer
import org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer
import org.jetbrains.plugins.gradle.util.GradleConstants
private val IS_JUNIT_ENABLED by lazy { isPluginEnabled("JUnit") }
private val IS_TESTNG_ENABLED by lazy { isPluginEnabled("TestNG-J") }
@@ -69,61 +68,35 @@ class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationP
sourceElement: Ref<PsiElement>
): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
context.module?.asJvmModule() ?: return false
val contextLocation = context.location ?: return false
val module = context.module?.asJvmModule() ?: return false
return super.doSetupConfigurationFromContext(configuration, context, sourceElement)
}
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
override fun getPsiClassForLocation(contextLocation: Location<*>): PsiClass? {
val leaf = contextLocation.psiElement ?: return null
return getTestClass(leaf)
}
override fun getPsiMethodForLocation(contextLocation: Location<*>): PsiMethod? {
val leaf = contextLocation.psiElement ?: return null
return getTestMethod(leaf)
}
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
if (context.location?.module?.isMPPModule == true) {
// TODO: remove hack when IDEA has new API
performRunnable.run()
} else {
super.onFirstRun(fromContext, context, performRunnable)
}
val leaf = context.location?.psiElement ?: return false
val testClass = getTestClass(leaf) ?: return false
sourceElement.set(testClass)
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false
val projectPath = resolveProjectPath(module) ?: return false
val tasksToRun = getTasksToRun(module)
if (tasksToRun.isEmpty()) return false
configuration.settings.externalProjectPath = projectPath
configuration.settings.taskNames = tasksToRun
configuration.settings.scriptParameters = String.format("--tests \"%s\"", testClass.qualifiedName)
configuration.name = testClass.name ?: "unknown"
JavaRunConfigurationExtensionManagerUtil.getInstance().extendCreatedConfiguration(configuration, contextLocation)
return true
}
override fun doIsConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
context.module?.asJvmModule() ?: return false
val leaf = context.location?.psiElement ?: return false
val module = context.module?.asJvmModule() ?: return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
}
if (getTestMethod(leaf) != null) return false
val testClass = getTestClass(leaf)
if (testClass == null || testClass.qualifiedName == null) return false
val projectPath = resolveProjectPath(module) ?: return false
if (projectPath != configuration.settings.externalProjectPath) {
return false
}
if (!configuration.settings.taskNames.containsAll(getTasksToRun(module))) return false
val scriptParameters = configuration.settings.scriptParameters + ' '
val i = scriptParameters.indexOf("--tests ")
if (i == -1) return false
val str = scriptParameters.substringAfter("--tests ").trim() + ' '
return str.startsWith("\"" + testClass.qualifiedName + "\"" + ' ') && !str.contains("--tests")
return super.doIsConfigurationFromContext(configuration, context)
}
}
@@ -134,88 +107,29 @@ class KotlinTestMethodGradleConfigurationProducer : TestMethodGradleConfiguratio
sourceElement: Ref<PsiElement>
): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
val contextLocation = context.location ?: return false
context.module?.asJvmModule() ?: return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
return super.doSetupConfigurationFromContext(configuration, context, sourceElement)
}
override fun getPsiMethodForLocation(contextLocation: Location<*>): PsiMethod? {
val leaf = contextLocation.psiElement ?: return null
return getTestMethod(leaf)
}
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
if (context.location?.module?.isMPPModule == true) {
// TODO: remove hack when IDEA has new API
performRunnable.run()
} else {
super.onFirstRun(fromContext, context, performRunnable)
}
val psiMethod = getTestMethod(contextLocation.psiElement) ?: return false
sourceElement.set(psiMethod)
val containingClass = psiMethod.containingClass ?: return false
if (!applyTestMethodConfiguration(configuration, context, psiMethod, containingClass)) return false
JavaRunConfigurationExtensionManagerUtil.getInstance().extendCreatedConfiguration(configuration, contextLocation)
return true
}
override fun doIsConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
context.module?.asJvmModule() ?: return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
}
val contextLocation = context.location ?: return false
val module = context.module?.asJvmModule() ?: return false
val psiMethod = getTestMethod(contextLocation.psiElement) ?: return false
val containingClass = psiMethod.containingClass ?: return false
val projectPath = resolveProjectPath(module) ?: return false
if (projectPath != configuration.settings.externalProjectPath) {
return false
}
if (!configuration.settings.taskNames.containsAll(getTasksToRun(module))) return false
val scriptParameters = configuration.settings.scriptParameters + ' '
val testFilter = createTestFilter(containingClass, psiMethod)
return scriptParameters.contains(testFilter!!)
}
private fun applyTestMethodConfiguration(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
psiMethod: PsiMethod,
vararg containingClasses: PsiClass
): Boolean {
val module = context.module ?: return false
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false
val projectPath = resolveProjectPath(module) ?: return false
val tasksToRun = getTasksToRun(module)
if (tasksToRun.isEmpty()) return false
configuration.settings.externalProjectPath = projectPath
configuration.settings.taskNames = tasksToRun
val params = containingClasses.joinToString("") { aClass -> createTestFilter(aClass, psiMethod) ?: "" }
configuration.settings.scriptParameters = params.trim()
configuration.name = (if (containingClasses.size == 1) containingClasses[0].name + "." else "") + psiMethod.name
return true
}
companion object {
private fun createTestFilter(aClass: PsiClass, psiMethod: PsiMethod): String? {
return createTestFilter(aClass.qualifiedName, psiMethod.name)
}
fun createTestFilter(aClass: String?, method: String?): String? {
if (aClass == null) return null
val testFilterPattern = aClass + if (method == null) "" else '.' + method
return "--tests \"$testFilterPattern\" "
}
return super.doIsConfigurationFromContext(configuration, context)
}
}
@@ -0,0 +1,221 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.run
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.execution.junit.PatternConfigurationProducer
import com.intellij.ide.plugins.PluginManager
import com.intellij.openapi.extensions.PluginId.getId
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.component1
import com.intellij.openapi.util.component2
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer
import org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer
import org.jetbrains.plugins.gradle.util.GradleConstants
private val IS_JUNIT_ENABLED by lazy { isPluginEnabled("JUnit") }
private val IS_TESTNG_ENABLED by lazy { isPluginEnabled("TestNG-J") }
private val IS_TEST_FRAMEWORK_PLUGIN_ENABLED by lazy { IS_JUNIT_ENABLED || IS_TESTNG_ENABLED }
private fun isPluginEnabled(id: String): Boolean {
return PluginManager.isPluginInstalled(getId(id)) && id !in PluginManager.getDisabledPlugins()
}
private fun getTestClass(leaf: PsiElement): PsiClass? {
if (IS_JUNIT_ENABLED) {
KotlinJUnitRunConfigurationProducer.getTestClass(leaf)?.let { return it }
}
if (IS_TESTNG_ENABLED) {
KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.let { (testClass, testMethod) ->
return if (testMethod == null) testClass else null
}
}
return null
}
private fun getTestMethod(leaf: PsiElement): PsiMethod? {
if (IS_JUNIT_ENABLED) {
KotlinJUnitRunConfigurationProducer.getTestMethod(leaf)?.let { return it }
}
if (IS_TESTNG_ENABLED) {
KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.second?.let { return it }
}
return null
}
class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationProducer() {
override fun doSetupConfigurationFromContext(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
val contextLocation = context.location ?: return false
val module = context.module?.asJvmModule() ?: return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
}
val leaf = context.location?.psiElement ?: return false
val testClass = getTestClass(leaf) ?: return false
sourceElement.set(testClass)
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false
val projectPath = resolveProjectPath(module) ?: return false
val tasksToRun = getTasksToRun(module)
if (tasksToRun.isEmpty()) return false
configuration.settings.externalProjectPath = projectPath
configuration.settings.taskNames = tasksToRun
configuration.settings.scriptParameters = String.format("--tests \"%s\"", testClass.qualifiedName)
configuration.name = testClass.name ?: "unknown"
JavaRunConfigurationExtensionManagerUtil.getInstance().extendCreatedConfiguration(configuration, contextLocation)
return true
}
override fun doIsConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
val leaf = context.location?.psiElement ?: return false
val module = context.module?.asJvmModule() ?: return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
}
if (getTestMethod(leaf) != null) return false
val testClass = getTestClass(leaf)
if (testClass == null || testClass.qualifiedName == null) return false
val projectPath = resolveProjectPath(module) ?: return false
if (projectPath != configuration.settings.externalProjectPath) {
return false
}
if (!configuration.settings.taskNames.containsAll(getTasksToRun(module))) return false
val scriptParameters = configuration.settings.scriptParameters + ' '
val i = scriptParameters.indexOf("--tests ")
if (i == -1) return false
val str = scriptParameters.substringAfter("--tests ").trim() + ' '
return str.startsWith("\"" + testClass.qualifiedName + "\"" + ' ') && !str.contains("--tests")
}
}
class KotlinTestMethodGradleConfigurationProducer : TestMethodGradleConfigurationProducer() {
override fun doSetupConfigurationFromContext(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
val contextLocation = context.location ?: return false
context.module?.asJvmModule() ?: return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
}
val psiMethod = getTestMethod(contextLocation.psiElement) ?: return false
sourceElement.set(psiMethod)
val containingClass = psiMethod.containingClass ?: return false
if (!applyTestMethodConfiguration(configuration, context, psiMethod, containingClass)) return false
JavaRunConfigurationExtensionManagerUtil.getInstance().extendCreatedConfiguration(configuration, contextLocation)
return true
}
override fun doIsConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
if (RunConfigurationProducer.getInstance(PatternConfigurationProducer::class.java).isMultipleElementsSelected(context)) {
return false
}
val contextLocation = context.location ?: return false
val module = context.module?.asJvmModule() ?: return false
val psiMethod = getTestMethod(contextLocation.psiElement) ?: return false
val containingClass = psiMethod.containingClass ?: return false
val projectPath = resolveProjectPath(module) ?: return false
if (projectPath != configuration.settings.externalProjectPath) {
return false
}
if (!configuration.settings.taskNames.containsAll(getTasksToRun(module))) return false
val scriptParameters = configuration.settings.scriptParameters + ' '
val testFilter = createTestFilter(containingClass, psiMethod)
return scriptParameters.contains(testFilter!!)
}
private fun applyTestMethodConfiguration(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
psiMethod: PsiMethod,
vararg containingClasses: PsiClass
): Boolean {
val module = context.module ?: return false
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false
val projectPath = resolveProjectPath(module) ?: return false
val tasksToRun = getTasksToRun(module)
if (tasksToRun.isEmpty()) return false
configuration.settings.externalProjectPath = projectPath
configuration.settings.taskNames = tasksToRun
val params = containingClasses.joinToString("") { aClass -> createTestFilter(aClass, psiMethod) ?: "" }
configuration.settings.scriptParameters = params.trim()
configuration.name = (if (containingClasses.size == 1) containingClasses[0].name + "." else "") + psiMethod.name
return true
}
companion object {
private fun createTestFilter(aClass: PsiClass, psiMethod: PsiMethod): String? {
return createTestFilter(aClass.qualifiedName, psiMethod.name)
}
fun createTestFilter(aClass: String?, method: String?): String? {
if (aClass == null) return null
val testFilterPattern = aClass + if (method == null) "" else '.' + method
return "--tests \"$testFilterPattern\" "
}
}
}
@@ -1,135 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.run
import com.intellij.execution.Location
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.ConfigurationFromContext
import com.intellij.ide.plugins.PluginManager
import com.intellij.openapi.extensions.PluginId.getId
import com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration
import com.intellij.openapi.util.Ref
import com.intellij.openapi.util.component1
import com.intellij.openapi.util.component2
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import org.jetbrains.kotlin.idea.caches.project.isMPPModule
import org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer
import org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer
private val IS_JUNIT_ENABLED by lazy { isPluginEnabled("JUnit") }
private val IS_TESTNG_ENABLED by lazy { isPluginEnabled("TestNG-J") }
private val IS_TEST_FRAMEWORK_PLUGIN_ENABLED by lazy { IS_JUNIT_ENABLED || IS_TESTNG_ENABLED }
private fun isPluginEnabled(id: String): Boolean {
return PluginManager.isPluginInstalled(getId(id)) && id !in PluginManager.getDisabledPlugins()
}
private fun getTestClass(leaf: PsiElement): PsiClass? {
if (IS_JUNIT_ENABLED) {
KotlinJUnitRunConfigurationProducer.getTestClass(leaf)?.let { return it }
}
if (IS_TESTNG_ENABLED) {
KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.let { (testClass, testMethod) ->
return if (testMethod == null) testClass else null
}
}
return null
}
private fun getTestMethod(leaf: PsiElement): PsiMethod? {
if (IS_JUNIT_ENABLED) {
KotlinJUnitRunConfigurationProducer.getTestMethod(leaf)?.let { return it }
}
if (IS_TESTNG_ENABLED) {
KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.second?.let { return it }
}
return null
}
class KotlinTestClassGradleConfigurationProducer : TestClassGradleConfigurationProducer() {
override fun doSetupConfigurationFromContext(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
context.module?.asJvmModule() ?: return false
return super.doSetupConfigurationFromContext(configuration, context, sourceElement)
}
override fun getPsiClassForLocation(contextLocation: Location<*>): PsiClass? {
val leaf = contextLocation.psiElement ?: return null
return getTestClass(leaf)
}
override fun getPsiMethodForLocation(contextLocation: Location<*>): PsiMethod? {
val leaf = contextLocation.psiElement ?: return null
return getTestMethod(leaf)
}
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
if (context.location?.module?.isMPPModule == true) {
// TODO: remove hack when IDEA has new API
performRunnable.run()
} else {
super.onFirstRun(fromContext, context, performRunnable)
}
}
override fun doIsConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
context.module?.asJvmModule() ?: return false
return super.doIsConfigurationFromContext(configuration, context)
}
}
class KotlinTestMethodGradleConfigurationProducer : TestMethodGradleConfigurationProducer() {
override fun doSetupConfigurationFromContext(
configuration: ExternalSystemRunConfiguration,
context: ConfigurationContext,
sourceElement: Ref<PsiElement>
): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
context.module?.asJvmModule() ?: return false
return super.doSetupConfigurationFromContext(configuration, context, sourceElement)
}
override fun getPsiMethodForLocation(contextLocation: Location<*>): PsiMethod? {
val leaf = contextLocation.psiElement ?: return null
return getTestMethod(leaf)
}
override fun onFirstRun(fromContext: ConfigurationFromContext, context: ConfigurationContext, performRunnable: Runnable) {
if (context.location?.module?.isMPPModule == true) {
// TODO: remove hack when IDEA has new API
performRunnable.run()
} else {
super.onFirstRun(fromContext, context, performRunnable)
}
}
override fun doIsConfigurationFromContext(configuration: ExternalSystemRunConfiguration, context: ConfigurationContext): Boolean {
if (!IS_TEST_FRAMEWORK_PLUGIN_ENABLED) return false
context.module?.asJvmModule() ?: return false
return super.doIsConfigurationFromContext(configuration, context)
}
}
@@ -31,6 +31,7 @@ import org.gradle.tooling.model.DomainObjectSet;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.util.GradleVersion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.ClassSetProjectImportExtraModelProvider;
import org.jetbrains.plugins.gradle.model.ExternalProject;
import org.jetbrains.plugins.gradle.model.ProjectImportAction;
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper;
@@ -140,7 +141,7 @@ public abstract class AbstractModelBuilderTest {
try {
ProjectImportAction projectImportAction = new ProjectImportAction(false);
projectImportAction.addExtraProjectModelClasses(getModels());
projectImportAction.addProjectImportExtraModelProvider(new ClassSetProjectImportExtraModelProvider(getModels()));
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
File initScript = GradleExecutionHelper.generateInitScript(false, getToolingExtensionClasses());
assertNotNull(initScript);
@@ -31,7 +31,6 @@ import org.gradle.tooling.model.DomainObjectSet;
import org.gradle.tooling.model.idea.IdeaModule;
import org.gradle.util.GradleVersion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.ClassSetProjectImportExtraModelProvider;
import org.jetbrains.plugins.gradle.model.ExternalProject;
import org.jetbrains.plugins.gradle.model.ProjectImportAction;
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper;
@@ -141,7 +140,7 @@ public abstract class AbstractModelBuilderTest {
try {
ProjectImportAction projectImportAction = new ProjectImportAction(false);
projectImportAction.addProjectImportExtraModelProvider(new ClassSetProjectImportExtraModelProvider(getModels()));
projectImportAction.addExtraProjectModelClasses(getModels());
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
File initScript = GradleExecutionHelper.generateInitScript(false, getToolingExtensionClasses());
assertNotNull(initScript);
@@ -11,18 +11,15 @@ import org.jetbrains.jps.model.java.JavaResourceRootType
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
sealed class KotlinResourceRootType(val isTest: Boolean) : JpsElementTypeBase<JavaResourceRootProperties>(),
JpsModuleSourceRootType<JavaResourceRootProperties>, KotlinRootType {
sealed class KotlinResourceRootType() : JpsElementTypeBase<JavaResourceRootProperties>(),
JpsModuleSourceRootType<JavaResourceRootProperties> {
override fun createDefaultProperties() =
JpsJavaExtensionService.getInstance().createResourceRootProperties("", false)
override fun isTestRoot() = isTest
override fun isForTests() = isTest
override fun equals(other: Any?) = if (super.equals(other)) true else isSameRootType(this, other)
}
object ResourceKotlinRootType : KotlinResourceRootType(false)
object TestResourceKotlinRootType : KotlinResourceRootType(true)
object ResourceKotlinRootType : KotlinResourceRootType()
object TestResourceKotlinRootType : KotlinResourceRootType() {
override fun isForTests() = true
}
@@ -11,15 +11,18 @@ import org.jetbrains.jps.model.java.JavaResourceRootType
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
sealed class KotlinResourceRootType() : JpsElementTypeBase<JavaResourceRootProperties>(),
JpsModuleSourceRootType<JavaResourceRootProperties> {
sealed class KotlinResourceRootType(val isTest: Boolean) : JpsElementTypeBase<JavaResourceRootProperties>(),
JpsModuleSourceRootType<JavaResourceRootProperties>, KotlinRootType {
override fun createDefaultProperties() =
JpsJavaExtensionService.getInstance().createResourceRootProperties("", false)
override fun isTestRoot() = isTest
override fun isForTests() = isTest
override fun equals(other: Any?) = if (super.equals(other)) true else isSameRootType(this, other)
}
object ResourceKotlinRootType : KotlinResourceRootType()
object TestResourceKotlinRootType : KotlinResourceRootType() {
override fun isForTests() = true
}
object ResourceKotlinRootType : KotlinResourceRootType(false)
object TestResourceKotlinRootType : KotlinResourceRootType(true)
@@ -11,21 +11,16 @@ import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
sealed class KotlinSourceRootType(val isTest: Boolean) : JpsElementTypeBase<JavaSourceRootProperties>(), JpsModuleSourceRootType<JavaSourceRootProperties>, KotlinRootType {
sealed class KotlinSourceRootType() : JpsElementTypeBase<JavaSourceRootProperties>(), JpsModuleSourceRootType<JavaSourceRootProperties> {
override fun createDefaultProperties() = JpsJavaExtensionService.getInstance().createSourceRootProperties("")
override fun isTestRoot() = isTest
override fun isForTests() = isTest
override fun equals(other: Any?) = if (super.equals(other)) true else isSameRootType(this, other)
}
object SourceKotlinRootType : KotlinSourceRootType(false)
object SourceKotlinRootType : KotlinSourceRootType()
object TestSourceKotlinRootType : KotlinSourceRootType(true)
object TestSourceKotlinRootType : KotlinSourceRootType() {
override fun isForTests() = true
}
val ALL_KOTLIN_SOURCE_ROOT_TYPES = setOf(SourceKotlinRootType, TestSourceKotlinRootType)
@@ -11,16 +11,21 @@ import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
sealed class KotlinSourceRootType() : JpsElementTypeBase<JavaSourceRootProperties>(), JpsModuleSourceRootType<JavaSourceRootProperties> {
sealed class KotlinSourceRootType(val isTest: Boolean) : JpsElementTypeBase<JavaSourceRootProperties>(), JpsModuleSourceRootType<JavaSourceRootProperties>, KotlinRootType {
override fun createDefaultProperties() = JpsJavaExtensionService.getInstance().createSourceRootProperties("")
override fun isTestRoot() = isTest
override fun isForTests() = isTest
override fun equals(other: Any?) = if (super.equals(other)) true else isSameRootType(this, other)
}
object SourceKotlinRootType : KotlinSourceRootType()
object SourceKotlinRootType : KotlinSourceRootType(false)
object TestSourceKotlinRootType : KotlinSourceRootType() {
override fun isForTests() = true
}
object TestSourceKotlinRootType : KotlinSourceRootType(true)
val ALL_KOTLIN_SOURCE_ROOT_TYPES = setOf(SourceKotlinRootType, TestSourceKotlinRootType)
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.idea.maven
import com.intellij.openapi.util.AsyncResult
import org.jetbrains.concurrency.AsyncPromise
import org.jetbrains.idea.maven.model.MavenArtifact
import org.jetbrains.idea.maven.project.MavenProject
import org.jetbrains.idea.maven.project.MavenProjectsManager
@@ -17,5 +17,5 @@ fun scheduleArtifactsDownloading(
toBeDownloaded: List<MavenArtifact>
) {
//true, false, AsyncResult()
projectsManager.scheduleArtifactsDownloading(projects, toBeDownloaded, true, false, AsyncResult())
projectsManager.scheduleArtifactsDownloading(projects, toBeDownloaded, true, false, AsyncPromise())
}
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.idea.maven
import org.jetbrains.concurrency.AsyncPromise
import com.intellij.openapi.util.AsyncResult
import org.jetbrains.idea.maven.model.MavenArtifact
import org.jetbrains.idea.maven.project.MavenProject
import org.jetbrains.idea.maven.project.MavenProjectsManager
@@ -17,5 +17,5 @@ fun scheduleArtifactsDownloading(
toBeDownloaded: List<MavenArtifact>
) {
//true, false, AsyncResult()
projectsManager.scheduleArtifactsDownloading(projects, toBeDownloaded, true, false, AsyncPromise())
projectsManager.scheduleArtifactsDownloading(projects, toBeDownloaded, true, false, AsyncResult())
}
+4 -12
View File
@@ -7,14 +7,6 @@
interface="org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension"
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.androidDexer"
interface="org.jetbrains.kotlin.idea.debugger.evaluate.classLoading.AndroidDexer"
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.android.model.androidModuleInfoProvider"
interface="org.jetbrains.kotlin.android.model.AndroidModuleInfoProvider"
area="IDEA_MODULE"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.idePlatformKindResolution"
interface="org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution"/>
@@ -94,12 +86,12 @@
<j2kConverterExtension implementation="org.jetbrains.kotlin.idea.j2k.OldJ2kConverterExtension"/>
<j2kConverterExtension implementation="org.jetbrains.kotlin.nj2k.NewJ2kConverterExtension"/>
</extensions>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<registryKey key="kotlin.use.new.j2k"
description="Use new Java to Kotlin Converter (experimental)"
defaultValue="false"
restartRequired="false"/>
description="Use new Java to Kotlin Converter (experimental)"
defaultValue="false"
restartRequired="false"/>
</extensions>
</idea-plugin>
@@ -7,6 +7,14 @@
interface="org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension"
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.androidDexer"
interface="org.jetbrains.kotlin.idea.debugger.evaluate.classLoading.AndroidDexer"
area="IDEA_PROJECT"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.android.model.androidModuleInfoProvider"
interface="org.jetbrains.kotlin.android.model.AndroidModuleInfoProvider"
area="IDEA_MODULE"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.idePlatformKindResolution"
interface="org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution"/>
@@ -86,12 +94,12 @@
<j2kConverterExtension implementation="org.jetbrains.kotlin.idea.j2k.OldJ2kConverterExtension"/>
<j2kConverterExtension implementation="org.jetbrains.kotlin.nj2k.NewJ2kConverterExtension"/>
</extensions>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<registryKey key="kotlin.use.new.j2k"
description="Use new Java to Kotlin Converter (experimental)"
defaultValue="false"
restartRequired="false"/>
description="Use new Java to Kotlin Converter (experimental)"
defaultValue="false"
restartRequired="false"/>
</extensions>
</idea-plugin>
+2 -1
View File
@@ -20,9 +20,10 @@
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.KotlinJavaMPPSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinNativeLibraryDataService"/>
<externalSystemTaskNotificationListener implementation="org.jetbrains.kotlin.idea.core.script.ReloadGradleTemplatesOnSync"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.android.KotlinAndroidGradleOrderEnumerationHandler$FactoryImpl" order="first"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
@@ -20,10 +20,9 @@
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.KotlinJavaMPPSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinNativeLibraryDataService"/>
<externalSystemTaskNotificationListener implementation="org.jetbrains.kotlin.idea.core.script.ReloadGradleTemplatesOnSync"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestClassGradleConfigurationProducer"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinTestMethodGradleConfigurationProducer"/>
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.android.KotlinAndroidGradleOrderEnumerationHandler$FactoryImpl" order="first"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
+1
View File
@@ -14,6 +14,7 @@
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinGradleOrderEnumerationHandler$Factory" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver"/>
<testTasksProvider implementation="org.jetbrains.kotlin.idea.run.KotlinMPPGradleTestTasksProvider"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
@@ -14,7 +14,6 @@
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinGradleOrderEnumerationHandler$Factory" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver"/>
<testTasksProvider implementation="org.jetbrains.kotlin.idea.run.KotlinMPPGradleTestTasksProvider"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
+5
View File
@@ -166,6 +166,11 @@
description="Whether to use multi resolve for UAST in Kotlin provided by `Call.resolveCandidates`, otherwise PsiPolyVariantReference-based multiResolve will be performed"
defaultValue="true"
restartRequired="false"/>
<registryKey key="kotlin.uast.force.uinjectionhost"
description="Whether to convert `KtStringTemplateExpression` to `KotlinStringTemplateUPolyadicExpression` in all cases"
defaultValue="false"
restartRequired="false"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.uast">
@@ -166,11 +166,6 @@
description="Whether to use multi resolve for UAST in Kotlin provided by `Call.resolveCandidates`, otherwise PsiPolyVariantReference-based multiResolve will be performed"
defaultValue="true"
restartRequired="false"/>
<registryKey key="kotlin.uast.force.uinjectionhost"
description="Whether to convert `KtStringTemplateExpression` to `KotlinStringTemplateUPolyadicExpression` in all cases"
defaultValue="false"
restartRequired="false"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.uast">
+10 -3
View File
@@ -13,7 +13,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<version>@snapshot@</version>
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
<idea-version since-build="183.3283.2" until-build="183.*"/>
<idea-version since-build="191.5109.14" until-build="192.*"/>
<depends>com.intellij.modules.platform</depends>
@@ -26,7 +26,6 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<depends optional="true" config-file="gradle-groovy.xml">org.intellij.groovy</depends>
<depends optional="true" config-file="maven.xml">org.jetbrains.idea.maven</depends>
<depends optional="true" config-file="testng-j.xml">TestNG-J</depends>
<depends optional="true" config-file="android.xml">org.jetbrains.android</depends>
<depends optional="true" config-file="coverage.xml">Coverage</depends>
<depends optional="true" config-file="i18n.xml">com.intellij.java-i18n</depends>
<depends optional="true" config-file="decompiler.xml">org.jetbrains.java.decompiler</depends>
@@ -70,7 +69,15 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
</extensions>
<extensions defaultExtensionNs="com.intellij.codeInsight">
<nonBlockingContextChecker implementation="org.jetbrains.kotlin.idea.inspections.blockingCallsDetection.CoroutineNonBlockingContextChecker"/>
<nonBlockingContextChecker implementation="org.jetbrains.kotlin.idea.inspections.blockingCallsDetection.CoroutineNonBlockingContextChecker"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.action.refactoring" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
</extensions>
</idea-plugin>
@@ -13,7 +13,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<version>@snapshot@</version>
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
<idea-version since-build="191.5109.14" until-build="192.*"/>
<idea-version since-build="183.3283.2" until-build="183.*"/>
<depends>com.intellij.modules.platform</depends>
@@ -26,6 +26,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<depends optional="true" config-file="gradle-groovy.xml">org.intellij.groovy</depends>
<depends optional="true" config-file="maven.xml">org.jetbrains.idea.maven</depends>
<depends optional="true" config-file="testng-j.xml">TestNG-J</depends>
<depends optional="true" config-file="android.xml">org.jetbrains.android</depends>
<depends optional="true" config-file="coverage.xml">Coverage</depends>
<depends optional="true" config-file="i18n.xml">com.intellij.java-i18n</depends>
<depends optional="true" config-file="decompiler.xml">org.jetbrains.java.decompiler</depends>
@@ -69,15 +70,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
</extensions>
<extensions defaultExtensionNs="com.intellij.codeInsight">
<nonBlockingContextChecker implementation="org.jetbrains.kotlin.idea.inspections.blockingCallsDetection.CoroutineNonBlockingContextChecker"/>
<nonBlockingContextChecker implementation="org.jetbrains.kotlin.idea.inspections.blockingCallsDetection.CoroutineNonBlockingContextChecker"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.action.refactoring" version="1"/>
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
</extensions>
</idea-plugin>
@@ -64,6 +64,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.utils.ifEmpty
import org.jetbrains.kotlin.utils.keysToMap
import java.lang.AssertionError
import java.util.*
interface Mover : (KtNamedDeclaration, KtElement) -> KtNamedDeclaration {
@@ -202,12 +203,8 @@ class MoveKotlinDeclarationsProcessor(
fun collectUsages(kotlinToLightElements: Map<KtNamedDeclaration, List<PsiNamedElement>>, result: MutableCollection<UsageInfo>) {
kotlinToLightElements.values.flatten().flatMapTo(result) { lightElement ->
val searchScope = getSearchScope(lightElement) ?: return@flatMapTo emptyList()
val newFqName = StringUtil.getQualifiedName(newContainerName, lightElement.name)
val newFqNameForKt = StringUtil.getQualifiedName(
newContainerName,
lightElement.namedUnwrappedElement?.name?: lightElement.name
)
val elementName = lightElement.name ?: return@flatMapTo emptyList()
val newFqName = StringUtil.getQualifiedName(newContainerName, elementName)
val foundReferences = HashSet<PsiReference>()
val results = ReferencesSearch
@@ -235,19 +232,6 @@ class MoveKotlinDeclarationsProcessor(
if (handler !is MoveKotlinClassHandler) handler.preprocessUsages(results)
}
results
.filter { it is NonCodeUsageInfo && it.file is KtFile }
.forEach {
val newText = NonCodeUsageInfo::class.java.getField("newText")
// A 'newText' is marked as final initially, but here we need to change it to prevent
// light-class names in kotlin files.
val oldAccessibility = newText.isAccessible
newText.isAccessible = true
newText.set(it, newFqNameForKt)
// Restore initial accessibility of 'newText' field.
newText.isAccessible = oldAccessibility
}
results
}
}
@@ -64,7 +64,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.utils.ifEmpty
import org.jetbrains.kotlin.utils.keysToMap
import java.lang.AssertionError
import java.util.*
interface Mover : (KtNamedDeclaration, KtElement) -> KtNamedDeclaration {
@@ -203,8 +202,12 @@ class MoveKotlinDeclarationsProcessor(
fun collectUsages(kotlinToLightElements: Map<KtNamedDeclaration, List<PsiNamedElement>>, result: MutableCollection<UsageInfo>) {
kotlinToLightElements.values.flatten().flatMapTo(result) { lightElement ->
val searchScope = getSearchScope(lightElement) ?: return@flatMapTo emptyList()
val elementName = lightElement.name ?: return@flatMapTo emptyList()
val newFqName = StringUtil.getQualifiedName(newContainerName, elementName)
val newFqName = StringUtil.getQualifiedName(newContainerName, lightElement.name)
val newFqNameForKt = StringUtil.getQualifiedName(
newContainerName,
lightElement.namedUnwrappedElement?.name?: lightElement.name
)
val foundReferences = HashSet<PsiReference>()
val results = ReferencesSearch
@@ -232,6 +235,19 @@ class MoveKotlinDeclarationsProcessor(
if (handler !is MoveKotlinClassHandler) handler.preprocessUsages(results)
}
results
.filter { it is NonCodeUsageInfo && it.file is KtFile }
.forEach {
val newText = NonCodeUsageInfo::class.java.getField("newText")
// A 'newText' is marked as final initially, but here we need to change it to prevent
// light-class names in kotlin files.
val oldAccessibility = newText.isAccessible
newText.isAccessible = true
newText.set(it, newFqNameForKt)
// Restore initial accessibility of 'newText' field.
newText.isAccessible = oldAccessibility
}
results
}
}
@@ -100,7 +100,7 @@ class KotlinTargetElementEvaluator : TargetElementEvaluatorEx, TargetElementUtil
val calleeExpression = refExpression?.getParentOfTypeAndBranch<KtCallElement> { calleeExpression }
if (calleeExpression != null) {
(ref.resolve() as? KtConstructor<*>)?.let {
return if (flags and JavaTargetElementEvaluator.NEW_AS_CONSTRUCTOR != 0) it else it.containingClassOrObject
return if (flags and JavaTargetElementEvaluator().additionalReferenceSearchFlags != 0) it else it.containingClassOrObject
}
}
@@ -100,7 +100,7 @@ class KotlinTargetElementEvaluator : TargetElementEvaluatorEx, TargetElementUtil
val calleeExpression = refExpression?.getParentOfTypeAndBranch<KtCallElement> { calleeExpression }
if (calleeExpression != null) {
(ref.resolve() as? KtConstructor<*>)?.let {
return if (flags and JavaTargetElementEvaluator().additionalReferenceSearchFlags != 0) it else it.containingClassOrObject
return if (flags and JavaTargetElementEvaluator.NEW_AS_CONSTRUCTOR != 0) it else it.containingClassOrObject
}
}
@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.idea.slicer.compat
import com.intellij.psi.PsiElement
// BUNCH: 183
internal typealias PsiElement_N183_NN191 = PsiElement?
internal typealias PsiElement_N183_NN191 = PsiElement
@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.idea.slicer.compat
import com.intellij.psi.PsiElement
// BUNCH: 183
internal typealias PsiElement_N183_NN191 = PsiElement
internal typealias PsiElement_N183_NN191 = PsiElement?
@@ -1,14 +1,21 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.statistics
import com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger
import com.intellij.internal.statistic.eventLog.FeatureUsageData
import org.jetbrains.kotlin.idea.KotlinPluginUtil
open class KotlinStatisticsTrigger {
companion object {
public fun trigger(trigger: KotlinEventTrigger, event: String) {
// Not whitelisted for 183
private val context = FeatureUsageData().addData("plugin_version", KotlinPluginUtil.getPluginVersion())
fun trigger(trigger: KotlinEventTrigger, event: String) {
FUCounterUsageLogger.getInstance().logEvent(trigger.GROUP_ID, event, context)
}
}
}
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.statistics
open class KotlinStatisticsTrigger {
companion object {
public fun trigger(trigger: KotlinEventTrigger, event: String) {
// Not whitelisted for 183
}
}
}
@@ -1,21 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.statistics
import com.intellij.internal.statistic.service.fus.collectors.FUCounterUsageLogger
import com.intellij.internal.statistic.eventLog.FeatureUsageData
import org.jetbrains.kotlin.idea.KotlinPluginUtil
open class KotlinStatisticsTrigger {
companion object {
private val context = FeatureUsageData().addData("plugin_version", KotlinPluginUtil.getPluginVersion())
fun trigger(trigger: KotlinEventTrigger, event: String) {
FUCounterUsageLogger.getInstance().logEvent(trigger.GROUP_ID, event, context)
}
}
}
@@ -5,8 +5,11 @@
package org.jetbrains.kotlin.idea.highlighter
import com.intellij.testFramework.ExpectedHighlightingData
// Idea 191 has an additional check for duplicate highlighting
// BUNCH: 183
fun expectedDuplicatedHighlighting(runnable: Runnable) {
runnable.run()
@Suppress("DEPRECATION")
ExpectedHighlightingData.expectedDuplicatedHighlighting(runnable)
}
@@ -5,11 +5,8 @@
package org.jetbrains.kotlin.idea.highlighter
import com.intellij.testFramework.ExpectedHighlightingData
// Idea 191 has an additional check for duplicate highlighting
// BUNCH: 183
fun expectedDuplicatedHighlighting(runnable: Runnable) {
@Suppress("DEPRECATION")
ExpectedHighlightingData.expectedDuplicatedHighlighting(runnable)
runnable.run()
}
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.android.model.impl
import com.android.builder.model.SourceProvider
import com.android.tools.idea.gradle.project.GradleProjectInfo
import com.android.tools.idea.gradle.project.model.AndroidModuleModel
import com.android.tools.idea.res.AppResourceRepository
import com.android.tools.idea.res.ResourceRepositoryManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.android.facet.AndroidFacet
@@ -36,7 +36,7 @@ class AndroidModuleInfoProviderImpl(override val module: Module) : AndroidModule
}
override fun getApplicationResourceDirectories(createIfNecessary: Boolean): Collection<VirtualFile> {
return AppResourceRepository.getOrCreateInstance(module)?.resourceDirs ?: emptyList()
return ResourceRepositoryManager.getOrCreateInstance(module)?.getAppResources(createIfNecessary)?.resourceDirs ?: emptyList()
}
override fun getAllSourceProviders(): List<AndroidModuleInfoProvider.SourceProviderMirror> {
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.android.model.impl
import com.android.builder.model.SourceProvider
import com.android.tools.idea.gradle.project.GradleProjectInfo
import com.android.tools.idea.gradle.project.model.AndroidModuleModel
import com.android.tools.idea.res.ResourceRepositoryManager
import com.android.tools.idea.res.AppResourceRepository
import com.intellij.openapi.module.Module
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.android.facet.AndroidFacet
@@ -36,7 +36,7 @@ class AndroidModuleInfoProviderImpl(override val module: Module) : AndroidModule
}
override fun getApplicationResourceDirectories(createIfNecessary: Boolean): Collection<VirtualFile> {
return ResourceRepositoryManager.getOrCreateInstance(module)?.getAppResources(createIfNecessary)?.resourceDirs ?: emptyList()
return AppResourceRepository.getOrCreateInstance(module)?.resourceDirs ?: emptyList()
}
override fun getAllSourceProviders(): List<AndroidModuleInfoProvider.SourceProviderMirror> {
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.kapt.idea
import com.android.tools.idea.gradle.project.model.AndroidModuleModel
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.ProjectKeys
@@ -80,8 +79,6 @@ class KaptProjectResolverExtension : AbstractProjectResolverExtension() {
if (kaptModel != null && kaptModel.isEnabled) {
for (sourceSet in kaptModel.sourceSets) {
populateAndroidModuleModelIfNeeded(ideModule, sourceSet)
val sourceSetDataNode = ideModule.findGradleSourceSet(sourceSet.sourceSetName) ?: continue
fun addSourceSet(path: String, type: ExternalSystemSourceType) {
@@ -106,42 +103,6 @@ class KaptProjectResolverExtension : AbstractProjectResolverExtension() {
super.populateModuleExtraModels(gradleModule, ideModule)
}
private fun populateAndroidModuleModelIfNeeded(ideModule: DataNode<ModuleData>, sourceSet: KaptSourceSetModel) {
ideModule.findAndroidModuleModel()?.let { androidModelAny ->
// We can cast to AndroidModuleModel cause we already checked in findAndroidModuleModel() that the class exists
val generatedKotlinSources = sourceSet.generatedKotlinSourcesDirFile ?: return
val androidModel = androidModelAny.data as? AndroidModuleModel ?: return
val variant = androidModel.findVariantByName(sourceSet.sourceSetName) ?: return
androidModel.registerExtraGeneratedSourceFolder(generatedKotlinSources)
// TODO remove this when IDEA eventually migrate to the newer Android plugin
try {
variant.mainArtifact.generatedSourceFolders += generatedKotlinSources
} catch (e: Throwable) {
// There was an error being thrown here, but the code above doesn't work for the newer versions of Android Studio 3
// (generatedSourceFolders returns a wrapped unmodifiable list), and the thrown exception breaks the import.
// The error will be moved back when I find a work-around for AS3.
}
}
}
private fun DataNode<ModuleData>.findAndroidModuleModel(): DataNode<*>? {
val modelClassName = "com.android.tools.idea.gradle.project.model.AndroidModuleModel"
val node = children.firstOrNull { it.key.dataType == modelClassName } ?: return null
return if (!hasClassInClasspath(modelClassName)) null else node
}
private fun hasClassInClasspath(name: String): Boolean {
return try {
Class.forName(name) != null
} catch (thr: Throwable) {
false
}
}
private fun DataNode<ModuleData>.findGradleSourceSet(sourceSetName: String): DataNode<GradleSourceSetData>? {
val moduleName = data.id
for (child in children) {
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.kapt.idea
import com.android.tools.idea.gradle.project.model.AndroidModuleModel
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.ProjectKeys
@@ -79,6 +80,8 @@ class KaptProjectResolverExtension : AbstractProjectResolverExtension() {
if (kaptModel != null && kaptModel.isEnabled) {
for (sourceSet in kaptModel.sourceSets) {
populateAndroidModuleModelIfNeeded(ideModule, sourceSet)
val sourceSetDataNode = ideModule.findGradleSourceSet(sourceSet.sourceSetName) ?: continue
fun addSourceSet(path: String, type: ExternalSystemSourceType) {
@@ -103,6 +106,42 @@ class KaptProjectResolverExtension : AbstractProjectResolverExtension() {
super.populateModuleExtraModels(gradleModule, ideModule)
}
private fun populateAndroidModuleModelIfNeeded(ideModule: DataNode<ModuleData>, sourceSet: KaptSourceSetModel) {
ideModule.findAndroidModuleModel()?.let { androidModelAny ->
// We can cast to AndroidModuleModel cause we already checked in findAndroidModuleModel() that the class exists
val generatedKotlinSources = sourceSet.generatedKotlinSourcesDirFile ?: return
val androidModel = androidModelAny.data as? AndroidModuleModel ?: return
val variant = androidModel.findVariantByName(sourceSet.sourceSetName) ?: return
androidModel.registerExtraGeneratedSourceFolder(generatedKotlinSources)
// TODO remove this when IDEA eventually migrate to the newer Android plugin
try {
variant.mainArtifact.generatedSourceFolders += generatedKotlinSources
} catch (e: Throwable) {
// There was an error being thrown here, but the code above doesn't work for the newer versions of Android Studio 3
// (generatedSourceFolders returns a wrapped unmodifiable list), and the thrown exception breaks the import.
// The error will be moved back when I find a work-around for AS3.
}
}
}
private fun DataNode<ModuleData>.findAndroidModuleModel(): DataNode<*>? {
val modelClassName = "com.android.tools.idea.gradle.project.model.AndroidModuleModel"
val node = children.firstOrNull { it.key.dataType == modelClassName } ?: return null
return if (!hasClassInClasspath(modelClassName)) null else node
}
private fun hasClassInClasspath(name: String): Boolean {
return try {
Class.forName(name) != null
} catch (thr: Throwable) {
false
}
}
private fun DataNode<ModuleData>.findGradleSourceSet(sourceSetName: String): DataNode<GradleSourceSetData>? {
val moduleName = data.id
for (child in children) {
@@ -79,10 +79,14 @@ abstract class KotlinAbstractUElement(private val givenParent: UElement?) : Kotl
parent = parent.parent
}
while (parent is KtStringTemplateEntryWithExpression ||
parent is KtStringTemplateExpression && parent.entries.size == 1) {
parent = parent.parent
}
if (KotlinConverter.forceUInjectionHost) {
if (parent is KtBlockStringTemplateEntry) {
parent = parent.parent
}
} else
while (parent is KtStringTemplateEntryWithExpression || parent is KtStringTemplateExpression && parent.entries.size == 1) {
parent = parent.parent
}
if (parent is KtWhenConditionWithExpression) {
parent = parent.parent
@@ -110,7 +114,7 @@ abstract class KotlinAbstractUElement(private val givenParent: UElement?) : Kotl
val result = doConvertParent(this, parent)
if (result == this) {
throw IllegalStateException("Loop in parent structure when converting a $psi of type ${psi?.javaClass} with parent $parent of type ${parent?.javaClass} text: [${parent?.text}]")
throw IllegalStateException("Loop in parent structure when converting a $psi of type ${psi?.javaClass} with parent $parent of type ${parent?.javaClass} text: [${parent?.text}], result = $result")
}
return result
@@ -79,14 +79,10 @@ abstract class KotlinAbstractUElement(private val givenParent: UElement?) : Kotl
parent = parent.parent
}
if (KotlinConverter.forceUInjectionHost) {
if (parent is KtBlockStringTemplateEntry) {
parent = parent.parent
}
} else
while (parent is KtStringTemplateEntryWithExpression || parent is KtStringTemplateExpression && parent.entries.size == 1) {
parent = parent.parent
}
while (parent is KtStringTemplateEntryWithExpression ||
parent is KtStringTemplateExpression && parent.entries.size == 1) {
parent = parent.parent
}
if (parent is KtWhenConditionWithExpression) {
parent = parent.parent
@@ -114,7 +110,7 @@ abstract class KotlinAbstractUElement(private val givenParent: UElement?) : Kotl
val result = doConvertParent(this, parent)
if (result == this) {
throw IllegalStateException("Loop in parent structure when converting a $psi of type ${psi?.javaClass} with parent $parent of type ${parent?.javaClass} text: [${parent?.text}], result = $result")
throw IllegalStateException("Loop in parent structure when converting a $psi of type ${psi?.javaClass} with parent $parent of type ${parent?.javaClass} text: [${parent?.text}]")
}
return result
@@ -19,13 +19,16 @@ package org.jetbrains.uast.kotlin
import com.intellij.lang.Language
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.asJava.findFacadeClass
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings
@@ -39,6 +42,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.uast.*
import org.jetbrains.uast.expressions.UInjectionHost
import org.jetbrains.uast.kotlin.KotlinConverter.convertDeclaration
import org.jetbrains.uast.kotlin.KotlinConverter.convertDeclarationOrElement
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
@@ -75,15 +79,15 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
if (!element.isJvmElement) return null
return convertDeclarationOrElement(element, parent, requiredType)
return convertDeclarationOrElement(element, parent, elementTypes(requiredType))
}
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
if (!element.isJvmElement) return null
if (element is PsiFile) return convertDeclaration(element, null, requiredType)
if (element is KtLightClassForFacade) return convertDeclaration(element, null, requiredType)
if (element is PsiFile) return convertDeclaration(element, null, elementTypes(requiredType))
if (element is KtLightClassForFacade) return convertDeclaration(element, null, elementTypes(requiredType))
return convertDeclarationOrElement(element, null, requiredType)
return convertDeclarationOrElement(element, null, elementTypes(requiredType))
}
override fun getMethodCallExpression(
@@ -136,16 +140,45 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
else -> false
}
}
@Suppress("UNCHECKED_CAST")
fun <T : UElement> convertElement(element: PsiElement, parent: UElement?, expectedTypes: Array<out Class<out T>>): T? {
if (!element.isJvmElement) return null
val nonEmptyExpectedTypes = expectedTypes.nonEmptyOr(DEFAULT_TYPES_LIST)
return (convertDeclaration(element, parent, nonEmptyExpectedTypes)
?: KotlinConverter.convertPsiElement(element, parent, nonEmptyExpectedTypes)) as? T
}
override fun <T : UElement> convertElementWithParent(element: PsiElement, requiredTypes: Array<out Class<out T>>): T? {
return convertElement(element, null, requiredTypes)
}
@Suppress("UNCHECKED_CAST")
override fun <T : UElement> convertToAlternatives(element: PsiElement, requiredTypes: Array<out Class<out T>>): Sequence<T> =
if (!element.isJvmElement) emptySequence() else when {
element is KtFile -> KotlinConverter.convertKtFile(element, null, requiredTypes) as Sequence<T>
(element is KtProperty && !element.isLocal) ->
KotlinConverter.convertNonLocalProperty(element, null, requiredTypes) as Sequence<T>
element is KtParameter -> KotlinConverter.convertParameter(element, null, requiredTypes) as Sequence<T>
element is KtClassOrObject -> KotlinConverter.convertClassOrObject(element, null, requiredTypes) as Sequence<T>
else -> sequenceOf(convertElementWithParent(element, requiredTypes.nonEmptyOr(DEFAULT_TYPES_LIST)) as? T).filterNotNull()
}
}
internal inline fun <reified ActualT : UElement> Class<out UElement>?.el(f: () -> UElement?): UElement? {
internal inline fun <reified ActualT : UElement> Class<*>?.el(f: () -> UElement?): UElement? {
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
}
internal inline fun <reified ActualT : UElement> Class<out UElement>?.expr(f: () -> UExpression?): UExpression? {
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
internal inline fun <reified ActualT : UElement> Array<out Class<out UElement>>.el(f: () -> UElement?): UElement? {
return if (isAssignableFrom(ActualT::class.java)) f() else null
}
internal inline fun <reified ActualT : UElement> Array<out Class<out UElement>>.expr(f: () -> UExpression?): UExpression? {
return if (isAssignableFrom(ActualT::class.java)) f() else null
}
internal fun Array<out Class<out UElement>>.isAssignableFrom(cls: Class<*>) = any { it.isAssignableFrom(cls) }
internal object KotlinConverter {
@@ -166,12 +199,13 @@ internal object KotlinConverter {
internal fun convertPsiElement(element: PsiElement?,
givenParent: UElement?,
requiredType: Class<out UElement>?): UElement? {
expectedTypes: Array<out Class<out UElement>>
): UElement? {
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? {
return { ctor(element as P, givenParent) }
}
return with (requiredType) { when (element) {
return with (expectedTypes) { when (element) {
is KtParameterList -> el<UDeclarationsExpression> {
val declarationsExpression = KotlinUDeclarationsExpression(givenParent)
declarationsExpression.apply {
@@ -184,11 +218,7 @@ internal object KotlinConverter {
is KtCatchClause -> el<UCatchClause>(build(::KotlinUCatchClause))
is KtVariableDeclaration ->
if (element is KtProperty && !element.isLocal) {
el<UField> {
LightClassUtil.getLightClassBackingField(element)?.let {
KotlinUField(it, element, givenParent)
}
}
convertNonLocalProperty(element, givenParent, this).firstOrNull()
}
else {
el<UVariable> {
@@ -196,19 +226,19 @@ internal object KotlinConverter {
}
}
is KtExpression -> KotlinConverter.convertExpression(element, givenParent, requiredType)
is KtLambdaArgument -> element.getLambdaExpression()?.let { KotlinConverter.convertExpression(it, givenParent, requiredType) }
is KtExpression -> KotlinConverter.convertExpression(element, givenParent, expectedTypes)
is KtLambdaArgument -> element.getLambdaExpression()?.let { KotlinConverter.convertExpression(it, givenParent, expectedTypes) }
is KtLightElementBase -> {
val expression = element.kotlinOrigin
when (expression) {
is KtExpression -> KotlinConverter.convertExpression(expression, givenParent, requiredType)
is KtExpression -> KotlinConverter.convertExpression(expression, givenParent, expectedTypes)
else -> el<UExpression> { UastEmptyExpression(givenParent) }
}
}
is KtLiteralStringTemplateEntry, is KtEscapeStringTemplateEntry -> el<ULiteralExpression>(build(::KotlinStringULiteralExpression))
is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, givenParent, requiredType) } ?: expr<UExpression> { UastEmptyExpression }
is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, givenParent, expectedTypes) } ?: expr<UExpression> { UastEmptyExpression }
is KtWhenEntry -> el<USwitchClauseExpressionWithBody>(build(::KotlinUSwitchEntry))
is KtWhenCondition -> convertWhenCondition(element, givenParent, requiredType)
is KtWhenCondition -> convertWhenCondition(element, givenParent, expectedTypes)
is KtTypeReference -> el<UTypeReferenceExpression> { LazyKotlinUTypeReferenceExpression(element, givenParent) }
is KtConstructorDelegationCall ->
el<UCallExpression> { KotlinUFunctionCallExpression(element, givenParent) }
@@ -246,7 +276,8 @@ internal object KotlinConverter {
internal fun convertEntry(entry: KtStringTemplateEntry,
givenParent: UElement?,
requiredType: Class<out UElement>? = null): UExpression? {
requiredType: Array<out Class<out UElement>>
): UExpression? {
return with(requiredType) {
if (entry is KtStringTemplateEntryWithExpression) {
expr<UExpression> {
@@ -264,9 +295,16 @@ internal object KotlinConverter {
}
}
var forceUInjectionHost = Registry.`is`("kotlin.uast.force.uinjectionhost", false)
@TestOnly
set(value) {
field = value
}
internal fun convertExpression(expression: KtExpression,
givenParent: UElement?,
requiredType: Class<out UElement>? = null): UExpression? {
requiredType: Array<out Class<out UElement>>
): UExpression? {
fun <P : PsiElement> build(ctor: (P, UElement?) -> UExpression): () -> UExpression? {
return { ctor(expression as P, givenParent) }
}
@@ -276,13 +314,16 @@ internal object KotlinConverter {
is KtStringTemplateExpression -> {
when {
forceUInjectionHost || requiredType.contains(UInjectionHost::class.java) ->
expr<UInjectionHost> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
expression.entries.isEmpty() -> {
expr<ULiteralExpression> { KotlinStringULiteralExpression(expression, givenParent, "") }
}
expression.entries.size == 1 -> convertEntry(expression.entries[0], givenParent, requiredType)
else -> {
expr<UExpression> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
}
else ->
expr<KotlinStringTemplateUPolyadicExpression> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
}
}
is KtDestructuringDeclaration -> expr<UDeclarationsExpression> {
@@ -355,7 +396,7 @@ internal object KotlinConverter {
internal fun convertWhenCondition(condition: KtWhenCondition,
givenParent: UElement?,
requiredType: Class<out UElement>? = null
requiredType: Array<out Class<out UElement>>
): UExpression? {
return with(requiredType) {
when (condition) {
@@ -405,7 +446,7 @@ internal object KotlinConverter {
internal fun convertDeclaration(
element: PsiElement,
givenParent: UElement?,
requiredType: Class<out UElement>?
expectedTypes: Array<out Class<out UElement>>
): UElement? {
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? = { ctor(element as P, givenParent) }
@@ -416,7 +457,7 @@ internal object KotlinConverter {
{ ctor(element as P, ktElement, givenParent) }
val original = element.originalElement
return with(requiredType) {
return with(expectedTypes) {
when (original) {
is KtLightMethod -> el<UMethod>(build(KotlinUMethod.Companion::create)) // .Companion is needed because of KT-13934
is KtLightClass -> when (original.kotlinOrigin) {
@@ -434,11 +475,7 @@ internal object KotlinConverter {
is KtEnumEntry -> el<UEnumConstant> {
convertEnumEntry(original, givenParent)
}
is KtClassOrObject -> el<UClass> {
original.toLightClass()?.let { lightClass ->
KotlinUClass.create(lightClass, givenParent)
}
}
is KtClassOrObject -> convertClassOrObject(original, givenParent, this).firstOrNull()
is KtFunction ->
if (original.isLocal) {
el<ULambdaExpression> {
@@ -447,49 +484,41 @@ internal object KotlinConverter {
KotlinULambdaExpression(parent, givenParent) // your parent is the ULambdaExpression
} else if (original.name.isNullOrEmpty()) {
createLocalFunctionLambdaExpression(original, givenParent)
}
else {
} else {
val uDeclarationsExpression = createLocalFunctionDeclaration(original, givenParent)
val localFunctionVar = uDeclarationsExpression.declarations.single() as KotlinLocalFunctionUVariable
localFunctionVar.uastInitializer
}
}
}
else {
} else {
el<UMethod> {
val lightMethod = LightClassUtil.getLightClassMethod(original) ?: return null
convertDeclaration(lightMethod, givenParent, requiredType)
convertDeclaration(lightMethod, givenParent, expectedTypes)
}
}
is KtPropertyAccessor -> el<UMethod> {
val lightMethod = LightClassUtil.getLightClassAccessorMethod(original) ?: return null
convertDeclaration(lightMethod, givenParent, requiredType)
convertDeclaration(lightMethod, givenParent, expectedTypes)
}
is KtProperty ->
if (original.isLocal) {
KotlinConverter.convertPsiElement(element, givenParent, requiredType)
}
else {
convertNonLocalProperty(original, givenParent, requiredType)
KotlinConverter.convertPsiElement(element, givenParent, expectedTypes)
} else {
convertNonLocalProperty(original, givenParent, expectedTypes).firstOrNull()
}
is KtParameter -> el<UParameter> {
val ownerFunction = original.ownerFunction as? KtFunction ?: return null
val lightMethod = LightClassUtil.getLightClassMethod(ownerFunction) ?: return null
val lightParameter = lightMethod.parameterList.parameters.find { it.name == original.name } ?: return null
KotlinUParameter(lightParameter, original, givenParent)
}
is KtParameter -> convertParameter(original, givenParent, this).firstOrNull()
is KtFile -> el<UFile> { KotlinUFile(original) }
is KtFile -> convertKtFile(original, givenParent, this).firstOrNull()
is FakeFileForLightClass -> el<UFile> { KotlinUFile(original.navigationElement) }
is KtAnnotationEntry -> el<UAnnotation>(build(::KotlinUAnnotation))
is KtCallExpression ->
if (requiredType != null && UAnnotation::class.java.isAssignableFrom(requiredType)) {
if (expectedTypes.isAssignableFrom(KotlinUNestedAnnotation::class.java) && !expectedTypes.isAssignableFrom(UCallExpression::class.java)) {
el<UAnnotation> { KotlinUNestedAnnotation.tryCreate(original, givenParent) }
} else null
is KtLightAnnotationForSourceEntry -> convertDeclarationOrElement(original.kotlinOrigin, givenParent, requiredType)
is KtLightAnnotationForSourceEntry -> convertDeclarationOrElement(original.kotlinOrigin, givenParent, expectedTypes)
is KtDelegatedSuperTypeEntry -> el<KotlinSupertypeDelegationUExpression> {
KotlinSupertypeDelegationUExpression(original, givenParent)
}
@@ -499,17 +528,21 @@ internal object KotlinConverter {
}
fun convertDeclarationOrElement(element: PsiElement, givenParent: UElement?, requiredType: Class<out UElement>?): UElement? {
fun convertDeclarationOrElement(
element: PsiElement,
givenParent: UElement?,
expectedTypes: Array<out Class<out UElement>>
): UElement? {
if (element is UElement) return element
if (element.isValid) {
element.getUserData(KOTLIN_CACHED_UELEMENT_KEY)?.get()?.let { cachedUElement ->
return if (requiredType == null || requiredType.isInstance(cachedUElement)) cachedUElement else null
return if (expectedTypes.isAssignableFrom(cachedUElement.javaClass)) cachedUElement else null
}
}
val uElement = convertDeclaration(element, givenParent, requiredType)
?: KotlinConverter.convertPsiElement(element, givenParent, requiredType)
val uElement = convertDeclaration(element, givenParent, expectedTypes)
?: KotlinConverter.convertPsiElement(element, givenParent, expectedTypes)
/*
if (uElement != null) {
element.putUserData(KOTLIN_CACHED_UELEMENT_KEY, WeakReference(uElement))
@@ -518,27 +551,71 @@ internal object KotlinConverter {
return uElement
}
private fun convertNonLocalProperty(
private fun convertToPropertyAlternatives(
methods: LightClassUtil.PropertyAccessorsPsiMethods?,
givenParent: UElement?
): Array<UElementAlternative<*>> = if (methods != null) arrayOf(
alternative { methods.backingField?.let { KotlinUField(it, (it as? KtLightElement<*, *>)?.kotlinOrigin, givenParent) } },
alternative { methods.getter?.let { convertDeclaration(it, givenParent, arrayOf(UMethod::class.java)) as? UMethod } },
alternative { methods.setter?.let { convertDeclaration(it, givenParent, arrayOf(UMethod::class.java)) as? UMethod } }
) else emptyArray()
fun convertNonLocalProperty(
property: KtProperty,
givenParent: UElement?,
requiredType: Class<out UElement>?
): UElement? {
val methods = LightClassUtil.getLightClassPropertyMethods(property)
return methods.backingField?.let { backingField ->
with(requiredType) {
el<UField> { KotlinUField(backingField, (backingField as? KtLightElement<*,*>)?.kotlinOrigin, givenParent) }
expectedTypes: Array<out Class<out UElement>>
): Sequence<UElement> =
expectedTypes.accommodate(*convertToPropertyAlternatives(LightClassUtil.getLightClassPropertyMethods(property), givenParent))
fun convertParameter(
element: KtParameter,
givenParent: UElement?,
expectedTypes: Array<out Class<out UElement>>
): Sequence<UElement> = expectedTypes.accommodate(
alternative uParam@{
val ownerFunction = element.ownerFunction as? KtFunction ?: return@uParam null
val lightMethod = LightClassUtil.getLightClassMethod(ownerFunction) ?: return@uParam null
val lightParameter = lightMethod.parameterList.parameters.find { it.name == element.name } ?: return@uParam null
KotlinUParameter(lightParameter, element, givenParent)
},
*convertToPropertyAlternatives(LightClassUtil.getLightClassPropertyMethods(element), givenParent)
)
fun convertClassOrObject(
element: KtClassOrObject,
givenParent: UElement?,
expectedTypes: Array<out Class<out UElement>>
): Sequence<UElement> {
val ktLightClass = element.toLightClass() ?: return emptySequence()
val uClass = KotlinUClass.create(ktLightClass, givenParent)
return expectedTypes.accommodate(
alternative { uClass },
alternative primaryConstructor@{
val primaryConstructor = element.primaryConstructor ?: return@primaryConstructor null
uClass.methods.asSequence()
.filter { it.sourcePsi == primaryConstructor }
.firstOrNull()
}
} ?: methods.getter?.let { getter ->
convertDeclaration(getter, givenParent, requiredType)
}
)
}
fun convertKtFile(
element: KtFile,
givenParent: UElement?,
requiredTypes: Array<out Class<out UElement>>
): Sequence<UElement> = requiredTypes.accommodate(
alternative { KotlinUFile(element) },
alternative { element.findFacadeClass()?.let { KotlinUClass.create(it, givenParent) } }
)
internal fun convertOrEmpty(expression: KtExpression?, parent: UElement?): UExpression {
return expression?.let { convertExpression(it, parent, null) } ?: UastEmptyExpression
return expression?.let { convertExpression(it, parent, DEFAULT_EXPRESSION_TYPES_LIST) } ?: UastEmptyExpression
}
internal fun convertOrNull(expression: KtExpression?, parent: UElement?): UExpression? {
return if (expression != null) convertExpression(expression, parent, null) else null
return if (expression != null) convertExpression(expression, parent, DEFAULT_EXPRESSION_TYPES_LIST) else null
}
internal fun KtPsiFactory.createAnalyzableExpression(text: String, context: PsiElement): KtExpression =
@@ -571,3 +648,22 @@ private fun convertVariablesDeclaration(
}
val kotlinUastPlugin get() = UastLanguagePlugin.getInstances().find { it.language == KotlinLanguage.INSTANCE } ?: KotlinUastLanguagePlugin()
private fun expressionTypes(requiredType: Class<out UElement>?) = requiredType?.let { arrayOf(it) } ?: DEFAULT_EXPRESSION_TYPES_LIST
private fun elementTypes(requiredType: Class<out UElement>?) = requiredType?.let { arrayOf(it) } ?: DEFAULT_TYPES_LIST
private fun <T : UElement> Array<out Class<out T>>.nonEmptyOr(default: Array<out Class<out UElement>>) = takeIf { it.isNotEmpty() }
?: default
private fun <U : UElement> Array<out Class<out UElement>>.accommodate(vararg makers: UElementAlternative<out U>): Sequence<UElement> {
val makersSeq = makers.asSequence()
return this.asSequence()
.flatMap { requiredType -> makersSeq.filter { requiredType.isAssignableFrom(it.uType) } }
.distinct()
.mapNotNull { it.make.invoke() }
}
private inline fun <reified U : UElement> alternative(noinline make: () -> U?) = UElementAlternative(U::class.java, make)
private class UElementAlternative<U : UElement>(val uType: Class<U>, val make: () -> U?)
@@ -19,16 +19,13 @@ package org.jetbrains.uast.kotlin
import com.intellij.lang.Language
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.util.Key
import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.elements.*
import org.jetbrains.kotlin.asJava.findFacadeClass
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.LanguageVersionSettings
@@ -42,7 +39,6 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.uast.*
import org.jetbrains.uast.expressions.UInjectionHost
import org.jetbrains.uast.kotlin.KotlinConverter.convertDeclaration
import org.jetbrains.uast.kotlin.KotlinConverter.convertDeclarationOrElement
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
@@ -79,15 +75,15 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
if (!element.isJvmElement) return null
return convertDeclarationOrElement(element, parent, elementTypes(requiredType))
return convertDeclarationOrElement(element, parent, requiredType)
}
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
if (!element.isJvmElement) return null
if (element is PsiFile) return convertDeclaration(element, null, elementTypes(requiredType))
if (element is KtLightClassForFacade) return convertDeclaration(element, null, elementTypes(requiredType))
if (element is PsiFile) return convertDeclaration(element, null, requiredType)
if (element is KtLightClassForFacade) return convertDeclaration(element, null, requiredType)
return convertDeclarationOrElement(element, null, elementTypes(requiredType))
return convertDeclarationOrElement(element, null, requiredType)
}
override fun getMethodCallExpression(
@@ -140,45 +136,16 @@ class KotlinUastLanguagePlugin : UastLanguagePlugin {
else -> false
}
}
@Suppress("UNCHECKED_CAST")
fun <T : UElement> convertElement(element: PsiElement, parent: UElement?, expectedTypes: Array<out Class<out T>>): T? {
if (!element.isJvmElement) return null
val nonEmptyExpectedTypes = expectedTypes.nonEmptyOr(DEFAULT_TYPES_LIST)
return (convertDeclaration(element, parent, nonEmptyExpectedTypes)
?: KotlinConverter.convertPsiElement(element, parent, nonEmptyExpectedTypes)) as? T
}
override fun <T : UElement> convertElementWithParent(element: PsiElement, requiredTypes: Array<out Class<out T>>): T? {
return convertElement(element, null, requiredTypes)
}
@Suppress("UNCHECKED_CAST")
override fun <T : UElement> convertToAlternatives(element: PsiElement, requiredTypes: Array<out Class<out T>>): Sequence<T> =
if (!element.isJvmElement) emptySequence() else when {
element is KtFile -> KotlinConverter.convertKtFile(element, null, requiredTypes) as Sequence<T>
(element is KtProperty && !element.isLocal) ->
KotlinConverter.convertNonLocalProperty(element, null, requiredTypes) as Sequence<T>
element is KtParameter -> KotlinConverter.convertParameter(element, null, requiredTypes) as Sequence<T>
element is KtClassOrObject -> KotlinConverter.convertClassOrObject(element, null, requiredTypes) as Sequence<T>
else -> sequenceOf(convertElementWithParent(element, requiredTypes.nonEmptyOr(DEFAULT_TYPES_LIST)) as? T).filterNotNull()
}
}
internal inline fun <reified ActualT : UElement> Class<*>?.el(f: () -> UElement?): UElement? {
internal inline fun <reified ActualT : UElement> Class<out UElement>?.el(f: () -> UElement?): UElement? {
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
}
internal inline fun <reified ActualT : UElement> Array<out Class<out UElement>>.el(f: () -> UElement?): UElement? {
return if (isAssignableFrom(ActualT::class.java)) f() else null
internal inline fun <reified ActualT : UElement> Class<out UElement>?.expr(f: () -> UExpression?): UExpression? {
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
}
internal inline fun <reified ActualT : UElement> Array<out Class<out UElement>>.expr(f: () -> UExpression?): UExpression? {
return if (isAssignableFrom(ActualT::class.java)) f() else null
}
internal fun Array<out Class<out UElement>>.isAssignableFrom(cls: Class<*>) = any { it.isAssignableFrom(cls) }
internal object KotlinConverter {
@@ -199,13 +166,12 @@ internal object KotlinConverter {
internal fun convertPsiElement(element: PsiElement?,
givenParent: UElement?,
expectedTypes: Array<out Class<out UElement>>
): UElement? {
requiredType: Class<out UElement>?): UElement? {
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? {
return { ctor(element as P, givenParent) }
}
return with (expectedTypes) { when (element) {
return with (requiredType) { when (element) {
is KtParameterList -> el<UDeclarationsExpression> {
val declarationsExpression = KotlinUDeclarationsExpression(givenParent)
declarationsExpression.apply {
@@ -218,7 +184,11 @@ internal object KotlinConverter {
is KtCatchClause -> el<UCatchClause>(build(::KotlinUCatchClause))
is KtVariableDeclaration ->
if (element is KtProperty && !element.isLocal) {
convertNonLocalProperty(element, givenParent, this).firstOrNull()
el<UField> {
LightClassUtil.getLightClassBackingField(element)?.let {
KotlinUField(it, element, givenParent)
}
}
}
else {
el<UVariable> {
@@ -226,19 +196,19 @@ internal object KotlinConverter {
}
}
is KtExpression -> KotlinConverter.convertExpression(element, givenParent, expectedTypes)
is KtLambdaArgument -> element.getLambdaExpression()?.let { KotlinConverter.convertExpression(it, givenParent, expectedTypes) }
is KtExpression -> KotlinConverter.convertExpression(element, givenParent, requiredType)
is KtLambdaArgument -> element.getLambdaExpression()?.let { KotlinConverter.convertExpression(it, givenParent, requiredType) }
is KtLightElementBase -> {
val expression = element.kotlinOrigin
when (expression) {
is KtExpression -> KotlinConverter.convertExpression(expression, givenParent, expectedTypes)
is KtExpression -> KotlinConverter.convertExpression(expression, givenParent, requiredType)
else -> el<UExpression> { UastEmptyExpression(givenParent) }
}
}
is KtLiteralStringTemplateEntry, is KtEscapeStringTemplateEntry -> el<ULiteralExpression>(build(::KotlinStringULiteralExpression))
is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, givenParent, expectedTypes) } ?: expr<UExpression> { UastEmptyExpression }
is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, givenParent, requiredType) } ?: expr<UExpression> { UastEmptyExpression }
is KtWhenEntry -> el<USwitchClauseExpressionWithBody>(build(::KotlinUSwitchEntry))
is KtWhenCondition -> convertWhenCondition(element, givenParent, expectedTypes)
is KtWhenCondition -> convertWhenCondition(element, givenParent, requiredType)
is KtTypeReference -> el<UTypeReferenceExpression> { LazyKotlinUTypeReferenceExpression(element, givenParent) }
is KtConstructorDelegationCall ->
el<UCallExpression> { KotlinUFunctionCallExpression(element, givenParent) }
@@ -276,8 +246,7 @@ internal object KotlinConverter {
internal fun convertEntry(entry: KtStringTemplateEntry,
givenParent: UElement?,
requiredType: Array<out Class<out UElement>>
): UExpression? {
requiredType: Class<out UElement>? = null): UExpression? {
return with(requiredType) {
if (entry is KtStringTemplateEntryWithExpression) {
expr<UExpression> {
@@ -295,16 +264,9 @@ internal object KotlinConverter {
}
}
var forceUInjectionHost = Registry.`is`("kotlin.uast.force.uinjectionhost", false)
@TestOnly
set(value) {
field = value
}
internal fun convertExpression(expression: KtExpression,
givenParent: UElement?,
requiredType: Array<out Class<out UElement>>
): UExpression? {
requiredType: Class<out UElement>? = null): UExpression? {
fun <P : PsiElement> build(ctor: (P, UElement?) -> UExpression): () -> UExpression? {
return { ctor(expression as P, givenParent) }
}
@@ -314,16 +276,13 @@ internal object KotlinConverter {
is KtStringTemplateExpression -> {
when {
forceUInjectionHost || requiredType.contains(UInjectionHost::class.java) ->
expr<UInjectionHost> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
expression.entries.isEmpty() -> {
expr<ULiteralExpression> { KotlinStringULiteralExpression(expression, givenParent, "") }
}
expression.entries.size == 1 -> convertEntry(expression.entries[0], givenParent, requiredType)
else ->
expr<KotlinStringTemplateUPolyadicExpression> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
else -> {
expr<UExpression> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
}
}
}
is KtDestructuringDeclaration -> expr<UDeclarationsExpression> {
@@ -396,7 +355,7 @@ internal object KotlinConverter {
internal fun convertWhenCondition(condition: KtWhenCondition,
givenParent: UElement?,
requiredType: Array<out Class<out UElement>>
requiredType: Class<out UElement>? = null
): UExpression? {
return with(requiredType) {
when (condition) {
@@ -446,7 +405,7 @@ internal object KotlinConverter {
internal fun convertDeclaration(
element: PsiElement,
givenParent: UElement?,
expectedTypes: Array<out Class<out UElement>>
requiredType: Class<out UElement>?
): UElement? {
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? = { ctor(element as P, givenParent) }
@@ -457,7 +416,7 @@ internal object KotlinConverter {
{ ctor(element as P, ktElement, givenParent) }
val original = element.originalElement
return with(expectedTypes) {
return with(requiredType) {
when (original) {
is KtLightMethod -> el<UMethod>(build(KotlinUMethod.Companion::create)) // .Companion is needed because of KT-13934
is KtLightClass -> when (original.kotlinOrigin) {
@@ -475,7 +434,11 @@ internal object KotlinConverter {
is KtEnumEntry -> el<UEnumConstant> {
convertEnumEntry(original, givenParent)
}
is KtClassOrObject -> convertClassOrObject(original, givenParent, this).firstOrNull()
is KtClassOrObject -> el<UClass> {
original.toLightClass()?.let { lightClass ->
KotlinUClass.create(lightClass, givenParent)
}
}
is KtFunction ->
if (original.isLocal) {
el<ULambdaExpression> {
@@ -484,41 +447,49 @@ internal object KotlinConverter {
KotlinULambdaExpression(parent, givenParent) // your parent is the ULambdaExpression
} else if (original.name.isNullOrEmpty()) {
createLocalFunctionLambdaExpression(original, givenParent)
} else {
}
else {
val uDeclarationsExpression = createLocalFunctionDeclaration(original, givenParent)
val localFunctionVar = uDeclarationsExpression.declarations.single() as KotlinLocalFunctionUVariable
localFunctionVar.uastInitializer
}
}
} else {
}
else {
el<UMethod> {
val lightMethod = LightClassUtil.getLightClassMethod(original) ?: return null
convertDeclaration(lightMethod, givenParent, expectedTypes)
convertDeclaration(lightMethod, givenParent, requiredType)
}
}
is KtPropertyAccessor -> el<UMethod> {
val lightMethod = LightClassUtil.getLightClassAccessorMethod(original) ?: return null
convertDeclaration(lightMethod, givenParent, expectedTypes)
convertDeclaration(lightMethod, givenParent, requiredType)
}
is KtProperty ->
if (original.isLocal) {
KotlinConverter.convertPsiElement(element, givenParent, expectedTypes)
} else {
convertNonLocalProperty(original, givenParent, expectedTypes).firstOrNull()
KotlinConverter.convertPsiElement(element, givenParent, requiredType)
}
else {
convertNonLocalProperty(original, givenParent, requiredType)
}
is KtParameter -> convertParameter(original, givenParent, this).firstOrNull()
is KtParameter -> el<UParameter> {
val ownerFunction = original.ownerFunction as? KtFunction ?: return null
val lightMethod = LightClassUtil.getLightClassMethod(ownerFunction) ?: return null
val lightParameter = lightMethod.parameterList.parameters.find { it.name == original.name } ?: return null
KotlinUParameter(lightParameter, original, givenParent)
}
is KtFile -> convertKtFile(original, givenParent, this).firstOrNull()
is KtFile -> el<UFile> { KotlinUFile(original) }
is FakeFileForLightClass -> el<UFile> { KotlinUFile(original.navigationElement) }
is KtAnnotationEntry -> el<UAnnotation>(build(::KotlinUAnnotation))
is KtCallExpression ->
if (expectedTypes.isAssignableFrom(KotlinUNestedAnnotation::class.java) && !expectedTypes.isAssignableFrom(UCallExpression::class.java)) {
if (requiredType != null && UAnnotation::class.java.isAssignableFrom(requiredType)) {
el<UAnnotation> { KotlinUNestedAnnotation.tryCreate(original, givenParent) }
} else null
is KtLightAnnotationForSourceEntry -> convertDeclarationOrElement(original.kotlinOrigin, givenParent, expectedTypes)
is KtLightAnnotationForSourceEntry -> convertDeclarationOrElement(original.kotlinOrigin, givenParent, requiredType)
is KtDelegatedSuperTypeEntry -> el<KotlinSupertypeDelegationUExpression> {
KotlinSupertypeDelegationUExpression(original, givenParent)
}
@@ -528,21 +499,17 @@ internal object KotlinConverter {
}
fun convertDeclarationOrElement(
element: PsiElement,
givenParent: UElement?,
expectedTypes: Array<out Class<out UElement>>
): UElement? {
fun convertDeclarationOrElement(element: PsiElement, givenParent: UElement?, requiredType: Class<out UElement>?): UElement? {
if (element is UElement) return element
if (element.isValid) {
element.getUserData(KOTLIN_CACHED_UELEMENT_KEY)?.get()?.let { cachedUElement ->
return if (expectedTypes.isAssignableFrom(cachedUElement.javaClass)) cachedUElement else null
return if (requiredType == null || requiredType.isInstance(cachedUElement)) cachedUElement else null
}
}
val uElement = convertDeclaration(element, givenParent, expectedTypes)
?: KotlinConverter.convertPsiElement(element, givenParent, expectedTypes)
val uElement = convertDeclaration(element, givenParent, requiredType)
?: KotlinConverter.convertPsiElement(element, givenParent, requiredType)
/*
if (uElement != null) {
element.putUserData(KOTLIN_CACHED_UELEMENT_KEY, WeakReference(uElement))
@@ -551,71 +518,27 @@ internal object KotlinConverter {
return uElement
}
private fun convertToPropertyAlternatives(
methods: LightClassUtil.PropertyAccessorsPsiMethods?,
givenParent: UElement?
): Array<UElementAlternative<*>> = if (methods != null) arrayOf(
alternative { methods.backingField?.let { KotlinUField(it, (it as? KtLightElement<*, *>)?.kotlinOrigin, givenParent) } },
alternative { methods.getter?.let { convertDeclaration(it, givenParent, arrayOf(UMethod::class.java)) as? UMethod } },
alternative { methods.setter?.let { convertDeclaration(it, givenParent, arrayOf(UMethod::class.java)) as? UMethod } }
) else emptyArray()
fun convertNonLocalProperty(
private fun convertNonLocalProperty(
property: KtProperty,
givenParent: UElement?,
expectedTypes: Array<out Class<out UElement>>
): Sequence<UElement> =
expectedTypes.accommodate(*convertToPropertyAlternatives(LightClassUtil.getLightClassPropertyMethods(property), givenParent))
fun convertParameter(
element: KtParameter,
givenParent: UElement?,
expectedTypes: Array<out Class<out UElement>>
): Sequence<UElement> = expectedTypes.accommodate(
alternative uParam@{
val ownerFunction = element.ownerFunction as? KtFunction ?: return@uParam null
val lightMethod = LightClassUtil.getLightClassMethod(ownerFunction) ?: return@uParam null
val lightParameter = lightMethod.parameterList.parameters.find { it.name == element.name } ?: return@uParam null
KotlinUParameter(lightParameter, element, givenParent)
},
*convertToPropertyAlternatives(LightClassUtil.getLightClassPropertyMethods(element), givenParent)
)
fun convertClassOrObject(
element: KtClassOrObject,
givenParent: UElement?,
expectedTypes: Array<out Class<out UElement>>
): Sequence<UElement> {
val ktLightClass = element.toLightClass() ?: return emptySequence()
val uClass = KotlinUClass.create(ktLightClass, givenParent)
return expectedTypes.accommodate(
alternative { uClass },
alternative primaryConstructor@{
val primaryConstructor = element.primaryConstructor ?: return@primaryConstructor null
uClass.methods.asSequence()
.filter { it.sourcePsi == primaryConstructor }
.firstOrNull()
requiredType: Class<out UElement>?
): UElement? {
val methods = LightClassUtil.getLightClassPropertyMethods(property)
return methods.backingField?.let { backingField ->
with(requiredType) {
el<UField> { KotlinUField(backingField, (backingField as? KtLightElement<*,*>)?.kotlinOrigin, givenParent) }
}
)
} ?: methods.getter?.let { getter ->
convertDeclaration(getter, givenParent, requiredType)
}
}
fun convertKtFile(
element: KtFile,
givenParent: UElement?,
requiredTypes: Array<out Class<out UElement>>
): Sequence<UElement> = requiredTypes.accommodate(
alternative { KotlinUFile(element) },
alternative { element.findFacadeClass()?.let { KotlinUClass.create(it, givenParent) } }
)
internal fun convertOrEmpty(expression: KtExpression?, parent: UElement?): UExpression {
return expression?.let { convertExpression(it, parent, DEFAULT_EXPRESSION_TYPES_LIST) } ?: UastEmptyExpression
return expression?.let { convertExpression(it, parent, null) } ?: UastEmptyExpression
}
internal fun convertOrNull(expression: KtExpression?, parent: UElement?): UExpression? {
return if (expression != null) convertExpression(expression, parent, DEFAULT_EXPRESSION_TYPES_LIST) else null
return if (expression != null) convertExpression(expression, parent, null) else null
}
internal fun KtPsiFactory.createAnalyzableExpression(text: String, context: PsiElement): KtExpression =
@@ -648,22 +571,3 @@ private fun convertVariablesDeclaration(
}
val kotlinUastPlugin get() = UastLanguagePlugin.getInstances().find { it.language == KotlinLanguage.INSTANCE } ?: KotlinUastLanguagePlugin()
private fun expressionTypes(requiredType: Class<out UElement>?) = requiredType?.let { arrayOf(it) } ?: DEFAULT_EXPRESSION_TYPES_LIST
private fun elementTypes(requiredType: Class<out UElement>?) = requiredType?.let { arrayOf(it) } ?: DEFAULT_TYPES_LIST
private fun <T : UElement> Array<out Class<out T>>.nonEmptyOr(default: Array<out Class<out UElement>>) = takeIf { it.isNotEmpty() }
?: default
private fun <U : UElement> Array<out Class<out UElement>>.accommodate(vararg makers: UElementAlternative<out U>): Sequence<UElement> {
val makersSeq = makers.asSequence()
return this.asSequence()
.flatMap { requiredType -> makersSeq.filter { requiredType.isAssignableFrom(it.uType) } }
.distinct()
.mapNotNull { it.make.invoke() }
}
private inline fun <reified U : UElement> alternative(noinline make: () -> U?) = UElementAlternative(U::class.java, make)
private class UElementAlternative<U : UElement>(val uType: Class<U>, val make: () -> U?)
@@ -107,7 +107,7 @@ open class KotlinUMethod(
KotlinUBlockExpression.KotlinLazyUBlockExpression(this, { block ->
val implicitReturn = KotlinUImplicitReturnExpression(block)
val uBody = getLanguagePlugin().convertElement(bodyExpression, implicitReturn) as? UExpression
?: return@KotlinLazyUBlockExpression emptyList()
?: return@KotlinLazyUBlockExpression emptyList()
listOf(implicitReturn.apply { returnExpression = uBody })
})
@@ -123,6 +123,12 @@ open class KotlinUMethod(
override fun getOriginalElement(): PsiElement? = super<UAnnotationMethod>.getOriginalElement()
override val returnTypeReference: UTypeReferenceExpression? by lz {
(sourcePsi as? KtCallableDeclaration)?.typeReference?.let {
LazyKotlinUTypeReferenceExpression(it, this) { javaPsi.returnType ?: UastErrorType }
}
}
override fun equals(other: Any?) = other is KotlinUMethod && psi == other.psi
companion object {
@@ -107,7 +107,7 @@ open class KotlinUMethod(
KotlinUBlockExpression.KotlinLazyUBlockExpression(this, { block ->
val implicitReturn = KotlinUImplicitReturnExpression(block)
val uBody = getLanguagePlugin().convertElement(bodyExpression, implicitReturn) as? UExpression
?: return@KotlinLazyUBlockExpression emptyList()
?: return@KotlinLazyUBlockExpression emptyList()
listOf(implicitReturn.apply { returnExpression = uBody })
})
@@ -123,12 +123,6 @@ open class KotlinUMethod(
override fun getOriginalElement(): PsiElement? = super<UAnnotationMethod>.getOriginalElement()
override val returnTypeReference: UTypeReferenceExpression? by lz {
(sourcePsi as? KtCallableDeclaration)?.typeReference?.let {
LazyKotlinUTypeReferenceExpression(it, this) { javaPsi.returnType ?: UastErrorType }
}
}
override fun equals(other: Any?) = other is KotlinUMethod && psi == other.psi
companion object {
@@ -9,6 +9,7 @@ import org.jetbrains.uast.evaluation.UEvaluationState
import org.jetbrains.uast.kotlin.KotlinBinaryOperators
import org.jetbrains.uast.kotlin.KotlinPostfixOperators
import org.jetbrains.uast.values.*
import org.jetbrains.uast.evaluation.to
class KotlinEvaluatorExtension : AbstractEvaluatorExtension(KotlinLanguage.INSTANCE) {
@@ -9,7 +9,6 @@ import org.jetbrains.uast.evaluation.UEvaluationState
import org.jetbrains.uast.kotlin.KotlinBinaryOperators
import org.jetbrains.uast.kotlin.KotlinPostfixOperators
import org.jetbrains.uast.values.*
import org.jetbrains.uast.evaluation.to
class KotlinEvaluatorExtension : AbstractEvaluatorExtension(KotlinLanguage.INSTANCE) {
@@ -67,7 +67,7 @@ private fun createElvisExpressions(
override val sourcePsi: PsiElement? = null
override val condition: UExpression by lz { createNotEqWithNullExpression(tempVariable, this) }
override val thenExpression: UExpression? by lz { createVariableReferenceExpression(tempVariable, this) }
override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this ) }
override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this, DEFAULT_EXPRESSION_TYPES_LIST) }
override val isTernary: Boolean = false
override val annotations: List<UAnnotation> = emptyList()
override val ifIdentifier: UIdentifier = KotlinUIdentifier(null, this)
@@ -67,7 +67,7 @@ private fun createElvisExpressions(
override val sourcePsi: PsiElement? = null
override val condition: UExpression by lz { createNotEqWithNullExpression(tempVariable, this) }
override val thenExpression: UExpression? by lz { createVariableReferenceExpression(tempVariable, this) }
override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this, DEFAULT_EXPRESSION_TYPES_LIST) }
override val elseExpression: UExpression? by lz { KotlinConverter.convertExpression(right, this ) }
override val isTernary: Boolean = false
override val annotations: List<UAnnotation> = emptyList()
override val ifIdentifier: UIdentifier = KotlinUIdentifier(null, this)
@@ -16,19 +16,33 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiLanguageInjectionHost
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UPolyadicExpression
import org.jetbrains.uast.UastBinaryOperator
import org.jetbrains.uast.*
import org.jetbrains.uast.expressions.UInjectionHost
class KotlinStringTemplateUPolyadicExpression(
override val psi: KtStringTemplateExpression,
givenParent: UElement?
override val psi: KtStringTemplateExpression,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent),
UPolyadicExpression,
KotlinUElementWithType,
KotlinEvaluatableUElement {
override val operands: List<UExpression> by lz { psi.entries.map { KotlinConverter.convertEntry(it, this)!! } }
UPolyadicExpression,
KotlinUElementWithType,
KotlinEvaluatableUElement,
UInjectionHost {
override val operands: List<UExpression> by lz {
psi.entries.map {
KotlinConverter.convertEntry(
it,
this,
DEFAULT_EXPRESSION_TYPES_LIST
)!!
}
}
override val operator = UastBinaryOperator.PLUS
override val psiLanguageInjectionHost: PsiLanguageInjectionHost get() = psi
override val isString: Boolean get() = true
override fun asRenderString(): String = if (operands.isEmpty()) "\"\"" else super<UPolyadicExpression>.asRenderString()
override fun asLogString(): String = if (operands.isEmpty()) "UPolyadicExpression (value = \"\")" else super.asLogString()
}
@@ -0,0 +1,34 @@
/*
* Copyright 2010-2016 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.uast.kotlin
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UPolyadicExpression
import org.jetbrains.uast.UastBinaryOperator
class KotlinStringTemplateUPolyadicExpression(
override val psi: KtStringTemplateExpression,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent),
UPolyadicExpression,
KotlinUElementWithType,
KotlinEvaluatableUElement {
override val operands: List<UExpression> by lz { psi.entries.map { KotlinConverter.convertEntry(it, this)!! } }
override val operator = UastBinaryOperator.PLUS
}
@@ -1,48 +0,0 @@
/*
* Copyright 2010-2016 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.uast.kotlin
import com.intellij.psi.PsiLanguageInjectionHost
import org.jetbrains.kotlin.psi.KtStringTemplateExpression
import org.jetbrains.uast.*
import org.jetbrains.uast.expressions.UInjectionHost
class KotlinStringTemplateUPolyadicExpression(
override val psi: KtStringTemplateExpression,
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent),
UPolyadicExpression,
KotlinUElementWithType,
KotlinEvaluatableUElement,
UInjectionHost {
override val operands: List<UExpression> by lz {
psi.entries.map {
KotlinConverter.convertEntry(
it,
this,
DEFAULT_EXPRESSION_TYPES_LIST
)!!
}
}
override val operator = UastBinaryOperator.PLUS
override val psiLanguageInjectionHost: PsiLanguageInjectionHost get() = psi
override val isString: Boolean get() = true
override fun asRenderString(): String = if (operands.isEmpty()) "\"\"" else super<UPolyadicExpression>.asRenderString()
override fun asLogString(): String = if (operands.isEmpty()) "UPolyadicExpression (value = \"\")" else super.asLogString()
}
@@ -20,10 +20,7 @@ import com.intellij.psi.PsiNamedElement
import com.intellij.psi.ResolveResult
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
import org.jetbrains.uast.UCallableReferenceExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UMultiResolvable
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.internal.getResolveResultVariants
class KotlinUCallableReferenceExpression(
@@ -34,7 +31,7 @@ class KotlinUCallableReferenceExpression(
get() {
if (qualifierType != null) return null
val receiverExpression = psi.receiverExpression ?: return null
return KotlinConverter.convertExpression(receiverExpression, this)
return KotlinConverter.convertExpression(receiverExpression, this, DEFAULT_EXPRESSION_TYPES_LIST)
}
override val qualifierType by lz {
@@ -20,7 +20,10 @@ import com.intellij.psi.PsiNamedElement
import com.intellij.psi.ResolveResult
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
import org.jetbrains.uast.*
import org.jetbrains.uast.UCallableReferenceExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
import org.jetbrains.uast.UMultiResolvable
import org.jetbrains.uast.kotlin.internal.getResolveResultVariants
class KotlinUCallableReferenceExpression(
@@ -31,7 +34,7 @@ class KotlinUCallableReferenceExpression(
get() {
if (qualifierType != null) return null
val receiverExpression = psi.receiverExpression ?: return null
return KotlinConverter.convertExpression(receiverExpression, this, DEFAULT_EXPRESSION_TYPES_LIST)
return KotlinConverter.convertExpression(receiverExpression, this)
}
override val qualifierType by lz {
@@ -18,6 +18,7 @@ package org.jetbrains.uast.kotlin
import org.jetbrains.kotlin.psi.KtClassLiteralExpression
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
import org.jetbrains.uast.DEFAULT_EXPRESSION_TYPES_LIST
import org.jetbrains.uast.UClassLiteralExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
@@ -35,6 +36,6 @@ class KotlinUClassLiteralExpression(
get() {
if (type != null) return null
val receiverExpression = psi.receiverExpression ?: return null
return KotlinConverter.convertExpression(receiverExpression, this)
return KotlinConverter.convertExpression(receiverExpression, this, DEFAULT_EXPRESSION_TYPES_LIST)
}
}
@@ -18,7 +18,6 @@ package org.jetbrains.uast.kotlin
import org.jetbrains.kotlin.psi.KtClassLiteralExpression
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
import org.jetbrains.uast.DEFAULT_EXPRESSION_TYPES_LIST
import org.jetbrains.uast.UClassLiteralExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UExpression
@@ -36,6 +35,6 @@ class KotlinUClassLiteralExpression(
get() {
if (type != null) return null
val receiverExpression = psi.receiverExpression ?: return null
return KotlinConverter.convertExpression(receiverExpression, this, DEFAULT_EXPRESSION_TYPES_LIST)
return KotlinConverter.convertExpression(receiverExpression, this)
}
}
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve
class KotlinUObjectLiteralExpression(
@@ -82,7 +83,10 @@ class KotlinUObjectLiteralExpression(
get() = identifier
override val identifier: String
get() = psi.name ?: "<error>"
get() = psi.name ?: referenceNameElement.sourcePsi?.text ?: "<error>"
override val referenceNameElement: UElement
get() = KotlinUIdentifier(psi.typeReference?.nameElement, this)
}
}
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve
class KotlinUObjectLiteralExpression(
@@ -83,10 +82,7 @@ class KotlinUObjectLiteralExpression(
get() = identifier
override val identifier: String
get() = psi.name ?: referenceNameElement.sourcePsi?.text ?: "<error>"
override val referenceNameElement: UElement
get() = KotlinUIdentifier(psi.typeReference?.nameElement, this)
get() = psi.name ?: "<error>"
}
}
@@ -18,6 +18,7 @@ package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiNamedElement
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UQualifiedReferenceExpression
import org.jetbrains.uast.UastQualifiedExpressionAccessType
@@ -36,4 +37,10 @@ class KotlinUQualifiedReferenceExpression(
override val resolvedName: String?
get() = (resolve() as? PsiNamedElement)?.name
override val referenceNameElement: UElement?
get() = when (val selector = selector) {
is UCallExpression -> selector.methodIdentifier
else -> super.referenceNameElement
}
}
@@ -18,7 +18,6 @@ package org.jetbrains.uast.kotlin
import com.intellij.psi.PsiNamedElement
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UQualifiedReferenceExpression
import org.jetbrains.uast.UastQualifiedExpressionAccessType
@@ -37,10 +36,4 @@ class KotlinUQualifiedReferenceExpression(
override val resolvedName: String?
get() = (resolve() as? PsiNamedElement)?.name
override val referenceNameElement: UElement?
get() = when (val selector = selector) {
is UCallExpression -> selector.methodIdentifier
else -> super.referenceNameElement
}
}
@@ -71,6 +71,8 @@ open class KotlinUSimpleReferenceExpression(
visitor.afterVisitSimpleNameReferenceExpression(this)
}
override val referenceNameElement: UElement? by lz { psi.getIdentifier()?.toUElement() }
private fun visitAccessorCalls(visitor: UastVisitor) {
// Visit Kotlin get-set synthetic Java property calls as function calls
val bindingContext = psi.analyze()
@@ -71,8 +71,6 @@ open class KotlinUSimpleReferenceExpression(
visitor.afterVisitSimpleNameReferenceExpression(this)
}
override val referenceNameElement: UElement? by lz { psi.getIdentifier()?.toUElement() }
private fun visitAccessorCalls(visitor: UastVisitor) {
// Visit Kotlin get-set synthetic Java property calls as function calls
val bindingContext = psi.analyze()
@@ -54,7 +54,7 @@ class KotlinUSwitchEntry(
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), USwitchClauseExpressionWithBody {
override val caseValues by lz {
psi.conditions.map { KotlinConverter.convertWhenCondition(it, this) ?: UastEmptyExpression }
psi.conditions.map { KotlinConverter.convertWhenCondition(it, this, DEFAULT_EXPRESSION_TYPES_LIST) ?: UastEmptyExpression }
}
override val body: UExpressionList by lz {
@@ -54,7 +54,7 @@ class KotlinUSwitchEntry(
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), USwitchClauseExpressionWithBody {
override val caseValues by lz {
psi.conditions.map { KotlinConverter.convertWhenCondition(it, this, DEFAULT_EXPRESSION_TYPES_LIST) ?: UastEmptyExpression }
psi.conditions.map { KotlinConverter.convertWhenCondition(it, this) ?: UastEmptyExpression }
}
override val body: UExpressionList by lz {
@@ -17,10 +17,7 @@
package org.jetbrains.uast.kotlin
import org.jetbrains.kotlin.psi.KtTryExpression
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UIdentifier
import org.jetbrains.uast.UTryExpression
import org.jetbrains.uast.UVariable
import org.jetbrains.uast.*
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
class KotlinUTryExpression(
@@ -29,7 +26,15 @@ class KotlinUTryExpression(
) : KotlinAbstractUExpression(givenParent), UTryExpression, KotlinUElementWithType {
override val tryClause by lz { KotlinConverter.convertOrEmpty(psi.tryBlock, this) }
override val catchClauses by lz { psi.catchClauses.map { KotlinUCatchClause(it, this) } }
override val finallyClause by lz { psi.finallyBlock?.finalExpression?.let { KotlinConverter.convertExpression(it, this) } }
override val finallyClause by lz {
psi.finallyBlock?.finalExpression?.let {
KotlinConverter.convertExpression(
it,
this,
DEFAULT_EXPRESSION_TYPES_LIST
)
}
}
override val resourceVariables: List<UVariable>
get() = emptyList()
@@ -17,7 +17,10 @@
package org.jetbrains.uast.kotlin
import org.jetbrains.kotlin.psi.KtTryExpression
import org.jetbrains.uast.*
import org.jetbrains.uast.UElement
import org.jetbrains.uast.UIdentifier
import org.jetbrains.uast.UTryExpression
import org.jetbrains.uast.UVariable
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
class KotlinUTryExpression(
@@ -26,15 +29,7 @@ class KotlinUTryExpression(
) : KotlinAbstractUExpression(givenParent), UTryExpression, KotlinUElementWithType {
override val tryClause by lz { KotlinConverter.convertOrEmpty(psi.tryBlock, this) }
override val catchClauses by lz { psi.catchClauses.map { KotlinUCatchClause(it, this) } }
override val finallyClause by lz {
psi.finallyBlock?.finalExpression?.let {
KotlinConverter.convertExpression(
it,
this,
DEFAULT_EXPRESSION_TYPES_LIST
)
}
}
override val finallyClause by lz { psi.finallyBlock?.finalExpression?.let { KotlinConverter.convertExpression(it, this) } }
override val resourceVariables: List<UVariable>
get() = emptyList()
@@ -1,7 +1,7 @@
Test -> UAnnotation (fqName = null)
A -> UClass (name = A)
MyAnnotation -> UClass (name = MyAnnotation)
text -> [!] UnknownKotlinExpression (VALUE_PARAMETER)
text -> UAnnotationMethod (name = text)
String -> USimpleNameReferenceExpression (identifier = String)
MyAnnotation -> UAnnotation (fqName = MyAnnotation)
B -> UClass (name = B)
@@ -1,7 +1,7 @@
Test -> UAnnotation (fqName = null)
A -> UClass (name = A)
MyAnnotation -> UClass (name = MyAnnotation)
text -> UAnnotationMethod (name = text)
text -> [!] UnknownKotlinExpression (VALUE_PARAMETER)
String -> USimpleNameReferenceExpression (identifier = String)
MyAnnotation -> UAnnotation (fqName = MyAnnotation)
B -> UClass (name = B)

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