Remove 181 bunch files

This commit is contained in:
Vyacheslav Gerasimov
2019-04-19 18:43:37 +03:00
parent e261e46e52
commit 952d2b6287
249 changed files with 0 additions and 13329 deletions
-195
View File
@@ -1,195 +0,0 @@
@file:Suppress("unused")
/*
* 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.
*/
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.FileCollection
import org.gradle.api.internal.ConventionTask
import org.gradle.api.plugins.ExtensionAware
import org.gradle.api.tasks.*
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.kotlin.dsl.*
import java.io.File
fun Project.configureFormInstrumentation() {
plugins.matching { it::class.java.canonicalName.startsWith("org.jetbrains.kotlin.gradle.plugin") }.all {
// When we change the output classes directory, Gradle will automatically configure
// the test compile tasks to use the instrumented classes. Normally this is fine,
// however, it causes problems for Kotlin projects:
// The "internal" modifier can be used to restrict access to the same module.
// To make it possible to use internal methods from the main source set in test classes,
// the Kotlin Gradle plugin adds the original output directory of the Java task
// as "friendly directory" which makes it possible to access internal members
// of the main module. Also this directory should be available on classpath during compilation
// This fails when we change the classes dir. The easiest fix is to prepend the
// classes from the "friendly directory" to the compile classpath.
val testCompile = tasks.findByName("compileTestKotlin") as AbstractCompile?
testCompile?.doFirst {
testCompile.classpath = (testCompile.classpath
- mainSourceSet.output.classesDirs
+ files((mainSourceSet as ExtensionAware).extra.get("classesDirsCopy")))
}
}
val instrumentationClasspathCfg = configurations.create("instrumentationClasspath")
dependencies {
instrumentationClasspathCfg(intellijDep()) { includeJars("javac2", "jdom", "asm-all", "jgoodies-forms", rootProject = rootProject) }
}
afterEvaluate {
sourceSets.all { sourceSetParam ->
// This copy will ignore filters, but they are unlikely to be used.
val classesDirs = (sourceSetParam.output.classesDirs as ConfigurableFileCollection).from as Collection<Any>
val classesDirsCopy = project.files(classesDirs.toTypedArray()).filter { it.exists() }
(sourceSetParam as ExtensionAware).extra.set("classesDirsCopy", classesDirsCopy)
logger.info("Saving old sources dir for project ${project.name}")
val instrumentedClassesDir = File(project.buildDir, "classes/${sourceSetParam.name}-instrumented")
(sourceSetParam.output.classesDirs as ConfigurableFileCollection).setFrom(instrumentedClassesDir)
val instrumentTask =
project.tasks.create(sourceSetParam.getTaskName("instrument", "classes"), IntelliJInstrumentCodeTask::class.java)
instrumentTask.apply {
dependsOn(sourceSetParam.classesTaskName).onlyIf { !classesDirsCopy.isEmpty }
sourceSet = sourceSetParam
instrumentationClasspath = instrumentationClasspathCfg
originalClassesDirs = classesDirsCopy
output = instrumentedClassesDir
}
instrumentTask.outputs.dir(instrumentedClassesDir)
// Ensure that our task is invoked when the source set is built
sourceSetParam.compiledBy(instrumentTask)
@Suppress("UNUSED_EXPRESSION")
true
}
}
}
@CacheableTask
open class IntelliJInstrumentCodeTask : ConventionTask() {
companion object {
private const val FILTER_ANNOTATION_REGEXP_CLASS = "com.intellij.ant.ClassFilterAnnotationRegexp"
private const val LOADER_REF = "java2.loader"
}
var sourceSet: SourceSet? = null
var instrumentationClasspath: Configuration? = null
@Input
var originalClassesDirs: FileCollection? = null
@get:Input
var instrumentNotNull: Boolean = false
@get:InputFiles
val sourceDirs: FileCollection
get() = project.files(sourceSet!!.allSource.srcDirs.filter { !sourceSet!!.resources.contains(it) && it.exists() })
@get:OutputDirectory
lateinit var output: File
@TaskAction
fun instrumentClasses() {
logger.info(
"input files are: ${originalClassesDirs?.joinToString(
"; ",
transform = { "'${it.name}'${if (it.exists()) "" else " (does not exists)"}" })}"
)
output.deleteRecursively()
copyOriginalClasses()
val classpath = instrumentationClasspath!!
ant.withGroovyBuilder {
"taskdef"(
"name" to "instrumentIdeaExtensions",
"classpath" to classpath.asPath,
"loaderref" to LOADER_REF,
"classname" to "com.intellij.ant.InstrumentIdeaExtensions"
)
}
logger.info("Compiling forms and instrumenting code with nullability preconditions")
if (instrumentNotNull) {
prepareNotNullInstrumenting(classpath.asPath)
}
instrumentCode(sourceDirs, instrumentNotNull)
}
private fun copyOriginalClasses() {
project.copy {
from(originalClassesDirs)
into(output)
}
}
private fun prepareNotNullInstrumenting(classpath: String) {
ant.withGroovyBuilder {
"typedef"(
"name" to "skip",
"classpath" to classpath,
"loaderref" to LOADER_REF,
"classname" to FILTER_ANNOTATION_REGEXP_CLASS
)
}
}
private fun instrumentCode(srcDirs: FileCollection, instrumentNotNull: Boolean) {
val headlessOldValue = System.setProperty("java.awt.headless", "true")
// Instrumentation needs to have access to sources of forms for inclusion
val depSourceDirectorySets = project.configurations["compile"].dependencies.withType(ProjectDependency::class.java)
.map { p -> p.dependencyProject.mainSourceSet.allSource.sourceDirectories }
val instrumentationClasspath =
depSourceDirectorySets.fold(sourceSet!!.compileClasspath) { acc, v -> acc + v }.asPath.also {
logger.info("Using following dependency source dirs: $it")
}
logger.info("Running instrumentIdeaExtensions with srcdir=${srcDirs.asPath}}, destdir=$output and classpath=$instrumentationClasspath")
ant.withGroovyBuilder {
"instrumentIdeaExtensions"(
"srcdir" to srcDirs.asPath,
"destdir" to output,
"classpath" to instrumentationClasspath,
"includeantruntime" to false,
"instrumentNotNull" to instrumentNotNull
) {
if (instrumentNotNull) {
ant.withGroovyBuilder {
"skip"("pattern" to "kotlin/Metadata")
}
}
}
}
if (headlessOldValue != null) {
System.setProperty("java.awt.headless", headlessOldValue)
} else {
System.clearProperty("java.awt.headless")
}
}
}
@@ -1,54 +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.codegen.inline
import jdk.internal.org.objectweb.asm.Opcodes
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.load.kotlin.getContainingKotlinJvmBinaryClass
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
// KLUDGE: Inline suspend function built with compiler version less than 1.1.4/1.2-M1 did not contain proper
// before/after suspension point marks, so we detect those functions here and insert the corresponding marks
fun insertLegacySuspendInlineMarks(node: MethodNode) {
with (node.instructions) {
// look for return instruction before the end and insert "afterSuspendMarker" there
insertBefore(findLastReturn(last) ?: return, produceSuspendMarker(false).instructions)
// insert "beforeSuspendMarker" at the beginning
insertBefore(first, produceSuspendMarker(true).instructions)
}
node.maxStack = node.maxStack.coerceAtLeast(2) // min stack need for suspend marker before return
}
fun findLastReturn(node: AbstractInsnNode?): AbstractInsnNode? {
var cur = node
while (cur != null && cur.opcode != Opcodes.ARETURN) cur = cur.previous
return cur
}
private fun produceSuspendMarker(isStartNotEnd: Boolean): MethodNode =
MethodNode().also { addSuspendMarker(InstructionAdapter(it), isStartNotEnd) }
fun isLegacySuspendInlineFunction(descriptor: CallableMemberDescriptor): Boolean {
if (descriptor !is FunctionDescriptor) return false
if (!descriptor.isSuspend || !descriptor.isInline) return false
val jvmBytecodeVersion = descriptor.getContainingKotlinJvmBinaryClass()?.classHeader?.bytecodeVersion ?: return false
return !jvmBytecodeVersion.isAtLeast(1, 0, 2)
}
-237
View File
@@ -1,237 +0,0 @@
-injars '<kotlin-compiler-jar-before-shrink>'(
!org/apache/log4j/jmx/Agent*,
!org/apache/log4j/net/JMS*,
!org/apache/log4j/net/SMTP*,
!org/apache/log4j/or/jms/MessageRenderer*,
!org/jdom/xpath/Jaxen*,
!org/jline/builtins/ssh/**,
!org/mozilla/javascript/xml/impl/xmlbeans/**,
!net/sf/cglib/**,
!META-INF/maven**,
**.class,**.properties,**.kt,**.kotlin_*,**.jnilib,**.so,**.dll,**.txt,**.caps,
META-INF/services/**,META-INF/native/**,META-INF/extensions/**,META-INF/MANIFEST.MF,
messages/**)
-outjars '<kotlin-compiler-jar>'
-dontnote **
-dontwarn com.intellij.util.ui.IsRetina*
-dontwarn com.intellij.util.RetinaImage*
-dontwarn apple.awt.*
-dontwarn dk.brics.automaton.*
-dontwarn org.fusesource.**
-dontwarn org.imgscalr.Scalr**
-dontwarn org.xerial.snappy.SnappyBundleActivator
-dontwarn com.intellij.util.CompressionUtil
-dontwarn com.intellij.util.SnappyInitializer
-dontwarn com.intellij.util.SVGLoader
-dontwarn com.intellij.util.SVGLoader$MyTranscoder
-dontwarn net.sf.cglib.**
-dontwarn org.objectweb.asm.** # this is ASM3, the old version that we do not use
-dontwarn com.sun.jna.NativeString
-dontwarn com.sun.jna.WString
-dontwarn com.intellij.psi.util.PsiClassUtil
-dontwarn org.apache.hadoop.io.compress.*
-dontwarn com.google.j2objc.annotations.Weak
-dontwarn org.iq80.snappy.HadoopSnappyCodec$SnappyCompressionInputStream
-dontwarn org.iq80.snappy.HadoopSnappyCodec$SnappyCompressionOutputStream
-dontwarn com.google.common.util.concurrent.*
-dontwarn org.apache.xerces.dom.**
-dontwarn org.apache.xerces.util.**
-dontwarn org.w3c.dom.ElementTraversal
-dontwarn javaslang.match.annotation.Unapply
-dontwarn javaslang.match.annotation.Patterns
-dontwarn javaslang.*
-dontwarn com.google.errorprone.**
-dontwarn com.google.j2objc.**
-dontwarn javax.crypto.**
-dontwarn java.lang.invoke.MethodHandle
-dontwarn org.jline.builtins.Nano$Buffer
-dontwarn org.jetbrains.annotations.ReadOnly
-dontwarn org.jetbrains.annotations.Mutable
-dontwarn com.intellij.util.io.TarUtil
# Annotations from intellijCore/annotations.jar that not presented in org.jetbrains.annotations
-dontwarn org.jetbrains.annotations.Async*
-dontwarn org.jetbrains.annotations.Nls$Capitalization
# Depends on apache batik which has lots of dependencies
-dontwarn com.intellij.util.SVGLoader*
# The appropriate jar is either loaded separately or added explicitly to the classpath then needed
-dontwarn org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar
#-libraryjars '<rtjar>'
#-libraryjars '<jssejar>'
#-libraryjars '<bootstrap.runtime>'
#-libraryjars '<bootstrap.reflect>'
#-libraryjars '<bootstrap.script.runtime>'
#-libraryjars '<tools.jar>'
-dontoptimize
-dontobfuscate
-keep class org.fusesource.** { *; }
-keep class com.sun.jna.** { *; }
-keep class org.jetbrains.annotations.** {
public protected *;
}
-keep class javax.inject.** {
public protected *;
}
-keep class org.jetbrains.kotlin.** {
public protected *;
}
-keep class org.jetbrains.kotlin.compiler.plugin.** {
public protected *;
}
-keep class org.jetbrains.kotlin.extensions.** {
public protected *;
}
-keep class org.jetbrains.kotlin.protobuf.** {
public protected *;
}
-keep class org.jetbrains.kotlin.container.** { *; }
-keep class org.jetbrains.org.objectweb.asm.Opcodes { *; }
-keep class org.jetbrains.kotlin.codegen.extensions.** {
public protected *;
}
-keepclassmembers class com.intellij.openapi.vfs.VirtualFile {
public protected *;
}
-keep class com.intellij.openapi.vfs.StandardFileSystems {
public static *;
}
# needed for jar cache cleanup in the gradle plugin and compile daemon
-keepclassmembers class com.intellij.openapi.vfs.impl.ZipHandler {
public static void clearFileAccessorCache();
}
-keep class jet.** {
public protected *;
}
-keep class com.intellij.psi.** {
public protected *;
}
# This is needed so that the platform code which parses XML wouldn't fail, see KT-16968
# This API is used from org.jdom.input.SAXBuilder via reflection.
-keep class org.jdom.input.JAXPParserFactory { public ** createParser(...); }
# for kdoc & dokka
-keep class com.intellij.openapi.util.TextRange { *; }
-keep class com.intellij.lang.impl.PsiBuilderImpl* {
public protected *;
}
-keep class com.intellij.openapi.util.text.StringHash { *; }
# for j2k
-keep class com.intellij.codeInsight.NullableNotNullManager { public protected *; }
# for gradle (see KT-12549)
-keep class com.intellij.lang.properties.charset.Native2AsciiCharsetProvider { *; }
# for kotlin-build-common (consider repacking compiler together with kotlin-build-common and remove this part afterwards)
-keep class com.intellij.util.io.IOUtil { public *; }
-keep class com.intellij.openapi.util.io.FileUtil { public *; }
-keep class com.intellij.util.SystemProperties { public *; }
-keep class com.intellij.util.containers.hash.LinkedHashMap { *; }
-keep class com.intellij.util.containers.ConcurrentIntObjectMap { *; }
-keep class com.intellij.util.containers.ComparatorUtil { *; }
-keep class com.intellij.util.io.PersistentHashMapValueStorage { *; }
-keep class com.intellij.util.io.PersistentHashMap { *; }
-keep class com.intellij.util.io.BooleanDataDescriptor { *; }
-keep class com.intellij.util.io.EnumeratorStringDescriptor { *; }
-keep class com.intellij.util.io.ExternalIntegerKeyDescriptor { *; }
-keep class com.intellij.util.containers.hash.EqualityPolicy { *; }
-keep class com.intellij.util.containers.hash.EqualityPolicy.* { *; }
-keep class com.intellij.util.containers.Interner { *; }
-keep class gnu.trove.TIntHashSet { *; }
-keep class gnu.trove.TIntIterator { *; }
-keep class org.iq80.snappy.SlowMemory { *; }
-keep class javaslang.match.PatternsProcessor { *; }
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keepclassmembers class * {
** toString();
** hashCode();
void start();
void stop();
void dispose();
}
-keep class org.jetbrains.org.objectweb.asm.tree.AnnotationNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.ClassNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.LocalVariableNode { *; }
-keep class org.jetbrains.org.objectweb.asm.tree.MethodNode { *; }
-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.signature.SignatureReader { *; }
-keep class org.jetbrains.org.objectweb.asm.signature.SignatureVisitor { *; }
-keep class org.jetbrains.org.objectweb.asm.Type {
public protected *;
}
-keepclassmembers class org.jetbrains.org.objectweb.asm.ClassReader {
*** SKIP_CODE;
*** SKIP_DEBUG;
*** SKIP_FRAMES;
}
-keepclassmembers class com.intellij.openapi.project.Project {
** getBasePath();
}
# for kotlin-android-extensions in maven
-keep class com.intellij.openapi.module.ModuleServiceManager { public *; }
# for building kotlin-build-common-test
-keep class org.jetbrains.kotlin.build.SerializationUtilsKt { *; }
# for tools.jar
-keep class com.sun.tools.javac.** { *; }
-keep class com.sun.source.** { *; }
# for coroutines
-keep class kotlinx.coroutines.** { *; }
# for webdemo
-keep class com.intellij.openapi.progress.ProgressManager { *; }
# for kapt
-keep class com.intellij.openapi.project.Project { *; }
-keepclassmembers class com.intellij.util.PathUtil {
public static java.lang.String getJarPathForClass(java.lang.Class);
}
-keepclassmembers class com.intellij.util.PathUtil {
public static java.lang.String getJarPathForClass(java.lang.Class);
}
# remove when KT-18563 would be fixed
-keep class org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt { *; }
-keep class net.jpountz.lz4.* { *; }
# used in LazyScriptDescriptor
-keep class org.jetbrains.kotlin.utils.addToStdlib.AddToStdlibKt { *; }
@@ -1,89 +0,0 @@
/*
* 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.fir
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import junit.framework.TestCase
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.fir.backend.Fir2IrConverter
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
import org.jetbrains.kotlin.ir.AbstractIrTextTestCase
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import java.io.File
abstract class AbstractFir2IrTextTest : AbstractIrTextTestCase() {
private fun prepareProjectExtensions(project: Project) {
}
override fun doTest(filePath: String?) {
if (filePath != null) {
val originalTextPath = filePath.replace(".kt", ".txt")
val firTextPath = filePath.replace(".kt", ".fir.txt")
val originalText = File(originalTextPath)
val firText = File(firTextPath)
if (originalText.exists() && firText.exists()) {
val originalLines = originalText.readLines()
val firLines = firText.readLines()
TestCase.assertFalse(
"Dumps via FIR & via old FE are the same. Please delete .fir.txt dump and add // FIR_IDENTICAL to test source",
firLines.withIndex().all { (index, line) ->
val trimmed = line.trim()
val originalTrimmed = originalLines.getOrNull(index)?.trim()
trimmed.isEmpty() && originalTrimmed?.isEmpty() != false || trimmed == originalTrimmed
} && originalLines.withIndex().all { (index, line) ->
index < firLines.size || line.trim().isEmpty()
}
)
}
}
super.doTest(filePath)
}
override fun getExpectedTextFileName(testFile: TestFile, name: String): String {
// NB: replace with if (true) to make test against old FE results
if ("// FIR_IDENTICAL" in testFile.content.split("\n")) {
return super.getExpectedTextFileName(testFile, name)
}
return name.replace(".txt", ".fir.txt").replace(".kt", ".fir.txt")
}
override fun generateIrModule(ignoreErrors: Boolean): IrModuleFragment {
val psiFiles = myFiles.psiFiles
val project = psiFiles.first().project
prepareProjectExtensions(project)
val scope = GlobalSearchScope.filesScope(project, psiFiles.map { it.virtualFile })
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
val session = createSession(myEnvironment, scope)
val builder = RawFirBuilder(session, stubMode = false)
val resolveTransformer = FirTotalResolveTransformer()
val firFiles = psiFiles.map {
val firFile = builder.buildFirFile(it)
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
firFile
}.also {
try {
resolveTransformer.processFiles(it)
} catch (e: Exception) {
throw e
}
}
return Fir2IrConverter.createModuleFragment(session, firFiles, myEnvironment.configuration.languageVersionSettings)
}
}
@@ -1,159 +0,0 @@
/*
* 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.fir
import com.intellij.openapi.extensions.Extensions
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.checkers.BaseDiagnosticsTest
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession
import org.jetbrains.kotlin.fir.java.FirLibrarySession
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.fir.resolve.FirProvider
import org.jetbrains.kotlin.fir.resolve.impl.FirProviderImpl
import org.jetbrains.kotlin.fir.resolve.transformers.FirTotalResolveTransformer
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import java.io.File
import java.util.*
abstract class AbstractFirDiagnosticsSmokeTest : BaseDiagnosticsTest() {
override fun analyzeAndCheck(testDataFile: File, files: List<TestFile>) {
try {
analyzeAndCheckUnhandled(files)
} catch (t: AssertionError) {
throw t
} catch (t: Throwable) {
throw t
}
}
private fun analyzeAndCheckUnhandled(files: List<TestFile>) {
val groupedByModule = files.groupBy(TestFile::module)
val modules = createModules(groupedByModule)
val sessionProvider = FirProjectSessionProvider(project)
//For BuiltIns, registered in sessionProvider automatically
val allProjectScope = GlobalSearchScope.allScope(project)
FirLibrarySession.create(
builtInsModuleInfo, sessionProvider, allProjectScope,
environment
)
val configToSession = modules.mapValues { (config, info) ->
val moduleFiles = groupedByModule.getValue(config)
val scope = TopDownAnalyzerFacadeForJVM.newModuleSearchScope(project, moduleFiles.mapNotNull { it.ktFile })
FirJavaModuleBasedSession(info, sessionProvider, scope)
}
val firFiles = mutableListOf<FirFile>()
for ((testModule, testFilesInModule) in groupedByModule) {
val ktFiles = getKtFiles(testFilesInModule, true)
val session = configToSession.getValue(testModule)
val firBuilder = RawFirBuilder(session, false)
ktFiles.mapTo(firFiles) {
val firFile = firBuilder.buildFirFile(it)
(session.service<FirProvider>() as FirProviderImpl).recordFile(firFile)
firFile
}
}
doFirResolveTestBench(firFiles, FirTotalResolveTransformer().transformers, gc = false)
}
private fun createModules(
groupedByModule: Map<TestModule?, List<TestFile>>
): MutableMap<TestModule?, ModuleInfo> {
val modules = HashMap<TestModule?, ModuleInfo>()
for (testModule in groupedByModule.keys) {
val module = if (testModule == null)
createSealedModule()
else
createModule(testModule.name)
modules[testModule] = module
}
for (testModule in groupedByModule.keys) {
if (testModule == null) continue
val module = modules[testModule]!!
val dependencies = ArrayList<ModuleInfo>()
dependencies.add(module)
for (dependency in testModule.getDependencies()) {
dependencies.add(modules[dependency]!!)
}
dependencies.add(builtInsModuleInfo)
//dependencies.addAll(getAdditionalDependencies(module))
(module as TestModuleInfo).dependencies.addAll(dependencies)
}
return modules
}
private val builtInsModuleInfo = BuiltInModuleInfo(Name.special("<built-ins>"))
protected open fun createModule(moduleName: String): TestModuleInfo {
val nameSuffix = moduleName.substringAfterLast("-", "")
// TODO: use platform
@Suppress("UNUSED_VARIABLE")
val platform =
when {
nameSuffix.isEmpty() -> null
nameSuffix == "common" -> MultiTargetPlatform.Common
else -> MultiTargetPlatform.Specific(nameSuffix.toUpperCase())
}
return TestModuleInfo(Name.special("<$moduleName>"))
}
class BuiltInModuleInfo(override val name: Name) : ModuleInfo {
override val platform: TargetPlatform?
get() = JvmPlatform
override fun dependencies(): List<ModuleInfo> {
return listOf(this)
}
}
protected class TestModuleInfo(override val name: Name) : ModuleInfo {
override val platform: TargetPlatform?
get() = JvmPlatform
val dependencies = mutableListOf<ModuleInfo>(this)
override fun dependencies(): List<ModuleInfo> {
return dependencies
}
}
protected open fun createSealedModule(): TestModuleInfo =
createModule("test-module").apply {
dependencies += builtInsModuleInfo
}
}
@@ -1,32 +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.fir
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElementFinder
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.fir.java.FirJavaModuleBasedSession
import org.jetbrains.kotlin.fir.java.FirLibrarySession
import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider
import org.jetbrains.kotlin.test.KotlinTestWithEnvironment
abstract class AbstractFirResolveWithSessionTestCase : KotlinTestWithEnvironment() {
override fun setUp() {
super.setUp()
prepareProjectExtensions(project)
}
protected fun prepareProjectExtensions(project: Project) {
// No relevant API in 181
// Extensions.getArea(project)
// .getExtensionPoint(PsiElementFinder.EP_NAME)
// .unregisterExtension(JavaElementFinder::class.java)
}
}
@@ -1,235 +0,0 @@
/*
* 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.fir.java
import com.intellij.lang.java.JavaLanguage
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtilRt
import com.intellij.psi.*
import com.intellij.psi.impl.PsiFileFactoryImpl
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.testFramework.LightVirtualFile
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.createSession
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
import org.jetbrains.kotlin.fir.java.scopes.JavaClassEnhancementScope
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.impl.FirCompositeSymbolProvider
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
import org.jetbrains.kotlin.fir.scopes.impl.FirCompositeScope
import org.jetbrains.kotlin.fir.service
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
import org.jetbrains.kotlin.test.*
import org.jetbrains.kotlin.test.KotlinTestUtils.getAnnotationsJar
import org.jetbrains.kotlin.test.KotlinTestUtils.newConfiguration
import org.jetbrains.kotlin.test.testFramework.KtUsefulTestCase
import java.io.File
import java.io.IOException
abstract class AbstractFirTypeEnhancementTest : KtUsefulTestCase() {
private lateinit var javaFilesDir: File
private lateinit var environment: KotlinCoreEnvironment
val project: Project
get() {
return environment.project
}
@Throws(Exception::class)
override fun setUp() {
super.setUp()
javaFilesDir = KotlinTestUtils.tmpDirForTest(this)
}
override fun tearDown() {
FileUtil.delete(javaFilesDir)
super.tearDown()
}
private fun createJarWithForeignAnnotations(): File =
MockLibraryUtil.compileJavaFilesLibraryToJar(FOREIGN_ANNOTATIONS_SOURCES_PATH, "foreign-annotations")
private fun createEnvironment(content: String): KotlinCoreEnvironment {
val classpath = mutableListOf(getAnnotationsJar(), ForTestCompileRuntime.runtimeJarForTests())
if (InTextDirectivesUtils.isDirectiveDefined(content, "ANDROID_ANNOTATIONS")) {
classpath.add(ForTestCompileRuntime.androidAnnotationsForTests())
}
if (InTextDirectivesUtils.isDirectiveDefined(content, "JVM_ANNOTATIONS")) {
classpath.add(ForTestCompileRuntime.jvmAnnotationsForTests())
}
if (InTextDirectivesUtils.isDirectiveDefined(content, "FOREIGN_ANNOTATIONS")) {
classpath.add(createJarWithForeignAnnotations())
}
return KotlinCoreEnvironment.createForTests(
testRootDisposable,
newConfiguration(
ConfigurationKind.JDK_NO_RUNTIME, TestJdkKind.FULL_JDK, classpath, listOf(javaFilesDir)
),
EnvironmentConfigFiles.JVM_CONFIG_FILES
)
}
fun doTest(path: String) {
val javaFile = File(path)
val javaLines = javaFile.readLines()
val content = javaLines.joinToString(separator = "\n")
if (InTextDirectivesUtils.isDirectiveDefined(content, "SKIP_IN_FIR_TEST")) return
val srcFiles = KotlinTestUtils.createTestFiles<Void, File>(
javaFile.name, FileUtil.loadFile(javaFile, true),
object : KotlinTestUtils.TestFileFactoryNoModules<File>() {
override fun create(fileName: String, text: String, directives: Map<String, String>): File {
var currentDir = javaFilesDir
if ("/" !in fileName) {
val packageFqName =
text.split("\n").firstOrNull {
it.startsWith("package")
}?.substringAfter("package")?.trim()?.substringBefore(";")?.let { name ->
FqName(name)
} ?: FqName.ROOT
for (segment in packageFqName.pathSegments()) {
currentDir = File(currentDir, segment.asString()).apply { mkdir() }
}
}
val targetFile = File(currentDir, fileName)
try {
FileUtil.writeToFile(targetFile, text)
} catch (e: IOException) {
throw AssertionError(e)
}
return targetFile
}
}, ""
)
environment = createEnvironment(content)
val virtualFiles = srcFiles.map {
object : LightVirtualFile(
it.name, JavaLanguage.INSTANCE, StringUtilRt.convertLineSeparators(it.readText())
) {
override fun getPath(): String {
//TODO: patch LightVirtualFile
return "/${it.name}"
}
}
}
val factory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl
val psiFiles = virtualFiles.map { factory.trySetupPsiForFile(it, JavaLanguage.INSTANCE, true, false)!! }
val scope = GlobalSearchScope.filesScope(project, virtualFiles)
.uniteWith(TopDownAnalyzerFacadeForJVM.AllJavaSourcesInProjectScope(project))
val session = createSession(environment, scope)
val topPsiClasses = psiFiles.flatMap { it.getChildrenOfType<PsiClass>().toList() }
val javaFirDump = StringBuilder().also { builder ->
val renderer = FirRenderer(builder)
val symbolProvider = session.service<FirSymbolProvider>() as FirCompositeSymbolProvider
val javaProvider = symbolProvider.providers.filterIsInstance<JavaSymbolProvider>().first()
fun processClassWithChildren(psiClass: PsiClass, parentFqName: FqName) {
val psiFile = psiClass.containingFile
val packageStatement = psiFile.children.filterIsInstance<PsiPackageStatement>().firstOrNull()
val packageName = packageStatement?.packageName
val fqName = parentFqName.child(Name.identifier(psiClass.name!!))
val classId = ClassId(packageName?.let { FqName(it) } ?: FqName.ROOT, fqName, false)
javaProvider.getClassLikeSymbolByFqName(classId)
?: throw AssertionError(classId.asString())
psiClass.innerClasses.forEach {
processClassWithChildren(psiClass = it, parentFqName = fqName)
}
}
for (psiClass in topPsiClasses) {
processClassWithChildren(psiClass, FqName.ROOT)
}
val processedJavaClasses = mutableSetOf<FirJavaClass>()
for (javaClass in javaProvider.getJavaTopLevelClasses().sortedBy { it.name }) {
if (javaClass !is FirJavaClass || javaClass in processedJavaClasses) continue
val enhancementScope = javaClass.buildClassSpecificUseSiteScope(session).let {
when (it) {
is FirCompositeScope -> it.scopes.filterIsInstance<JavaClassEnhancementScope>().first()
is JavaClassEnhancementScope -> it
else -> null
}
}
if (enhancementScope == null) {
javaClass.accept(renderer, null)
} else {
renderer.visitMemberDeclaration(javaClass)
renderer.renderSupertypes(javaClass)
renderer.renderInBraces {
val renderedDeclarations = mutableListOf<FirDeclaration>()
for (declaration in javaClass.declarations) {
if (declaration in renderedDeclarations) continue
when (declaration) {
is FirJavaConstructor -> enhancementScope.processFunctionsByName(javaClass.name) { symbol ->
val enhanced = (symbol as? FirFunctionSymbol)?.fir
if (enhanced != null && enhanced !in renderedDeclarations) {
enhanced.accept(renderer, null)
renderer.newLine()
renderedDeclarations += enhanced
}
ProcessorAction.NEXT
}
is FirJavaMethod -> enhancementScope.processFunctionsByName(declaration.name) { symbol ->
val enhanced = (symbol as? FirFunctionSymbol)?.fir
if (enhanced != null && enhanced !in renderedDeclarations) {
enhanced.accept(renderer, null)
renderer.newLine()
renderedDeclarations += enhanced
}
ProcessorAction.NEXT
}
is FirJavaField -> enhancementScope.processPropertiesByName(declaration.name) { symbol ->
val enhanced = (symbol as? FirPropertySymbol)?.fir
if (enhanced != null && enhanced !in renderedDeclarations) {
enhanced.accept(renderer, null)
renderer.newLine()
renderedDeclarations += enhanced
}
ProcessorAction.NEXT
}
else -> {
declaration.accept(renderer, null)
renderer.newLine()
renderedDeclarations += declaration
}
}
}
}
}
processedJavaClasses += javaClass
}
}.toString()
val expectedFile = File(javaFile.absolutePath.replace(".java", ".fir.txt"))
KotlinTestUtils.assertEqualsToFile(expectedFile, javaFirDump)
}
companion object {
private const val FOREIGN_ANNOTATIONS_SOURCES_PATH = "third-party/annotations"
}
}
abstract class AbstractOwnFirTypeEnhancementTest : AbstractFirTypeEnhancementTest()
@@ -1,15 +0,0 @@
/*
* 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.psi
import com.intellij.psi.JavaCodeFragment
import com.intellij.psi.PsiClass
interface KtCodeFragmentBase : JavaCodeFragment {
override fun importClass(aClass: PsiClass?): Boolean {
return true
}
}
@@ -1,96 +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.kotlin.psi
import com.intellij.lang.ASTNode
import com.intellij.navigation.ItemPresentationProviders
import com.intellij.psi.PsiElement
import com.intellij.psi.search.SearchScope
import com.intellij.util.IncorrectOperationException
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub
import org.jetbrains.kotlin.psi.stubs.elements.KtPlaceHolderStubElementType
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
abstract class KtConstructor<T : KtConstructor<T>> : KtDeclarationStub<KotlinPlaceHolderStub<T>>, KtFunction {
protected constructor(node: ASTNode) : super(node)
protected constructor(stub: KotlinPlaceHolderStub<T>, nodeType: KtPlaceHolderStubElementType<T>) : super(stub, nodeType)
abstract fun getContainingClassOrObject(): KtClassOrObject
override fun isLocal() = false
override fun getValueParameterList() = getStubOrPsiChild(KtStubElementTypes.VALUE_PARAMETER_LIST)
override fun getValueParameters() = valueParameterList?.parameters ?: emptyList()
override fun getReceiverTypeReference() = null
override fun getTypeReference() = null
@Throws(IncorrectOperationException::class)
override fun setTypeReference(typeRef: KtTypeReference?) = throw IncorrectOperationException("setTypeReference to constructor")
override fun getColon() = findChildByType<PsiElement>(KtTokens.COLON)
override fun getBodyExpression(): KtBlockExpression? = null
override fun getEqualsToken() = null
override fun hasBlockBody() = bodyExpression != null
override fun hasBody() = bodyExpression != null
override fun hasDeclaredReturnType() = false
override fun getTypeParameterList() = null
override fun getTypeConstraintList() = null
override fun getTypeConstraints() = emptyList<KtTypeConstraint>()
override fun getTypeParameters() = emptyList<KtTypeParameter>()
override fun getName(): String? = getContainingClassOrObject().name
override fun getNameAsSafeName() = KtPsiUtil.safeName(name)
override fun getFqName() = null
override fun getNameAsName() = nameAsSafeName
override fun getNameIdentifier() = null
@Throws(IncorrectOperationException::class)
override fun setName(name: String): PsiElement = throw IncorrectOperationException("setName to constructor")
override fun getPresentation() = ItemPresentationProviders.getItemPresentation(this)
open fun getConstructorKeyword(): PsiElement? = findChildByType(KtTokens.CONSTRUCTOR_KEYWORD)
fun hasConstructorKeyword(): Boolean = stub != null || getConstructorKeyword() != null
override fun getTextOffset(): Int {
return getConstructorKeyword()?.textOffset
?: valueParameterList?.textOffset
?: super.getTextOffset()
}
override fun getUseScope(): SearchScope {
return getContainingClassOrObject().useScope
}
}
@@ -1,71 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi
import com.intellij.lang.ASTNode
import com.intellij.psi.PsiElement
import org.jetbrains.annotations.NonNls
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.stubs.KotlinObjectStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
class KtObjectDeclaration : KtClassOrObject {
constructor(node: ASTNode) : super(node)
constructor(stub: KotlinObjectStub) : super(stub, KtStubElementTypes.OBJECT_DECLARATION)
private val _stub: KotlinObjectStub?
get() = stub as? KotlinObjectStub
override fun getName(): String? {
super.getName()?.let { return it }
if (isCompanion() && !isTopLevel()) {
//NOTE: a hack in PSI that simplifies writing frontend code
return SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT.toString()
}
return null
}
override fun setName(@NonNls name: String): PsiElement {
return if (nameIdentifier == null) {
val psiFactory = KtPsiFactory(project)
val result = addAfter(psiFactory.createIdentifier(name), getObjectKeyword()!!)
addAfter(psiFactory.createWhiteSpace(), getObjectKeyword()!!)
result
} else {
super.setName(name)
}
}
fun isCompanion(): Boolean = _stub?.isCompanion() ?: hasModifier(KtTokens.COMPANION_KEYWORD)
override fun getTextOffset(): Int = nameIdentifier?.textRange?.startOffset
?: getObjectKeyword()!!.textRange.startOffset
override fun <R, D> accept(visitor: KtVisitor<R, D>, data: D): R {
return visitor.visitObjectDeclaration(this, data)
}
fun isObjectLiteral(): Boolean = _stub?.isObjectLiteral() ?: (parent is KtObjectLiteralExpression)
fun getObjectKeyword(): PsiElement? = findChildByType(KtTokens.OBJECT_KEYWORD)
override fun getCompanionObjects(): List<KtObjectDeclaration> = emptyList()
}
@@ -1,22 +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.util
import com.intellij.openapi.util.ThrowableComputable
import com.intellij.psi.PsiFile
/**
* Absent in 181. Methods were renamed in 183.
*
* BUNCH: 182
*/
@Suppress("IncompatibleAPI", "MissingRecentApi")
object AstLoadingFilter {
@JvmStatic
fun <T, E : Throwable> forceAllowTreeLoading(psiFile: PsiFile, computable: ThrowableComputable<out T, E>): T {
return computable.compute()
}
}
-13
View File
@@ -1,13 +0,0 @@
versions.intellijSdk=181.5540.7
versions.androidBuildTools=r23.0.1
versions.idea.NodeJS=181.3494.12
versions.jar.guava=21.0
versions.jar.groovy-all=2.4.12
versions.jar.lombok-ast=0.2.3
versions.jar.swingx-core=1.6.2-2
versions.jar.kxml2=2.3.0
versions.jar.streamex=0.6.5
versions.jar.gson=2.8.2
versions.jar.oro=2.0.8
versions.jar.snappy-in-java=0.5.1
versions.gradle-api=4.4
@@ -1,14 +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.compatibility
import com.intellij.util.Processor
/**
* Processor<T> till IDEA 181 and Processor<in T> since 182.
* BUNCH: 181
*/
typealias ExecutorProcessor<T> = Processor<T>
@@ -1,132 +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.kotlin.idea.compiler.configuration
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.components.StoragePathMacros.PROJECT_CONFIG_DIR
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Comparing
import com.intellij.openapi.util.JDOMUtil
import com.intellij.util.ReflectionUtil
import com.intellij.util.messages.Topic
import com.intellij.util.xmlb.Accessor
import com.intellij.util.xmlb.SerializationFilterBase
import com.intellij.util.xmlb.XmlSerializer
import gnu.trove.THashMap
import org.jdom.Element
import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.config.SettingConstants
import org.jetbrains.kotlin.idea.syncPublisherWithDisposeCheck
import kotlin.reflect.KClass
abstract class BaseKotlinCompilerSettings<T : Freezable> protected constructor(private val project: Project) : PersistentStateComponent<Element>, Cloneable {
// Based on com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters
private object DefaultValuesFilter : SerializationFilterBase() {
private val defaultBeans = THashMap<Class<*>, Any>()
private fun createDefaultBean(beanClass: Class<Any>): Any {
return ReflectionUtil.newInstance<Any>(beanClass).apply {
if (this is K2JSCompilerArguments) {
sourceMapPrefix = ""
}
}
}
private fun getDefaultValue(accessor: Accessor, bean: Any): Any? {
if (bean is K2JSCompilerArguments && accessor.name == K2JSCompilerArguments::sourceMapEmbedSources.name) {
return if (bean.sourceMap) K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_INLINING else null
}
val beanClass = bean.javaClass
val defaultBean = defaultBeans.getOrPut(beanClass) { createDefaultBean(beanClass) }
return accessor.read(defaultBean)
}
override fun accepts(accessor: Accessor, bean: Any, beanValue: Any?): Boolean {
val defValue = getDefaultValue(accessor, bean)
return if (defValue is Element && beanValue is Element) {
!JDOMUtil.areElementsEqual(beanValue, defValue)
} else {
!Comparing.equal(beanValue, defValue)
}
}
}
@Suppress("LeakingThis", "UNCHECKED_CAST")
private var _settings: T = createSettings().frozen() as T
private set(value) {
field = value.frozen() as T
}
var settings: T
get() = _settings
set(value) {
validateNewSettings(value)
_settings = value
project.syncPublisherWithDisposeCheck(KotlinCompilerSettingsListener.TOPIC).settingsChanged(value)
}
fun update(changer: T.() -> Unit) {
@Suppress("UNCHECKED_CAST")
settings = (settings.unfrozen() as T).apply { changer() }
}
protected fun validateInheritedFieldsUnchanged(settings: T) {
@Suppress("UNCHECKED_CAST")
val inheritedProperties = collectProperties<T>(settings::class as KClass<T>, true)
val defaultInstance = createSettings()
val invalidFields = inheritedProperties.filter { it.get(settings) != it.get(defaultInstance) }
if (invalidFields.isNotEmpty()) {
throw IllegalArgumentException("Following fields are expected to be left unchanged in ${settings.javaClass}: ${invalidFields.joinToString { it.name }}")
}
}
protected open fun validateNewSettings(settings: T) {
}
protected abstract fun createSettings(): T
override fun getState() = XmlSerializer.serialize(_settings, DefaultValuesFilter)
override fun loadState(state: Element) {
_settings = ReflectionUtil.newInstance(_settings.javaClass).apply {
if (this is CommonCompilerArguments) {
freeArgs = mutableListOf()
internalArguments = mutableListOf()
}
XmlSerializer.deserializeInto(this, state)
}
project.syncPublisherWithDisposeCheck(KotlinCompilerSettingsListener.TOPIC).settingsChanged(settings)
}
public override fun clone(): Any = super.clone()
companion object {
const val KOTLIN_COMPILER_SETTINGS_PATH = PROJECT_CONFIG_DIR + "/" + SettingConstants.KOTLIN_COMPILER_SETTINGS_FILE
}
}
interface KotlinCompilerSettingsListener {
fun <T> settingsChanged(newSettings: T)
companion object {
val TOPIC = Topic.create("KotlinCompilerSettingsListener", KotlinCompilerSettingsListener::class.java)
}
}
@@ -1,39 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.compiler.configuration
import com.intellij.openapi.components.*
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.config.SettingConstants.KOTLIN_TO_JS_COMPILER_ARGUMENTS_SECTION
import org.jetbrains.kotlin.idea.compiler.configuration.BaseKotlinCompilerSettings.Companion.KOTLIN_COMPILER_SETTINGS_PATH
@State(name = KOTLIN_TO_JS_COMPILER_ARGUMENTS_SECTION,
storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE),
Storage(file = KOTLIN_COMPILER_SETTINGS_PATH, scheme = StorageScheme.DIRECTORY_BASED)))
class Kotlin2JsCompilerArgumentsHolder(project: Project) : BaseKotlinCompilerSettings<K2JSCompilerArguments>(project) {
override fun createSettings() = K2JSCompilerArguments()
override fun validateNewSettings(settings: K2JSCompilerArguments) {
validateInheritedFieldsUnchanged(settings)
}
companion object {
fun getInstance(project: Project) = ServiceManager.getService(project, Kotlin2JsCompilerArgumentsHolder::class.java)!!
}
}
@@ -1,38 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.compiler.configuration
import com.intellij.openapi.components.*
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.config.SettingConstants.KOTLIN_TO_JVM_COMPILER_ARGUMENTS_SECTION
import org.jetbrains.kotlin.idea.compiler.configuration.BaseKotlinCompilerSettings.Companion.KOTLIN_COMPILER_SETTINGS_PATH
@State(name = KOTLIN_TO_JVM_COMPILER_ARGUMENTS_SECTION,
storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE),
Storage(file = KOTLIN_COMPILER_SETTINGS_PATH, scheme = StorageScheme.DIRECTORY_BASED)))
class Kotlin2JvmCompilerArgumentsHolder(project: Project) : BaseKotlinCompilerSettings<K2JVMCompilerArguments>(project) {
override fun createSettings() = K2JVMCompilerArguments()
override fun validateNewSettings(settings: K2JVMCompilerArguments) {
validateInheritedFieldsUnchanged(settings)
}
companion object {
fun getInstance(project: Project) = ServiceManager.getService(project, Kotlin2JvmCompilerArgumentsHolder::class.java)!!
}
}
@@ -1,56 +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.compiler.configuration
import com.intellij.openapi.components.*
import com.intellij.openapi.project.Project
import com.intellij.util.text.VersionComparatorUtil
import org.jdom.Element
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.setApiVersionToLanguageVersionIfNeeded
import org.jetbrains.kotlin.config.SettingConstants.KOTLIN_COMMON_COMPILER_ARGUMENTS_SECTION
import org.jetbrains.kotlin.config.detectVersionAutoAdvance
import org.jetbrains.kotlin.config.dropVersionsIfNecessary
@State(name = KOTLIN_COMMON_COMPILER_ARGUMENTS_SECTION,
storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE),
Storage(file = BaseKotlinCompilerSettings.KOTLIN_COMPILER_SETTINGS_PATH,
scheme = StorageScheme.DIRECTORY_BASED)))
class KotlinCommonCompilerArgumentsHolder(project: Project) : BaseKotlinCompilerSettings<CommonCompilerArguments>(project) {
override fun getState(): Element {
return super.getState().apply {
dropVersionsIfNecessary(settings)
}
}
override fun loadState(state: Element) {
super.loadState(state)
update {
// To fix earlier configurations with incorrect combination of language and API version
setApiVersionToLanguageVersionIfNeeded()
detectVersionAutoAdvance()
}
}
override fun createSettings() = CommonCompilerArguments.DummyImpl()
companion object {
fun getInstance(project: Project) =
ServiceManager.getService<KotlinCommonCompilerArgumentsHolder>(project, KotlinCommonCompilerArgumentsHolder::class.java)!!
}
}
@@ -1,35 +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.kotlin.idea.compiler.configuration
import com.intellij.openapi.components.*
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.config.CompilerSettings
import org.jetbrains.kotlin.config.SettingConstants.KOTLIN_COMPILER_SETTINGS_SECTION
@State(name = KOTLIN_COMPILER_SETTINGS_SECTION,
storages = arrayOf(Storage(file = StoragePathMacros.PROJECT_FILE),
Storage(file = BaseKotlinCompilerSettings.KOTLIN_COMPILER_SETTINGS_PATH, scheme = StorageScheme.DIRECTORY_BASED)))
class KotlinCompilerSettings(project: Project) : BaseKotlinCompilerSettings<CompilerSettings>(project) {
override fun createSettings() = CompilerSettings()
companion object {
fun getInstance(project: Project) = ServiceManager.getService(project, KotlinCompilerSettings::class.java)!!
}
}
@@ -1,12 +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.highlighter;
public class ErrorIconUtil {
public static String getErrorIconUrl() {
return "/general/error.png";
}
}
@@ -1,18 +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.highlighter
import com.intellij.openapi.vfs.VirtualFile
object OutsidersPsiFileSupportWrapper {
fun isOutsiderFile(virtualFile: VirtualFile): Boolean {
return false
}
fun getOriginalFilePath(virtualFile: VirtualFile): String? {
return null
}
}
@@ -1,15 +0,0 @@
/*
* 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.util.compat
import com.intellij.openapi.project.Project
import com.intellij.psi.search.PsiSearchHelper
// BUNCH: 181
@Suppress("IncompatibleAPI", "MissingRecentApi")
fun psiSearchHelperInstance(project: Project): PsiSearchHelper {
return PsiSearchHelper.SERVICE.getInstance(project)
}
@@ -1,65 +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.android.configure
import com.android.tools.idea.gradle.project.model.JavaModuleModel
import com.android.tools.idea.gradle.project.sync.idea.data.service.AndroidProjectKeys
import com.android.tools.idea.gradle.util.FilePaths
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.project.ModuleData
import com.intellij.openapi.externalSystem.model.project.ProjectData
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.roots.impl.libraries.LibraryEx
import com.intellij.openapi.roots.libraries.Library
import org.jetbrains.kotlin.idea.configuration.detectPlatformKindByPlugin
import org.jetbrains.kotlin.idea.framework.detectLibraryKind
import org.jetbrains.kotlin.idea.platform.tooling
import java.io.File
class KotlinAndroidGradleLibraryDataService : AbstractProjectDataService<JavaModuleModel, Void>() {
override fun getTargetDataKey() = AndroidProjectKeys.JAVA_MODULE_MODEL
override fun postProcess(
toImport: MutableCollection<DataNode<JavaModuleModel>>,
projectData: ProjectData?,
project: Project,
modelsProvider: IdeModifiableModelsProvider
) {
for (dataNode in toImport) {
@Suppress("UNCHECKED_CAST")
val targetLibraryKind = detectPlatformKindByPlugin(dataNode.parent as DataNode<ModuleData>)?.tooling?.libraryKind
if (targetLibraryKind != null) {
for (dep in dataNode.data.jarLibraryDependencies) {
val library = modelsProvider.findLibraryByBinaryPath(dep.binaryPath) as LibraryEx? ?: continue
if (library.kind == null) {
val model = modelsProvider.getModifiableLibraryModel(library) as LibraryEx.ModifiableModelEx
detectLibraryKind(model.getFiles(OrderRootType.CLASSES))?.let { model.kind = it }
}
}
}
}
}
private fun IdeModifiableModelsProvider.findLibraryByBinaryPath(path: File?): Library? {
if (path == null) return null
val url = FilePaths.pathToIdeaUrl(path)
return allLibraries.firstOrNull { url in getModifiableLibraryModel(it).getUrls(OrderRootType.CLASSES) }
}
}
@@ -1,236 +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.android.configure
import com.android.tools.idea.gradle.project.sync.idea.data.service.AndroidProjectKeys
import com.android.tools.idea.gradle.util.ContentEntries.findParentContentEntry
import com.android.tools.idea.gradle.util.FilePaths
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.ProjectKeys
import com.intellij.openapi.externalSystem.model.project.ModuleData
import com.intellij.openapi.externalSystem.model.project.ProjectData
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
import com.intellij.openapi.externalSystem.service.project.manage.AbstractProjectDataService
import com.intellij.openapi.externalSystem.service.project.manage.ContentRootDataService.CREATE_EMPTY_DIRECTORIES
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.DependencyScope
import com.intellij.openapi.roots.ModifiableRootModel
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.util.SmartList
import com.intellij.util.containers.stream
import org.jetbrains.jps.model.java.JavaResourceRootType
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
import org.jetbrains.kotlin.gradle.KotlinCompilation
import org.jetbrains.kotlin.gradle.KotlinPlatform
import org.jetbrains.kotlin.gradle.KotlinSourceSet
import org.jetbrains.kotlin.idea.addModuleDependencyIfNeeded
import org.jetbrains.kotlin.idea.configuration.*
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.plugins.gradle.model.data.GradleSourceSetData
import java.io.File
import java.io.IOException
import org.jetbrains.kotlin.idea.configuration.kotlinSourceSet
class KotlinAndroidGradleMPPModuleDataService : AbstractProjectDataService<ModuleData, Void>() {
override fun getTargetDataKey() = ProjectKeys.MODULE
private fun shouldCreateEmptySourceRoots(
moduleDataNode: DataNode<ModuleData>,
module: Module
): Boolean {
val projectDataNode = ExternalSystemApiUtil.findParent(moduleDataNode, ProjectKeys.PROJECT) ?: return false
if (projectDataNode.getUserData<Boolean>(CREATE_EMPTY_DIRECTORIES) == true) return true
val projectSystemId = projectDataNode.data.owner
val externalSystemSettings = ExternalSystemApiUtil.getSettings(module.project, projectSystemId)
val path = ExternalSystemModulePropertyManager.getInstance(module).getRootProjectPath() ?: return false
return externalSystemSettings.getLinkedProjectSettings(path)?.isCreateEmptyContentRootDirectories ?: false
}
override fun postProcess(
toImport: MutableCollection<DataNode<ModuleData>>,
projectData: ProjectData?,
project: Project,
modelsProvider: IdeModifiableModelsProvider
) {
for (nodeToImport in toImport) {
val projectNode = ExternalSystemApiUtil.findParent(nodeToImport, ProjectKeys.PROJECT) ?: continue
val moduleData = nodeToImport.data
val module = modelsProvider.findIdeModule(moduleData) ?: continue
val shouldCreateEmptySourceRoots = shouldCreateEmptySourceRoots(nodeToImport, module)
val rootModel = modelsProvider.getModifiableRootModel(module)
val kotlinAndroidSourceSets = nodeToImport.kotlinAndroidSourceSets ?: emptyList()
for (sourceSetInfo in kotlinAndroidSourceSets) {
val compilation = sourceSetInfo.kotlinModule as? KotlinCompilation ?: continue
for (sourceSet in compilation.sourceSets) {
if (sourceSet.platform == KotlinPlatform.ANDROID) {
val sourceType = if (sourceSet.isTestModule) JavaSourceRootType.TEST_SOURCE else JavaSourceRootType.SOURCE
val resourceType = if (sourceSet.isTestModule) JavaResourceRootType.TEST_RESOURCE else JavaResourceRootType.RESOURCE
sourceSet.sourceDirs.forEach { addSourceRoot(it, sourceType, rootModel, shouldCreateEmptySourceRoots) }
sourceSet.resourceDirs.forEach { addSourceRoot(it, resourceType, rootModel, shouldCreateEmptySourceRoots) }
}
}
}
addExtraDependeeModules(nodeToImport, projectNode, modelsProvider, rootModel, false)
addExtraDependeeModules(nodeToImport, projectNode, modelsProvider, rootModel, true)
if (nodeToImport.kotlinAndroidSourceSets == null) {
continue
}
val androidModel = getAndroidModuleModel(nodeToImport) ?: continue
val variantName = androidModel.selectedVariant.name
val activeSourceSetInfos = nodeToImport.kotlinAndroidSourceSets?.filter { it.kotlinModule.name.startsWith(variantName) } ?: emptyList()
for (activeSourceSetInfo in activeSourceSetInfos) {
val activeCompilation = activeSourceSetInfo.kotlinModule as? KotlinCompilation ?: continue
for (sourceSet in activeCompilation.sourceSets) {
if (sourceSet.platform != KotlinPlatform.ANDROID) {
val sourceSetId = activeSourceSetInfo.sourceSetIdsByName[sourceSet.name] ?: continue
val sourceSetNode = ExternalSystemApiUtil.findFirstRecursively(projectNode) {
(it.data as? ModuleData)?.id == sourceSetId
} as? DataNode<out ModuleData>? ?: continue
val sourceSetData = sourceSetNode.data as? ModuleData ?: continue
val sourceSetModule = modelsProvider.findIdeModule(sourceSetData) ?: continue
addModuleDependencyIfNeeded(
rootModel,
sourceSetModule,
activeSourceSetInfo.isTestModule,
sourceSetNode.kotlinSourceSet?.isTestModule ?: false
)
}
}
}
val mainSourceSetInfo = activeSourceSetInfos.firstOrNull { it.kotlinModule.name == variantName }
if (mainSourceSetInfo != null) {
KotlinSourceSetDataService.configureFacet(moduleData, mainSourceSetInfo, nodeToImport, module, modelsProvider)
}
val kotlinFacet = KotlinFacet.get(module)
if (kotlinFacet != null) {
GradleProjectImportHandler.getInstances(project).forEach { it.importByModule(kotlinFacet, nodeToImport) }
}
}
}
private fun getDependeeModuleNodes(
moduleNode: DataNode<ModuleData>,
projectNode: DataNode<ProjectData>,
modelsProvider: IdeModifiableModelsProvider,
testScope: Boolean
): List<DataNode<out ModuleData>> {
val androidModel = getAndroidModuleModel(moduleNode)
if (androidModel != null) {
val dependencies = if (testScope) {
androidModel.selectedAndroidTestCompileDependencies
} else {
androidModel.selectedMainCompileLevel2Dependencies
} ?: return emptyList()
return dependencies
.moduleDependencies
.mapNotNull { projectNode.findChildModuleById(it.projectPath) }
}
val javaModel = getJavaModuleModel(moduleNode)
if (javaModel != null) {
val scope = if (testScope) DependencyScope.TEST.name else DependencyScope.COMPILE.name
val moduleNames = javaModel
.javaModuleDependencies
.filter { scope == it.scope ?: DependencyScope.COMPILE.name }
.mapTo(HashSet()) { it.moduleName }
return ExternalSystemApiUtil
.getChildren(projectNode, ProjectKeys.MODULE)
.filter { modelsProvider.findIdeModule(it.data)?.name in moduleNames }
}
return emptyList()
}
private fun List<DataNode<GradleSourceSetData>>.firstByPlatformOrNull(platform: KotlinPlatform) = firstOrNull {
it.kotlinSourceSet?.platform == platform
}
private fun addExtraDependeeModules(
moduleNode: DataNode<ModuleData>,
projectNode: DataNode<ProjectData>,
modelsProvider: IdeModifiableModelsProvider,
rootModel: ModifiableRootModel,
testScope: Boolean
) {
val dependeeModuleNodes = getDependeeModuleNodes(moduleNode, projectNode, modelsProvider, testScope)
val relevantNodes = dependeeModuleNodes
.flatMap { ExternalSystemApiUtil.getChildren(it, GradleSourceSetData.KEY) }
.filter {
val ktModule = it.kotlinSourceSet?.kotlinModule
ktModule != null && ktModule.isTestModule == testScope
}
val commonSourceSetName = KotlinSourceSet.commonName(testScope)
val isAndroidModule = getAndroidModuleModel(moduleNode) != null
val gradleSourceSetDataNodes = SmartList<DataNode<GradleSourceSetData>>()
.apply {
addIfNotNull(
(if (isAndroidModule) relevantNodes.firstByPlatformOrNull(KotlinPlatform.ANDROID) else null)
?: relevantNodes.firstByPlatformOrNull(KotlinPlatform.JVM)
)
addIfNotNull(
relevantNodes.firstOrNull {
it.kotlinSourceSet?.platform == KotlinPlatform.COMMON && it.kotlinSourceSet?.kotlinModule?.name == commonSourceSetName
}
)
}
val testKotlinModules =
gradleSourceSetDataNodes.filter { it.kotlinSourceSet?.isTestModule ?: false }.mapNotNull { modelsProvider.findIdeModule(it.data) }
.toSet()
gradleSourceSetDataNodes.forEach { node ->
val module = modelsProvider.findIdeModule(node.data) ?: return
addModuleDependencyIfNeeded(rootModel, module, testScope, node.kotlinSourceSet?.isTestModule ?: false)
val dependeeRootModel = modelsProvider.getModifiableRootModel(module)
dependeeRootModel.getModuleDependencies(testScope).forEach { transitiveDependee ->
addModuleDependencyIfNeeded(rootModel, transitiveDependee, testScope, testKotlinModules.contains(transitiveDependee))
}
}
}
private fun getAndroidModuleModel(moduleNode: DataNode<ModuleData>) =
ExternalSystemApiUtil.getChildren(moduleNode, AndroidProjectKeys.ANDROID_MODEL).firstOrNull()?.data
private fun getJavaModuleModel(moduleNode: DataNode<ModuleData>) =
ExternalSystemApiUtil.getChildren(moduleNode, AndroidProjectKeys.JAVA_MODULE_MODEL).firstOrNull()?.data
private fun addSourceRoot(
sourceRoot: File,
type: JpsModuleSourceRootType<*>,
rootModel: ModifiableRootModel,
shouldCreateEmptySourceRoots: Boolean
) {
val parent = findParentContentEntry(sourceRoot, rootModel.contentEntries.stream()) ?: return
val url = FilePaths.pathToIdeaUrl(sourceRoot)
parent.addSourceFolder(url, type)
if (shouldCreateEmptySourceRoots) {
ExternalSystemApiUtil.doWriteAction {
try {
VfsUtil.createDirectoryIfMissing(sourceRoot.path)
} catch (e: IOException) {
LOG.warn(String.format("Unable to create directory for the path: %s", sourceRoot.path), e)
}
}
}
}
companion object {
private val LOG = Logger.getInstance(KotlinAndroidGradleMPPModuleDataService::class.java)
}
}
@@ -1,388 +0,0 @@
/*
* Copyright 2000-2009 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.android;
import com.android.SdkConstants;
import com.android.tools.idea.rendering.RenderSecurityManager;
import com.android.tools.idea.startup.AndroidCodeStyleSettingsModifier;
import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInspection.GlobalInspectionTool;
import com.intellij.codeInspection.InspectionManager;
import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper;
import com.intellij.codeInspection.ex.InspectionManagerEx;
import com.intellij.facet.FacetManager;
import com.intellij.facet.ModifiableFacetModel;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.roots.ModuleRootModificationUtil;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.codeStyle.CodeStyleSchemes;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.testFramework.InspectionTestUtil;
import com.intellij.testFramework.ThreadTracker;
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.testFramework.fixtures.JavaTestFixtureFactory;
import com.intellij.testFramework.fixtures.TestFixtureBuilder;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import com.intellij.testFramework.fixtures.impl.GlobalInspectionContextForTests;
import com.intellij.util.ArrayUtil;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.android.facet.AndroidRootUtil;
import org.jetbrains.android.formatter.AndroidXmlCodeStyleSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.picocontainer.MutablePicoContainer;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* Copied from AS 2.3 sources
*/
@SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"})
public abstract class AndroidTestCase extends AndroidTestBase {
protected Module myModule;
protected List<Module> myAdditionalModules;
protected AndroidFacet myFacet;
protected CodeStyleSettings mySettings;
private List<String> myAllowedRoots = new ArrayList<>();
private boolean myUseCustomSettings;
@Override
protected void setUp() throws Exception {
super.setUp();
VfsRootAccess.allowRootAccess(KotlinTestUtils.getHomeDirectory());
TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName());
myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture());
JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
File moduleRoot = new File(myFixture.getTempDirPath());
if (!moduleRoot.exists()) {
assertTrue(moduleRoot.mkdirs());
}
initializeModuleFixtureBuilderWithSrcAndGen(moduleFixtureBuilder, moduleRoot.toString());
ArrayList<MyAdditionalModuleData> modules = new ArrayList<>();
configureAdditionalModules(projectBuilder, modules);
myFixture.setUp();
myFixture.setTestDataPath(getTestDataPath());
myModule = moduleFixtureBuilder.getFixture().getModule();
// Must be done before addAndroidFacet, and must always be done, even if a test provides
// its own custom manifest file. However, in that case, we will delete it shortly below.
createManifest();
myFacet = addAndroidFacet(myModule);
LanguageLevel languageLevel = getLanguageLevel();
if (languageLevel != null) {
LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(myModule.getProject());
if (extension != null) {
extension.setLanguageLevel(languageLevel);
}
}
// TODO: myFixture.copyDirectoryToProject(getResDir(), "res");
myAdditionalModules = new ArrayList<>();
for (MyAdditionalModuleData data : modules) {
Module additionalModule = data.myModuleFixtureBuilder.getFixture().getModule();
myAdditionalModules.add(additionalModule);
AndroidFacet facet = addAndroidFacet(additionalModule);
facet.setProjectType(data.myProjectType);
String rootPath = getAdditionalModulePath(data.myDirName);
myFixture.copyDirectoryToProject(getResDir(), rootPath + "/res");
myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, rootPath + '/' + SdkConstants.FN_ANDROID_MANIFEST_XML);
if (data.myIsMainModuleDependency) {
ModuleRootModificationUtil.addDependency(myModule, additionalModule);
}
}
if (providesCustomManifest()) {
deleteManifest();
}
if (RenderSecurityManager.RESTRICT_READS) {
// Unit test class loader includes disk directories which security manager does not allow access to
RenderSecurityManager.sEnabled = false;
}
ArrayList<String> allowedRoots = new ArrayList<>();
collectAllowedRoots(allowedRoots);
// TODO: registerAllowedRoots(allowedRoots, myTestRootDisposable);
mySettings = CodeStyleSettingsManager.getSettings(getProject()).clone();
AndroidCodeStyleSettingsModifier.modify(mySettings);
CodeStyleSettingsManager.getInstance(getProject()).setTemporarySettings(mySettings);
myUseCustomSettings = getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS;
getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS = true;
// Layoutlib rendering thread will be shutdown when the app is closed so do not report it as a leak
ThreadTracker.longRunningThreadCreated(ApplicationManager.getApplication(), "Layoutlib");
}
@Override
protected void tearDown() throws Exception {
try {
Sdk androidSdk = ProjectJdkTable.getInstance().findJdk(ANDROID_SDK_NAME);
if (androidSdk != null) {
ApplicationManager.getApplication().runWriteAction(() -> ProjectJdkTable.getInstance().removeJdk(androidSdk));
}
CodeStyleSettingsManager.getInstance(getProject()).dropTemporarySettings();
myModule = null;
myAdditionalModules = null;
myFixture.tearDown();
myFixture = null;
myFacet = null;
getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS = myUseCustomSettings;
if (RenderSecurityManager.RESTRICT_READS) {
RenderSecurityManager.sEnabled = true;
}
}
finally {
super.tearDown();
VfsRootAccess.disallowRootAccess(KotlinTestUtils.getHomeDirectory());
}
}
private static void initializeModuleFixtureBuilderWithSrcAndGen(JavaModuleFixtureBuilder moduleFixtureBuilder, String moduleRoot) {
moduleFixtureBuilder.addContentRoot(moduleRoot);
//noinspection ResultOfMethodCallIgnored
new File(moduleRoot + "/src/").mkdir();
moduleFixtureBuilder.addSourceRoot("src");
//noinspection ResultOfMethodCallIgnored
new File(moduleRoot + "/gen/").mkdir();
moduleFixtureBuilder.addSourceRoot("gen");
}
/**
* Returns the path that any additional modules registered by
* {@link #configureAdditionalModules(TestFixtureBuilder, List)} or
* {@link #addModuleWithAndroidFacet(TestFixtureBuilder, List, String, int, boolean)} are
* installed into.
*/
protected static String getAdditionalModulePath(@NotNull String moduleName) {
return "/additionalModules/" + moduleName;
}
/**
* Indicates whether this class provides its own {@code AndroidManifest.xml} for its tests. If
* {@code true}, then {@link #setUp()} calls {@link #deleteManifest()} before finishing.
*/
protected boolean providesCustomManifest() {
return false;
}
/**
* Get the "res" directory for this SDK. Children classes can override this if they need to
* provide a custom "res" location for tests.
*/
protected String getResDir() {
return "res";
}
/**
* Defines the project level to set for the test project, or null to get the default language
* level associated with the test project.
*/
@Nullable
protected LanguageLevel getLanguageLevel() {
return null;
}
protected static AndroidXmlCodeStyleSettings getAndroidCodeStyleSettings() {
return AndroidXmlCodeStyleSettings.getInstance(CodeStyleSchemes.getInstance().getDefaultScheme().getCodeStyleSettings());
}
/**
* Hook point for child test classes to register directories that can be safely accessed by all
* of its tests.
*
* @see {@link VfsRootAccess}
*/
protected void collectAllowedRoots(List<String> roots) throws IOException {
}
private void registerAllowedRoots(List<String> roots, @NotNull Disposable disposable) {
List<String> newRoots = new ArrayList<>(roots);
newRoots.removeAll(myAllowedRoots);
String[] newRootsArray = ArrayUtil.toStringArray(newRoots);
VfsRootAccess.allowRootAccess(newRootsArray);
myAllowedRoots.addAll(newRoots);
Disposer.register(disposable, () -> {
VfsRootAccess.disallowRootAccess(newRootsArray);
myAllowedRoots.removeAll(newRoots);
});
}
public static AndroidFacet addAndroidFacet(Module module) {
return addAndroidFacet(module, true);
}
private static AndroidFacet addAndroidFacet(Module module, boolean attachSdk) {
FacetManager facetManager = FacetManager.getInstance(module);
AndroidFacet facet = facetManager.createFacet(AndroidFacet.getFacetType(), "Android", null);
if (attachSdk) {
addLatestAndroidSdk(module);
}
ModifiableFacetModel facetModel = facetManager.createModifiableModel();
facetModel.addFacet(facet);
ApplicationManager.getApplication().runWriteAction(facetModel::commit);
return facet;
}
protected void configureAdditionalModules(
@NotNull TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder, @NotNull List<MyAdditionalModuleData> modules) {
}
protected final void addModuleWithAndroidFacet(
@NotNull TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder,
@NotNull List<MyAdditionalModuleData> modules,
@NotNull String dirName,
int projectType) {
// By default, created module is declared as a main module's dependency
addModuleWithAndroidFacet(projectBuilder, modules, dirName, projectType, true);
}
protected final void addModuleWithAndroidFacet(
@NotNull TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder,
@NotNull List<MyAdditionalModuleData> modules,
@NotNull String dirName,
int projectType,
boolean isMainModuleDependency) {
JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
String moduleDirPath = myFixture.getTempDirPath() + getAdditionalModulePath(dirName);
//noinspection ResultOfMethodCallIgnored
new File(moduleDirPath).mkdirs();
initializeModuleFixtureBuilderWithSrcAndGen(moduleFixtureBuilder, moduleDirPath);
modules.add(new MyAdditionalModuleData(moduleFixtureBuilder, dirName, projectType, isMainModuleDependency));
}
protected void createManifest() throws IOException {
myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, SdkConstants.FN_ANDROID_MANIFEST_XML);
}
protected final void createProjectProperties() throws IOException {
myFixture.copyFileToProject(SdkConstants.FN_PROJECT_PROPERTIES, SdkConstants.FN_PROJECT_PROPERTIES);
}
protected final void deleteManifest() throws IOException {
deleteManifest(myModule);
}
protected final void deleteManifest(final Module module) throws IOException {
AndroidFacet facet = AndroidFacet.getInstance(module);
assertNotNull(facet);
ApplicationManager.getApplication().runWriteAction(new Runnable() {
@Override
public void run() {
String manifestRelativePath = facet.getProperties().MANIFEST_FILE_RELATIVE_PATH;
VirtualFile manifest = AndroidRootUtil.getFileByRelativeModulePath(module, manifestRelativePath, true);
if (manifest != null) {
try {
manifest.delete(this);
}
catch (IOException e) {
fail("Could not delete default manifest");
}
}
}
});
}
protected final void doGlobalInspectionTest(
@NotNull GlobalInspectionTool inspection, @NotNull String globalTestDir, @NotNull AnalysisScope scope) {
doGlobalInspectionTest(new GlobalInspectionToolWrapper(inspection), globalTestDir, scope);
}
/**
* Given an inspection and a path to a directory that contains an "expected.xml" file, run the
* inspection on the current test project and verify that its output matches that of the
* expected file.
*/
protected final void doGlobalInspectionTest(
@NotNull GlobalInspectionToolWrapper wrapper, @NotNull String globalTestDir, @NotNull AnalysisScope scope) {
myFixture.enableInspections(wrapper.getTool());
scope.invalidate();
InspectionManagerEx inspectionManager = (InspectionManagerEx)InspectionManager.getInstance(getProject());
GlobalInspectionContextForTests globalContext =
CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, getProject(), inspectionManager, wrapper);
InspectionTestUtil.runTool(wrapper, scope, globalContext);
InspectionTestUtil.compareToolResults(globalContext, wrapper, false, getTestDataPath() + globalTestDir);
}
protected static class MyAdditionalModuleData {
final JavaModuleFixtureBuilder myModuleFixtureBuilder;
final String myDirName;
final int myProjectType;
final boolean myIsMainModuleDependency;
private MyAdditionalModuleData(
@NotNull JavaModuleFixtureBuilder moduleFixtureBuilder, @NotNull String dirName, int projectType, boolean isMainModuleDependency) {
myModuleFixtureBuilder = moduleFixtureBuilder;
myDirName = dirName;
myProjectType = projectType;
myIsMainModuleDependency = isMainModuleDependency;
}
}
@NotNull
protected <T> T registerApplicationComponent(@NotNull Class<T> key, @NotNull T instance) throws Exception {
MutablePicoContainer picoContainer = (MutablePicoContainer)ApplicationManager.getApplication().getPicoContainer();
@SuppressWarnings("unchecked")
T old = (T)picoContainer.getComponentInstance(key.getName());
picoContainer.unregisterComponent(key.getName());
picoContainer.registerComponentInstance(key.getName(), instance);
return old;
}
@NotNull
protected <T> T registerProjectComponent(@NotNull Class<T> key, @NotNull T instance) {
MutablePicoContainer picoContainer = (MutablePicoContainer)getProject().getPicoContainer();
@SuppressWarnings("unchecked")
T old = (T)picoContainer.getComponentInstance(key.getName());
picoContainer.unregisterComponent(key.getName());
picoContainer.registerComponentInstance(key.getName(), instance);
return old;
}
}
@@ -1,40 +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.android;
import com.android.annotations.NonNull;
import com.intellij.openapi.application.PathManager;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import java.io.File;
/**
* Stub for com.android.testutils.TestUtils
* stabbed to minimize changes in AndroidTestBase
*/
public class TestUtils {
@NonNull
public static File getSdk() {
return KotlinTestUtils.findAndroidSdk();
}
@NonNull
public static String getLatestAndroidPlatform() {
return "android-26";
}
}
@@ -1,31 +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.gradle
import org.jetbrains.kotlin.idea.configuration.KotlinGradleSharedMultiplatformModuleBuilder
import org.jetbrains.kotlin.idea.configuration.KotlinGradleWebMultiplatformModuleBuilder
import org.jetbrains.kotlin.idea.test.KotlinSdkCreationChecker
import org.junit.Test
class GradleMultiplatformWizardTest : AbstractGradleMultiplatformWizardTest() {
lateinit var sdkCreationChecker: KotlinSdkCreationChecker
override fun setUp() {
super.setUp()
sdkCreationChecker = KotlinSdkCreationChecker()
}
override fun tearDown() {
sdkCreationChecker.removeNewKotlinSdk()
super.tearDown()
}
@Test
fun testWeb() {
testImportFromBuilder(KotlinGradleWebMultiplatformModuleBuilder(), "SampleTests", "SampleTestsJVM")
}
}
@@ -1,17 +0,0 @@
/*
* 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.gradle
import org.jetbrains.kotlin.idea.codeInsight.gradle.MultiplePluginVersionGradleImportingTestCase
//BUNCH 181
fun MultiplatformProjectImportingTest.shouldRunTest(kotlinPluginVersion: String, gradleVersion: String): Boolean {
return kotlinPluginVersion != MultiplePluginVersionGradleImportingTestCase.MINIMAL_SUPPORTED_VERSION
}
fun NewMultiplatformProjectImportingTest.shouldRunTest(kotlinPluginVersion: String, gradleVersion: String): Boolean {
return !gradleVersion.startsWith("3.")
}
@@ -1,18 +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.internal
import org.jetbrains.java.decompiler.main.decompiler.BaseDecompiler
import java.io.File
/**
* `addSpace` method is deprecated in 182. `addSource` and `addLibrary` were introduced instead.
* BUNCH: 181
*/
@Suppress("IncompatibleAPI")
fun BaseDecompiler.addSpaceEx(file: File, isOwn: Boolean) {
addSpace(file, isOwn)
}
@@ -1,128 +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.core.platform.impl
import com.intellij.execution.PsiLocation
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.libraries.Library
import com.intellij.openapi.util.io.FileUtil
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.gradle.KotlinPlatform
import org.jetbrains.kotlin.idea.compiler.configuration.Kotlin2JsCompilerArgumentsHolder
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription
import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil
import org.jetbrains.kotlin.idea.highlighter.KotlinTestRunLineMarkerContributor.Companion.getTestStateIcon
import org.jetbrains.kotlin.idea.js.KotlinJSRunConfigurationDataProvider
import org.jetbrains.kotlin.idea.platform.IdePlatformKindTooling
import org.jetbrains.kotlin.idea.util.string.joinWithEscape
import org.jetbrains.kotlin.js.resolve.JsAnalyzerFacade
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtNamedDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.utils.PathUtil
import org.jetbrains.kotlin.utils.ifEmpty
import javax.swing.Icon
class JsIdePlatformKindTooling : IdePlatformKindTooling() {
companion object {
private const val MAVEN_OLD_JS_STDLIB_ID = "kotlin-js-library"
private val TEST_FQ_NAME = FqName("kotlin.test.Test")
private val IGNORE_FQ_NAME = FqName("kotlin.test.Ignore")
}
override val kind = JsIdePlatformKind
override fun compilerArgumentsForProject(project: Project) = Kotlin2JsCompilerArgumentsHolder.getInstance(project).settings
override val resolverForModuleFactory = JsAnalyzerFacade
override val mavenLibraryIds = listOf(PathUtil.JS_LIB_NAME, MAVEN_OLD_JS_STDLIB_ID)
override val gradlePluginId = "kotlin-platform-js"
override val gradlePlatformIds: List<KotlinPlatform> get() = listOf(KotlinPlatform.JS)
override val libraryKind = JSLibraryKind
override fun getLibraryDescription(project: Project) = JSLibraryStdDescription(project)
override fun getLibraryVersionProvider(project: Project) = { library: Library ->
JsLibraryStdDetectionUtil.getJsLibraryStdVersion(library, project)
}
override fun getTestIcon(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor): Icon? {
if (!descriptor.isTest()) return null
val contexts by lazy { computeConfigurationContexts(declaration) }
val runConfigData = RunConfigurationProducer
.getProducers(declaration.project)
.asSequence()
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
.filter { it.isForTests }
.flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } }
.firstOrNull { it != null } ?: return null
val locations = ArrayList<String>()
locations += FileUtil.toSystemDependentName(runConfigData.jsOutputFilePath)
val klass = when (declaration) {
is KtClassOrObject -> declaration
is KtNamedFunction -> declaration.containingClassOrObject ?: return null
else -> return null
}
locations += klass.parentsWithSelf.filterIsInstance<KtNamedDeclaration>().mapNotNull { it.name }.toList().asReversed()
val testName = (declaration as? KtNamedFunction)?.name
if (testName != null) {
locations += "$testName"
}
val prefix = if (testName != null) "test://" else "suite://"
val url = prefix + locations.joinWithEscape('.')
return getTestStateIcon(url, declaration.project)
}
override fun acceptsAsEntryPoint(function: KtFunction): Boolean {
val contexts by lazy { computeConfigurationContexts(function) }
return RunConfigurationProducer
.getProducers(function.project)
.asSequence()
.filterIsInstance<KotlinJSRunConfigurationDataProvider<*>>()
.filter { !it.isForTests }
.flatMap { provider -> contexts.map { context -> provider.getConfigurationData(context) } }
.any { it != null }
}
private fun computeConfigurationContexts(declaration: KtNamedDeclaration): Sequence<ConfigurationContext> {
return sequenceOf(ConfigurationContext(declaration))
}
private fun DeclarationDescriptor.isIgnored(): Boolean =
annotations.any { it.fqName == IGNORE_FQ_NAME } || ((containingDeclaration as? ClassDescriptor)?.isIgnored() ?: false)
private fun DeclarationDescriptor.isTest(): Boolean {
if (isIgnored()) return false
if (annotations.any { it.fqName == TEST_FQ_NAME }) return true
if (this is ClassDescriptorWithResolutionScopes) {
return declaredCallableMembers.any { it.isTest() }
}
return false
}
}
@@ -1,22 +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.run
import com.intellij.openapi.module.Module
import org.jetbrains.kotlin.idea.caches.project.implementingModules
import org.jetbrains.kotlin.idea.project.platform
import org.jetbrains.kotlin.platform.impl.isCommon
import org.jetbrains.kotlin.platform.impl.isJvm
fun Module.asJvmModule(): Module? {
if (platform.isJvm) return this
if (platform.isCommon) {
return implementingModules.firstOrNull { it.platform.isJvm }
}
return null
}
@@ -1,13 +0,0 @@
/*
* 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.scratch
import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
fun isScratchChanged(project: Project, file: VirtualFile) : Boolean {
return true
}
@@ -1,42 +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.kotlin.idea.test;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
public abstract class KotlinLightCodeInsightFixtureTestCaseBase extends LightCodeInsightFixtureTestCase {
@NotNull
@Override
public Project getProject() {
return super.getProject();
}
@NotNull
@Override
public Editor getEditor() {
return super.getEditor();
}
@Override
public PsiFile getFile() {
return super.getFile();
}
}
@@ -1,21 +0,0 @@
description = "Kotlin Gradle Tooling support"
plugins {
kotlin("jvm")
id("jps-compatible")
}
dependencies {
compile(kotlinStdlib())
compile(project(":compiler:cli-common"))
compile(intellijPluginDep("gradle"))
compileOnly(intellijDep()) { includeJars("slf4j-api-1.7.10") }
}
sourceSets {
"main" { projectDefault() }
"test" {}
}
runtimeJar()
@@ -1,445 +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.gradle
import org.gradle.api.Named
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.file.FileCollection
import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.logging.Logging
import org.gradle.api.provider.Property
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModel.Companion.NO_KOTLIN_NATIVE_HOME
import org.jetbrains.plugins.gradle.model.*
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
import org.jetbrains.plugins.gradle.tooling.ModelBuilderService
import org.jetbrains.plugins.gradle.tooling.util.DependencyResolver
import org.jetbrains.plugins.gradle.tooling.util.DependencyResolverImpl
import org.jetbrains.plugins.gradle.tooling.util.SourceSetCachedFinder
import java.io.File
import java.lang.reflect.Method
class KotlinMPPGradleModelBuilder : ModelBuilderService {
override fun getErrorMessageBuilder(project: Project, e: Exception): ErrorMessageBuilder {
return ErrorMessageBuilder
.create(project, e, "Gradle import errors")
.withDescription("Unable to build Kotlin project configuration")
}
override fun canBuild(modelName: String?): Boolean {
return modelName == KotlinMPPGradleModel::class.java.name
}
override fun buildAll(modelName: String, project: Project): Any? {
val dependencyResolver = DependencyResolverImpl(
project,
false,
false,
true,
SourceSetCachedFinder(project)
)
val sourceSets = buildSourceSets(dependencyResolver, project) ?: return null
val sourceSetMap = sourceSets.map { it.name to it }.toMap()
val targets = buildTargets(sourceSetMap, dependencyResolver, project) ?: return null
computeSourceSetsDeferredInfo(sourceSets, targets)
val coroutinesState = getCoroutinesState(project)
reportUnresolvedDependencies(targets)
val kotlinNativeHome = KotlinNativeHomeEvaluator.getKotlinNativeHome(project) ?: NO_KOTLIN_NATIVE_HOME
return KotlinMPPGradleModelImpl(sourceSetMap, targets, ExtraFeaturesImpl(coroutinesState), kotlinNativeHome)
}
private fun reportUnresolvedDependencies(targets: Collection<KotlinTarget>) {
targets
.asSequence()
.flatMap { it.compilations.asSequence() }
.flatMap { it.dependencies.asSequence() }
.mapNotNull { (it as? UnresolvedExternalDependency)?.failureMessage }
.toSet()
.forEach { logger.warn(it) }
}
private fun getCoroutinesState(project: Project): String? {
val kotlinExt = project.extensions.findByName("kotlin") ?: return null
val getExperimental = kotlinExt.javaClass.getMethodOrNull("getExperimental") ?: return null
val experimentalExt = getExperimental(kotlinExt) ?: return null
val getCoroutines = experimentalExt.javaClass.getMethodOrNull("getCoroutines") ?: return null
return getCoroutines(experimentalExt) as? String
}
private fun buildSourceSets(dependencyResolver: DependencyResolver, project: Project): Collection<KotlinSourceSetImpl>? {
val kotlinExt = project.extensions.findByName("kotlin") ?: return null
val getSourceSets = kotlinExt.javaClass.getMethodOrNull("getSourceSets") ?: return null
@Suppress("UNCHECKED_CAST")
val sourceSets =
(getSourceSets(kotlinExt) as? NamedDomainObjectContainer<Named>)?.asMap?.values ?: emptyList<Named>()
return sourceSets.mapNotNull { buildSourceSet(it, dependencyResolver, project) }
}
private fun buildSourceSet(
gradleSourceSet: Named,
dependencyResolver: DependencyResolver,
project: Project
): KotlinSourceSetImpl? {
val sourceSetClass = gradleSourceSet.javaClass
val getLanguageSettings = sourceSetClass.getMethodOrNull("getLanguageSettings") ?: return null
val getSourceDirSet = sourceSetClass.getMethodOrNull("getKotlin") ?: return null
val getResourceDirSet = sourceSetClass.getMethodOrNull("getResources") ?: return null
val getDependsOn = sourceSetClass.getMethodOrNull("getDependsOn") ?: return null
val languageSettings = getLanguageSettings(gradleSourceSet)?.let { buildLanguageSettings(it) } ?: return null
val sourceDirs = (getSourceDirSet(gradleSourceSet) as? SourceDirectorySet)?.srcDirs ?: emptySet()
val resourceDirs = (getResourceDirSet(gradleSourceSet) as? SourceDirectorySet)?.srcDirs ?: emptySet()
val dependencies = buildSourceSetDependencies(gradleSourceSet, dependencyResolver, project)
@Suppress("UNCHECKED_CAST")
val dependsOnSourceSets = (getDependsOn(gradleSourceSet) as? Set<Named>)?.mapTo(LinkedHashSet()) { it.name } ?: emptySet<String>()
return KotlinSourceSetImpl(gradleSourceSet.name, languageSettings, sourceDirs, resourceDirs, dependencies, dependsOnSourceSets)
}
private fun buildLanguageSettings(gradleLanguageSettings: Any): KotlinLanguageSettings? {
val languageSettingsClass = gradleLanguageSettings.javaClass
val getLanguageVersion = languageSettingsClass.getMethodOrNull("getLanguageVersion") ?: return null
val getApiVersion = languageSettingsClass.getMethodOrNull("getApiVersion") ?: return null
val getProgressiveMode = languageSettingsClass.getMethodOrNull("getProgressiveMode") ?: return null
val getEnabledLanguageFeatures = languageSettingsClass.getMethodOrNull("getEnabledLanguageFeatures") ?: return null
val getExperimentalAnnotationsInUse = languageSettingsClass.getMethodOrNull("getExperimentalAnnotationsInUse")
val getCompilerPluginArguments = languageSettingsClass.getMethodOrNull("getCompilerPluginArguments")
val getCompilerPluginClasspath = languageSettingsClass.getMethodOrNull("getCompilerPluginClasspath")
@Suppress("UNCHECKED_CAST")
return KotlinLanguageSettingsImpl(
getLanguageVersion(gradleLanguageSettings) as? String,
getApiVersion(gradleLanguageSettings) as? String,
getProgressiveMode(gradleLanguageSettings) as? Boolean ?: false,
getEnabledLanguageFeatures(gradleLanguageSettings) as? Set<String> ?: emptySet(),
getExperimentalAnnotationsInUse?.invoke(gradleLanguageSettings) as? Set<String> ?: emptySet(),
getCompilerPluginArguments?.invoke(gradleLanguageSettings) as? List<String> ?: emptyList(),
(getCompilerPluginClasspath?.invoke(gradleLanguageSettings) as? FileCollection)?.files ?: emptySet()
)
}
private fun buildDependencies(
dependencyHolder: Any,
dependencyResolver: DependencyResolver,
configurationNameAccessor: String,
scope: String,
project: Project
): Collection<KotlinDependency> {
val dependencyHolderClass = dependencyHolder.javaClass
val getConfigurationName = dependencyHolderClass.getMethodOrNull(configurationNameAccessor) ?: return emptyList()
val configurationName = getConfigurationName(dependencyHolder) as? String ?: return emptyList()
val configuration = project.configurations.findByName(configurationName) ?: return emptyList()
if (!configuration.isCanBeResolved) return emptyList()
val dependencyAdjuster = DependencyAdjuster(configuration, scope, project)
val resolvedDependencies = dependencyResolver
.resolveDependencies(configuration)
.apply {
forEach<ExternalDependency?> { (it as? AbstractExternalDependency)?.scope = scope }
}
.flatMap(dependencyAdjuster::adjustDependency)
val singleDependencyFiles = resolvedDependencies.mapNotNullTo(LinkedHashSet<File>()) {
(it as? FileCollectionDependency)?.files?.singleOrNull()
}
// Workaround for duplicated dependencies specified as a file collection (KT-26675)
// Drop this code when the issue is fixed in the platform
return resolvedDependencies.filter { dependency ->
if (dependency !is FileCollectionDependency) return@filter true
val files = dependency.files
if (files.size <= 1) return@filter true
(files.any { it !in singleDependencyFiles })
}
}
private fun buildTargets(
sourceSetMap: Map<String, KotlinSourceSet>,
dependencyResolver: DependencyResolver,
project: Project
): Collection<KotlinTarget>? {
return project.getTargets()?.mapNotNull { buildTarget(it, sourceSetMap, dependencyResolver, project) }
}
private fun buildTarget(
gradleTarget: Named,
sourceSetMap: Map<String, KotlinSourceSet>,
dependencyResolver: DependencyResolver,
project: Project
): KotlinTarget? {
val targetClass = gradleTarget.javaClass
val getPlatformType = targetClass.getMethodOrNull("getPlatformType") ?: return null
val getCompilations = targetClass.getMethodOrNull("getCompilations") ?: return null
val getDisambiguationClassifier = targetClass.getMethodOrNull("getDisambiguationClassifier") ?: return null
val platformId = (getPlatformType.invoke(gradleTarget) as? Named)?.name ?: return null
val platform = KotlinPlatform.byId(platformId) ?: return null
val disambiguationClassifier = getDisambiguationClassifier(gradleTarget) as? String
@Suppress("UNCHECKED_CAST")
val gradleCompilations =
(getCompilations.invoke(gradleTarget) as? NamedDomainObjectContainer<Named>)?.asMap?.values ?: emptyList<Named>()
val compilations = gradleCompilations.mapNotNull {
buildCompilation(it, disambiguationClassifier, sourceSetMap, dependencyResolver, project)
}
val jar = buildTargetJar(gradleTarget, project)
val target = KotlinTargetImpl(gradleTarget.name, null, disambiguationClassifier, platform, compilations, jar)
compilations.forEach {
it.disambiguationClassifier = target.disambiguationClassifier
it.platform = target.platform
}
return target
}
private fun buildTargetJar(gradleTarget: Named, project: Project): KotlinTargetJar? {
val targetClass = gradleTarget.javaClass
val getArtifactsTaskName = targetClass.getMethodOrNull("getArtifactsTaskName") ?: return null
val artifactsTaskName = getArtifactsTaskName(gradleTarget) as? String ?: return null
val jarTask = project.tasks.findByName(artifactsTaskName) ?: return null
val jarTaskClass = jarTask.javaClass
val getArchivePath = jarTaskClass.getMethodOrNull("getArchivePath")
val archiveFile = getArchivePath?.invoke(jarTask) as? File?
return KotlinTargetJarImpl(archiveFile)
}
private fun buildCompilation(
gradleCompilation: Named,
classifier: String?,
sourceSetMap: Map<String, KotlinSourceSet>,
dependencyResolver: DependencyResolver,
project: Project
): KotlinCompilationImpl? {
val compilationClass = gradleCompilation.javaClass
val getKotlinSourceSets = compilationClass.getMethodOrNull("getKotlinSourceSets") ?: return null
@Suppress("UNCHECKED_CAST")
val kotlinGradleSourceSets = (getKotlinSourceSets(gradleCompilation) as? Collection<Named>) ?: return null
val kotlinSourceSets = kotlinGradleSourceSets.mapNotNull { sourceSetMap[it.name] }
val getCompileKotlinTaskName = compilationClass.getMethodOrNull("getCompileKotlinTaskName") ?: return null
@Suppress("UNCHECKED_CAST")
val compileKotlinTaskName = (getCompileKotlinTaskName(gradleCompilation) as? String) ?: return null
val compileKotlinTask = project.tasks.findByName(compileKotlinTaskName) ?: return null
val output = buildCompilationOutput(gradleCompilation, compileKotlinTask) ?: return null
val arguments = buildCompilationArguments(compileKotlinTask) ?: return null
val dependencyClasspath = buildDependencyClasspath(compileKotlinTask)
val dependencies = buildCompilationDependencies(gradleCompilation, classifier, sourceSetMap, dependencyResolver, project)
return KotlinCompilationImpl(gradleCompilation.name, kotlinSourceSets, dependencies, output, arguments, dependencyClasspath)
}
private fun buildCompilationDependencies(
gradleCompilation: Named,
classifier: String?,
sourceSetMap: Map<String, KotlinSourceSet>,
dependencyResolver: DependencyResolver,
project: Project
): Set<KotlinDependency> {
return LinkedHashSet<KotlinDependency>().apply {
this += buildDependencies(
gradleCompilation, dependencyResolver, "getCompileDependencyConfigurationName", "COMPILE", project
)
this += buildDependencies(
gradleCompilation, dependencyResolver, "getRuntimeDependencyConfigurationName", "RUNTIME", project
)
this += sourceSetMap[compilationFullName(gradleCompilation.name, classifier)]?.dependencies ?: emptySet()
}
}
private fun buildSourceSetDependencies(
gradleSourceSet: Named,
dependencyResolver: DependencyResolver,
project: Project
): Set<KotlinDependency> {
return LinkedHashSet<KotlinDependency>().apply {
this += buildDependencies(
gradleSourceSet, dependencyResolver, "getApiMetadataConfigurationName", "COMPILE", project
)
this += buildDependencies(
gradleSourceSet, dependencyResolver, "getImplementationMetadataConfigurationName", "COMPILE", project
)
this += buildDependencies(
gradleSourceSet, dependencyResolver, "getCompileOnlyMetadataConfigurationName", "COMPILE", project
)
this += buildDependencies(
gradleSourceSet, dependencyResolver, "getRuntimeOnlyMetadataConfigurationName", "RUNTIME", project
)
}
}
@Suppress("UNCHECKED_CAST")
private fun safelyGetArguments(compileKotlinTask: Task, accessor: Method?) = try {
accessor?.invoke(compileKotlinTask) as? List<String>
} catch (e: Exception) {
logger.info(e.message ?: "Unexpected exception: $e", e)
null
} ?: emptyList()
private fun buildCompilationArguments(compileKotlinTask: Task): KotlinCompilationArguments? {
val compileTaskClass = compileKotlinTask.javaClass
val getCurrentArguments = compileTaskClass.getMethodOrNull("getSerializedCompilerArguments")
val getDefaultArguments = compileTaskClass.getMethodOrNull("getDefaultSerializedCompilerArguments")
val currentArguments = safelyGetArguments(compileKotlinTask, getCurrentArguments)
val defaultArguments = safelyGetArguments(compileKotlinTask, getDefaultArguments)
return KotlinCompilationArgumentsImpl(defaultArguments, currentArguments)
}
private fun buildDependencyClasspath(compileKotlinTask: Task): List<String> {
val abstractKotlinCompileClass =
compileKotlinTask.javaClass.classLoader.loadClass(AbstractKotlinGradleModelBuilder.ABSTRACT_KOTLIN_COMPILE_CLASS)
val getCompileClasspath =
abstractKotlinCompileClass.getDeclaredMethodOrNull("getCompileClasspath") ?: return emptyList()
@Suppress("UNCHECKED_CAST")
return (getCompileClasspath(compileKotlinTask) as? Collection<File>)?.map { it.path } ?: emptyList()
}
private fun buildCompilationOutput(
gradleCompilation: Named,
compileKotlinTask: Task
): KotlinCompilationOutput? {
val compilationClass = gradleCompilation.javaClass
val getOutput = compilationClass.getMethodOrNull("getOutput") ?: return null
val gradleOutput = getOutput(gradleCompilation) ?: return null
val gradleOutputClass = gradleOutput.javaClass
val getClassesDirs = gradleOutputClass.getMethodOrNull("getClassesDirs") ?: return null
val getResourcesDir = gradleOutputClass.getMethodOrNull("getResourcesDir") ?: return null
val compileKotlinTaskClass = compileKotlinTask.javaClass
val getDestinationDir = compileKotlinTaskClass.getMethodOrNull("getDestinationDir")
val getOutputFile = compileKotlinTaskClass.getMethodOrNull("getOutputFile")
val classesDirs = getClassesDirs(gradleOutput) as? FileCollection ?: return null
val resourcesDir = getResourcesDir(gradleOutput) as? File ?: return null
val destinationDir =
getDestinationDir?.invoke(compileKotlinTask) as? File
//TODO: Hack for KotlinNativeCompile
?: (getOutputFile?.invoke(compileKotlinTask) as? Property<File>)?.orNull?.parentFile
?: return null
return KotlinCompilationOutputImpl(classesDirs.files, destinationDir, resourcesDir)
}
private fun computeSourceSetsDeferredInfo(
sourceSets: Collection<KotlinSourceSetImpl>,
targets: Collection<KotlinTarget>
) {
val sourceSetToCompilations = LinkedHashMap<KotlinSourceSet, MutableSet<KotlinCompilation>>()
for (target in targets) {
for (compilation in target.compilations) {
for (sourceSet in compilation.sourceSets) {
sourceSetToCompilations.getOrPut(sourceSet) { LinkedHashSet() } += compilation
}
}
}
for (sourceSet in sourceSets) {
val name = sourceSet.name
if (name == KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME) {
sourceSet.platform = KotlinPlatform.COMMON
sourceSet.isTestModule = false
continue
}
if (name == KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME) {
sourceSet.platform = KotlinPlatform.COMMON
sourceSet.isTestModule = true
continue
}
val compilations = sourceSetToCompilations[sourceSet]
if (compilations != null) {
sourceSet.platform = compilations.map { it.platform }.distinct().singleOrNull() ?: KotlinPlatform.COMMON
sourceSet.isTestModule = compilations.all { it.isTestModule }
} else {
// TODO: change me after design about it
sourceSet.isTestModule = "Test" in sourceSet.name
}
}
}
private class DependencyAdjuster(
private val configuration: Configuration,
private val scope: String,
private val project: Project
) {
private val adjustmentMap = HashMap<ExternalDependency, List<ExternalDependency>>()
val dependenciesByProjectPath by lazy {
configuration
.resolvedConfiguration
.lenientConfiguration
.allModuleDependencies
.mapNotNull { dependency ->
val artifact = dependency.moduleArtifacts.firstOrNull {
it.id.componentIdentifier is ProjectComponentIdentifier
} ?: return@mapNotNull null
dependency to artifact
}
.groupBy { (it.second.id.componentIdentifier as ProjectComponentIdentifier).projectPath }
}
private fun wrapDependency(dependency: ExternalProjectDependency, newConfigurationName: String): ExternalProjectDependency {
return DefaultExternalProjectDependency(dependency).apply {
this.configurationName = newConfigurationName
val nestedDependencies = this.dependencies.flatMap(::adjustDependency)
this.dependencies.clear()
this.dependencies.addAll(nestedDependencies)
}
}
fun adjustDependency(dependency: ExternalDependency): List<ExternalDependency> {
return adjustmentMap.getOrPut(dependency) {
if (dependency !is ExternalProjectDependency
|| dependency.configurationName != Dependency.DEFAULT_CONFIGURATION
) return@getOrPut listOf(dependency)
val artifacts = dependenciesByProjectPath[dependency.projectPath] ?: return@getOrPut listOf(dependency)
val artifactConfiguration = artifacts.mapTo(LinkedHashSet()) {
it.first.configuration
}.singleOrNull() ?: return@getOrPut listOf(dependency)
val taskGetterName = when (scope) {
"COMPILE" -> "getApiElementsConfigurationName"
"RUNTIME" -> "getRuntimeElementsConfigurationName"
else -> return@getOrPut listOf(dependency)
}
val dependencyProject =
if (project.rootProject.path == dependency.projectPath)
project.rootProject
else
project.rootProject.getChildProjectByPath(dependency.projectPath)
val targets = dependencyProject?.getTargets() ?: return@getOrPut listOf(dependency)
val gradleTarget = targets.firstOrNull {
val getter = it.javaClass.getMethodOrNull(taskGetterName) ?: return@firstOrNull false
getter(it) == artifactConfiguration
} ?: return@getOrPut listOf(dependency)
val classifier = gradleTarget.javaClass.getMethodOrNull("getDisambiguationClassifier")?.invoke(gradleTarget) as? String
?: return@getOrPut listOf(dependency)
val platformDependency = if (classifier != KotlinTarget.METADATA_TARGET_NAME) {
wrapDependency(dependency, compilationFullName(KotlinCompilation.MAIN_COMPILATION_NAME, classifier))
} else null
val commonDependency = wrapDependency(dependency, KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME)
return if (platformDependency != null) listOf(platformDependency, commonDependency) else listOf(commonDependency)
}
}
}
companion object {
private val logger = Logging.getLogger(KotlinMPPGradleModelBuilder::class.java)
fun Project.getTargets(): Collection<Named>? {
val kotlinExt = project.extensions.findByName("kotlin") ?: return null
val getTargets = kotlinExt.javaClass.getMethodOrNull("getTargets") ?: return null
@Suppress("UNCHECKED_CAST")
return (getTargets.invoke(kotlinExt) as? NamedDomainObjectContainer<Named>)?.asMap?.values ?: emptyList()
}
}
}
private fun Project.getChildProjectByPath(path: String): Project? {
var project = this
for (name in path.split(":").asSequence().drop(1)) {
project = project.childProjects[name] ?: return null
}
return project
}
private fun Project.getTargets(): Collection<Named>? {
val kotlinExt = project.extensions.findByName("kotlin") ?: return null
val getTargets = kotlinExt.javaClass.getMethodOrNull("getTargets") ?: return null
@Suppress("UNCHECKED_CAST")
return (getTargets.invoke(kotlinExt) as? NamedDomainObjectContainer<Named>)?.asMap?.values ?: emptyList()
}
-4
View File
@@ -1,4 +0,0 @@
<idea-plugin>
<extensions defaultExtensionNs="Git4Idea">
</extensions>
</idea-plugin>
-96
View File
@@ -1,96 +0,0 @@
<idea-plugin>
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSFrameworkSupportProvider"/>
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJavaFrameworkSupportProvider"/>
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSFrameworkSupportProvider"/>
<pluginDescriptions implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradlePluginDescription"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectResolverExtension" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.kapt.idea.KaptProjectResolverExtension" order="last"/>
<projectResolve implementation="org.jetbrains.kotlin.allopen.ide.AllOpenProjectResolverExtension" order="last"/>
<projectResolve implementation="org.jetbrains.kotlin.noarg.ide.NoArgProjectResolverExtension" order="last"/>
<projectResolve implementation="org.jetbrains.kotlin.samWithReceiver.ide.SamWithReceiverProjectResolverExtension" order="last"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver"/>
</extensions>
<extensionPoints>
<extensionPoint qualifiedName="org.jetbrains.kotlin.gradleProjectImportHandler" area="IDEA_PROJECT"
interface="org.jetbrains.kotlin.idea.configuration.GradleProjectImportHandler"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.gradleModelFacade"
interface="org.jetbrains.kotlin.idea.inspections.gradle.KotlinGradleModelFacade"/>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleLibraryDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinTargetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectSettingsDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.KotlinJavaMPPSourceSetDataService"/>
<externalSystemTaskNotificationListener implementation="org.jetbrains.kotlin.idea.core.script.ReloadGradleTemplatesOnSync"/>
<localInspection
implementationClass="org.jetbrains.kotlin.idea.inspections.gradle.DifferentKotlinGradleVersionInspection"
displayName="Kotlin Gradle and IDE plugins versions are different"
groupName="Kotlin"
enabledByDefault="true"
language="Groovy"
hasStaticDescription="true"
level="WARNING"/>
<localInspection
implementationClass="org.jetbrains.kotlin.idea.inspections.gradle.DifferentStdlibGradleVersionInspection"
displayName="Kotlin library and Gradle plugin versions are different"
groupName="Kotlin"
enabledByDefault="true"
language="Groovy"
hasStaticDescription="true"
level="WARNING"/>
<localInspection
implementationClass="org.jetbrains.kotlin.idea.inspections.gradle.DeprecatedGradleDependencyInspection"
displayName="Deprecated library is used in Gradle"
groupName="Kotlin"
enabledByDefault="true"
cleanupTool="true"
language="Groovy"
hasStaticDescription="true"
level="WARNING"/>
<localInspection
implementationClass="org.jetbrains.kotlin.idea.inspections.gradle.GradleKotlinxCoroutinesDeprecationInspection"
displayName="Incompatible kotlinx.coroutines dependency is used with Kotlin 1.3+ in Gradle"
groupPath="Kotlin,Migration"
groupName="Gradle"
enabledByDefault="true"
language="Groovy"
hasStaticDescription="true"
level="ERROR"/>
<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">
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.allopen.ide.AllOpenGradleProjectImportHandler"/>
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.scripting.idea.plugin.ScriptingGradleProjectImportHandler"/>
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.kapt.idea.KaptGradleProjectImportHandler"/>
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.noarg.ide.NoArgGradleProjectImportHandler"/>
<gradleProjectImportHandler implementation="org.jetbrains.kotlin.samWithReceiver.ide.SamWithReceiverGradleProjectImportHandler"/>
<gradleProjectImportHandler implementation="org.jetbrains.kotlinx.serialization.idea.KotlinSerializationGradleImportHandler"/>
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleModuleConfigurator"/>
<projectConfigurator implementation="org.jetbrains.kotlin.idea.configuration.KotlinJsGradleModuleConfigurator"/>
<gradleModelFacade implementation="org.jetbrains.kotlin.idea.inspections.gradle.DefaultGradleModelFacade"/>
<scriptDefinitionContributor implementation="org.jetbrains.kotlin.idea.core.script.GradleScriptDefinitionsContributor" order="first"/>
<scriptAdditionalIdeaDependenciesProvider implementation="org.jetbrains.kotlin.idea.core.script.GradleScriptAdditionalIdeaDependenciesProvider"/>
<moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleWebMultiplatformModuleBuilder"/>
<buildSystemTypeDetector implementation="org.jetbrains.kotlin.idea.configuration.GradleDetector"/>
</extensions>
</idea-plugin>
-192
View File
@@ -1,192 +0,0 @@
<idea-plugin>
<extensionPoints>
<extensionPoint qualifiedName="org.jetbrains.kotlin.platformGradleDetector"
interface="org.jetbrains.kotlin.idea.inspections.gradle.KotlinPlatformGradleDetector"/>
</extensionPoints>
<application-components>
<component>
<implementation-class>org.jetbrains.kotlin.idea.JvmPluginStartupComponent</implementation-class>
</component>
</application-components>
<project-components>
<component>
<implementation-class>org.jetbrains.kotlin.idea.compiler.KotlinCompilerManager</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerComponent</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.kotlin.idea.scratch.ui.ScratchFileHook</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.kotlin.idea.scratch.ScratchFileModuleInfoProvider</implementation-class>
</component>
</project-components>
<actions>
<!-- Kotlin Console REPL-->
<action id="KotlinConsoleREPL" class="org.jetbrains.kotlin.console.actions.RunKotlinConsoleAction"
text="Kotlin REPL"
icon="/org/jetbrains/kotlin/idea/icons/kotlin_launch_configuration.png">
<add-to-group group-id="KotlinToolsGroup" anchor="last"/>
</action>
<action id="ConfigureKotlinInProject" class="org.jetbrains.kotlin.idea.actions.ConfigureKotlinJavaInProjectAction"
text="Configure Kotlin in Project">
<add-to-group group-id="KotlinToolsGroup"/>
</action>
<action id="ConfigureKotlinJsInProject" class="org.jetbrains.kotlin.idea.actions.ConfigureKotlinJsInProjectAction"
text="Configure Kotlin (JavaScript) in Project">
<add-to-group group-id="KotlinToolsGroup"/>
</action>
<action id="ShowKotlinBytecode" class="org.jetbrains.kotlin.idea.actions.ShowKotlinBytecodeAction"
text="Show Kotlin Bytecode">
<add-to-group group-id="KotlinToolsGroup"/>
</action>
<action id="CreateIncrementalCompilationBackup"
class="org.jetbrains.kotlin.idea.internal.makeBackup.CreateIncrementalCompilationBackup" internal="true">
<add-to-group group-id="KotlinInternalGroup"/>
</action>
<action id="ReactivePostOpenProjectActionsAction" class="org.jetbrains.kotlin.idea.actions.internal.ReactivePostOpenProjectActionsAction"
text="Kotlin Project Post-Open Activity" internal="true">
<add-to-group group-id="KotlinInternalGroup"/>
</action>
<action id="AddToProblemApiInspection" class="org.jetbrains.kotlin.idea.inspections.api.AddIncompatibleApiAction"
text="Report as incompatible API">
</action>
<group id="Kotlin.XDebugger.Actions">
<action id="Kotlin.XDebugger.ToggleKotlinVariableView"
class="org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesView"
icon="/org/jetbrains/kotlin/idea/icons/kotlin.png"/>
</group>
<group id="Kotlin.XDebugger.Watches.Tree.Toolbar">
<reference ref="Kotlin.XDebugger.ToggleKotlinVariableView"/>
<add-to-group group-id="XDebugger.Watches.Tree.Toolbar" relative-to-action="XDebugger.SwitchWatchesInVariables" anchor="after"/>
</group>
</actions>
<extensions defaultExtensionNs="com.intellij">
<projectService serviceInterface="org.jetbrains.kotlin.console.KotlinConsoleKeeper"
serviceImplementation="org.jetbrains.kotlin.console.KotlinConsoleKeeper"/>
<buildProcess.parametersProvider implementation="org.jetbrains.kotlin.idea.compiler.configuration.KotlinBuildProcessParametersProvider"/>
<projectService serviceInterface="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches"
serviceImplementation="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches"/>
<projectService serviceInterface="org.jetbrains.kotlin.idea.scratch.ScratchFileAutoRunner"
serviceImplementation="org.jetbrains.kotlin.idea.scratch.ScratchFileAutoRunner"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.versions.SuppressNotificationState"/>
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesState"/>
<debugger.jvmSmartStepIntoHandler implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSmartStepIntoHandler"/>
<debugger.positionManagerFactory implementation="org.jetbrains.kotlin.idea.debugger.KotlinPositionManagerFactory"/>
<debugger.codeFragmentFactory implementation="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory"/>
<debuggerEditorTextProvider language="kotlin" implementationClass="org.jetbrains.kotlin.idea.debugger.KotlinEditorTextProvider"/>
<debuggerClassFilterProvider implementation="org.jetbrains.kotlin.idea.debugger.filter.KotlinDebuggerInternalClassesFilterProvider"/>
<debugger.nodeRenderer implementation="org.jetbrains.kotlin.idea.debugger.render.KotlinClassWithDelegatedPropertyRenderer"/>
<debugger.sourcePositionProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinSourcePositionProvider"/>
<debugger.sourcePositionHighlighter implementation="org.jetbrains.kotlin.idea.debugger.KotlinSourcePositionHighlighter"/>
<debugger.frameExtraVarsProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinFrameExtraVariablesProvider"/>
<debugger.extraSteppingFilter implementation="org.jetbrains.kotlin.idea.KotlinExtraSteppingFilter"/>
<xdebugger.settings implementation="org.jetbrains.kotlin.idea.debugger.KotlinDebuggerSettings"/>
<xdebugger.breakpointType implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpointType"/>
<xdebugger.breakpointType implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinLineBreakpointType" order="first"/>
<debugger.syntheticProvider implementation="org.jetbrains.kotlin.idea.debugger.filter.KotlinSyntheticTypeComponentProvider"/>
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpointHandlerFactory"/>
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinLineBreakpointHandlerFactory"/>
<debugger.jvmSteppingCommandProvider implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSteppingCommandProvider"/>
<debugger.simplePropertyGetterProvider implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSimpleGetterProvider"/>
<framework.type implementation="org.jetbrains.kotlin.idea.framework.JavaFrameworkType"/>
<projectTemplatesFactory implementation="org.jetbrains.kotlin.idea.framework.KotlinTemplatesFactory" />
<library.presentationProvider implementation="org.jetbrains.kotlin.idea.framework.JavaRuntimePresentationProvider"/>
<configurationType implementation="org.jetbrains.kotlin.idea.run.KotlinRunConfigurationType"/>
<configurationType implementation="org.jetbrains.kotlin.idea.run.script.standalone.KotlinStandaloneScriptRunConfigurationType"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinRunConfigurationProducer"/>
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.script.standalone.KotlinStandaloneScriptRunConfigurationProducer"/>
<library.type implementation="org.jetbrains.kotlin.idea.framework.JSLibraryType"/>
<library.javaSourceRootDetector implementation="org.jetbrains.kotlin.idea.configuration.KotlinSourceRootDetector"/>
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.configuration.KotlinSetupEnvironmentNotificationProvider"/>
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinAlternativeSourceNotificationProvider"/>
<consoleFilterProvider implementation="org.jetbrains.kotlin.idea.run.KotlinConsoleFilterProvider"/>
<exceptionFilter implementation="org.jetbrains.kotlin.idea.filters.KotlinExceptionFilterFactory" order="first"/>
<externalSystemTaskNotificationListener implementation="org.jetbrains.kotlin.idea.configuration.KotlinExternalSystemSyncListener"/>
<lang.surroundDescriptor language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.debugger.surroundWith.KotlinDebuggerExpressionSurroundDescriptor"/>
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.versions.UnsupportedAbiVersionNotificationPanelProvider"/>
<localInspection
groupName="Plugin DevKit"
shortName="IncompatibleAPI"
enabledByDefault="false"
level="ERROR"
displayName="Incompatible API usage"
implementationClass="org.jetbrains.kotlin.idea.inspections.api.IncompatibleAPIInspection"/>
<projectService serviceInterface="org.jetbrains.uast.kotlin.KotlinUastResolveProviderService"
serviceImplementation="org.jetbrains.uast.kotlin.internal.IdeaKotlinUastResolveProviderService"/>
<applicationService
serviceInterface="org.jetbrains.kotlin.platform.DefaultIdeTargetPlatformKindProvider"
serviceImplementation="org.jetbrains.kotlin.platform.impl.IdeaDefaultIdeTargetPlatformKindProvider"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.uast">
<uastLanguagePlugin implementation="org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<diagnosticSuppressor implementation="org.jetbrains.kotlin.idea.debugger.DiagnosticSuppressorForDebugger"/>
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.samWithReceiver.ide.IdeSamWithReceiverComponentContributor"/>
<declarationAttributeAltererExtension implementation="org.jetbrains.kotlin.allopen.ide.IdeAllOpenDeclarationAttributeAltererExtension"/>
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.noarg.ide.IdeNoArgComponentContainerContributor"/>
<expressionCodegenExtension implementation="org.jetbrains.kotlin.noarg.NoArgExpressionCodegenExtension"/>
<defaultErrorMessages implementation="org.jetbrains.kotlin.noarg.diagnostic.DefaultErrorMessagesNoArg"/>
<completionExtension implementation="org.jetbrains.kotlin.idea.properties.PropertyKeyCompletion"/>
<newFileHook implementation="org.jetbrains.kotlin.idea.configuration.NewKotlinFileConfigurationHook"/>
<quickFixContributor implementation="org.jetbrains.kotlin.idea.quickfix.JvmQuickFixRegistrar"/>
<clearBuildState implementation="org.jetbrains.kotlin.idea.compiler.configuration.ClearBuildManagerState"/>
<facetValidatorCreator implementation="org.jetbrains.kotlin.idea.facet.KotlinLibraryValidatorCreator"/>
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleJavaFrameworkSupportProvider" />
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJavaFrameworkSupportProvider" />
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJSFrameworkSupportProvider" />
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleGroovyFrameworkSupportProvider" />
<idePlatformKind implementation="org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind"/>
<idePlatformKind implementation="org.jetbrains.kotlin.platform.impl.JsIdePlatformKind"/>
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JvmIdePlatformKindTooling"/>
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JsIdePlatformKindTooling"/>
<syntheticScopeProviderExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldSyntheticScopeProvider"/>
<expressionCodegenExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldExpressionCodegenExtension"/>
<completionInformationProvider implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldCompletionInformationProvider" />
<kotlinIndicesHelperExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldKotlinIndicesHelperExtension"/>
</extensions>
</idea-plugin>
-74
View File
@@ -1,74 +0,0 @@
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude" version="2" url="http://kotlinlang.org" allow-bundled-update="true">
<id>org.jetbrains.kotlin</id>
<name>Kotlin</name>
<description><![CDATA[
The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<br>
<a href="http://kotlinlang.org/docs/tutorials/getting-started.html">Getting Started in IntelliJ IDEA</a><br>
<a href="http://kotlinlang.org/docs/tutorials/kotlin-android.html">Getting Started in Android Studio</a><br>
<a href="http://slack.kotlinlang.org/">Public Slack</a><br>
<a href="https://youtrack.jetbrains.com/issues/KT">Issue tracker</a><br>
]]></description>
<version>@snapshot@</version>
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
<idea-version since-build="181.3" until-build="181.*"/>
<depends>com.intellij.modules.platform</depends>
<depends>com.intellij.modules.remoteServers</depends>
<!-- required for Kotlin/Native plugin -->
<depends optional="true">org.jetbrains.kotlin.native.platform.deps</depends>
<depends optional="true" config-file="junit.xml">JUnit</depends>
<depends optional="true" config-file="gradle.xml">org.jetbrains.plugins.gradle</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>
<depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
<depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
<depends>com.intellij.modules.java</depends>
<depends optional="true" config-file="javaScriptDebug.xml">JavaScriptDebugger</depends>
<depends optional="true" config-file="kotlin-copyright.xml">com.intellij.copyright</depends>
<depends optional="true" config-file="injection.xml">org.intellij.intelliLang</depends>
<!-- CIDR-PLUGIN-PLACEHOLDER-END -->
<xi:include href="plugin-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
<!-- CIDR-PLUGIN-EXCLUDE-START -->
<xi:include href="jvm.xml" xpointer="xpointer(/idea-plugin/*)"/>
<!-- CIDR-PLUGIN-EXCLUDE-END -->
<xi:include href="tipsAndTricks.xml" xpointer="xpointer(/idea-plugin/*)"/>
<xi:include href="extensions/ide.xml" xpointer="xpointer(/idea-plugin/*)"/>
<project-components>
<component>
<!-- This is a workaround for IDEA < 183. For details, see IDEA-200525. -->
<implementation-class>org.jetbrains.kotlin.idea.caches.ProjectRootModificationTrackerFixer</implementation-class>
</component>
</project-components>
<extensionPoints>
<xi:include href="extensions/compiler.xml" xpointer="xpointer(/idea-plugin/extensionPoints/*)"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.pluginUpdateVerifier"
interface="org.jetbrains.kotlin.idea.update.PluginUpdateVerifier"/>
</extensionPoints>
<xi:include href="plugin-kotlin-extensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
<extensions defaultExtensionNs="com.intellij">
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"
serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/>
</extensions>
</idea-plugin>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 714 B

@@ -1,243 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.actions
import com.intellij.codeInsight.navigation.NavigationUtil
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.ide.scratch.ScratchFileService
import com.intellij.ide.scratch.ScratchRootType
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.MessageType
import com.intellij.openapi.ui.Messages
import com.intellij.openapi.ui.ex.MessagesEx
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileVisitor
import com.intellij.openapi.wm.WindowManager
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiErrorElement
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiManager
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
import org.jetbrains.kotlin.idea.j2k.JavaToKotlinConverterFactory
import org.jetbrains.kotlin.idea.refactoring.toPsiFile
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.idea.util.application.progressIndicatorNullable
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.j2k.ConverterSettings
import org.jetbrains.kotlin.j2k.FilesResult
import org.jetbrains.kotlin.psi.KtFile
import java.io.File
import java.io.IOException
import java.util.*
class JavaToKotlinAction : AnAction() {
companion object {
private fun uniqueKotlinFileName(javaFile: VirtualFile): String {
val ioFile = File(javaFile.path.replace('/', File.separatorChar))
var i = 0
while (true) {
val fileName = javaFile.nameWithoutExtension + (if (i > 0) i else "") + ".kt"
if (!ioFile.resolveSibling(fileName).exists()) return fileName
i++
}
}
val title = "Convert Java to Kotlin"
private fun saveResults(javaFiles: List<PsiJavaFile>, convertedTexts: List<String>): List<VirtualFile> {
val result = ArrayList<VirtualFile>()
for ((psiFile, text) in javaFiles.zip(convertedTexts)) {
try {
val document = PsiDocumentManager.getInstance(psiFile.project).getDocument(psiFile)
if (document == null) {
MessagesEx.error(psiFile.project, "Failed to save conversion result: couldn't find document for " + psiFile.name).showLater()
continue
}
document.replaceString(0, document.textLength, text)
FileDocumentManager.getInstance().saveDocument(document)
val virtualFile = psiFile.virtualFile
if (ScratchRootType.getInstance().containsFile(virtualFile)) {
val mapping = ScratchFileService.getInstance().scratchesMapping
mapping.setMapping(virtualFile, KotlinFileType.INSTANCE.language)
}
else {
val fileName = uniqueKotlinFileName(virtualFile)
virtualFile.rename(this, fileName)
}
}
catch (e: IOException) {
MessagesEx.error(psiFile.project, e.message ?: "").showLater()
}
}
return result
}
fun convertFiles(
javaFiles: List<PsiJavaFile>, project: Project,
enableExternalCodeProcessing: Boolean = true,
askExternalCodeProcessing: Boolean = true
): List<KtFile> {
var converterResult: FilesResult? = null
fun convert() {
val converter =
JavaToKotlinConverterFactory.createJavaToKotlinConverter(
project,
ConverterSettings.defaultSettings,
IdeaJavaToKotlinServices
)
converterResult = converter.filesToKotlin(
javaFiles,
JavaToKotlinConverterFactory.createPostProcessor(formatCode = true),
ProgressManager.getInstance().progressIndicatorNullable!!
)
}
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(
::convert,
title,
true,
project)) return emptyList()
var externalCodeUpdate: (() -> Unit)? = null
if (enableExternalCodeProcessing && converterResult!!.externalCodeProcessing != null) {
val question = "Some code in the rest of your project may require corrections after performing this conversion. Do you want to find such code and correct it too?"
if (!askExternalCodeProcessing || (Messages.showYesNoDialog(project, question, title, Messages.getQuestionIcon()) == Messages.YES)) {
ProgressManager.getInstance().runProcessWithProgressSynchronously(
{
runReadAction {
externalCodeUpdate = converterResult!!.externalCodeProcessing!!.prepareWriteOperation(
ProgressManager.getInstance().progressIndicatorNullable!!
)
}
},
title,
true,
project)
}
}
return project.executeWriteCommand("Convert files from Java to Kotlin", null) {
CommandProcessor.getInstance().markCurrentCommandAsGlobal(project)
val newFiles = saveResults(javaFiles, converterResult!!.results)
externalCodeUpdate?.invoke()
PsiDocumentManager.getInstance(project).commitAllDocuments()
newFiles.singleOrNull()?.let {
FileEditorManager.getInstance(project).openFile(it, true)
}
newFiles.map { it.toPsiFile(project) as KtFile }
}
}
}
override fun actionPerformed(e: AnActionEvent) {
val javaFiles = selectedJavaFiles(e).filter { it.isWritable }.toList()
val project = CommonDataKeys.PROJECT.getData(e.dataContext)!!
if (javaFiles.isEmpty()) {
val statusBar = WindowManager.getInstance().getStatusBar(project)
JBPopupFactory.getInstance()
.createHtmlTextBalloonBuilder("Nothing to convert:<br>No writable Java files found", MessageType.ERROR, null)
.createBalloon()
.showInCenterOf(statusBar.component)
}
val firstSyntaxError = javaFiles.asSequence().map { PsiTreeUtil.findChildOfType(it, PsiErrorElement::class.java) }.firstOrNull()
if (firstSyntaxError != null) {
val count = javaFiles.filter { PsiTreeUtil.hasErrorElements(it) }.count()
val question = firstSyntaxError.containingFile.name +
(if (count > 1) " and ${count - 1} more Java files" else " file") +
" contain syntax errors, the conversion result may be incorrect"
val okText = "Investigate Errors"
val cancelText = "Proceed with Conversion"
if (Messages.showOkCancelDialog(
project,
question,
title,
okText,
cancelText,
Messages.getWarningIcon()
) == Messages.OK) {
NavigationUtil.activateFileWithPsiElement(firstSyntaxError.navigationElement)
return
}
}
convertFiles(javaFiles, project)
}
override fun update(e: AnActionEvent) {
val virtualFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) ?: return
val project = e.project ?: return
e.presentation.isEnabled = isAnyJavaFileSelected(project, virtualFiles)
}
private fun isAnyJavaFileSelected(project: Project, files: Array<VirtualFile>): Boolean {
if (files.any { it.isDirectory }) return true // Giving up on directories
val manager = PsiManager.getInstance(project)
return files.any { it.extension == JavaFileType.DEFAULT_EXTENSION && manager.findFile(it) is PsiJavaFile && it.isWritable }
}
private fun selectedJavaFiles(e: AnActionEvent): Sequence<PsiJavaFile> {
val virtualFiles = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) ?: return sequenceOf()
val project = e.project ?: return sequenceOf()
return allJavaFiles(virtualFiles, project)
}
private fun allJavaFiles(filesOrDirs: Array<VirtualFile>, project: Project): Sequence<PsiJavaFile> {
val manager = PsiManager.getInstance(project)
return allFiles(filesOrDirs)
.asSequence()
.mapNotNull { manager.findFile(it) as? PsiJavaFile }
}
private fun allFiles(filesOrDirs: Array<VirtualFile>): Collection<VirtualFile> {
val result = ArrayList<VirtualFile>()
for (file in filesOrDirs) {
VfsUtilCore.visitChildrenRecursively(file, object : VirtualFileVisitor<Unit>() {
override fun visitFile(file: VirtualFile): Boolean {
result.add(file)
return true
}
})
}
return result
}
}
@@ -1,14 +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.inspections
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.codeInsight.intention.QuickFixFactory
import com.intellij.openapi.project.Project
fun createAddToDependencyInjectionAnnotationsFix(project: Project, fqName: String): IntentionAction {
return QuickFixFactory.getInstance().createAddToDependencyInjectionAnnotationsFix(project, fqName, "declarations")
}
@@ -1,59 +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.js
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.CompilerModuleExtension
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.analyzer.common.CommonPlatform
import org.jetbrains.kotlin.idea.caches.project.implementingModules
import org.jetbrains.kotlin.idea.facet.KotlinFacet
import org.jetbrains.kotlin.idea.framework.isGradleModule
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
import org.jetbrains.kotlin.js.resolve.JsPlatform
import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings
val Module.jsTestOutputFilePath: String?
get() {
KotlinFacet.get(this)?.configuration?.settings?.testOutputPath?.let { return it }
if (!shouldUseJpsOutput) return null
val compilerExtension = CompilerModuleExtension.getInstance(this)
val outputDir = compilerExtension?.compilerOutputUrlForTests ?: return null
return JpsPathUtil.urlToPath("$outputDir/${name}_test.js")
}
val Module.jsProductionOutputFilePath: String?
get() {
KotlinFacet.get(this)?.configuration?.settings?.productionOutputPath?.let { return it }
if (!shouldUseJpsOutput) return null
val compilerExtension = CompilerModuleExtension.getInstance(this)
val outputDir = compilerExtension?.compilerOutputUrl ?: return null
return JpsPathUtil.urlToPath("$outputDir/$name.js")
}
fun Module.asJsModule(): Module? = when (TargetPlatformDetector.getPlatform(this)) {
is CommonPlatform -> implementingModules.firstOrNull { TargetPlatformDetector.getPlatform(it) is JsPlatform }
is JsPlatform -> this
else -> null
}
val Module.shouldUseJpsOutput: Boolean
get() = !(isGradleModule() && GradleSystemRunningSettings.getInstance().isUseGradleAwareMake)
@@ -1,67 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.quickfix
import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixActionRegistrarImpl
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import com.intellij.psi.PsiReferenceBase
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference.ShorteningMode
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.idea.util.runWhenSmart
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedElement
import org.jetbrains.kotlin.psi.psiUtil.startOffset
object KotlinAddOrderEntryActionFactory : KotlinIntentionActionsFactory() {
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
val simpleExpression = diagnostic.psiElement as? KtSimpleNameExpression ?: return emptyList()
val refElement = simpleExpression.getQualifiedElement()
val reference = object: PsiReferenceBase<KtElement>(refElement) {
override fun resolve() = null
override fun getVariants() = PsiReference.EMPTY_ARRAY
override fun getRangeInElement(): TextRange? {
val offset = simpleExpression.startOffset - refElement.startOffset
return TextRange(offset, offset + simpleExpression.textLength)
}
override fun getCanonicalText() = refElement.text
override fun bindToElement(element: PsiElement): PsiElement {
val project = element.project
project.runWhenSmart {
project.executeWriteCommand("") {
simpleExpression.mainReference.bindToElement(element, ShorteningMode.FORCED_SHORTENING)
}
}
return element
}
}
@Suppress("UNCHECKED_CAST")
return OrderEntryFix.registerFixes(QuickFixActionRegistrarImpl(null), reference) as List<IntentionAction>? ?: emptyList()
}
}
@@ -1,410 +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.quickfix.crossLanguage
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.codeInsight.intention.QuickFixFactory
import com.intellij.lang.jvm.JvmClass
import com.intellij.lang.jvm.JvmElement
import com.intellij.lang.jvm.JvmModifier
import com.intellij.lang.jvm.JvmModifiersOwner
import com.intellij.lang.jvm.actions.*
import com.intellij.openapi.project.Project
import com.intellij.psi.*
import com.intellij.psi.codeStyle.SuggestedNameInfo
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
import org.jetbrains.kotlin.asJava.toLightMethods
import org.jetbrains.kotlin.asJava.unwrapped
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.appendModifier
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.CreateCallableFromUsageFix
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.load.java.components.TypeUsage
import org.jetbrains.kotlin.load.java.lazy.JavaResolverComponents
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.TypeParameterResolver
import org.jetbrains.kotlin.load.java.lazy.child
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeAttributes
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeImpl
import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeParameterImpl
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.typeUtil.supertypes
class KotlinElementActionsFactory : JvmElementActionsFactory() {
companion object {
val javaPsiModifiersMapping = mapOf(
JvmModifier.PRIVATE to KtTokens.PRIVATE_KEYWORD,
JvmModifier.PUBLIC to KtTokens.PUBLIC_KEYWORD,
JvmModifier.PROTECTED to KtTokens.PUBLIC_KEYWORD,
JvmModifier.ABSTRACT to KtTokens.ABSTRACT_KEYWORD
)
}
private class FakeExpressionFromParameter(private val psiParam: PsiParameter) : PsiReferenceExpressionImpl() {
override fun getText(): String = psiParam.name!!
override fun getProject(): Project = psiParam.project
override fun getParent(): PsiElement = psiParam.parent
override fun getType(): PsiType? = psiParam.type
override fun isValid(): Boolean = true
override fun getContainingFile(): PsiFile = psiParam.containingFile
override fun getReferenceName(): String? = psiParam.name
override fun resolve(): PsiElement? = psiParam
}
private class ModifierBuilder(
private val targetContainer: KtElement,
private val allowJvmStatic: Boolean = true
) {
private val psiFactory = KtPsiFactory(targetContainer.project)
val modifierList = psiFactory.createEmptyModifierList()
private fun JvmModifier.transformAndAppend(): Boolean {
javaPsiModifiersMapping[this]?.let {
modifierList.appendModifier(it)
return true
}
when (this) {
JvmModifier.STATIC -> {
if (allowJvmStatic && targetContainer is KtClassOrObject) {
addAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME)
}
}
JvmModifier.ABSTRACT -> modifierList.appendModifier(KtTokens.ABSTRACT_KEYWORD)
JvmModifier.FINAL -> modifierList.appendModifier(KtTokens.FINAL_KEYWORD)
else -> return false
}
return true
}
var isValid = true
private set
fun addJvmModifier(modifier: JvmModifier) {
isValid = isValid && modifier.transformAndAppend()
}
fun addJvmModifiers(modifiers: Iterable<JvmModifier>) {
modifiers.forEach { addJvmModifier(it) }
}
fun addAnnotation(fqName: FqName) {
if (!isValid) return
modifierList.add(psiFactory.createAnnotationEntry("@${fqName.asString()}"))
}
}
class CreatePropertyFix(
private val targetClass: JvmClass,
contextElement: KtElement,
propertyInfo: PropertyInfo
) : CreateCallableFromUsageFix<KtElement>(contextElement, listOf(propertyInfo)) {
override fun getFamilyName() = "Add property"
override fun getText(): String {
val info = callableInfos.first() as PropertyInfo
return buildString {
append("Add '")
if (info.isLateinitPreferred) {
append("lateinit ")
}
append(if (info.writable) "var" else "val")
append("' property '${info.name}' to '${targetClass.name}'")
}
}
}
private fun JvmClass.toKtClassOrFile(): KtElement? {
val psi = sourceElement
return when (psi) {
is KtClassOrObject -> psi
is KtLightClassForSourceDeclaration -> psi.kotlinOrigin
is KtLightClassForFacade -> psi.files.firstOrNull()
else -> null
}
}
private inline fun <reified T : KtElement> JvmElement.toKtElement() = sourceElement?.unwrapped as? T
private fun fakeParametersExpressions(parameters: List<Pair<SuggestedNameInfo, List<ExpectedType>>>, project: Project): Array<PsiExpression>? =
when {
parameters.isEmpty() -> emptyArray()
else -> JavaPsiFacade
.getElementFactory(project)
.createParameterList(
parameters.map { it.first.names.firstOrNull() }.toTypedArray(),
parameters.map { JvmPsiConversionHelper.getInstance(project).asPsiType(it) ?: return null }.toTypedArray()
)
.parameters
.map(::FakeExpressionFromParameter)
.toTypedArray()
}
private fun PsiType.collectTypeParameters(): List<PsiTypeParameter> {
val results = ArrayList<PsiTypeParameter>()
accept(
object : PsiTypeVisitor<Unit>() {
override fun visitArrayType(arrayType: PsiArrayType) {
arrayType.componentType.accept(this)
}
override fun visitClassType(classType: PsiClassType) {
(classType.resolve() as? PsiTypeParameter)?.let { results += it }
classType.parameters.forEach { it.accept(this) }
}
override fun visitWildcardType(wildcardType: PsiWildcardType) {
wildcardType.bound?.accept(this)
}
}
)
return results
}
private fun PsiType.resolveToKotlinType(resolutionFacade: ResolutionFacade): KotlinType? {
val typeParameters = collectTypeParameters()
val components = resolutionFacade.getFrontendService(JavaResolverComponents::class.java)
val rootContext = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY) { null }
val dummyPackageDescriptor = MutablePackageFragmentDescriptor(resolutionFacade.moduleDescriptor, FqName("dummy"))
val dummyClassDescriptor = ClassDescriptorImpl(
dummyPackageDescriptor,
Name.identifier("Dummy"),
Modality.FINAL,
ClassKind.CLASS,
emptyList(),
SourceElement.NO_SOURCE,
false,
LockBasedStorageManager.NO_LOCKS
)
val typeParameterResolver = object : TypeParameterResolver {
override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? {
val psiTypeParameter = (javaTypeParameter as JavaTypeParameterImpl).psi
val index = typeParameters.indexOf(psiTypeParameter)
if (index < 0) return null
return LazyJavaTypeParameterDescriptor(rootContext.child(this), javaTypeParameter, index, dummyClassDescriptor)
}
}
val typeResolver = JavaTypeResolver(rootContext, typeParameterResolver)
val attributes = JavaTypeAttributes(TypeUsage.COMMON)
return typeResolver.transformJavaType(JavaTypeImpl.create(this), attributes).approximateFlexibleTypes(preferNotNull = true)
}
private fun ExpectedTypes.toKotlinTypeInfo(resolutionFacade: ResolutionFacade): TypeInfo {
val candidateTypes = flatMapTo(LinkedHashSet<KotlinType>()) {
val ktType = (it.theType as? PsiType)?.resolveToKotlinType(resolutionFacade) ?: return@flatMapTo emptyList()
when (it.theKind) {
ExpectedType.Kind.EXACT, ExpectedType.Kind.SUBTYPE -> listOf(ktType)
ExpectedType.Kind.SUPERTYPE -> listOf(ktType) + ktType.supertypes()
}
}
if (candidateTypes.isEmpty()) {
val nullableAnyType = resolutionFacade.moduleDescriptor.builtIns.nullableAnyType
return TypeInfo(nullableAnyType, Variance.INVARIANT)
}
return TypeInfo.ByExplicitCandidateTypes(candidateTypes.toList())
}
override fun createChangeModifierActions(target: JvmModifiersOwner, request: MemberRequest.Modifier): List<IntentionAction> {
val kModifierOwner = target.toKtElement<KtModifierListOwner>() ?: return emptyList()
val modifier = request.modifier
val shouldPresent = request.shouldPresent
//TODO: make similar to `createAddMethodActions`
val (kToken, shouldPresentMapped) = when {
modifier == JvmModifier.FINAL -> KtTokens.OPEN_KEYWORD to !shouldPresent
modifier == JvmModifier.PUBLIC && shouldPresent ->
kModifierOwner.visibilityModifierType()
?.takeIf { it != KtTokens.DEFAULT_VISIBILITY_KEYWORD }
?.let { it to false } ?: return emptyList()
else -> javaPsiModifiersMapping[modifier] to shouldPresent
}
if (kToken == null) return emptyList()
val action = if (shouldPresentMapped)
AddModifierFix.createIfApplicable(kModifierOwner, kToken)
else
RemoveModifierFix(kModifierOwner, kToken, false)
return listOfNotNull(action)
}
override fun createAddConstructorActions(targetClass: JvmClass, request: CreateConstructorRequest): List<IntentionAction> {
val targetKtClass = targetClass.toKtClassOrFile() as? KtClass ?: return emptyList()
val modifierBuilder = ModifierBuilder(targetKtClass).apply { addJvmModifiers(request.modifiers) }
if (!modifierBuilder.isValid) return emptyList()
val resolutionFacade = targetKtClass.getResolutionFacade()
val nullableAnyType = resolutionFacade.moduleDescriptor.builtIns.nullableAnyType
val helper = JvmPsiConversionHelper.getInstance(targetKtClass.project)
val parameters = request.parameters as List<Pair<SuggestedNameInfo, List<ExpectedType>>>
val parameterInfos = parameters.mapIndexed { index, param: Pair<SuggestedNameInfo, List<ExpectedType>> ->
val ktType = helper.asPsiType(param)?.resolveToKotlinType(resolutionFacade) ?: nullableAnyType
val name = param.first.names.firstOrNull() ?: "arg${index + 1}"
ParameterInfo(TypeInfo(ktType, Variance.IN_VARIANCE), listOf(name))
}
val needPrimary = !targetKtClass.hasExplicitPrimaryConstructor()
val constructorInfo = ConstructorInfo(
parameterInfos,
targetKtClass,
isPrimary = needPrimary,
modifierList = modifierBuilder.modifierList,
withBody = true
)
val targetClassName = targetClass.name
val addConstructorAction = object : CreateCallableFromUsageFix<KtElement>(targetKtClass, listOf(constructorInfo)) {
override fun getFamilyName() = "Add method"
override fun getText() = "Add ${if (needPrimary) "primary" else "secondary"} constructor to '$targetClassName'"
}
val changePrimaryConstructorAction = run {
val primaryConstructor = targetKtClass.primaryConstructor ?: return@run null
val lightMethod = primaryConstructor.toLightMethods().firstOrNull() ?: return@run null
val project = targetKtClass.project
val fakeParametersExpressions = fakeParametersExpressions(parameters, project) ?: return@run null
QuickFixFactory.getInstance()
.createChangeMethodSignatureFromUsageFix(
lightMethod,
fakeParametersExpressions,
PsiSubstitutor.EMPTY,
targetKtClass,
false,
2
).takeIf { it.isAvailable(project, null, targetKtClass.containingFile) }
}
return listOfNotNull(changePrimaryConstructorAction, addConstructorAction)
}
override fun createAddPropertyActions(targetClass: JvmClass, request: MemberRequest.Property): List<IntentionAction> {
val targetContainer = targetClass.toKtClassOrFile() ?: return emptyList()
val modifierBuilder = ModifierBuilder(targetContainer).apply { addJvmModifier(request.visibilityModifier) }
if (!modifierBuilder.isValid) return emptyList()
val resolutionFacade = targetContainer.getResolutionFacade()
val nullableAnyType = resolutionFacade.moduleDescriptor.builtIns.nullableAnyType
val ktType = (request.propertyType as? PsiType)?.resolveToKotlinType(resolutionFacade) ?: nullableAnyType
val propertyInfo = PropertyInfo(
request.propertyName,
TypeInfo.Empty,
TypeInfo(ktType, Variance.INVARIANT),
request.setterRequired,
listOf(targetContainer),
modifierList = modifierBuilder.modifierList,
withInitializer = true
)
val propertyInfos = if (request.setterRequired) {
listOf(propertyInfo, propertyInfo.copyProperty(isLateinitPreferred = true))
}
else {
listOf(propertyInfo)
}
return propertyInfos.map { CreatePropertyFix(targetClass, targetContainer, it) }
}
override fun createAddFieldActions(targetClass: JvmClass, request: CreateFieldRequest): List<IntentionAction> {
val targetContainer = targetClass.toKtClassOrFile() ?: return emptyList()
val modifierBuilder = ModifierBuilder(targetContainer, allowJvmStatic = false).apply {
addJvmModifiers(request.modifiers)
addAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME)
}
if (!modifierBuilder.isValid) return emptyList()
val resolutionFacade = targetContainer.getResolutionFacade()
val typeInfo = request.fieldType.toKotlinTypeInfo(resolutionFacade)
val writable = JvmModifier.FINAL !in request.modifiers
val propertyInfo = PropertyInfo(
request.fieldName,
TypeInfo.Empty,
typeInfo,
writable,
listOf(targetContainer),
isForCompanion = JvmModifier.STATIC in request.modifiers,
modifierList = modifierBuilder.modifierList,
withInitializer = true
)
val propertyInfos = if (writable) {
listOf(propertyInfo, propertyInfo.copyProperty(isLateinitPreferred = true))
}
else {
listOf(propertyInfo)
}
return propertyInfos.map { CreatePropertyFix(targetClass, targetContainer, it) }
}
override fun createAddMethodActions(targetClass: JvmClass, request: CreateMethodRequest): List<IntentionAction> {
val targetContainer = targetClass.toKtClassOrFile() ?: return emptyList()
val modifierBuilder = ModifierBuilder(targetContainer).apply { addJvmModifiers(request.modifiers) }
if (!modifierBuilder.isValid) return emptyList()
val resolutionFacade = KotlinCacheService.getInstance(targetContainer.project)
.getResolutionFacadeByFile(targetContainer.containingFile, JvmPlatform) ?: return emptyList()
val returnTypeInfo = request.returnType.toKotlinTypeInfo(resolutionFacade)
val parameters = request.parameters as List<Pair<SuggestedNameInfo, List<ExpectedType>>>
val parameterInfos = parameters.map { (suggestedNames, expectedTypes) ->
ParameterInfo(expectedTypes.toKotlinTypeInfo(resolutionFacade), suggestedNames.names.toList())
}
val methodName = request.methodName
val functionInfo = FunctionInfo(
methodName,
TypeInfo.Empty,
returnTypeInfo,
listOf(targetContainer),
parameterInfos,
isForCompanion = JvmModifier.STATIC in request.modifiers,
modifierList = modifierBuilder.modifierList,
preferEmptyBody = true
)
val targetClassName = targetClass.name
val action = object : CreateCallableFromUsageFix<KtElement>(targetContainer, listOf(functionInfo)) {
override fun getFamilyName() = "Add method"
override fun getText() = "Add method '$methodName' to '$targetClassName'"
}
return listOf(action)
}
}
private fun JvmPsiConversionHelper.asPsiType(param: Pair<SuggestedNameInfo, List<ExpectedType>>): PsiType? =
param.second.firstOrNull()?.theType?.let { convertType(it) }
@@ -1,55 +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.refactoring.rename
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.extensions.ExtensionPointName
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.refactoring.rename.RenameHandler
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
import java.util.*
class KotlinRenameDispatcherHandler : RenameHandler {
companion object {
val EP_NAME = ExtensionPointName<RenameHandler>("org.jetbrains.kotlin.renameHandler")
private val handlers: Array<out RenameHandler> get() = Extensions.getExtensions(EP_NAME)
}
internal fun getRenameHandler(dataContext: DataContext?): RenameHandler? {
val availableHandlers = handlers.filterTo(LinkedHashSet()) { it.isRenaming(dataContext) }
availableHandlers.singleOrNull()?.let { return it }
availableHandlers.firstIsInstanceOrNull<KotlinMemberInplaceRenameHandler>()?.let { availableHandlers -= it }
return availableHandlers.firstOrNull()
}
override fun isAvailableOnDataContext(dataContext: DataContext?) = handlers.any { it.isAvailableOnDataContext(dataContext) }
override fun isRenaming(dataContext: DataContext?) = isAvailableOnDataContext(dataContext)
override fun invoke(project: Project, editor: Editor?, file: PsiFile?, dataContext: DataContext?) {
getRenameHandler(dataContext)?.invoke(project, editor, file, dataContext)
}
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext?) {
getRenameHandler(dataContext)?.invoke(project, elements, dataContext)
}
}
@@ -1,71 +0,0 @@
/*
* Copyright 2000-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.refactoring.rename
import com.intellij.openapi.editor.Editor
import com.intellij.psi.*
import com.intellij.refactoring.RefactoringActionHandler
import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler
import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer
import org.jetbrains.kotlin.idea.core.unquote
import org.jetbrains.kotlin.psi.*
open class KotlinVariableInplaceRenameHandler : VariableInplaceRenameHandler() {
companion object {
fun isInplaceRenameAvailable(element: PsiElement): Boolean {
when (element) {
is KtTypeParameter -> return true
is KtDestructuringDeclarationEntry -> return true
is KtParameter -> {
val parent = element.parent
if (parent is KtForExpression) {
return true
}
if (parent is KtParameterList) {
val grandparent = parent.parent
return grandparent is KtCatchClause || grandparent is KtFunctionLiteral
}
}
is KtLabeledExpression, is KtImportAlias -> return true
}
return false
}
}
protected open class RenamerImpl : VariableInplaceRenamer {
constructor(elementToRename: PsiNamedElement, editor: Editor): super(elementToRename, editor)
constructor(
elementToRename: PsiNamedElement,
editor: Editor,
currentName: String,
oldName: String
) : super(elementToRename, editor, editor.project, currentName, oldName)
override fun acceptReference(reference: PsiReference): Boolean {
val refElement = reference.element
val textRange = reference.rangeInElement
val referenceText = refElement.text.substring(textRange.startOffset, textRange.endOffset).unquote()
return referenceText == myElementToRename.name
}
override fun startsOnTheSameElement(handler: RefactoringActionHandler?, element: PsiElement?): Boolean {
return variable == element && (handler is VariableInplaceRenameHandler || handler is KotlinRenameDispatcherHandler)
}
override fun createInplaceRenamerToRestart(variable: PsiNamedElement, editor: Editor, initialName: String): VariableInplaceRenamer {
return RenamerImpl(variable, editor, initialName, myOldName)
}
}
override fun createRenamer(elementToRename: PsiElement, editor: Editor): VariableInplaceRenamer? {
val currentElementToRename = elementToRename as PsiNameIdentifierOwner
val currentName = currentElementToRename.nameIdentifier?.text ?: ""
return RenamerImpl(currentElementToRename, editor, currentName, currentName)
}
override public fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile) =
editor.settings.isVariableInplaceRenameEnabled && element != null && isInplaceRenameAvailable(element)
}
@@ -1,45 +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.refactoring.rename
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
class RenameBackingFieldReferenceHandler: KotlinVariableInplaceRenameHandler() {
override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean {
val refExpression = file.findElementForRename<KtSimpleNameExpression>(editor.caretModel.offset) ?: return false
if (refExpression.text != "field") return false
return refExpression.resolveToCall()?.resultingDescriptor is SyntheticFieldDescriptor
}
override fun invoke(project: Project, editor: Editor?, file: PsiFile?, dataContext: DataContext) {
editor?.let {
CodeInsightUtils.showErrorHint(project, editor, "Rename is not applicable to backing field reference", "Rename", null)
}
}
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext) {
// Do nothing: this method is called not from editor
}
}
@@ -1,49 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.refactoring.rename
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
class RenameDynamicMemberHandler: KotlinVariableInplaceRenameHandler() {
override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean {
val callee = PsiTreeUtil.findElementOfClassAtOffset(
file, editor.caretModel.offset, KtSimpleNameExpression::class.java, false
) ?: return false
val calleeDescriptor = callee.resolveToCall()?.resultingDescriptor ?: return false
return calleeDescriptor.isDynamic()
}
override fun invoke(project: Project, editor: Editor?, file: PsiFile?, dataContext: DataContext) {
super.invoke(project, editor, file, dataContext)
editor?.let {
CodeInsightUtils.showErrorHint(project, editor, "Rename is not applicable to dynamically invoked members", "Rename", null)
}
}
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext) {
// Do nothing: this method is called not from editor
}
}
@@ -1,48 +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.refactoring.rename
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.intentions.ReplaceItWithExplicitFunctionLiteralParamIntention
import org.jetbrains.kotlin.idea.intentions.isAutoCreatedItUsage
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
class RenameKotlinImplicitLambdaParameter : KotlinVariableInplaceRenameHandler() {
override fun isAvailable(element: PsiElement?, editor: Editor, file: PsiFile): Boolean {
val nameExpression = file.findElementForRename<KtNameReferenceExpression>(editor.caretModel.offset)
return nameExpression != null && isAutoCreatedItUsage(nameExpression)
}
override fun invoke(project: Project, editor: Editor?, file: PsiFile?, dataContext: DataContext) {
val intention = ReplaceItWithExplicitFunctionLiteralParamIntention()
project.executeWriteCommand("Convert 'it' to explicit lambda parameter") {
file?.let {
intention.invoke(project, editor, file)
}
}
}
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext) {
// Do nothing: this method is called not from editor
}
}
@@ -1,54 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.refactoring.rename
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.refactoring.rename.RenameHandler
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
import org.jetbrains.kotlin.psi.*
class RenameOnSecondaryConstructorHandler : RenameHandler {
override fun isAvailableOnDataContext(dataContext: DataContext?): Boolean {
if (dataContext == null) return false
val editor = CommonDataKeys.EDITOR.getData(dataContext) ?: return false
val file = CommonDataKeys.PSI_FILE.getData(dataContext) ?: return false
val element = PsiTreeUtil.findElementOfClassAtOffsetWithStopSet(
file, editor.caretModel.offset, KtSecondaryConstructor::class.java, false,
KtBlockExpression::class.java, KtValueArgumentList::class.java, KtParameterList::class.java, KtConstructorDelegationCall::class.java
)
return element != null
}
override fun isRenaming(dataContext: DataContext?): Boolean = isAvailableOnDataContext(dataContext)
override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) {
CodeInsightUtils.showErrorHint(project, editor, "Rename is not applicable to secondary constructors", "Rename", null)
}
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext?) {
// Do nothing: this method is called not from editor
}
}
@@ -1,41 +0,0 @@
/*
* Copyright 2000-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.refactoring.rename
import org.jetbrains.kotlin.idea.statistics.KotlinStatisticsTrigger
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.refactoring.rename.RenameHandler
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.resolve.calls.tower.isSynthesized
import org.jetbrains.kotlin.idea.statistics.KotlinEventTrigger
class RenameSyntheticDeclarationByReferenceHandler : RenameHandler {
override fun isAvailableOnDataContext(dataContext: DataContext?): Boolean {
if (dataContext == null) return false
val file = CommonDataKeys.PSI_FILE.getData(dataContext) ?: return false
val editor = CommonDataKeys.EDITOR.getData(dataContext) ?: return false
val refExpression = file.findElementForRename<KtSimpleNameExpression>(editor.caretModel.offset) ?: return false
return (refExpression.resolveToCall()?.resultingDescriptor)?.isSynthesized ?: false
}
override fun isRenaming(dataContext: DataContext?) = isAvailableOnDataContext(dataContext)
override fun invoke(project: Project, editor: Editor, file: PsiFile, dataContext: DataContext?) {
CodeInsightUtils.showErrorHint(project, editor, "Rename is not applicable to synthetic declaration", "Rename", null)
KotlinStatisticsTrigger.trigger(KotlinEventTrigger.KotlinIdeRefactoringTrigger, this::class.java.name)
}
override fun invoke(project: Project, elements: Array<out PsiElement>, dataContext: DataContext?) {
// Do nothing: this method is not called from editor
}
}
@@ -1,141 +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.slicer
import com.intellij.analysis.AnalysisScope
import com.intellij.openapi.Disposable
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.wm.ToolWindowId
import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.psi.PsiElement
import com.intellij.slicer.DuplicateMap
import com.intellij.slicer.SliceAnalysisParams
import com.intellij.slicer.SlicePanel
import com.intellij.slicer.SliceRootNode
import com.intellij.usageView.UsageInfo
import com.intellij.usageView.UsageViewBundle
import com.intellij.usages.PsiElementUsageTarget
import com.intellij.usages.UsageContextPanel
import com.intellij.usages.UsageView
import com.intellij.usages.UsageViewPresentation
import com.intellij.usages.impl.UsageContextPanelBase
import com.intellij.usages.impl.UsageViewImpl
import org.jetbrains.kotlin.psi.KtDeclaration
import java.awt.BorderLayout
import javax.swing.JLabel
import javax.swing.JPanel
import javax.swing.SwingConstants
sealed class KotlinUsageContextDataFlowPanelBase(
project: Project,
presentation: UsageViewPresentation,
private val isInflow: Boolean
) : UsageContextPanelBase(project, presentation) {
private var panel: JPanel? = null
abstract class ProviderBase : UsageContextPanel.Provider {
override fun isAvailableFor(usageView: UsageView): Boolean {
val target = (usageView as UsageViewImpl).targets.firstOrNull() ?: return false
val element = (target as? PsiElementUsageTarget)?.element
return element is KtDeclaration && element.isValid
}
}
private fun createParams(element: PsiElement): SliceAnalysisParams {
return SliceAnalysisParams().apply {
scope = AnalysisScope(element.project)
dataFlowToThis = isInflow
showInstanceDereferences = true
}
}
protected fun createPanel(element: PsiElement, dataFlowToThis: Boolean): JPanel {
val toolWindow = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.FIND)
val params = createParams(element)
val rootNode = SliceRootNode(myProject, DuplicateMap(), KotlinSliceUsage(element, params))
return object : SlicePanel(myProject, dataFlowToThis, rootNode, false, toolWindow) {
override fun isToShowAutoScrollButton() = false
override fun isToShowPreviewButton() = false
override fun isToShowCloseButton() = false
override fun isAutoScroll() = false
override fun setAutoScroll(autoScroll: Boolean) {}
override fun isPreview() = false
override fun setPreview(preview: Boolean) {}
}
}
public override fun updateLayoutLater(infos: List<UsageInfo>?) {
if (infos == null) {
removeAll()
val title = UsageViewBundle.message("select.the.usage.to.preview", myPresentation.usagesWord)
add(JLabel(title, SwingConstants.CENTER), BorderLayout.CENTER)
}
else {
val element = infos.firstOrNull()?.element ?: return
if (panel != null) {
Disposer.dispose(panel as Disposable)
}
val panel = createPanel(element, isInflow)
Disposer.register(this, panel as Disposable)
removeAll()
add(panel, BorderLayout.CENTER)
this.panel = panel
}
revalidate()
}
override fun dispose() {
super.dispose()
panel = null
}
}
class KotlinUsageContextDataInflowPanel(
project: Project,
presentation: UsageViewPresentation
) : KotlinUsageContextDataFlowPanelBase(project, presentation, true) {
class Provider : ProviderBase() {
override fun create(usageView: UsageView): UsageContextPanel {
return KotlinUsageContextDataInflowPanel((usageView as UsageViewImpl).project, usageView.getPresentation())
}
override fun getTabTitle() = "Dataflow to Here"
}
}
class KotlinUsageContextDataOutflowPanel(
project: Project,
presentation: UsageViewPresentation
) : KotlinUsageContextDataFlowPanelBase(project, presentation, false) {
class Provider : ProviderBase() {
override fun create(usageView: UsageView): UsageContextPanel {
return KotlinUsageContextDataOutflowPanel((usageView as UsageViewImpl).project, usageView.getPresentation())
}
override fun getTabTitle() = "Dataflow from Here"
}
}
@@ -1,13 +0,0 @@
/*
* 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.util
import com.intellij.openapi.ui.popup.PopupChooserBuilder
import javax.swing.JList
// BUNCH: 181
@Suppress("IncompatibleAPI")
class PopupChooserBuilderWrapper<T>(list: JList<T>) : PopupChooserBuilder(list)
@@ -1,40 +0,0 @@
/*
* 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.
*/
@file:Suppress("MissingRecentApi", "IncompatibleAPI")
package org.jetbrains.kotlin.idea.util.compat
import com.intellij.codeInspection.dataFlow.Nullness
import com.intellij.codeInspection.dataFlow.DfaUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiVariable
import com.intellij.slicer.SliceLanguageSupportProvider
import com.intellij.slicer.SliceLeafEquality
import com.intellij.slicer.SliceNullnessAnalyzerBase
// BUNCH: 181
typealias Nullability = Nullness
// BUNCH: 181
fun dfaCheckNullability(variable: PsiVariable?, context: PsiElement?): Nullability =
DfaUtil.checkNullness(variable, context)
// BUNCH: 181
fun dfaInferMethodNullability(method: PsiMethod): Nullability =
DfaUtil.inferMethodNullity(method)
// BUNCH: 181
abstract class SliceNullnessAnalyzerBaseEx(
leafEquality: SliceLeafEquality,
provider: SliceLanguageSupportProvider
) : SliceNullnessAnalyzerBase(leafEquality, provider) {
override fun checkNullness(element: PsiElement?): Nullability {
return checkNullabilityEx(element)
}
abstract fun checkNullabilityEx(element: PsiElement?): Nullability
}
-193
View File
@@ -1,193 +0,0 @@
// INSPECTION_CLASS: com.android.tools.idea.lint.AndroidLintDrawAllocationInspection
// INSPECTION_CLASS2: com.android.tools.idea.lint.AndroidLintUseSparseArraysInspection
// INSPECTION_CLASS3: com.android.tools.idea.lint.AndroidLintUseValueOfInspection
import android.annotation.SuppressLint
import java.util.HashMap
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.util.SparseArray
import android.widget.Button
@SuppressWarnings("unused")
@Suppress("UsePropertyAccessSyntax", "UNUSED_VARIABLE", "unused", "UNUSED_PARAMETER", "DEPRECATION", "UNNECESSARY_NOT_NULL_ASSERTION", "NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS")
class JavaPerformanceTest(context: Context, attrs: AttributeSet, defStyle: Int) : Button(context, attrs, defStyle) {
private var cachedRect: Rect? = null
private var shader: LinearGradient? = null
private var lastHeight: Int = 0
private var lastWidth: Int = 0
override fun onDraw(canvas: android.graphics.Canvas) {
super.onDraw(canvas)
// Various allocations:
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">java.lang.String("foo")</warning>
val s = <warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">java.lang.String("bar")</warning>
// This one should not be reported:
@SuppressLint("DrawAllocation")
val i = 5
// Cached object initialized lazily: should not complain about these
if (cachedRect == null) {
cachedRect = Rect(0, 0, 100, 100)
}
if (cachedRect == null || cachedRect!!.width() != 50) {
cachedRect = Rect(0, 0, 50, 100)
}
val b = java.lang.Boolean.valueOf(true)!! // auto-boxing
dummy(1, 2)
// Non-allocations
super.animate()
dummy2(1, 2)
// This will involve allocations, but we don't track
// inter-procedural stuff here
someOtherMethod()
}
internal fun dummy(foo: Int?, bar: Int) {
dummy2(foo!!, bar)
}
internal fun dummy2(foo: Int, bar: Int) {
}
internal fun someOtherMethod() {
// Allocations are okay here
java.lang.String("foo")
val s = java.lang.String("bar")
val b = java.lang.Boolean.valueOf(true)!! // auto-boxing
// Sparse array candidates
val myMap = <warning descr="Use `new SparseArray<String>(...)` instead for better performance">HashMap<Int, String>()</warning>
// Should use SparseBooleanArray
val myBoolMap = <warning descr="Use `new SparseBooleanArray(...)` instead for better performance">HashMap<Int, Boolean>()</warning>
// Should use SparseIntArray
val myIntMap = <warning descr="Use new `SparseIntArray(...)` instead for better performance">java.util.HashMap<Int, Int>()</warning>
// This one should not be reported:
@SuppressLint("UseSparseArrays")
val myOtherMap = <warning descr="Use `new SparseArray<Object>(...)` instead for better performance">HashMap<Int, Any>()</warning>
}
protected fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int,
x: Boolean) {
// wrong signature
java.lang.String("not an error")
}
protected fun onMeasure(widthMeasureSpec: Int) {
// wrong signature
java.lang.String("not an error")
}
protected fun onLayout(changed: Boolean, left: Int, top: Int, right: Int,
bottom: Int, wrong: Int) {
// wrong signature
java.lang.String("not an error")
}
protected fun onLayout(changed: Boolean, left: Int, top: Int, right: Int) {
// wrong signature
java.lang.String("not an error")
}
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int,
bottom: Int) {
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">java.lang.String("flag me")</warning>
}
@SuppressWarnings("null") // not real code
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">java.lang.String("flag me")</warning>
// Forbidden factory methods:
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">Bitmap.createBitmap(100, 100, null)</warning>
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">android.graphics.Bitmap.createScaledBitmap(null, 100, 100, false)</warning>
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">BitmapFactory.decodeFile(null)</warning>
val canvas: Canvas? = null
<warning descr="Avoid object allocations during draw operations: Use `Canvas.getClipBounds(Rect)` instead of `Canvas.getClipBounds()` which allocates a temporary `Rect`">canvas!!.getClipBounds()</warning> // allocates on your behalf
<warning descr="Avoid object allocations during draw operations: Use `Canvas.getClipBounds(Rect)` instead of `Canvas.getClipBounds()` which allocates a temporary `Rect`">canvas.clipBounds</warning> // allocates on your behalf
canvas.getClipBounds(null) // NOT an error
val layoutWidth = width
val layoutHeight = height
if (mAllowCrop && (mOverlay == null || mOverlay!!.width != layoutWidth ||
mOverlay!!.height != layoutHeight)) {
mOverlay = Bitmap.createBitmap(layoutWidth, layoutHeight, Bitmap.Config.ARGB_8888)
mOverlayCanvas = Canvas(mOverlay!!)
}
if (widthMeasureSpec == 42) {
throw IllegalStateException("Test") // NOT an allocation
}
// More lazy init tests
var initialized = false
if (!initialized) {
java.lang.String("foo")
initialized = true
}
// NOT lazy initialization
if (!initialized || mOverlay == null) {
<warning descr="Avoid object allocations during draw/layout operations (preallocate and reuse instead)">java.lang.String("foo")</warning>
}
}
internal fun factories() {
val i1 = 42
val l1 = 42L
val b1 = true
val c1 = 'c'
val f1 = 1.0f
val d1 = 1.0
// The following should not generate errors:
val i3 = Integer.valueOf(42)
}
private val mAllowCrop: Boolean = false
private var mOverlayCanvas: Canvas? = null
private var mOverlay: Bitmap? = null
override fun layout(l: Int, t: Int, r: Int, b: Int) {
// Using "this." to reference fields
if (this.shader == null)
this.shader = LinearGradient(0f, 0f, width.toFloat(), 0f, intArrayOf(0), null,
Shader.TileMode.REPEAT)
val width = width
val height = height
if (shader == null || lastWidth != width || lastHeight != height) {
lastWidth = width
lastHeight = height
shader = LinearGradient(0f, 0f, width.toFloat(), 0f, intArrayOf(0), null, Shader.TileMode.REPEAT)
}
}
fun inefficientSparseArray() {
<warning descr="Use `new SparseIntArray(...)` instead for better performance">SparseArray<Int>()</warning> // Use SparseIntArray instead
SparseArray<Long>() // Use SparseLongArray instead
<warning descr="Use `new SparseBooleanArray(...)` instead for better performance">SparseArray<Boolean>()</warning> // Use SparseBooleanArray instead
SparseArray<Any>() // OK
}
fun longSparseArray() {
// but only minSdkVersion >= 17 or if has v4 support lib
val myStringMap = HashMap<Long, String>()
}
fun byteSparseArray() {
// bytes easily apply to ints
val myByteMap = <warning descr="Use `new SparseArray<String>(...)` instead for better performance">HashMap<Byte, String>()</warning>
}
}
@@ -1,5 +0,0 @@
// ALLOW_MULTIPLE_EXPRESSIONS
fun bar(x: (Int) -> String) = x(1)
fun foo() {
val bar = bar() { y: Int -> "abc" }
}
@@ -1,12 +0,0 @@
LineBreakpoint created at smartStepIntoInlinedFunLiteral.kt:6
Run Java
Connected to the target VM
smartStepIntoInlinedFunLiteral.kt:6
smartStepIntoInlinedFunLiteral.kt:11
smartStepIntoInlinedFunLiteral.kt:12
smartStepIntoInlinedFunLiteral.kt:17
smartStepIntoInlinedFunLiteral.kt:18
smartStepIntoInlinedFunLiteral.kt:1
Disconnected from the target VM
Process finished with exit code 0
@@ -1,12 +0,0 @@
LineBreakpoint created at smartStepIntoInlinedFunctionalExpression.kt:6
Run Java
Connected to the target VM
smartStepIntoInlinedFunctionalExpression.kt:6
smartStepIntoInlinedFunctionalExpression.kt:11
smartStepIntoInlinedFunctionalExpression.kt:12
smartStepIntoInlinedFunctionalExpression.kt:17
smartStepIntoInlinedFunctionalExpression.kt:18
smartStepIntoInlinedFunctionalExpression.kt:1
Disconnected from the target VM
Process finished with exit code 0
@@ -1,8 +0,0 @@
fun testing() {
<caret>SomeClass<List<String>>()
}
//INFO: <div class='definition'><pre>public class <b>SomeClass</b>&lt;T extends <a href="psi_element://java.util.List"><code>List</code></a>&gt;
//INFO: extends <a href="psi_element://java.lang.Object"><code>Object</code></a></pre></div><div class='content'>
//INFO: Some Java Class
//INFO: </div><table class='sections'><p><tr><td valign='top' class='section'><p>Type parameters:</td><td>&lt;T&gt; &ndash; </td></table>
@@ -1,9 +0,0 @@
class A : OverrideMe() {
override fun <caret>overrideMe() {
}
}
//INFO: <div class='definition'><pre><a href="psi_element://A"><code>A</code></a><br>protected open fun <b>overrideMe</b>(): Unit</pre></div></pre></div><table class='sections'><p><tr><td valign='top' class='section'><p>Description copied from class:</td><td><p><a href="psi_element://OverrideMe"><code>OverrideMe</code></a><br>
//INFO: Some comment
//INFO: </td><tr><td valign='top' class='section'><p>Overrides:</td><td><p><a href="psi_element://OverrideMe#overrideMe()"><code>overrideMe</code></a> in class <a href="psi_element://OverrideMe"><code>OverrideMe</code></a></td></table>
@@ -1,9 +0,0 @@
class A : OverrideMe {
override fun <caret>overrideMe() {
}
}
//INFO: <div class='definition'><pre><a href="psi_element://A"><code>A</code></a><br>public open fun <b>overrideMe</b>(): Unit</pre></div></pre></div><table class='sections'><p><tr><td valign='top' class='section'><p>Description copied from interface:</td><td><p><a href="psi_element://OverrideMe"><code>OverrideMe</code></a><br>
//INFO: Some comment
//INFO: </td><tr><td valign='top' class='section'><p>Specified by:</td><td><p><a href="psi_element://OverrideMe#overrideMe()"><code>overrideMe</code></a> in interface <a href="psi_element://OverrideMe"><code>OverrideMe</code></a></td></table>
@@ -1,9 +0,0 @@
fun ktTest() {
Test.<caret>foo("SomeTest")
}
//INFO: <div class='definition'><pre><a href="psi_element://Test"><code>Test</code></a><br><i>@Contract(pure = true)</i>&nbsp;
//INFO: <i>@<a href="psi_element://org.jetbrains.annotations.NotNull"><code>NotNull</code></a></i>&nbsp;
//INFO: public static&nbsp;<a href="psi_element://java.lang.Object"><code>Object</code></a>[]&nbsp;<b>foo</b>(<a href="psi_element://java.lang.String"><code>String</code></a>&nbsp;param)</pre></div><div class='content'>
//INFO: Java Method
//INFO: <p></div><table class='sections'><p><tr><td valign='top' class='section'><p><i>Inferred</i> annotations:</td><td><p><i>@org.jetbrains.annotations.Contract(pure = true)</i> <i>@<a href="psi_element://org.jetbrains.annotations.NotNull"><code>org.jetbrains.annotations.NotNull</code></a></i></td></table>
@@ -1,12 +0,0 @@
enum class E {
A
}
fun use() {
E.valueOf<caret>("A")
}
//INFO: <div class='definition'><pre><a href="psi_element://E"><code>E</code></a><br>public final fun <b>valueOf</b>(
//INFO: value: String
//INFO: ): <a href="psi_element://E">E</a></pre></div><div class='content'><p>Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)</p></div><table class='sections'><tr><td valign='top' class='section'><p>Throws:</td><td><p><code>IllegalArgumentException</code> - if this enum type has no constant with the specified name</td></table>
@@ -1,18 +0,0 @@
package test
/**
*
*
* Test function
*
* @param first Some
* @param second Other
*/
fun <caret>testFun(first: String, second: Int) = 12
//INFO: <div class='definition'><pre><a href="psi_element://test"><code>test</code></a> <font color="808080"><i>OnFunctionDeclarationWithPackage.kt</i></font><br>public fun <b>testFun</b>(
//INFO: first: String,
//INFO: second: Int
//INFO: ): Int</pre></div><div class='content'><p>Test function</p></div><table class='sections'><tr><td valign='top' class='section'><p>Params:</td><td><p><code>first</code> - Some<p><code>second</code> - Other</td></table>
-18
View File
@@ -1,18 +0,0 @@
/**
Some documentation
* @param a Some int
* @param b String
*/
fun testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <div class='definition'><pre><font color="808080"><i>OnMethodUsage.kt</i></font><br>public fun <b>testMethod</b>(
//INFO: a: Int,
//INFO: b: String
//INFO: ): Unit</pre></div><div class='content'><p>Some documentation</p></div><table class='sections'><tr><td valign='top' class='section'><p>Params:</td><td><p><code>a</code> - Some int<p><code>b</code> - String</td></table>
@@ -1,18 +0,0 @@
/**
Some documentation
* @param[a] Some int
* @param[b] String
*/
fun testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <div class='definition'><pre><font color="808080"><i>OnMethodUsageWithBracketsInParam.kt</i></font><br>public fun <b>testMethod</b>(
//INFO: a: Int,
//INFO: b: String
//INFO: ): Unit</pre></div><div class='content'><p>Some documentation</p></div><table class='sections'><tr><td valign='top' class='section'><p>Params:</td><td><p><code>a</code> - Some int<p><code>b</code> - String</td></table>
@@ -1,17 +0,0 @@
/**
* Some documentation
* on two lines.
*
* @param test String
* on two lines
*/
fun testMethod(test: String) {
}
fun test() {
<caret>testMethod("")
}
//INFO: <div class='definition'><pre><font color="808080"><i>OnMethodUsageWithMultilineParam.kt</i></font><br>public fun <b>testMethod</b>(
//INFO: test: String
//INFO: ): Unit</pre></div><div class='content'><p>Some documentation on two lines.</p></div><table class='sections'><tr><td valign='top' class='section'><p>Params:</td><td><p><code>test</code> - String on two lines</td></table>
@@ -1,18 +0,0 @@
/**
Some documentation
* @receiver Some int
* @param b String
* @return Return [a] and nothing else
*/
fun Int.testMethod(b: String) {
}
fun test() {
1.<caret>testMethod("value")
}
//INFO: <div class='definition'><pre><font color="808080"><i>OnMethodUsageWithReceiver.kt</i></font><br>public fun Int.<b>testMethod</b>(
//INFO: b: String
//INFO: ): Unit</pre></div><div class='content'><p>Some documentation</p></div><table class='sections'><tr><td valign='top' class='section'><p>Receiver:</td><td>Some int</td><tr><td valign='top' class='section'><p>Params:</td><td><p><code>b</code> - String</td><tr><td valign='top' class='section'><p>Returns:</td><td>Return <a href="psi_element://a">a</a> and nothing else</td></table>
@@ -1,19 +0,0 @@
/**
Some documentation
* @param a Some int
* @param b String
* @return Return [a] and nothing else
*/
fun testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <div class='definition'><pre><font color="808080"><i>OnMethodUsageWithReturnAndLink.kt</i></font><br>public fun <b>testMethod</b>(
//INFO: a: Int,
//INFO: b: String
//INFO: ): Unit</pre></div><div class='content'><p>Some documentation</p></div><table class='sections'><tr><td valign='top' class='section'><p>Params:</td><td><p><code>a</code> - Some int<p><code>b</code> - String</td><tr><td valign='top' class='section'><p>Returns:</td><td>Return <a href="psi_element://a">a</a> and nothing else</td></table>
@@ -1,20 +0,0 @@
/**
Some documentation
* @param a Some int
* @param b String
* @return Return value
* @throws IllegalArgumentException if the weather is bad
*/
fun testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <div class='definition'><pre><font color="808080"><i>OnMethodUsageWithReturnAndThrows.kt</i></font><br>public fun <b>testMethod</b>(
//INFO: a: Int,
//INFO: b: String
//INFO: ): Unit</pre></div><div class='content'><p>Some documentation</p></div><table class='sections'><tr><td valign='top' class='section'><p>Params:</td><td><p><code>a</code> - Some int<p><code>b</code> - String</td><tr><td valign='top' class='section'><p>Returns:</td><td>Return value</td><tr><td valign='top' class='section'><p>Throws:</td><td><p><code>IllegalArgumentException</code> - if the weather is bad</td></table>
@@ -1,20 +0,0 @@
/**
* @see C
* @see D
* @see <a href="https://kotl.in">kotlin</a>
*/
fun testMethod() {
}
class C {
}
class D {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <div class='definition'><pre><font color="808080"><i>OnMethodUsageWithSee.kt</i></font><br>public fun <b>testMethod</b>(): Unit</pre></div><div class='content'></div><table class='sections'><tr><td valign='top' class='section'><p>See Also:</td><td><a href="psi_element://C"><code>C</code></a>, <a href="psi_element://D"><code>D</code></a>, <a href="https://kotl.in">kotlin</a></td></table>
@@ -1,19 +0,0 @@
/**
Some documentation
* @param T the type parameter
* @param a Some int
* @param b String
*/
fun <T> testMethod(a: Int, b: String) {
}
fun test() {
<caret>testMethod(1, "value")
}
//INFO: <div class='definition'><pre><font color="808080"><i>OnMethodUsageWithTypeParameter.kt</i></font><br>public fun &lt;T&gt; <b>testMethod</b>(
//INFO: a: Int,
//INFO: b: String
//INFO: ): Unit</pre></div><div class='content'><p>Some documentation</p></div><table class='sections'><tr><td valign='top' class='section'><p>Params:</td><td><p><code>T</code> - the type parameter<p><code>a</code> - Some int<p><code>b</code> - String</td></table>
-29
View File
@@ -1,29 +0,0 @@
package magic
object Samples {
fun sampleMagic() {
castTextSpell("[asd] [dse] [asz]")
}
}
fun sampleScroll() {
val reader = Scroll("[asd] [dse] [asz]").reader()
castTextSpell(reader.readAll())
}
/**
* @sample Samples.sampleMagic
* @sample sampleScroll
*/
fun <caret>castTextSpell(spell: String) {
throw SecurityException("Magic prohibited outside Hogwarts")
}
//INFO: <div class='definition'><pre><a href="psi_element://magic"><code>magic</code></a> <font color="808080"><i>Samples.kt</i></font><br>public fun <b>castTextSpell</b>(
//INFO: spell: String
//INFO: ): Unit</pre></div><div class='content'></div><table class='sections'><tr><td valign='top' class='section'><p>Samples:</td><td><p><a href="psi_element://Samples.sampleMagic"><code>Samples.sampleMagic</code></a><pre><code>
//INFO: castTextSpell("[asd] [dse] [asz]")
//INFO: </code></pre><p><a href="psi_element://sampleScroll"><code>sampleScroll</code></a><pre><code>
//INFO: val reader = Scroll("[asd] [dse] [asz]").reader()
//INFO: castTextSpell(reader.readAll())
//INFO: </code></pre></td></table>
@@ -1,18 +0,0 @@
/**
* @sample samples.SampleGroup.mySample
* @sample samples.megasamples.MegaSamplesGroup.megaSample
* @sample samples.notindir.NotInDirSamples.sssample
* @sample smaplez.a.b.c.Samplez.sssample
*/
fun some<caret>() {
}
//INFO: <div class='definition'><pre><font color="808080"><i>usage.kt</i></font><br>public fun <b>some</b>(): Unit</pre></div><div class='content'></div><table class='sections'><tr><td valign='top' class='section'><p>Samples:</td><td><p><a href="psi_element://samples.SampleGroup.mySample"><code>samples.SampleGroup.mySample</code></a><pre><code>
//INFO: println("Hello, world")
//INFO: </code></pre><p><a href="psi_element://samples.megasamples.MegaSamplesGroup.megaSample"><code>samples.megasamples.MegaSamplesGroup.megaSample</code></a><pre><code>
//INFO: println("...---...")
//INFO: </code></pre><p><a href="psi_element://samples.notindir.NotInDirSamples.sssample"><code>samples.notindir.NotInDirSamples.sssample</code></a><pre><code>
//INFO: println("location is samplesTest/")
//INFO: </code></pre><p><a href="psi_element://smaplez.a.b.c.Samplez.sssample"><code>smaplez.a.b.c.Samplez.sssample</code></a><pre><code>// Unresolved</code></pre></td></table>
@@ -1,10 +0,0 @@
/**
* @sample samples.sample
*/
fun some<caret>() {
}
//INFO: <div class='definition'><pre><font color="808080"><i>usage.kt</i></font><br>public fun <b>some</b>(): Unit</pre></div><div class='content'></div><table class='sections'><tr><td valign='top' class='section'><p>Samples:</td><td><p><a href="psi_element://samples.sample"><code>samples.sample</code></a><pre><code>
//INFO: println("Hello, world")
//INFO: </code></pre></td></table>
@@ -1,8 +0,0 @@
package test;
import foo.A;
public class ThrowsOnGenericMethod {
public static void main(String[] args) {
new A().<error descr="Unhandled exception: java.io.IOException">foo("");</error>
}
}
@@ -1,5 +0,0 @@
// "Remove function body" "true"
abstract class A() {
/*1*/
abstract fun foo() // 3
}
@@ -1,12 +0,0 @@
// "Surround with lambda" "false"
// ERROR: Type mismatch: inferred type is Object but () -> String was expected
// ACTION: Annotate constructor 'Object' as @Deprecated
// ACTION: Change parameter 'block' type of function 'str' to 'Object'
// ACTION: Create function 'str'
// ACTION: Edit method contract of 'Object'
// ACTION: Introduce import alias
fun fn() {
str(<caret>Object())
}
fun str(block: () -> String) {}
@@ -1,7 +0,0 @@
// "Suppress for declarations annotated by 'xxx.XXX'" "true"
package xxx
annotation class XXX
@XXX
class <caret>UnusedClass
@@ -1,7 +0,0 @@
// "Suppress for declarations annotated by 'xxx.XXX'" "true"
package xxx
annotation class XXX
@XXX
class <caret>UnusedClass
@@ -1,240 +0,0 @@
/*
* 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.configuration
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.PathMacros
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.projectRoots.ProjectJdkTable
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess
import com.intellij.testFramework.PlatformTestCase
import com.intellij.testFramework.UsefulTestCase
import junit.framework.TestCase
import org.jetbrains.kotlin.idea.configuration.KotlinWithLibraryConfigurator.FileState
import org.jetbrains.kotlin.idea.framework.KotlinSdkType
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
import java.nio.file.Path
abstract class AbstractConfigureKotlinTest : PlatformTestCase() {
override fun setUp() {
super.setUp()
VfsRootAccess.allowRootAccess(KotlinTestUtils.getHomeDirectory())
}
@Throws(Exception::class)
override fun tearDown() {
VfsRootAccess.disallowRootAccess(KotlinTestUtils.getHomeDirectory())
PathMacros.getInstance().removeMacro(TEMP_DIR_MACRO_KEY)
super.tearDown()
}
@Throws(Exception::class)
override fun initApplication() {
super.initApplication()
KotlinSdkType.setUpIfNeeded()
ApplicationManager.getApplication().runWriteAction {
ProjectJdkTable.getInstance().addJdk(PluginTestCaseBase.mockJdk6())
ProjectJdkTable.getInstance().addJdk(PluginTestCaseBase.mockJdk8())
ProjectJdkTable.getInstance().addJdk(PluginTestCaseBase.mockJdk9())
}
PluginTestCaseBase.clearSdkTable(testRootDisposable)
val tempLibDir = FileUtil.createTempDirectory("temp", null)
PathMacros.getInstance().setMacro(TEMP_DIR_MACRO_KEY, FileUtilRt.toSystemDependentName(tempLibDir.absolutePath))
}
protected fun doTestConfigureModulesWithNonDefaultSetup(configurator: KotlinWithLibraryConfigurator) {
assertNoFilesInDefaultPaths()
val modules = modules
for (module in modules) {
assertNotConfigured(module, configurator)
}
configurator.configure(myProject, emptyList())
assertNoFilesInDefaultPaths()
for (module in modules) {
assertProperlyConfigured(module, configurator)
}
}
protected fun doTestOneJavaModule(jarState: FileState) {
doTestOneModule(jarState, JAVA_CONFIGURATOR)
}
protected fun doTestOneJsModule(jarState: FileState) {
doTestOneModule(jarState, JS_CONFIGURATOR)
}
private fun doTestOneModule(jarState: FileState, configurator: KotlinWithLibraryConfigurator) {
val module = module
assertNotConfigured(module, configurator)
configure(module, jarState, configurator)
assertProperlyConfigured(module, configurator)
}
override fun getModule(): Module {
val modules = ModuleManager.getInstance(myProject).modules
assert(modules.size == 1) { "One module should be loaded " + modules.size }
myModule = modules[0]
return super.getModule()
}
val modules: Array<Module>
get() = ModuleManager.getInstance(myProject).modules
override fun getProjectDirOrFile(): Path {
val projectFilePath = projectRoot + "/projectFile.ipr"
TestCase.assertTrue("Project file should exists " + projectFilePath, File(projectFilePath).exists())
return File(projectFilePath).toPath()
}
override fun doCreateProject(projectFile: Path): Project {
return myProjectManager.loadProject(projectFile.toFile().path)!!
}
private val projectName: String
get() {
val testName = getTestName(true)
return if (testName.contains("_")) {
testName.substring(0, testName.indexOf("_"))
}
else testName
}
protected val projectRoot: String
get() = BASE_PATH + projectName
override fun setUpModule() {}
private fun assertNoFilesInDefaultPaths() {
UsefulTestCase.assertDoesntExist(File(JAVA_CONFIGURATOR.getDefaultPathToJarFile(project)))
UsefulTestCase.assertDoesntExist(File(JS_CONFIGURATOR.getDefaultPathToJarFile(project)))
}
companion object {
private val BASE_PATH = "idea/testData/configuration/"
private val TEMP_DIR_MACRO_KEY = "TEMP_TEST_DIR"
protected val JAVA_CONFIGURATOR: KotlinJavaModuleConfigurator by lazy {
object : KotlinJavaModuleConfigurator() {
override fun getDefaultPathToJarFile(project: Project) = getPathRelativeToTemp("default_jvm_lib")
}
}
protected val JS_CONFIGURATOR: KotlinJsModuleConfigurator by lazy {
object : KotlinJsModuleConfigurator() {
override fun getDefaultPathToJarFile(project: Project) = getPathRelativeToTemp("default_js_lib")
}
}
private fun configure(
modules: List<Module>,
runtimeState: FileState,
configurator: KotlinWithLibraryConfigurator,
jarFromDist: String,
jarFromTemp: String
) {
val project = modules.first().project
val collector = createConfigureKotlinNotificationCollector(project)
val pathToJar = getPathToJar(runtimeState, jarFromDist, jarFromTemp)
for (module in modules) {
configurator.configureModule(module, pathToJar, pathToJar, collector, runtimeState)
}
collector.showNotification()
}
private fun getPathToJar(runtimeState: FileState, jarFromDist: String, jarFromTemp: String) = when (runtimeState) {
KotlinWithLibraryConfigurator.FileState.EXISTS -> jarFromDist
KotlinWithLibraryConfigurator.FileState.COPY -> jarFromTemp
KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY -> jarFromDist
}
protected fun configure(module: Module, jarState: FileState, configurator: KotlinProjectConfigurator) {
if (configurator is KotlinJavaModuleConfigurator) {
configure(listOf(module), jarState,
configurator as KotlinWithLibraryConfigurator,
pathToExistentRuntimeJar, pathToNonexistentRuntimeJar)
}
if (configurator is KotlinJsModuleConfigurator) {
configure(listOf(module), jarState,
configurator as KotlinWithLibraryConfigurator,
pathToExistentJsJar, pathToNonexistentJsJar)
}
}
private val pathToNonexistentRuntimeJar: String
get() {
val pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.KOTLIN_JAVA_STDLIB_JAR
PlatformTestCase.myFilesToDelete.add(File(pathToTempKotlinRuntimeJar))
return pathToTempKotlinRuntimeJar
}
private val pathToNonexistentJsJar: String
get() {
val pathToTempKotlinRuntimeJar = FileUtil.getTempDirectory() + "/" + PathUtil.JS_LIB_JAR_NAME
PlatformTestCase.myFilesToDelete.add(File(pathToTempKotlinRuntimeJar))
return pathToTempKotlinRuntimeJar
}
private val pathToExistentRuntimeJar: String
get() = PathUtil.kotlinPathsForDistDirectory.stdlibPath.parent
private val pathToExistentJsJar: String
get() = PathUtil.kotlinPathsForDistDirectory.jsStdLibJarPath.parent
protected fun assertNotConfigured(module: Module, configurator: KotlinWithLibraryConfigurator) {
TestCase.assertFalse(
String.format("Module %s should not be configured as %s Module", module.name, configurator.presentableText),
configurator.isConfigured(module))
}
protected fun assertConfigured(module: Module, configurator: KotlinWithLibraryConfigurator) {
TestCase.assertTrue(String.format("Module %s should be configured with configurator '%s'", module.name,
configurator.presentableText),
configurator.isConfigured(module))
}
protected fun assertProperlyConfigured(module: Module, configurator: KotlinWithLibraryConfigurator) {
assertConfigured(module, configurator)
assertNotConfigured(module, getOppositeConfigurator(configurator))
}
private fun getOppositeConfigurator(configurator: KotlinWithLibraryConfigurator): KotlinWithLibraryConfigurator {
if (configurator === JAVA_CONFIGURATOR) return JS_CONFIGURATOR
if (configurator === JS_CONFIGURATOR) return JAVA_CONFIGURATOR
throw IllegalArgumentException("Only JS_CONFIGURATOR and JAVA_CONFIGURATOR are supported")
}
private fun getPathRelativeToTemp(relativePath: String): String {
val tempPath = PathMacros.getInstance().getValue(TEMP_DIR_MACRO_KEY)
return tempPath + '/' + relativePath
}
}
override fun getTestProjectJdk(): Sdk {
val projectRootManager = ProjectRootManager.getInstance(project)
return projectRootManager.projectSdk ?: throw IllegalStateException("SDK ${projectRootManager.projectSdkName} was not found")
}
}
@@ -1,379 +0,0 @@
/*
* 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.configuration;
import com.intellij.jarRepository.RepositoryLibraryType;
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProviderImpl;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.LibraryOrderEntry;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.OrderRootType;
import com.intellij.openapi.roots.RootPolicy;
import com.intellij.openapi.roots.impl.libraries.LibraryEx;
import com.intellij.openapi.roots.libraries.Library;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiJavaModule;
import com.intellij.psi.PsiRequiresStatement;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.kotlin.cli.common.arguments.InternalArgument;
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments;
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments;
import org.jetbrains.kotlin.config.*;
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder;
import org.jetbrains.kotlin.idea.facet.FacetUtilsKt;
import org.jetbrains.kotlin.idea.facet.KotlinFacet;
import org.jetbrains.kotlin.idea.framework.JSLibraryKind;
import org.jetbrains.kotlin.idea.framework.JsLibraryStdDetectionUtil;
import org.jetbrains.kotlin.idea.framework.LibraryEffectiveKindProviderKt;
import org.jetbrains.kotlin.idea.project.PlatformKt;
import org.jetbrains.kotlin.idea.util.Java9StructureUtilKt;
import org.jetbrains.kotlin.idea.versions.KotlinRuntimeLibraryUtilKt;
import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind;
import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind;
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleKt;
import org.jetbrains.kotlin.utils.PathUtil;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.StreamSupport;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
public class ConfigureKotlinTest extends AbstractConfigureKotlinTest {
public void testNewLibrary_copyJar() {
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.COPY);
ModuleRootManager.getInstance(getModule()).orderEntries().forEachLibrary(library -> {
assertSameElements(
Arrays.stream(library.getRootProvider().getFiles(OrderRootType.CLASSES)).map(VirtualFile::getName).toArray(),
PathUtil.KOTLIN_JAVA_STDLIB_JAR, PathUtil.KOTLIN_JAVA_REFLECT_JAR, PathUtil.KOTLIN_TEST_JAR);
assertSameElements(
Arrays.stream(library.getRootProvider().getFiles(OrderRootType.SOURCES)).map(VirtualFile::getName).toArray(),
PathUtil.KOTLIN_JAVA_STDLIB_SRC_JAR, PathUtil.KOTLIN_REFLECT_SRC_JAR, PathUtil.KOTLIN_TEST_SRC_JAR);
return true;
});
}
public void testNewLibrary_doNotCopyJar() {
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY);
}
public void testLibraryWithoutPaths_jarExists() {
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.EXISTS);
}
public void testNewLibrary_jarExists() {
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.EXISTS);
}
public void testLibraryWithoutPaths_copyJar() {
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.COPY);
}
public void testLibraryWithoutPaths_doNotCopyJar() {
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY);
}
@SuppressWarnings("ConstantConditions")
public void testTwoModules_exists() {
Module[] modules = getModules();
for (Module module : modules) {
if (module.getName().equals("module1")) {
Companion.configure(module, KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY, Companion.getJAVA_CONFIGURATOR());
Companion.assertConfigured(module, Companion.getJAVA_CONFIGURATOR());
}
else if (module.getName().equals("module2")) {
Companion.assertNotConfigured(module, Companion.getJAVA_CONFIGURATOR());
Companion.configure(module, KotlinWithLibraryConfigurator.FileState.EXISTS, Companion.getJAVA_CONFIGURATOR());
Companion.assertConfigured(module, Companion.getJAVA_CONFIGURATOR());
}
}
}
public void testLibraryNonDefault_libExistInDefault() throws IOException {
Module module = getModule();
// Move fake runtime jar to default library path to pretend library is already configured
FileUtil.copy(
new File(getProject().getBasePath() + "/lib/" + PathUtil.KOTLIN_JAVA_STDLIB_JAR),
new File(Companion.getJAVA_CONFIGURATOR().getDefaultPathToJarFile(getProject()) + "/" + PathUtil.KOTLIN_JAVA_STDLIB_JAR));
Companion.assertNotConfigured(module, Companion.getJAVA_CONFIGURATOR());
Companion.getJAVA_CONFIGURATOR().configure(myProject, Collections.<Module>emptyList());
Companion.assertProperlyConfigured(module, Companion.getJAVA_CONFIGURATOR());
}
public void testTwoModulesWithNonDefaultPath_doNotCopyInDefault() throws IOException {
doTestConfigureModulesWithNonDefaultSetup(Companion.getJAVA_CONFIGURATOR());
assertEmpty(ConfigureKotlinInProjectUtilsKt.getCanBeConfiguredModules(myProject, Companion.getJS_CONFIGURATOR()));
}
public void testTwoModulesWithJSNonDefaultPath_doNotCopyInDefault() throws IOException {
doTestConfigureModulesWithNonDefaultSetup(Companion.getJS_CONFIGURATOR());
assertEmpty(ConfigureKotlinInProjectUtilsKt.getCanBeConfiguredModules(myProject, Companion.getJAVA_CONFIGURATOR()));
}
public void testNewLibrary_jarExists_js() {
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.EXISTS);
}
public void testNewLibrary_copyJar_js() {
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.COPY);
}
public void testNewLibrary_doNotCopyJar_js() {
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY);
}
public void testJsLibraryWithoutPaths_jarExists() {
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.EXISTS);
}
public void testJsLibraryWithoutPaths_copyJar() {
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.COPY);
}
public void testJsLibraryWithoutPaths_doNotCopyJar() {
doTestOneJsModule(KotlinWithLibraryConfigurator.FileState.DO_NOT_COPY);
}
public void testJsLibraryWrongKind() {
AbstractConfigureKotlinTest.Companion.assertProperlyConfigured(getModule(), AbstractConfigureKotlinTest.Companion.getJS_CONFIGURATOR());
assertEquals(1, ModuleRootManager.getInstance(getModule()).orderEntries().process(new LibraryCountingRootPolicy(), 0).intValue());
}
public void testProjectWithoutFacetWithRuntime106WithoutLanguageLevel() {
assertEquals(LanguageVersion.KOTLIN_1_0, PlatformKt.getLanguageVersionSettings(getModule()).getLanguageVersion());
assertEquals(LanguageVersion.KOTLIN_1_0, PlatformKt.getLanguageVersionSettings(myProject, null).getLanguageVersion());
}
public void testProjectWithoutFacetWithRuntime11WithoutLanguageLevel() {
assertEquals(LanguageVersion.KOTLIN_1_1, PlatformKt.getLanguageVersionSettings(getModule()).getLanguageVersion());
assertEquals(LanguageVersion.KOTLIN_1_1, PlatformKt.getLanguageVersionSettings(myProject, null).getLanguageVersion());
}
public void testProjectWithoutFacetWithRuntime11WithLanguageLevel10() {
assertEquals(LanguageVersion.KOTLIN_1_0, PlatformKt.getLanguageVersionSettings(getModule()).getLanguageVersion());
assertEquals(LanguageVersion.KOTLIN_1_0, PlatformKt.getLanguageVersionSettings(myProject, null).getLanguageVersion());
}
public void testProjectWithFacetWithRuntime11WithLanguageLevel10() {
assertEquals(LanguageVersion.KOTLIN_1_0, PlatformKt.getLanguageVersionSettings(getModule()).getLanguageVersion());
assertEquals(LanguageVersion.LATEST_STABLE, PlatformKt.getLanguageVersionSettings(myProject, null).getLanguageVersion());
}
public void testJsLibraryVersion11() {
Library jsRuntime = KotlinRuntimeLibraryUtilKt.findAllUsedLibraries(myProject).keySet().iterator().next();
String version = JsLibraryStdDetectionUtil.INSTANCE.getJsLibraryStdVersion(jsRuntime, myProject);
assertEquals("1.1.0", version);
}
public void testJsLibraryVersion106() {
Library jsRuntime = KotlinRuntimeLibraryUtilKt.findAllUsedLibraries(myProject).keySet().iterator().next();
String version = JsLibraryStdDetectionUtil.INSTANCE.getJsLibraryStdVersion(jsRuntime, myProject);
assertEquals("1.0.6", version);
}
@SuppressWarnings("ConstantConditions")
public void testMavenProvidedTestJsKind() {
LibraryEx jsTest = (LibraryEx) ContainerUtil.find(
KotlinRuntimeLibraryUtilKt.findAllUsedLibraries(myProject).keySet(),
(library) -> library.getName().contains("kotlin-test-js")
);
assertEquals(RepositoryLibraryType.REPOSITORY_LIBRARY_KIND, jsTest.getKind());
assertEquals(JSLibraryKind.INSTANCE, LibraryEffectiveKindProviderKt.effectiveKind(jsTest, myProject));
}
@SuppressWarnings("ConstantConditions")
public void testJvmProjectWithV1FacetConfig() {
KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getInitializedSettings(getModule());
K2JVMCompilerArguments arguments = (K2JVMCompilerArguments) settings.getCompilerArguments();
assertEquals(false, settings.getUseProjectSettings());
assertEquals("1.1", settings.getLanguageLevel().getDescription());
assertEquals("1.0", settings.getApiLevel().getDescription());
assertEquals(new JvmIdePlatformKind.Platform(JvmTarget.JVM_1_8), settings.getPlatform());
assertEquals("1.1", arguments.getLanguageVersion());
assertEquals("1.0", arguments.getApiVersion());
assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, CoroutineSupport.byCompilerArguments(arguments));
assertEquals("1.7", arguments.getJvmTarget());
assertEquals("-version -Xallow-kotlin-package -Xskip-metadata-version-check", settings.getCompilerSettings().getAdditionalArguments());
}
@SuppressWarnings("ConstantConditions")
public void testJsProjectWithV1FacetConfig() {
KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getInitializedSettings(getModule());
K2JSCompilerArguments arguments = (K2JSCompilerArguments) settings.getCompilerArguments();
assertEquals(false, settings.getUseProjectSettings());
assertEquals("1.1", settings.getLanguageLevel().getDescription());
assertEquals("1.0", settings.getApiLevel().getDescription());
assertEquals(JsIdePlatformKind.Platform.INSTANCE, settings.getPlatform());
assertEquals("1.1", arguments.getLanguageVersion());
assertEquals("1.0", arguments.getApiVersion());
assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, CoroutineSupport.byCompilerArguments(arguments));
assertEquals("amd", arguments.getModuleKind());
assertEquals("-version -meta-info", settings.getCompilerSettings().getAdditionalArguments());
}
@SuppressWarnings("ConstantConditions")
public void testJvmProjectWithV2FacetConfig() {
KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getInitializedSettings(getModule());
K2JVMCompilerArguments arguments = (K2JVMCompilerArguments) settings.getCompilerArguments();
assertEquals(false, settings.getUseProjectSettings());
assertEquals("1.1", settings.getLanguageLevel().getDescription());
assertEquals("1.0", settings.getApiLevel().getDescription());
assertEquals(new JvmIdePlatformKind.Platform(JvmTarget.JVM_1_8), settings.getPlatform());
assertEquals("1.1", arguments.getLanguageVersion());
assertEquals("1.0", arguments.getApiVersion());
assertEquals(LanguageFeature.State.ENABLED, CoroutineSupport.byCompilerArguments(arguments));
assertEquals("1.7", arguments.getJvmTarget());
assertEquals("-version -Xallow-kotlin-package -Xskip-metadata-version-check", settings.getCompilerSettings().getAdditionalArguments());
}
@SuppressWarnings("ConstantConditions")
public void testJsProjectWithV2FacetConfig() {
KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getInitializedSettings(getModule());
K2JSCompilerArguments arguments = (K2JSCompilerArguments) settings.getCompilerArguments();
assertEquals(false, settings.getUseProjectSettings());
assertEquals("1.1", settings.getLanguageLevel().getDescription());
assertEquals("1.0", settings.getApiLevel().getDescription());
assertEquals(JsIdePlatformKind.Platform.INSTANCE, settings.getPlatform());
assertEquals("1.1", arguments.getLanguageVersion());
assertEquals("1.0", arguments.getApiVersion());
assertEquals(LanguageFeature.State.ENABLED_WITH_ERROR, CoroutineSupport.byCompilerArguments(arguments));
assertEquals("amd", arguments.getModuleKind());
assertEquals("-version -meta-info", settings.getCompilerSettings().getAdditionalArguments());
}
@SuppressWarnings("ConstantConditions")
public void testJvmProjectWithV3FacetConfig() {
KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getInitializedSettings(getModule());
K2JVMCompilerArguments arguments = (K2JVMCompilerArguments) settings.getCompilerArguments();
assertEquals(false, settings.getUseProjectSettings());
assertEquals("1.1", settings.getLanguageLevel().getDescription());
assertEquals("1.0", settings.getApiLevel().getDescription());
assertEquals(new JvmIdePlatformKind.Platform(JvmTarget.JVM_1_8), settings.getPlatform());
assertEquals("1.1", arguments.getLanguageVersion());
assertEquals("1.0", arguments.getApiVersion());
assertEquals(LanguageFeature.State.ENABLED, CoroutineSupport.byCompilerArguments(arguments));
assertEquals("1.7", arguments.getJvmTarget());
assertEquals("-version -Xallow-kotlin-package -Xskip-metadata-version-check", settings.getCompilerSettings().getAdditionalArguments());
}
public void testJvmProjectWithJvmTarget11() {
KotlinFacetSettings settings = KotlinFacetSettingsProvider.Companion.getInstance(myProject).getInitializedSettings(getModule());
assertEquals(new JvmIdePlatformKind.Platform(JvmTarget.JVM_11), settings.getPlatform());
}
public void testImplementsDependency() {
ModuleManager moduleManager = ModuleManager.getInstance(myProject);
Module module1 = moduleManager.findModuleByName("module1");
assert module1 != null;
Module module2 = moduleManager.findModuleByName("module2");
assert module2 != null;
assertEquals(KotlinFacet.Companion.get(module1).getConfiguration().getSettings().getImplementedModuleNames(), emptyList());
assertEquals(KotlinFacet.Companion.get(module2).getConfiguration().getSettings().getImplementedModuleNames(), singletonList("module1"));
}
public void testJava9WithModuleInfo() {
checkAddStdlibModule();
}
public void testJava9WithModuleInfoWithStdlibAlready() {
checkAddStdlibModule();
}
public void testProjectWithFreeArgs() {
assertEquals(
Collections.singletonList("true"),
KotlinCommonCompilerArgumentsHolder.Companion.getInstance(myProject).getSettings().getFreeArgs()
);
}
public void testProjectWithInternalArgs() {
List<InternalArgument> internalArguments =
KotlinCommonCompilerArgumentsHolder.Companion.getInstance(myProject).getSettings().getInternalArguments();
assertEquals(
0,
internalArguments.size()
);
}
private void checkAddStdlibModule() {
doTestOneJavaModule(KotlinWithLibraryConfigurator.FileState.COPY);
Module module = getModule();
Sdk moduleSdk = ModuleRootManager.getInstance(getModule()).getSdk();
assertNotNull("Module SDK is not defined", moduleSdk);
PsiJavaModule javaModule = Java9StructureUtilKt.findFirstPsiJavaModule(module);
assertNotNull(javaModule);
PsiRequiresStatement stdlibDirective =
Java9StructureUtilKt.findRequireDirective(javaModule, JavaModuleKt.KOTLIN_STDLIB_MODULE_NAME);
assertNotNull("Require directive for " + JavaModuleKt.KOTLIN_STDLIB_MODULE_NAME + " is expected",
stdlibDirective);
long numberOfStdlib = StreamSupport.stream(javaModule.getRequires().spliterator(), false)
.filter((statement) -> JavaModuleKt.KOTLIN_STDLIB_MODULE_NAME.equals(statement.getModuleName()))
.count();
assertTrue("Only one standard library directive is expected", numberOfStdlib == 1);
}
private void configureFacetAndCheckJvm(JvmTarget jvmTarget) {
IdeModifiableModelsProviderImpl modelsProvider = new IdeModifiableModelsProviderImpl(getProject());
try {
KotlinFacet facet = FacetUtilsKt.getOrCreateFacet(getModule(), modelsProvider, false, null, false);
JvmIdePlatformKind.Platform platform = new JvmIdePlatformKind.Platform(jvmTarget);
FacetUtilsKt.configureFacet(
facet,
"1.1",
LanguageFeature.State.ENABLED,
platform,
modelsProvider
);
assertEquals(platform, facet.getConfiguration().getSettings().getPlatform());
assertEquals(jvmTarget.getDescription(),
((K2JVMCompilerArguments) facet.getConfiguration().getSettings().getCompilerArguments()).getJvmTarget());
}
finally {
modelsProvider.dispose();
}
}
@SuppressWarnings("ConstantConditions")
public void testJvm8InProjectJvm6InModule() {
configureFacetAndCheckJvm(JvmTarget.JVM_1_6);
}
@SuppressWarnings("ConstantConditions")
public void testJvm6InProjectJvm8InModule() {
configureFacetAndCheckJvm(JvmTarget.JVM_1_8);
}
public void testProjectWithoutFacetWithJvmTarget18() {
assertEquals(new JvmIdePlatformKind.Platform(JvmTarget.JVM_1_8), PlatformKt.getPlatform(getModule()));
}
private static class LibraryCountingRootPolicy extends RootPolicy<Integer> {
@Override
public Integer visitLibraryOrderEntry(LibraryOrderEntry libraryOrderEntry, Integer value) {
return value + 1;
}
}
}
@@ -1,119 +0,0 @@
/*
* 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.debugger
import com.intellij.debugger.impl.OutputChecker
import com.intellij.idea.IdeaLogger
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.openapi.util.text.StringUtilRt
import com.intellij.openapi.vfs.CharsetToolkit
import org.junit.Assert
import java.io.File
internal class KotlinOutputChecker(
private val testDir: String,
appPath: String, outputPath: String) : OutputChecker(appPath, outputPath) {
companion object {
@JvmStatic
private val LOG = Logger.getInstance(KotlinOutputChecker::class.java)
private val CONNECT_PREFIX = "Connected to the target VM"
private val DISCONNECT_PREFIX = "Disconnected from the target VM"
private val RUN_JAVA = "Run Java"
//ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2
private val JDI_BUG_OUTPUT_PATTERN_1 = Regex("ERROR:\\s+JDWP\\s+Unable\\s+to\\s+get\\s+JNI\\s+1\\.2\\s+environment,\\s+jvm->GetEnv\\(\\)\\s+return\\s+code\\s+=\\s+-2")
//JDWP exit error AGENT_ERROR_NO_JNI_ENV(183): [../../../src/share/back/util.c:820]
private val JDI_BUG_OUTPUT_PATTERN_2 = Regex("JDWP\\s+exit\\s+error\\s+AGENT_ERROR_NO_JNI_ENV.*]")
}
// Copied from the base OutputChecker.checkValid(). Need to intercept call to base preprocessBuffer() method
override fun checkValid(jdk: Sdk, sortClassPath: Boolean) {
if (IdeaLogger.ourErrorsOccurred != null) {
throw IdeaLogger.ourErrorsOccurred
}
val actual = preprocessBuffer(buildOutputString())
val outDir = File(testDir)
var outFile = File(outDir, myTestName + ".out")
if (!outFile.exists()) {
if (SystemInfo.isWindows) {
val winOut = File(outDir, myTestName + ".win.out")
if (winOut.exists()) {
outFile = winOut
}
}
else if (SystemInfo.isUnix) {
val unixOut = File(outDir, myTestName + ".unx.out")
if (unixOut.exists()) {
outFile = unixOut
}
}
}
if (!outFile.exists()) {
FileUtil.writeToFile(outFile, actual)
LOG.error("Test file created ${outFile.path}\n**************** Don't forget to put it into VCS! *******************")
}
else {
val originalText = FileUtilRt.loadFile(outFile, CharsetToolkit.UTF8)
val expected = StringUtilRt.convertLineSeparators(originalText)
if (expected != actual) {
println("expected:")
println(originalText)
println("actual:")
println(actual)
val len = Math.min(expected.length, actual.length)
if (expected.length != actual.length) {
println("Text sizes differ: expected " + expected.length + " but actual: " + actual.length)
}
if (expected.length > len) {
println("Rest from expected text is: \"" + expected.substring(len) + "\"")
}
else if (actual.length > len) {
println("Rest from actual text is: \"" + actual.substring(len) + "\"")
}
Assert.assertEquals(originalText, actual)
}
}
}
private fun preprocessBuffer(buffer: String): String {
val lines = buffer.lines().toMutableList()
val connectedIndex = lines.indexOfFirst { it.startsWith(CONNECT_PREFIX) }
lines[connectedIndex] = CONNECT_PREFIX
val runCommandIndex = connectedIndex - 1
lines[runCommandIndex] = RUN_JAVA
val disconnectedIndex = lines.indexOfFirst { it.startsWith(DISCONNECT_PREFIX) }
lines[disconnectedIndex] = DISCONNECT_PREFIX
return lines.filter { !(it.matches(JDI_BUG_OUTPUT_PATTERN_1) || it.matches(JDI_BUG_OUTPUT_PATTERN_2)) }.joinToString("\n")
}
private fun buildOutputString(): String {
// Call base method with reflection
val m = OutputChecker::class.java.getDeclaredMethod("buildOutputString")!!
val isAccessible = m.isAccessible
try {
m.isAccessible = true
return m.invoke(this) as String
}
finally {
m.isAccessible = isAccessible
}
}
}
@@ -1,101 +0,0 @@
/*
* 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.folding;
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
import com.intellij.codeInsight.folding.impl.JavaCodeFoldingSettingsImpl;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase;
import org.jetbrains.kotlin.test.SettingsConfigurator;
import org.junit.Assert;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.function.Consumer;
public abstract class AbstractKotlinFoldingTest extends KotlinLightCodeInsightFixtureTestCase {
protected void doTest(@NotNull String path) {
myFixture.testFolding(path);
}
protected void doSettingsFoldingTest(@NotNull String path) throws IOException{
String fileText = FileUtil.loadFile(new File(path), true);
String directText = fileText.replaceAll("~true~", "true").replaceAll("~false~", "false");
directText += "\n\n// Generated from: " + path;
Consumer<String> doExpandSettingsTestFunction = this::doExpandSettingsTest;
doTestWithSettings(directText, doExpandSettingsTestFunction);
String invertedText = fileText
.replaceAll("~false~", "true").replaceAll("~true~", "false")
.replaceAll(SettingsConfigurator.SET_TRUE_DIRECTIVE, "~TEMP_TRUE_DIRECTIVE~")
.replaceAll(SettingsConfigurator.SET_FALSE_DIRECTIVE, SettingsConfigurator.SET_TRUE_DIRECTIVE)
.replaceAll("~TEMP_TRUE_DIRECTIVE~", SettingsConfigurator.SET_FALSE_DIRECTIVE);
invertedText += "\n\n// Generated from: " + path + " with !INVERTED! settings";
doTestWithSettings(invertedText, doExpandSettingsTestFunction);
}
protected static void doTestWithSettings(@NotNull String fileText, @NotNull Consumer<String> runnable) {
JavaCodeFoldingSettings settings = JavaCodeFoldingSettings.getInstance();
JavaCodeFoldingSettingsImpl restoreSettings = new JavaCodeFoldingSettingsImpl();
restoreSettings.loadState((JavaCodeFoldingSettingsImpl) settings);
try {
SettingsConfigurator configurator = new SettingsConfigurator(fileText, settings);
configurator.configureSettings();
runnable.accept(fileText);
}
finally {
((JavaCodeFoldingSettingsImpl) JavaCodeFoldingSettings.getInstance()).loadState(restoreSettings);
}
}
private void doExpandSettingsTest(String fileText) {
try {
VirtualFile tempFile = PlatformTestCase.createTempFile("kt", null, fileText, Charset.defaultCharset());
assertFoldingRegionsForFile(tempFile.getPath());
}
catch (IOException e) {
throw new IllegalStateException(e);
}
}
// Rewritten version of CodeInsightTestFixtureImpl.testFoldingRegions(verificationFileName, true).
// Configure test with custom file name to force creating different editors for normal and inverted tests.
private void assertFoldingRegionsForFile(String verificationFileName) {
String START_FOLD = "<fold\\stext=\'[^\']*\'(\\sexpand=\'[^\']*\')*>";
String END_FOLD = "</fold>";
String expectedContent;
File file = new File(verificationFileName);
try {
expectedContent = FileUtil.loadFile(file);
}
catch (IOException e) {
throw new RuntimeException(e);
}
Assert.assertNotNull(expectedContent);
expectedContent = StringUtil.replace(expectedContent, "\r", "");
String cleanContent = expectedContent.replaceAll(START_FOLD, "").replaceAll(END_FOLD, "");
myFixture.configureByText(file.getName(), cleanContent);
String actual = ((CodeInsightTestFixtureImpl)myFixture).getFoldingDescription(true);
Assert.assertEquals(expectedContent, actual);
}
}
@@ -1,215 +0,0 @@
/*
* 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.multiplatform
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.module.Module
import com.intellij.openapi.module.StdModuleTypes
import com.intellij.openapi.roots.CompilerModuleExtension
import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.testFramework.PlatformTestCase
import junit.framework.TestCase
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
import org.jetbrains.kotlin.idea.framework.JSLibraryKind
import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest
import org.jetbrains.kotlin.idea.stubs.createFacet
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.platform.IdePlatform
import org.jetbrains.kotlin.platform.impl.*
import org.jetbrains.kotlin.test.TestJdkKind
import java.io.File
// allows to configure a test mpp project
// testRoot is supposed to contain several directories which contain module sources roots
// configuration is based on those directories names
fun AbstractMultiModuleTest.setupMppProjectFromDirStructure(testRoot: File) {
assert(testRoot.isDirectory) { testRoot.absolutePath + " must be a directory" }
val dirs = testRoot.listFiles().filter { it.isDirectory }
val rootInfos = dirs.map { parseDirName(it) }
val infosByModuleId = rootInfos.groupBy { it.moduleId }
val modulesById = infosByModuleId.mapValues { (moduleId, infos) ->
createModuleWithRoots(moduleId, infos)
}
infosByModuleId.entries.forEach { (id, rootInfos) ->
val module = modulesById[id]!!
rootInfos.flatMap { it.dependencies }.forEach {
val platform = id.platform
when (it) {
is ModuleDependency -> module.addDependency(modulesById[it.moduleId]!!)
is StdlibDependency -> {
when {
platform.isCommon -> module.addLibrary(
ForTestCompileRuntime.stdlibCommonForTests(), kind = CommonLibraryKind
)
platform.isJvm -> module.addLibrary(ForTestCompileRuntime.runtimeJarForTests())
platform.isJavaScript -> module.addLibrary(ForTestCompileRuntime.stdlibJsForTests(), kind = JSLibraryKind)
else -> error("Unknown platform $this")
}
}
is FullJdkDependency -> {
ConfigLibraryUtil.configureSdk(module, PluginTestCaseBase.addJdk(testRootDisposable) {
PluginTestCaseBase.jdk(TestJdkKind.FULL_JDK)
})
}
is CoroutinesDependency -> module.enableCoroutines()
is KotlinTestDependency -> when {
platform.isJvm -> module.addLibrary(ForTestCompileRuntime.kotlinTestJUnitJarForTests())
platform.isJavaScript -> module.addLibrary(ForTestCompileRuntime.kotlinTestJsJarForTests(), kind = JSLibraryKind)
}
}
}
}
modulesById.forEach { (nameAndPlatform, module) ->
val (name, platform) = nameAndPlatform
when {
platform.isCommon -> module.createFacet(platform, useProjectSettings = false)
else -> {
val commonModuleId = ModuleId(name, CommonIdePlatformKind.Platform)
module.createFacet(platform, implementedModuleName = commonModuleId.ideaModuleName())
module.enableMultiPlatform()
modulesById[commonModuleId]?.let { commonModule ->
module.addDependency(commonModule)
}
}
}
}
}
private fun AbstractMultiModuleTest.createModuleWithRoots(
moduleId: ModuleId,
infos: List<RootInfo>
): Module {
val module = createModule(moduleId.ideaModuleName())
for ((_, isTestRoot, moduleRoot) in infos) {
addRoot(module, moduleRoot, isTestRoot)
if (moduleId.platform.isJavaScript && isTestRoot) {
setupJsTestOutput(module)
}
}
return module
}
// test line markers for JS do not work without additional setup
private fun setupJsTestOutput(module: Module) {
ModuleRootModificationUtil.updateModel(module) {
with(it.getModuleExtension(CompilerModuleExtension::class.java)!!) {
inheritCompilerOutputPath(false)
setCompilerOutputPathForTests("js_out")
}
}
}
private fun AbstractMultiModuleTest.createModule(name: String): Module {
val moduleDir = PlatformTestCase.createTempDir("")
val module = createModule(moduleDir.toString() + "/" + name, StdModuleTypes.JAVA)
val root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(moduleDir)
TestCase.assertNotNull(root)
object : WriteCommandAction.Simple<Unit>(module.project) {
@Throws(Throwable::class)
override fun run() {
root!!.refresh(false, true)
}
}.execute().throwException()
return module
}
private val testSuffixes = setOf("test", "tests")
private val platformNames = mapOf(
listOf("header", "common", "expect") to CommonIdePlatformKind.Platform,
listOf("java", "jvm") to JvmIdePlatformKind.defaultPlatform,
listOf("java8", "jvm8") to JvmIdePlatformKind.Platform(JvmTarget.JVM_1_8),
listOf("java6", "jvm6") to JvmIdePlatformKind.Platform(JvmTarget.JVM_1_6),
listOf("js", "javascript") to JsIdePlatformKind.Platform
)
private fun parseDirName(dir: File): RootInfo {
val parts = dir.name.split("_")
return RootInfo(parseModuleId(parts), parseIsTestRoot(parts), dir, parseDependencies(parts))
}
private fun parseDependencies(parts: List<String>) =
parts.filter { it.startsWith("dep(") && it.endsWith(")") }.map {
parseDependency(it)
}
private fun parseDependency(it: String): Dependency {
val dependencyString = it.removePrefix("dep(").removeSuffix(")")
return when {
dependencyString.equals("stdlib", ignoreCase = true) -> StdlibDependency
dependencyString.equals("fulljdk", ignoreCase = true) -> FullJdkDependency
dependencyString.equals("coroutines", ignoreCase = true) -> CoroutinesDependency
dependencyString.equals("kotlin-test", ignoreCase = true) -> KotlinTestDependency
else -> ModuleDependency(parseModuleId(dependencyString.split("-")))
}
}
private fun parseModuleId(parts: List<String>): ModuleId {
val platform = parsePlatform(parts)
val name = parseModuleName(parts)
val id = parseIndex(parts) ?: 0
assert(id == 0 || !platform.isCommon)
return ModuleId(name, platform, id)
}
private fun parsePlatform(parts: List<String>) =
platformNames.entries.single { (names, _) ->
names.any { name -> parts.any { part -> part.equals(name, ignoreCase = true) } }
}.value
private fun parseModuleName(parts: List<String>) = when {
parts.size > 1 -> parts.first()
else -> "testModule"
}
private fun parseIsTestRoot(parts: List<String>) =
testSuffixes.any { suffix -> parts.any { it.equals(suffix, ignoreCase = true) } }
private fun parseIndex(parts: List<String>): Int? {
return parts.singleOrNull() { it.startsWith("id") }?.substringAfter("id")?.toInt()
}
private data class ModuleId(
val groupName: String,
val platform: IdePlatform<*, *>,
val index: Int = 0
) {
fun ideaModuleName(): String {
val suffix = "_$index".takeIf { index != 0 } ?: ""
return "${groupName}_${platform.presentableName}$suffix"
}
}
private val IdePlatform<*, *>.presentableName: String
get() = when {
isCommon -> "Common"
isJvm -> "JVM"
isJavaScript -> "JS"
else -> error("Unknown platform $this")
}
private data class RootInfo(
val moduleId: ModuleId,
val isTestRoot: Boolean,
val moduleRoot: File,
val dependencies: List<Dependency>
)
private sealed class Dependency
private class ModuleDependency(val moduleId: ModuleId) : Dependency()
private object StdlibDependency : Dependency()
private object FullJdkDependency : Dependency()
private object CoroutinesDependency : Dependency()
private object KotlinTestDependency : Dependency()
@@ -1,422 +0,0 @@
/*
* 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.quickfix
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.lang.jvm.JvmElement
import com.intellij.lang.jvm.JvmModifier
import com.intellij.lang.jvm.actions.*
import com.intellij.lang.jvm.types.JvmSubstitutor
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Pair.pair
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiJvmSubstitutor
import com.intellij.psi.PsiSubstitutor
import com.intellij.psi.PsiType
import com.intellij.psi.codeStyle.SuggestedNameInfo
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.search.allScope
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.uast.UParameter
import org.jetbrains.uast.UastContext
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
import org.jetbrains.uast.toUElement
import org.junit.Assert
import org.junit.runner.RunWith
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
private class SimpleMethodRequest(
project: Project,
private val methodName: String,
private val modifiers: Collection<JvmModifier> = emptyList(),
private val returnType: ExpectedTypes = emptyList(),
private val annotations: Collection<AnnotationRequest> = emptyList(),
private val parameters: List<Pair<SuggestedNameInfo, List<ExpectedType>>> = emptyList(),
private val targetSubstitutor: JvmSubstitutor = PsiJvmSubstitutor(project, PsiSubstitutor.EMPTY)
) : CreateMethodRequest {
override fun getTargetSubstitutor(): JvmSubstitutor = targetSubstitutor
override fun getModifiers() = modifiers
override fun getMethodName() = methodName
override fun getAnnotations() = annotations
override fun getParameters() = parameters
override fun getReturnType() = returnType
override fun isValid(): Boolean = true
}
private class NameInfo(vararg names: String) : SuggestedNameInfo(names)
override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
fun testMakeNotFinal() {
myFixture.configureByText("foo.kt", """
class Foo {
fun bar<caret>(){}
}
""")
myFixture.launchAction(
createModifierActions(
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.FINAL, false)
).findWithText("Make 'bar' open")
)
myFixture.checkResult("""
class Foo {
open fun bar(){}
}
""")
}
fun testMakePrivate() {
myFixture.configureByText("foo.kt", """
class Foo<caret> {
fun bar(){}
}
""")
myFixture.launchAction(
createModifierActions(
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PRIVATE, true)
).findWithText("Make 'Foo' private")
)
myFixture.checkResult("""
private class Foo {
fun bar(){}
}
""")
}
fun testMakeNotPrivate() {
myFixture.configureByText("foo.kt", """
private class Foo<caret> {
fun bar(){}
}
""".trim())
myFixture.launchAction(
createModifierActions(
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PRIVATE, false)
).findWithText("Remove 'private' modifier")
)
myFixture.checkResult("""
class Foo {
fun bar(){}
}
""".trim(), true)
}
fun testMakePrivatePublic() {
myFixture.configureByText(
"foo.kt", """class Foo {
| private fun <caret>bar(){}
|}""".trim().trimMargin()
)
myFixture.launchAction(
createModifierActions(
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PUBLIC, true)
).findWithText("Remove 'private' modifier")
)
myFixture.checkResult(
"""class Foo {
| fun <caret>bar(){}
|}""".trim().trimMargin(), true
)
}
fun testMakeProtectedPublic() {
myFixture.configureByText(
"foo.kt", """open class Foo {
| protected fun <caret>bar(){}
|}""".trim().trimMargin()
)
myFixture.launchAction(
createModifierActions(
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PUBLIC, true)
).findWithText("Remove 'protected' modifier")
)
myFixture.checkResult(
"""open class Foo {
| fun <caret>bar(){}
|}""".trim().trimMargin(), true
)
}
fun testMakeInternalPublic() {
myFixture.configureByText(
"foo.kt", """class Foo {
| internal fun <caret>bar(){}
|}""".trim().trimMargin()
)
myFixture.launchAction(
createModifierActions(
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PUBLIC, true)
).findWithText("Remove 'internal' modifier")
)
myFixture.checkResult(
"""class Foo {
| fun <caret>bar(){}
|}""".trim().trimMargin(), true
)
}
fun testDontMakePublicPublic() {
myFixture.configureByText(
"foo.kt", """class Foo {
| fun <caret>bar(){}
|}""".trim().trimMargin()
)
assertEmpty(createModifierActions(myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PUBLIC, true)))
}
fun testDontMakeFunInObjectsOpen() {
myFixture.configureByText("foo.kt", """
object Foo {
fun bar<caret>(){}
}
""".trim())
assertEmpty(createModifierActions(myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.FINAL, false)))
}
fun testAddVoidVoidMethod() {
myFixture.configureByText("foo.kt", """
|class Foo<caret> {
| fun bar() {}
|}
""".trim().trimMargin())
myFixture.launchAction(
createMethodActions(
myFixture.atCaret(),
methodRequest(project, "baz", JvmModifier.PRIVATE, PsiType.VOID)
).findWithText("Add method 'baz' to 'Foo'")
)
myFixture.checkResult("""
|class Foo {
| fun bar() {}
| private fun baz() {
|
| }
|}
""".trim().trimMargin(), true)
}
fun testAddIntIntMethod() {
myFixture.configureByText("foo.kt", """
|class Foo<caret> {
| fun bar() {}
|}
""".trim().trimMargin())
myFixture.launchAction(
createMethodActions(
myFixture.atCaret(),
SimpleMethodRequest(project,
methodName = "baz",
modifiers = listOf(JvmModifier.PUBLIC),
returnType = expectedTypes(PsiType.INT),
parameters = expectedParams(PsiType.INT))
).findWithText("Add method 'baz' to 'Foo'")
)
myFixture.checkResult("""
|class Foo {
| fun bar() {}
| fun baz(param0: Int): Int {
| TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
| }
|}
""".trim().trimMargin(), true)
}
fun testAddIntPrimaryConstructor() {
myFixture.configureByText("foo.kt", """
|class Foo<caret> {
|}
""".trim().trimMargin())
myFixture.launchAction(
createConstructorActions(
myFixture.atCaret(), constructorRequest(project, listOf(pair("param0", PsiType.INT as PsiType)))
).findWithText("Add primary constructor to 'Foo'")
)
myFixture.checkResult("""
|class Foo(param0: Int) {
|}
""".trim().trimMargin(), true)
}
fun testAddIntSecondaryConstructor() {
myFixture.configureByText("foo.kt", """
|class <caret>Foo() {
|}
""".trim().trimMargin())
myFixture.launchAction(
createConstructorActions(
myFixture.atCaret(),
constructorRequest(project, listOf(pair("param0", PsiType.INT as PsiType)))
).findWithText("Add secondary constructor to 'Foo'")
)
myFixture.checkResult("""
|class Foo() {
| constructor(param0: Int) {
|
| }
|}
""".trim().trimMargin(), true)
}
fun testChangePrimaryConstructorInt() {
myFixture.configureByText("foo.kt", """
|class <caret>Foo() {
|}
""".trim().trimMargin())
myFixture.launchAction(
createConstructorActions(
myFixture.atCaret(),
constructorRequest(project, listOf(pair("param0", PsiType.INT as PsiType)))
).findWithText("Add 'int' as 1st parameter to method 'Foo'")
)
myFixture.checkResult("""
|class Foo(param0: Int) {
|}
""".trim().trimMargin(), true)
}
fun testRemoveConstructorParameters() {
myFixture.configureByText("foo.kt", """
|class <caret>Foo(i: Int) {
|}
""".trim().trimMargin())
myFixture.launchAction(
createConstructorActions(
myFixture.atCaret(),
constructorRequest(project, emptyList())
).findWithText("Remove 1st parameter from method 'Foo'")
)
myFixture.checkResult("""
|class Foo() {
|}
""".trim().trimMargin(), true)
}
fun testAddStringVarProperty() {
myFixture.configureByText("foo.kt", """
|class Foo<caret> {
| fun bar() {}
|}
""".trim().trimMargin())
myFixture.launchAction(
createPropertyActions(
myFixture.atCaret(),
MemberRequest.Property(
propertyName = "baz",
visibilityModifier = JvmModifier.PUBLIC,
propertyType = PsiType.getTypeByName("java.lang.String", project, project.allScope()),
getterRequired = true,
setterRequired = true
)
).findWithText("Add 'var' property 'baz' to 'Foo'")
)
myFixture.checkResult("""
|class Foo {
| var baz: String = TODO("initialize me")
|
| fun bar() {}
|}
""".trim().trimMargin(), true)
}
fun testAddLateInitStringVarProperty() {
myFixture.configureByText("foo.kt", """
|class Foo<caret> {
| fun bar() {}
|}
""".trim().trimMargin())
myFixture.launchAction(
createPropertyActions(
myFixture.atCaret(),
MemberRequest.Property(
propertyName = "baz",
visibilityModifier = JvmModifier.PUBLIC,
propertyType = PsiType.getTypeByName("java.lang.String", project, project.allScope()),
getterRequired = true,
setterRequired = true
)
).findWithText("Add 'lateinit var' property 'baz' to 'Foo'")
)
myFixture.checkResult("""
|class Foo {
| lateinit var baz: String
|
| fun bar() {}
|}
""".trim().trimMargin(), true)
}
fun testAddStringValProperty() {
myFixture.configureByText("foo.kt", """
|class Foo<caret> {
| fun bar() {}
|}
""".trim().trimMargin())
myFixture.launchAction(
createPropertyActions(
myFixture.atCaret(),
MemberRequest.Property(
propertyName = "baz",
visibilityModifier = JvmModifier.PUBLIC,
propertyType = PsiType.getTypeByName("java.lang.String", project, project.allScope()),
getterRequired = true,
setterRequired = false
)
).findWithText("Add 'val' property 'baz' to 'Foo'")
)
myFixture.checkResult("""
|class Foo {
| val baz: String = TODO("initialize me")
|
| fun bar() {}
|}
""".trim().trimMargin(), true)
}
private fun makeParams(vararg psyTypes: PsiType): List<UParameter> {
val uastContext = UastContext(myFixture.project)
val factory = JavaPsiFacade.getElementFactory(myFixture.project)
val parameters = psyTypes.mapIndexed { index, psiType -> factory.createParameter("param$index", psiType) }
return parameters.map { uastContext.convertElement(it, null, UParameter::class.java) as UParameter }
}
private fun expectedTypes(vararg psiTypes: PsiType) = psiTypes.map { expectedType(it) }
private fun expectedParams(vararg psyTypes: PsiType) =
psyTypes.mapIndexed { index, psiType -> NameInfo("param$index") to expectedTypes(psiType) }
private inline fun <reified T : JvmElement> CodeInsightTestFixture.atCaret() = elementAtCaret.toUElement() as T
@Suppress("CAST_NEVER_SUCCEEDS")
private fun List<IntentionAction>.findWithText(text: String): IntentionAction =
this.firstOrNull { it.text == text } ?:
Assert.fail("intention with text '$text' was not found, only ${this.joinToString { "\"${it.text}\"" }} available") as Nothing
}
@@ -1,208 +0,0 @@
/*
* 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.refactoring.move
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement
import com.intellij.testFramework.PlatformTestCase
import com.intellij.testFramework.PsiTestUtil
import org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.MoveKotlinDeclarationsHandler
import org.jetbrains.kotlin.idea.refactoring.toPsiDirectory
import org.jetbrains.kotlin.idea.refactoring.toPsiFile
import org.jetbrains.kotlin.idea.test.KotlinMultiFileTestCase
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.idea.test.extractMultipleMarkerOffsets
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
import org.junit.runner.RunWith
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
class MoveKotlinDeclarationsHandlerTest : KotlinMultiFileTestCase() {
override fun getTestDataPath() = PluginTestCaseBase.getTestDataPathBase()
override fun getTestRoot() = "/refactoring/moveHandler/declarations"
private fun doTest(action: (rootDir: VirtualFile, handler: MoveKotlinDeclarationsHandler) -> Unit) {
val path = "$testDataPath$testRoot/${getTestName(true)}"
val rootDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, path, PlatformTestCase.myFilesToDelete, false)
prepareProject(rootDir)
PsiDocumentManager.getInstance(myProject).commitAllDocuments()
action(rootDir, MoveKotlinDeclarationsHandler())
}
private fun getPsiDirectory(rootDir: VirtualFile, path: String) = rootDir.findFileByRelativePath(path)!!.toPsiDirectory(project)!!
private fun getPsiFile(rootDir: VirtualFile, path: String) = rootDir.findFileByRelativePath(path)!!.toPsiFile(project)!!
private fun getElementAtCaret(rootDir: VirtualFile, path: String) = getElementsAtCarets(rootDir, path).single()
private fun getElementsAtCarets(rootDir: VirtualFile, path: String): List<PsiElement> {
val file = getPsiFile(rootDir, path)
val document = FileDocumentManager.getInstance().getDocument(file.virtualFile)!!
return document.extractMultipleMarkerOffsets(project).map { file.findElementAt(it)!! }
}
fun testObjectLiteral() = doTest { rootDir, handler ->
val objectDeclaration = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtObjectDeclaration>()!!
assert(!handler.canMove(arrayOf<PsiElement>(objectDeclaration), null))
}
fun testLocalClass() = doTest { rootDir, handler ->
val klass = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtClass>()!!
assert(!handler.canMove(arrayOf<PsiElement>(klass), null))
}
fun testLocalFun() = doTest { rootDir, handler ->
val function = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtNamedFunction>()!!
assert(!handler.canMove(arrayOf<PsiElement>(function), null))
}
fun testLocalVal() = doTest { rootDir, handler ->
val property = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtProperty>()!!
assert(!handler.canMove(arrayOf<PsiElement>(property), null))
}
fun testMemberFun() = doTest { rootDir, handler ->
val function = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtNamedFunction>()!!
assert(!handler.canMove(arrayOf<PsiElement>(function), null))
}
fun testMemberVal() = doTest { rootDir, handler ->
val property = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtProperty>()!!
assert(!handler.canMove(arrayOf<PsiElement>(property), null))
}
fun testNestedClass() = doTest { rootDir, handler ->
val klass = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtClass>()!!
assert(handler.canMove(arrayOf<PsiElement>(klass), null))
}
fun testInnerClass() = doTest { rootDir, handler ->
val klass = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtClass>()!!
assert(handler.canMove(arrayOf<PsiElement>(klass), null))
}
fun testTopLevelClass() = doTest { rootDir, handler ->
val klass = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtClass>()!!
assert(handler.canMove(arrayOf<PsiElement>(klass), null))
}
fun testTopLevelFun() = doTest { rootDir, handler ->
val function = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtNamedFunction>()!!
assert(handler.canMove(arrayOf<PsiElement>(function), null))
}
fun testTopLevelVal() = doTest { rootDir, handler ->
val property = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtProperty>()!!
assert(handler.canMove(arrayOf<PsiElement>(property), null))
}
fun testMultipleNestedClasses() = doTest { rootDir, handler ->
val classes = getElementsAtCarets(rootDir, "test.kt").map { it.getNonStrictParentOfType<KtClass>()!! }
assert(handler.canMove(classes.toTypedArray(), null))
}
fun testNestedAndTopLevelClass() = doTest { rootDir, handler ->
val classes = getElementsAtCarets(rootDir, "test.kt").map { it.getNonStrictParentOfType<KtClass>()!! }
assert(!handler.canMove(classes.toTypedArray(), null))
}
fun testMultipleTopLevelDeclarations() = doTest { rootDir, handler ->
val declarations = getElementsAtCarets(rootDir, "test.kt").map { it.getNonStrictParentOfType<KtNamedDeclaration>()!! }
assert(handler.canMove(declarations.toTypedArray(), null))
}
fun testMultipleTopLevelDeclarationsInDifferentFiles() = doTest { rootDir, handler ->
val declarations = listOf("test.kt", "test2.kt")
.flatMap { getElementsAtCarets(rootDir, it) }
.map { it.getNonStrictParentOfType<KtNamedDeclaration>()!! }
assert(handler.canMove(declarations.toTypedArray(), null))
val files = listOf("test.kt", "test2.kt").map { getPsiFile(rootDir, it) }
assert(handler.canMove(files.toTypedArray(), null))
}
fun testMultipleTopLevelDeclarationsInDifferentDirs() = doTest { rootDir, handler ->
val declarations = listOf("test1/test.kt", "test2/test2.kt")
.flatMap { getElementsAtCarets(rootDir, it) }
.map { it.getNonStrictParentOfType<KtNamedDeclaration>()!! }
assert(!handler.canMove(declarations.toTypedArray(), null))
val files = listOf("test1/test.kt", "test2/test2.kt").map { getPsiFile(rootDir, it) }
assert(!handler.canMove(files.toTypedArray(), null))
}
fun testFileAndTopLevelDeclarations() = doTest { rootDir, handler ->
val elements = getElementsAtCarets(rootDir, "test.kt").map { it.getNonStrictParentOfType<KtNamedDeclaration>()!! } +
getPsiFile(rootDir, "test2.kt")
assert(!handler.canMove(elements.toTypedArray(), null))
}
fun testCommonTargets() = doTest { rootDir, handler ->
val elementsToMove = arrayOf<PsiElement>(getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtClass>()!!)
val targetPackage = JavaPsiFacade.getInstance(project).findPackage("pack")!!
assert(handler.canMove(elementsToMove, targetPackage))
val targetDirectory = getPsiDirectory(rootDir, "pack")
assert(handler.canMove(elementsToMove, targetDirectory))
val targetFile = getPsiFile(rootDir, "pack/test2.kt")
assert(handler.canMove(elementsToMove, targetFile))
}
fun testTopLevelClassToClass() = doTest { rootDir, handler ->
val elementsToMove = arrayOf<PsiElement>(getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtClass>()!!)
val targetFile = getPsiFile(rootDir, "test2.kt") as KtFile
val topLevelTarget = targetFile.declarations.firstIsInstance<KtClass>()
assert(topLevelTarget.name == "B")
assert(!handler.canMove(elementsToMove, topLevelTarget))
val annotationTarget = targetFile.declarations.first { it.name == "Ann" } as KtClass
assert(!handler.canMove(elementsToMove, annotationTarget))
val nestedTarget = topLevelTarget.declarations.firstIsInstance<KtClass>()
assert(nestedTarget.name == "C")
assert(!handler.canMove(elementsToMove, nestedTarget))
}
fun testNestedClassToClass() = doTest { rootDir, handler ->
val elementsToMove = arrayOf<PsiElement>(getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtClass>()!!)
val targetFile = getPsiFile(rootDir, "test2.kt") as KtFile
val topLevelTarget = targetFile.declarations.firstIsInstance<KtClass>()
assert(topLevelTarget.name == "B")
assert(handler.canMove(elementsToMove, topLevelTarget))
val annotationTarget = targetFile.declarations.first { it.name == "Ann" } as KtClass
assert(!handler.canMove(elementsToMove, annotationTarget))
val nestedTarget = topLevelTarget.declarations.firstIsInstance<KtClass>()
assert(nestedTarget.name == "C")
assert(handler.canMove(elementsToMove, nestedTarget))
}
fun testTypeAlias() = doTest { rootDir, handler ->
val typeAlias = getElementAtCaret(rootDir, "test.kt").getNonStrictParentOfType<KtTypeAlias>()!!
assert(handler.canMove(arrayOf<PsiElement>(typeAlias), null))
}
fun testTopLevelFunInScript() = doTest { rootDir, handler ->
val function = getElementAtCaret(rootDir, "test.kts").getNonStrictParentOfType<KtNamedFunction>()!!
assert(handler.canMove(arrayOf<PsiElement>(function), null))
}
fun testTopLevelValInScript() = doTest { rootDir, handler ->
val property = getElementAtCaret(rootDir, "test.kts").getNonStrictParentOfType<KtProperty>()!!
assert(handler.canMove(arrayOf<PsiElement>(property), null))
}
}
@@ -1,297 +0,0 @@
/*
* 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.run
import com.intellij.execution.Location
import com.intellij.execution.PsiLocation
import com.intellij.execution.actions.ConfigurationContext
import com.intellij.openapi.module.Module
import com.intellij.openapi.projectRoots.Sdk
import com.intellij.openapi.roots.ModuleRootModificationUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiManager
import com.intellij.refactoring.RefactoringFactory
import com.intellij.testFramework.MapDataContext
import com.intellij.testFramework.PlatformTestCase
import com.intellij.testFramework.PsiTestUtil
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.idea.MainFunctionDetector
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
import org.jetbrains.kotlin.idea.search.allScope
import org.jetbrains.kotlin.idea.stubindex.KotlinFullClassNameIndex
import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
import org.jetbrains.kotlin.idea.test.KotlinCodeInsightTestCase
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase.*
import org.jetbrains.kotlin.idea.test.configureLanguageAndApiVersion
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.allChildren
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
import org.junit.Assert
import org.junit.runner.RunWith
import java.io.File
import java.util.*
private val RUN_PREFIX = "// RUN:"
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
class RunConfigurationTest: KotlinCodeInsightTestCase() {
fun getTestProject() = myProject!!
override fun getModule() = myModule!!
fun testMainInTest() {
val createResult = configureModule(moduleDirPath("module"), getTestProject().baseDir!!)
configureLanguageAndApiVersion(
createResult.module.project, createResult.module, LanguageVersionSettingsImpl.DEFAULT.languageVersion.versionString
)
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(createResult.module, addJdk(testRootDisposable, ::mockJdk))
val runConfiguration = createConfigurationFromMain("some.main")
val javaParameters = getJavaRunParameters(runConfiguration)
Assert.assertTrue(javaParameters.classPath.rootDirs.contains(createResult.srcOutputDir))
Assert.assertTrue(javaParameters.classPath.rootDirs.contains(createResult.testOutputDir))
fun functionVisitor(function: KtNamedFunction) {
val options = function.bodyExpression?.allChildren?.filterIsInstance<PsiComment>()?.map { it.text.trim().replace("//", "").trim() }?.filter { it.isNotBlank() }?.toList() ?: emptyList()
if (options.isNotEmpty()) {
val assertIsMain = "yes" in options
val assertIsNotMain = "no" in options
val isMainFunction =
MainFunctionDetector(LanguageVersionSettingsImpl.DEFAULT) { it.resolveToDescriptorIfAny() }.isMain(function)
if (assertIsMain) {
Assert.assertTrue("The function ${function.fqName?.asString()} should be main", isMainFunction)
}
if (assertIsNotMain) {
Assert.assertFalse("The function ${function.fqName?.asString()} should NOT be main", isMainFunction)
}
if (isMainFunction) {
createConfigurationFromMain(function.fqName?.asString()!!).checkConfiguration()
Assert.assertNotNull("Kotlin configuration producer should produce configuration for ${function.fqName?.asString()}",
KotlinRunConfigurationProducer.getEntryPointContainer(function))
} else {
try {
createConfigurationFromMain(function.fqName?.asString()!!).checkConfiguration()
Assert.fail("configuration for function ${function.fqName?.asString()} at least shouldn't pass checkConfiguration()")
} catch (expected: Throwable) {
}
if (function.containingFile.text.startsWith("// entryPointExists")) {
Assert.assertNotNull(
"Kotlin configuration producer should produce configuration for ${function.fqName?.asString()}",
KotlinRunConfigurationProducer.getEntryPointContainer(function)
)
} else {
Assert.assertNull(
"Kotlin configuration producer shouldn't produce configuration for ${function.fqName?.asString()}",
KotlinRunConfigurationProducer.getEntryPointContainer(function)
)
}
}
}
}
createResult.srcDir.children.filter { it.extension == "kt" }.forEach {
val psiFile = PsiManager.getInstance(createResult.module.project).findFile(it)
if (psiFile is KtFile) {
psiFile.acceptChildren(object : KtVisitorVoid() {
override fun visitNamedFunction(function: KtNamedFunction) {
functionVisitor(function)
}
})
}
}
}
fun testDependencyModuleClasspath() {
val dependencyModuleSrcDir = configureModule(moduleDirPath("module"), getTestProject().baseDir!!).srcOutputDir
val moduleWithDependencyDir = runWriteAction { getTestProject().baseDir!!.createChildDirectory(this, "moduleWithDependency") }
val moduleWithDependency = createModule("moduleWithDependency")
ModuleRootModificationUtil.setModuleSdk(moduleWithDependency, testProjectJdk)
val moduleWithDependencySrcDir = configureModule(
moduleDirPath("moduleWithDependency"), moduleWithDependencyDir, configModule = moduleWithDependency).srcOutputDir
ModuleRootModificationUtil.addDependency(moduleWithDependency, module)
val kotlinRunConfiguration = createConfigurationFromMain("some.test.main")
kotlinRunConfiguration.setModule(moduleWithDependency)
val javaParameters = getJavaRunParameters(kotlinRunConfiguration)
Assert.assertTrue(javaParameters.classPath.rootDirs.contains(dependencyModuleSrcDir))
Assert.assertTrue(javaParameters.classPath.rootDirs.contains(moduleWithDependencySrcDir))
}
fun testLongCommandLine() {
val myModule = configureModule(moduleDirPath("module"), getTestProject().baseDir).module
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(module, addJdk(testRootDisposable, ::mockJdk))
ModuleRootModificationUtil.addDependency(myModule, createLibraryWithLongPaths(project))
val kotlinRunConfiguration = createConfigurationFromMain("some.test.main")
kotlinRunConfiguration.setModule(myModule)
val javaParameters = getJavaRunParameters(kotlinRunConfiguration)
val commandLine = javaParameters.toCommandLine().commandLineString
Assert.assertTrue(commandLine.length < javaParameters.classPath.pathList.joinToString().length)
}
fun testClassesAndObjects() {
doTest(ConfigLibraryUtil::configureKotlinRuntimeAndSdk)
}
fun testInJsModule() {
doTest(ConfigLibraryUtil::configureKotlinJsRuntimeAndSdk)
}
fun testUpdateOnClassRename() {
val createModuleResult = configureModule(moduleDirPath("module"), getTestProject().baseDir!!)
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(createModuleResult.module, addJdk(testRootDisposable, ::mockJdk))
val runConfiguration = createConfigurationFromObject("renameTest.Foo", save = true)
val obj = KotlinFullClassNameIndex.getInstance().get("renameTest.Foo", getTestProject(), getTestProject().allScope()).single()
val rename = RefactoringFactory.getInstance(getTestProject()).createRename(obj, "Bar")
rename.run()
Assert.assertEquals("renameTest.Bar", runConfiguration.MAIN_CLASS_NAME)
}
fun testUpdateOnPackageRename() {
val createModuleResult = configureModule(moduleDirPath("module"), getTestProject().baseDir!!)
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(createModuleResult.module, addJdk(testRootDisposable, ::mockJdk))
val runConfiguration = createConfigurationFromObject("renameTest.Foo", save = true)
val pkg = JavaPsiFacade.getInstance(getTestProject()).findPackage("renameTest")!!
val rename = RefactoringFactory.getInstance(getTestProject()).createRename(pkg, "afterRenameTest")
rename.run()
Assert.assertEquals("afterRenameTest.Foo", runConfiguration.MAIN_CLASS_NAME)
}
fun testWithModuleForJdk6() {
checkModuleInfoName(null, addJdk(testRootDisposable, ::mockJdk))
}
fun testWithModuleForJdk9() {
checkModuleInfoName("MAIN", addJdk(testRootDisposable, ::mockJdk9))
}
fun testWithModuleForJdk9WithoutModuleInfo() {
checkModuleInfoName(null, addJdk(testRootDisposable, ::mockJdk9))
}
private fun checkModuleInfoName(moduleName: String?, sdk: Sdk) {
val module = configureModule(moduleDirPath("module"), getTestProject().baseDir!!).module
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(module, sdk)
val javaParameters = getJavaRunParameters(createConfigurationFromMain("some.main"))
Assert.assertEquals(moduleName, javaParameters.moduleName)
}
private fun doTest(configureRuntime: (Module, Sdk) -> Unit) {
val baseDir = getTestProject().baseDir!!
val createModuleResult = configureModule(moduleDirPath("module"), baseDir)
val srcDir = createModuleResult.srcDir
configureRuntime(createModuleResult.module, addJdk(testRootDisposable, ::mockJdk))
try {
val expectedClasses = ArrayList<String>()
val actualClasses = ArrayList<String>()
val testFile = PsiManager.getInstance(getTestProject()).findFile(srcDir.findFileByRelativePath("test.kt")!!)!!
testFile.accept(
object : KtTreeVisitorVoid() {
override fun visitComment(comment: PsiComment) {
val declaration = comment.getStrictParentOfType<KtNamedDeclaration>()!!
val text = comment.text ?: return
if (!text.startsWith(RUN_PREFIX)) return
val expectedClass = text.substring(RUN_PREFIX.length).trim()
if (expectedClass.isNotEmpty()) expectedClasses.add(expectedClass)
val dataContext = MapDataContext()
dataContext.put(Location.DATA_KEY, PsiLocation(getTestProject(), declaration))
val context = ConfigurationContext.getFromContext(dataContext)
val actualClass = (context.configuration?.configuration as? KotlinRunConfiguration)?.runClass
if (actualClass != null) {
actualClasses.add(actualClass)
}
}
}
)
Assert.assertEquals(expectedClasses, actualClasses)
}
finally {
ConfigLibraryUtil.unConfigureKotlinRuntimeAndSdk(createModuleResult.module, mockJdk())
}
}
private fun createConfigurationFromMain(mainFqn: String): KotlinRunConfiguration {
val mainFunction = KotlinTopLevelFunctionFqnNameIndex.getInstance().get(mainFqn, getTestProject(), getTestProject().allScope()).first()
return createConfigurationFromElement(mainFunction) as KotlinRunConfiguration
}
private fun createConfigurationFromObject(objectFqn: String, save: Boolean = false): KotlinRunConfiguration {
val obj = KotlinFullClassNameIndex.getInstance().get(objectFqn, getTestProject(), getTestProject().allScope()).single()
val mainFunction = obj.declarations.single { it is KtFunction && it.getName() == "main" }
return createConfigurationFromElement(mainFunction, save) as KotlinRunConfiguration
}
private fun configureModule(moduleDir: String, outputParentDir: VirtualFile, configModule: Module = module): CreateModuleResult {
val srcPath = moduleDir + "/src"
val srcDir = PsiTestUtil.createTestProjectStructure(project, configModule, srcPath, PlatformTestCase.myFilesToDelete, true)
val testPath = moduleDir + "/test"
if (File(testPath).exists()) {
val testDir = PsiTestUtil.createTestProjectStructure(project, configModule, testPath, PlatformTestCase.myFilesToDelete, false)
PsiTestUtil.addSourceRoot(module, testDir, true)
}
val (srcOutDir, testOutDir) = runWriteAction {
val outDir = outputParentDir.createChildDirectory(this, "out")
val srcOutDir = outDir.createChildDirectory(this, "production")
val testOutDir = outDir.createChildDirectory(this, "test")
PsiTestUtil.setCompilerOutputPath(configModule, srcOutDir.url, false)
PsiTestUtil.setCompilerOutputPath(configModule, testOutDir.url, true)
Pair(srcOutDir, testOutDir)
}
PsiDocumentManager.getInstance(getTestProject()).commitAllDocuments()
return CreateModuleResult(configModule, srcDir, srcOutDir, testOutDir)
}
private fun moduleDirPath(moduleName: String) = "${testDataPath}${getTestName(false)}/$moduleName"
override fun getTestDataPath() = getTestDataPathBase() + "/run/"
override fun getTestProjectJdk() = mockJdk()
private class CreateModuleResult(
val module: Module,
val srcDir: VirtualFile,
val srcOutputDir: VirtualFile,
val testOutputDir: VirtualFile
)
}
@@ -1,10 +0,0 @@
/*
* 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.test
// BUNCH: 181
@Suppress("IncompatibleAPI")
class HierarchyViewTestFixture : HierarchyViewTestFixtureCompat()
@@ -1,128 +0,0 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.j2k
import com.intellij.codeInsight.ContainerProvider
import com.intellij.codeInsight.NullableNotNullManager
import com.intellij.codeInsight.runner.JavaMainMethodProvider
import com.intellij.core.CoreApplicationEnvironment
import com.intellij.core.JavaCoreApplicationEnvironment
import com.intellij.core.JavaCoreProjectEnvironment
import com.intellij.lang.MetaLanguage
import com.intellij.lang.jvm.facade.JvmElementProvider
import com.intellij.openapi.extensions.Extensions
import com.intellij.openapi.extensions.ExtensionsArea
import com.intellij.openapi.fileTypes.FileTypeExtensionPoint
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.*
import com.intellij.psi.augment.PsiAugmentProvider
import com.intellij.psi.augment.TypeAnnotationModifier
import com.intellij.psi.compiled.ClassFileDecompilers
import com.intellij.psi.impl.JavaClassSupersImpl
import com.intellij.psi.impl.PsiTreeChangePreprocessor
import com.intellij.psi.impl.compiled.ClsCustomNavigationPolicy
import com.intellij.psi.meta.MetaDataContributor
import com.intellij.psi.stubs.BinaryFileStubBuilders
import com.intellij.psi.util.JavaClassSupers
import junit.framework.TestCase
import org.jetbrains.kotlin.utils.PathUtil
import java.io.File
import java.net.URLClassLoader
abstract class AbstractJavaToKotlinConverterForWebDemoTest : TestCase() {
val DISPOSABLE = Disposer.newDisposable()
fun doTest(javaPath: String) {
try {
val fileContents = FileUtil.loadFile(File(javaPath), true)
val javaCoreEnvironment: JavaCoreProjectEnvironment = setUpJavaCoreEnvironment()
translateToKotlin(fileContents, javaCoreEnvironment.project)
}
finally {
Disposer.dispose(DISPOSABLE)
}
}
fun setUpJavaCoreEnvironment(): JavaCoreProjectEnvironment {
Extensions.cleanRootArea(DISPOSABLE)
val area = Extensions.getRootArea()
registerExtensionPoints(area)
val applicationEnvironment = JavaCoreApplicationEnvironment(DISPOSABLE)
val javaCoreEnvironment = object : JavaCoreProjectEnvironment(DISPOSABLE, applicationEnvironment) {
override fun preregisterServices() {
val projectArea = Extensions.getArea(project)
CoreApplicationEnvironment.registerExtensionPoint(projectArea, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java)
CoreApplicationEnvironment.registerExtensionPoint(projectArea, PsiElementFinder.EP_NAME, PsiElementFinder::class.java)
CoreApplicationEnvironment.registerExtensionPoint(projectArea, JvmElementProvider.EP_NAME, JvmElementProvider::class.java)
}
}
javaCoreEnvironment.project.registerService(NullableNotNullManager::class.java, object : NullableNotNullManager(javaCoreEnvironment.project) {
override fun isNullable(owner: PsiModifierListOwner, checkBases: Boolean) = !isNotNull(owner, checkBases)
override fun isNotNull(owner: PsiModifierListOwner, checkBases: Boolean) = true
override fun hasHardcodedContracts(element: PsiElement): Boolean = false
override fun getPredefinedNotNulls() = emptyList<String>()
})
applicationEnvironment.application.registerService(JavaClassSupers::class.java, JavaClassSupersImpl::class.java)
for (root in PathUtil.getJdkClassesRootsFromCurrentJre()) {
javaCoreEnvironment.addJarToClassPath(root)
}
val annotations: File? = findAnnotations()
if (annotations != null && annotations.exists()) {
javaCoreEnvironment.addJarToClassPath(annotations)
}
return javaCoreEnvironment
}
private fun registerExtensionPoints(area: ExtensionsArea) {
CoreApplicationEnvironment.registerExtensionPoint(area, BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, FileContextProvider.EP_NAME, FileContextProvider::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, MetaDataContributor.EP_NAME, MetaDataContributor::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, PsiAugmentProvider.EP_NAME, PsiAugmentProvider::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, ContainerProvider.EP_NAME, ContainerProvider::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, ClsCustomNavigationPolicy.EP_NAME, ClsCustomNavigationPolicy::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, MetaLanguage.EP_NAME, MetaLanguage::class.java)
CoreApplicationEnvironment.registerExtensionPoint(area, JavaModuleSystem.EP_NAME, JavaModuleSystem::class.java)
}
fun findAnnotations(): File? {
var classLoader = JavaToKotlinTranslator::class.java.classLoader
while (classLoader != null) {
val loader = classLoader
if (loader is URLClassLoader) {
for (url in loader.urLs) {
if ("file" == url.protocol && url.file!!.endsWith("/annotations.jar")) {
return File(url.file!!)
}
}
}
classLoader = classLoader.parent
}
return null
}
}
@@ -1,13 +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.jps.build
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.messages.CompilerMessage
fun jpsReportInternalBuilderError(context: CompileContext, error: Throwable) {
KotlinBuilder.LOG.info(error)
}

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