mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 08:31:29 +00:00
Cleanup 191 extension files (KTI-240)
This commit is contained in:
@@ -1,81 +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.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.EnumeratorStringDescriptor
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.File
|
||||
|
||||
abstract class BasicMap<K : Comparable<K>, V>(
|
||||
internal val storageFile: File,
|
||||
keyDescriptor: KeyDescriptor<K>,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) {
|
||||
protected val storage = LazyStorage(storageFile, keyDescriptor, valueExternalizer)
|
||||
|
||||
fun clean() {
|
||||
storage.clean()
|
||||
}
|
||||
|
||||
fun flush(memoryCachesOnly: Boolean) {
|
||||
storage.flush(memoryCachesOnly)
|
||||
}
|
||||
|
||||
fun close() {
|
||||
storage.close()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun dump(): String {
|
||||
return with(StringBuilder()) {
|
||||
with(Printer(this)) {
|
||||
println(this@BasicMap::class.java.simpleName)
|
||||
pushIndent()
|
||||
|
||||
for (key in storage.keys.sorted()) {
|
||||
println("${dumpKey(key)} -> ${dumpValue(storage[key]!!)}")
|
||||
}
|
||||
|
||||
popIndent()
|
||||
}
|
||||
|
||||
this
|
||||
}.toString()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
protected abstract fun dumpKey(key: K): String
|
||||
|
||||
@TestOnly
|
||||
protected abstract fun dumpValue(value: V): String
|
||||
}
|
||||
|
||||
abstract class BasicStringMap<V>(
|
||||
storageFile: File,
|
||||
keyDescriptor: KeyDescriptor<String>,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) : BasicMap<String, V>(storageFile, keyDescriptor, valueExternalizer) {
|
||||
constructor(
|
||||
storageFile: File,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) : this(storageFile, EnumeratorStringDescriptor.INSTANCE, valueExternalizer)
|
||||
|
||||
override fun dumpKey(key: String): String = key
|
||||
}
|
||||
@@ -1,55 +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.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.File
|
||||
|
||||
internal open class ClassOneToManyMap(
|
||||
storageFile: File
|
||||
) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
|
||||
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
|
||||
|
||||
fun add(key: FqName, value: FqName) {
|
||||
storage.append(key.asString(), value.asString())
|
||||
}
|
||||
|
||||
operator fun get(key: FqName): Collection<FqName> =
|
||||
storage[key.asString()]?.map(::FqName) ?: setOf()
|
||||
|
||||
operator fun set(key: FqName, values: Collection<FqName>) {
|
||||
if (values.isEmpty()) {
|
||||
remove(key)
|
||||
return
|
||||
}
|
||||
|
||||
storage[key.asString()] = values.map(FqName::asString)
|
||||
}
|
||||
|
||||
fun remove(key: FqName) {
|
||||
storage.remove(key.asString())
|
||||
}
|
||||
|
||||
fun removeValues(key: FqName, removed: Set<FqName>) {
|
||||
val notRemoved = this[key].filter { it !in removed }
|
||||
this[key] = notRemoved
|
||||
}
|
||||
}
|
||||
|
||||
internal class SubtypesMap(storageFile: File) : ClassOneToManyMap(storageFile)
|
||||
internal class SupertypesMap(storageFile: File) : ClassOneToManyMap(storageFile)
|
||||
@@ -1,122 +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.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.IOUtil
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import com.intellij.util.io.PersistentHashMap
|
||||
import java.io.DataOutput
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
|
||||
/**
|
||||
* It's lazy in a sense that PersistentHashMap is created only on write
|
||||
*/
|
||||
class LazyStorage<K, V>(
|
||||
private val storageFile: File,
|
||||
private val keyDescriptor: KeyDescriptor<K>,
|
||||
private val valueExternalizer: DataExternalizer<V>
|
||||
) {
|
||||
@Volatile
|
||||
private var storage: PersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
if (storageFile.exists()) {
|
||||
storage = createMap()
|
||||
return storage
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
}
|
||||
|
||||
return storage!!
|
||||
}
|
||||
|
||||
val keys: Collection<K>
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
fun append(key: K, value: String) {
|
||||
append(key) { out -> IOUtil.writeUTF(out, value) }
|
||||
}
|
||||
|
||||
fun append(key: K, value: Int) {
|
||||
append(key) { out -> out.writeInt(value) }
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun clean() {
|
||||
try {
|
||||
storage?.close()
|
||||
}
|
||||
catch (ignored: Throwable) {
|
||||
}
|
||||
|
||||
PersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
storage = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun flush(memoryCachesOnly: Boolean) {
|
||||
val existingStorage = storage ?: return
|
||||
|
||||
if (memoryCachesOnly) {
|
||||
if (existingStorage.isDirty) {
|
||||
existingStorage.dropMemoryCaches()
|
||||
}
|
||||
}
|
||||
else {
|
||||
existingStorage.force()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun close() {
|
||||
storage?.close()
|
||||
}
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> =
|
||||
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
|
||||
private fun append(key: K, append: (DataOutput)->Unit) {
|
||||
getStorageOrCreateNew().appendData(key, append)
|
||||
}
|
||||
}
|
||||
@@ -1,42 +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.incremental.storage
|
||||
|
||||
import java.io.File
|
||||
|
||||
internal class LookupMap(storage: File) : BasicMap<LookupSymbolKey, Collection<Int>>(storage, LookupSymbolKeyDescriptor, IntCollectionExternalizer) {
|
||||
override fun dumpKey(key: LookupSymbolKey): String = key.toString()
|
||||
|
||||
override fun dumpValue(value: Collection<Int>): String = value.toString()
|
||||
|
||||
fun add(name: String, scope: String, fileId: Int) {
|
||||
storage.append(LookupSymbolKey(name, scope), fileId)
|
||||
}
|
||||
|
||||
operator fun get(key: LookupSymbolKey): Collection<Int>? = storage[key]
|
||||
|
||||
operator fun set(key: LookupSymbolKey, fileIds: Set<Int>) {
|
||||
storage[key] = fileIds
|
||||
}
|
||||
|
||||
fun remove(key: LookupSymbolKey) {
|
||||
storage.remove(key)
|
||||
}
|
||||
|
||||
val keys: Collection<LookupSymbolKey>
|
||||
get() = storage.keys
|
||||
}
|
||||
@@ -1,62 +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.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import java.io.File
|
||||
|
||||
internal class SourceToJvmNameMap(
|
||||
storageFile: File,
|
||||
pathConverter: FileToPathConverter
|
||||
) : AbstractSourceToOutputMap<JvmClassName>(JvmClassNameTransformer, storageFile, pathConverter)
|
||||
|
||||
internal class SourceToFqNameMap(
|
||||
storageFile: File,
|
||||
pathConverter: FileToPathConverter
|
||||
) : AbstractSourceToOutputMap<FqName>(FqNameTransformer, storageFile, pathConverter)
|
||||
|
||||
internal abstract class AbstractSourceToOutputMap<Name>(
|
||||
private val nameTransformer: NameTransformer<Name>,
|
||||
storageFile: File,
|
||||
private val pathConverter: FileToPathConverter
|
||||
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
|
||||
fun clearOutputsForSource(sourceFile: File) {
|
||||
remove(pathConverter.toPath(sourceFile))
|
||||
}
|
||||
|
||||
fun add(sourceFile: File, className: Name) {
|
||||
storage.append(pathConverter.toPath(sourceFile), nameTransformer.asString(className))
|
||||
}
|
||||
|
||||
fun contains(sourceFile: File): Boolean =
|
||||
pathConverter.toPath(sourceFile) in storage
|
||||
|
||||
operator fun get(sourceFile: File): Collection<Name> =
|
||||
storage[pathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asName)
|
||||
|
||||
fun getFqNames(sourceFile: File): Collection<FqName> =
|
||||
storage[pathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asFqName)
|
||||
|
||||
override fun dumpValue(value: Collection<String>) =
|
||||
value.dumpCollection()
|
||||
|
||||
private fun remove(path: String) {
|
||||
storage.remove(path)
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.asJava.builder
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
|
||||
fun stubComputationTrackerInstance(project: Project): StubComputationTracker? {
|
||||
return ServiceManager.getService(project, StubComputationTracker::class.java)
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
versions.intellijSdk=191.6707.61
|
||||
versions.androidBuildTools=r23.0.1
|
||||
versions.androidDxSources=5.0.0_r2
|
||||
versions.idea.NodeJS=181.3494.12
|
||||
versions.jar.asm-all=7.0.1
|
||||
versions.jar.guava=25.1-jre
|
||||
versions.jar.groovy-all=2.4.15
|
||||
versions.jar.lombok-ast=0.2.3
|
||||
versions.jar.swingx-core=1.6.2-2
|
||||
versions.jar.kxml2=2.3.0
|
||||
versions.jar.streamex=0.6.7
|
||||
versions.jar.gson=2.8.5
|
||||
versions.jar.oro=2.0.8
|
||||
versions.jar.picocontainer=1.2
|
||||
ignore.jar.snappy-in-java=true
|
||||
versions.gradle-api=4.5.1
|
||||
versions.shadow=5.2.0
|
||||
@@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.caches.trackers
|
||||
|
||||
import com.intellij.psi.impl.PsiModificationTrackerImpl
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
@Suppress("unused")
|
||||
val PsiModificationTrackerImpl.isEnableLanguageTrackerCompat get() = isEnableLanguageTracker
|
||||
@@ -1,114 +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.modules;
|
||||
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.roots.ProjectFileIndex;
|
||||
import com.intellij.openapi.vfs.JarFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiJavaFile;
|
||||
import com.intellij.psi.PsiJavaModule;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.light.LightJavaModule;
|
||||
import kotlin.collections.ArraysKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.idea.core.FileIndexUtilsKt;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import static com.intellij.psi.PsiJavaModule.MODULE_INFO_FILE;
|
||||
|
||||
// Copied from com.intellij.codeInsight.daemon.impl.analysis.ModuleHighlightUtil
|
||||
public class ModuleHighlightUtil2 {
|
||||
private static final Attributes.Name MULTI_RELEASE = new Attributes.Name("Multi-Release");
|
||||
|
||||
@Nullable
|
||||
static PsiJavaModule getModuleDescriptor(@NotNull VirtualFile file, @NotNull Project project) {
|
||||
ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(project);
|
||||
if (index.isInLibrary(file)) {
|
||||
VirtualFile root;
|
||||
if ((root = index.getClassRootForFile(file)) != null) {
|
||||
VirtualFile descriptorFile = root.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE);
|
||||
if (descriptorFile == null) {
|
||||
VirtualFile alt = root.findFileByRelativePath("META-INF/versions/9/" + PsiJavaModule.MODULE_INFO_CLS_FILE);
|
||||
if (alt != null && isMultiReleaseJar(root)) {
|
||||
descriptorFile = alt;
|
||||
}
|
||||
}
|
||||
if (descriptorFile != null) {
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(descriptorFile);
|
||||
if (psiFile instanceof PsiJavaFile) {
|
||||
return ((PsiJavaFile) psiFile).getModuleDeclaration();
|
||||
}
|
||||
}
|
||||
else if (root.getFileSystem() instanceof JarFileSystem && "jar".equalsIgnoreCase(root.getExtension())) {
|
||||
return LightJavaModule.getModule(PsiManager.getInstance(project), root);
|
||||
}
|
||||
}
|
||||
else if ((root = index.getSourceRootForFile(file)) != null) {
|
||||
VirtualFile descriptorFile = root.findChild(MODULE_INFO_FILE);
|
||||
if (descriptorFile != null) {
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(descriptorFile);
|
||||
if (psiFile instanceof PsiJavaFile) {
|
||||
return ((PsiJavaFile) psiFile).getModuleDeclaration();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Module module = index.getModuleForFile(file);
|
||||
if (module != null) {
|
||||
boolean isTest = FileIndexUtilsKt.isInTestSourceContentKotlinAware(index, file);
|
||||
VirtualFile modularRoot = ArraysKt.singleOrNull(ModuleRootManager.getInstance(module).getSourceRoots(isTest),
|
||||
root -> root.findChild(MODULE_INFO_FILE) != null);
|
||||
if (modularRoot != null) {
|
||||
VirtualFile moduleInfo = modularRoot.findChild(MODULE_INFO_FILE);
|
||||
assert moduleInfo != null : modularRoot;
|
||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(moduleInfo);
|
||||
if (psiFile instanceof PsiJavaFile) {
|
||||
return ((PsiJavaFile) psiFile).getModuleDeclaration();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isMultiReleaseJar(VirtualFile root) {
|
||||
if (root.getFileSystem() instanceof JarFileSystem) {
|
||||
VirtualFile manifest = root.findFileByRelativePath(JarFile.MANIFEST_NAME);
|
||||
if (manifest != null) {
|
||||
try (InputStream stream = manifest.getInputStream()) {
|
||||
return Boolean.valueOf(new Manifest(stream).getMainAttributes().getValue(MULTI_RELEASE));
|
||||
}
|
||||
catch (IOException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.completion.test.confidence;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.completion.*;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupManager;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.projectRoots.JavaSdk;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ThreeState;
|
||||
import org.apache.commons.lang.SystemUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.completion.test.CompletionTestUtilKt;
|
||||
import org.jetbrains.kotlin.idea.test.TestUtilsKt;
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(JUnit3WithIdeaConfigurationRunner.class)
|
||||
public class KotlinConfidenceTest extends LightCompletionTestCase {
|
||||
private static final String TYPE_DIRECTIVE_PREFIX = "// TYPE:";
|
||||
private final ThreadLocal<Boolean> skipComplete = ThreadLocal.withInitial(() -> false);
|
||||
|
||||
public void testCompleteOnDotOutOfRanges() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testImportAsConfidence() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInBlockOfFunctionLiteral() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testInModifierList() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoAutoCompletionForRangeOperator() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoAutoPopupInString() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testAutoPopupInStringTemplate() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testAutoPopupInStringTemplateAfterDollar() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoAutoPopupInStringTemplateAfterSpace() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNoAutoPopupInRawStringTemplateAfterNewLine() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
TestUtilsKt.invalidateLibraryCache(getProject());
|
||||
}
|
||||
|
||||
protected void doTest() {
|
||||
boolean completeByChars = CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS;
|
||||
|
||||
CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS = true;
|
||||
|
||||
try {
|
||||
skipComplete.set(true);
|
||||
try {
|
||||
configureByFile(getBeforeFileName());
|
||||
} finally {
|
||||
skipComplete.set(false);
|
||||
}
|
||||
|
||||
String text = getEditor().getDocument().getText();
|
||||
boolean noLookup = InTextDirectivesUtils.isDirectiveDefined(text, "// NO_LOOKUP");
|
||||
if (!noLookup) complete(); //This will cause NPE in case of absence of autopopup completion
|
||||
|
||||
List<String> expectedElements = InTextDirectivesUtils.findLinesWithPrefixesRemoved(text, "// ELEMENT:");
|
||||
assertFalse("Can't both expect lookup elements and no lookup", !expectedElements.isEmpty() && noLookup);
|
||||
|
||||
if (noLookup) {
|
||||
assertTrue("Should skip autopopup completion", shouldSkipAutoPopup(getEditor(), getFile()));
|
||||
return;
|
||||
}
|
||||
|
||||
String typeText = getTypeText(text);
|
||||
if (!expectedElements.isEmpty()) {
|
||||
assertContainsItems(ArrayUtil.toStringArray(expectedElements));
|
||||
return;
|
||||
}
|
||||
assertNotNull("You must type something, use // TYPE:", typeText);
|
||||
type(typeText);
|
||||
checkResultByFile(getAfterFileName());
|
||||
}
|
||||
finally {
|
||||
CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS = completeByChars;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTypeText(String text) {
|
||||
String[] directives = InTextDirectivesUtils.findArrayWithPrefixes(text, TYPE_DIRECTIVE_PREFIX);
|
||||
if (directives.length == 0) return null;
|
||||
assertEquals("One directive with \"" + TYPE_DIRECTIVE_PREFIX +"\" expected", 1, directives.length);
|
||||
|
||||
return StringUtil.unquoteString(directives[0]);
|
||||
}
|
||||
|
||||
private String getBeforeFileName() {
|
||||
return getTestName(false) + ".kt";
|
||||
}
|
||||
|
||||
private String getAfterFileName() {
|
||||
return getTestName(false) + ".kt.after";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return new File(CompletionTestUtilKt.getCOMPLETION_TEST_DATA_BASE_PATH(), "/confidence/").getPath() + File.separator;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return JavaSdk.getInstance().createJdk("JDK", SystemUtils.getJavaHome().getAbsolutePath());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void complete() {
|
||||
if (skipComplete.get()) return;
|
||||
new CodeCompletionHandlerBase(CompletionType.BASIC, false, true, true).invokeCompletion(
|
||||
getProject(), getEditor(), 0, false, false);
|
||||
|
||||
LookupImpl lookup = (LookupImpl) LookupManager.getActiveLookup(myEditor);
|
||||
myItems = lookup == null ? null : lookup.getItems().toArray(LookupElement.EMPTY_ARRAY);
|
||||
myPrefix = lookup == null ? null : lookup.itemPattern(lookup.getItems().get(0));
|
||||
}
|
||||
|
||||
private static boolean shouldSkipAutoPopup(Editor editor, PsiFile psiFile) {
|
||||
int offset = editor.getCaretModel().getOffset();
|
||||
int psiOffset = Math.max(0, offset - 1);
|
||||
|
||||
PsiElement elementAt = InjectedLanguageManager.getInstance(psiFile.getProject()).findInjectedElementAt(psiFile, psiOffset);
|
||||
if (elementAt == null) {
|
||||
elementAt = psiFile.findElementAt(psiOffset);
|
||||
}
|
||||
if (elementAt == null) return true;
|
||||
|
||||
Language language = PsiUtilCore.findLanguageFromElement(elementAt);
|
||||
|
||||
for (CompletionConfidence confidence : CompletionConfidenceEP.forLanguage(language)) {
|
||||
ThreeState result = confidence.shouldSkipAutopopup(elementAt, psiFile, offset);
|
||||
if (result != ThreeState.UNSURE) {
|
||||
return result == ThreeState.YES;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.statistics
|
||||
|
||||
import com.intellij.facet.ProjectFacetManager
|
||||
import com.intellij.internal.statistic.beans.UsageDescriptor
|
||||
import com.intellij.internal.statistic.eventLog.FeatureUsageData
|
||||
import com.intellij.internal.statistic.service.fus.collectors.ProjectUsagesCollector
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.idea.KotlinPluginUtil
|
||||
import org.jetbrains.kotlin.idea.configuration.BuildSystemType
|
||||
import org.jetbrains.kotlin.idea.configuration.getBuildSystemType
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacetType
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.project.platform
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.platform.js.isJs
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.platform.konan.isNative
|
||||
|
||||
class ProjectConfigurationCollector : ProjectUsagesCollector() {
|
||||
|
||||
override fun getUsages(project: Project): Set<UsageDescriptor> {
|
||||
val usages = mutableSetOf<UsageDescriptor>()
|
||||
val modulesWithFacet = ProjectFacetManager.getInstance(project).getModulesWithFacet(KotlinFacetType.TYPE_ID)
|
||||
|
||||
if (modulesWithFacet.isNotEmpty()) {
|
||||
val pluginVersion = KotlinPluginUtil.getPluginVersion()
|
||||
modulesWithFacet.forEach {
|
||||
|
||||
val buildSystem = getBuildSystemType(it)
|
||||
val platform = getPlatform(it)
|
||||
val languageVersion = it.languageVersionSettings.languageVersion.versionString
|
||||
|
||||
val data = FeatureUsageData()
|
||||
.addData("pluginVersion", pluginVersion)
|
||||
.addData("system", buildSystem)
|
||||
.addData("platform", platform)
|
||||
.addData("languageVersion", languageVersion)
|
||||
val usageDescriptor = UsageDescriptor("Build", data)
|
||||
usages.add(usageDescriptor)
|
||||
}
|
||||
}
|
||||
return usages
|
||||
}
|
||||
|
||||
private fun getPlatform(it: Module): String {
|
||||
return when {
|
||||
it.platform.isJvm() -> "jvm"
|
||||
it.platform.isJs() -> "js"
|
||||
it.platform.isCommon() -> "common"
|
||||
it.platform.isNative() -> "native"
|
||||
else -> "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBuildSystemType(it: Module): String {
|
||||
val buildSystem = it.getBuildSystemType()
|
||||
return when {
|
||||
buildSystem == BuildSystemType.JPS -> "JPS"
|
||||
buildSystem.toString().toLowerCase().contains("maven") -> "Maven"
|
||||
buildSystem.toString().toLowerCase().contains("gradle") -> "Gradle"
|
||||
else -> "unknown"
|
||||
}
|
||||
}
|
||||
|
||||
override fun getGroupId() = "kotlin.project.configuration"
|
||||
override fun getVersion(): Int = 1
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.cocoapods
|
||||
|
||||
class KotlinCocoaPodsModelResolver
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.externalSystem.model.DataNode
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys
|
||||
import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData
|
||||
import com.intellij.openapi.externalSystem.model.project.AbstractNamedData
|
||||
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.config.ExternalSystemRunTask
|
||||
import org.jetbrains.kotlin.gradle.*
|
||||
import org.jetbrains.kotlin.idea.util.CopyableDataNodeUserDataProperty
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import java.io.File
|
||||
import java.io.Serializable
|
||||
import com.intellij.openapi.externalSystem.model.Key as ExternalKey
|
||||
|
||||
var DataNode<out ModuleData>.kotlinSourceSet: KotlinSourceSetInfo?
|
||||
by CopyableDataNodeUserDataProperty(Key.create("KOTLIN_SOURCE_SET"))
|
||||
|
||||
val DataNode<ModuleData>.kotlinAndroidSourceSets: List<KotlinSourceSetInfo>?
|
||||
get() = ExternalSystemApiUtil.getChildren(this, KotlinAndroidSourceSetData.KEY).firstOrNull()?.data?.sourceSetInfos
|
||||
|
||||
class KotlinSourceSetInfo(val kotlinModule: KotlinModule) : Serializable {
|
||||
var moduleId: String? = null
|
||||
var gradleModuleId: String = ""
|
||||
|
||||
var actualPlatforms: KotlinPlatformContainer = KotlinPlatformContainerImpl()
|
||||
|
||||
@Deprecated("Returns only single TargetPlatform", ReplaceWith("actualPlatforms.actualPlatforms"), DeprecationLevel.ERROR)
|
||||
val platform: KotlinPlatform
|
||||
get() = actualPlatforms.getSinglePlatform()
|
||||
|
||||
var defaultCompilerArguments: CommonCompilerArguments? = null
|
||||
var compilerArguments: CommonCompilerArguments? = null
|
||||
var dependencyClasspath: List<String> = emptyList()
|
||||
var isTestModule: Boolean = false
|
||||
var sourceSetIdsByName: MutableMap<String, String> = LinkedHashMap()
|
||||
var dependsOn: List<String> = emptyList()
|
||||
var externalSystemRunTasks: Collection<ExternalSystemRunTask> = emptyList()
|
||||
}
|
||||
|
||||
class KotlinAndroidSourceSetData(
|
||||
val sourceSetInfos: List<KotlinSourceSetInfo>
|
||||
) : AbstractExternalEntityData(GradleConstants.SYSTEM_ID) {
|
||||
companion object {
|
||||
val KEY = ExternalKey.create(KotlinAndroidSourceSetData::class.java, KotlinTargetData.KEY.processingWeight + 1)
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinTargetData(name: String) : AbstractNamedData(GradleConstants.SYSTEM_ID, name) {
|
||||
var moduleIds: Set<String> = emptySet()
|
||||
var archiveFile: File? = null
|
||||
var konanArtifacts: Collection<KonanArtifactModel>? = null
|
||||
|
||||
companion object {
|
||||
val KEY = ExternalKey.create(KotlinTargetData::class.java, ProjectKeys.MODULE.processingWeight + 1)
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinOutputPathsData(val paths: MultiMap<ExternalSystemSourceType, String>) : AbstractExternalEntityData(GradleConstants.SYSTEM_ID) {
|
||||
companion object {
|
||||
val KEY = ExternalKey.create(KotlinOutputPathsData::class.java, ProjectKeys.CONTENT_ROOT.processingWeight + 1)
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.externalSystem.model.DataNode
|
||||
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.util.io.FileUtil
|
||||
import com.intellij.packaging.impl.artifacts.JarArtifactType
|
||||
import com.intellij.packaging.impl.elements.ProductionModuleOutputPackagingElement
|
||||
import org.jetbrains.kotlin.idea.util.createPointer
|
||||
|
||||
class KotlinTargetDataService : AbstractProjectDataService<KotlinTargetData, Void>() {
|
||||
override fun getTargetDataKey() = KotlinTargetData.KEY
|
||||
|
||||
override fun importData(
|
||||
toImport: MutableCollection<DataNode<KotlinTargetData>>,
|
||||
projectData: ProjectData?,
|
||||
project: Project,
|
||||
modelsProvider: IdeModifiableModelsProvider
|
||||
) {
|
||||
for (nodeToImport in toImport) {
|
||||
val targetData = nodeToImport.data
|
||||
val archiveFile = targetData.archiveFile ?: continue
|
||||
val artifactModel = modelsProvider.modifiableArtifactModel
|
||||
val artifactName = FileUtil.getNameWithoutExtension(archiveFile)
|
||||
artifactModel.findArtifact(artifactName)?.let { artifactModel.removeArtifact(it) }
|
||||
artifactModel.addArtifact(artifactName, JarArtifactType.getInstance()).also {
|
||||
it.outputPath = archiveFile.parent
|
||||
for (moduleId in targetData.moduleIds) {
|
||||
val compilationModuleDataNode = nodeToImport.parent?.findChildModuleById(moduleId) ?: continue
|
||||
val compilationData = compilationModuleDataNode.data
|
||||
val kotlinSourceSet = compilationModuleDataNode.kotlinSourceSet ?: continue
|
||||
if (kotlinSourceSet.isTestModule) continue
|
||||
val moduleToPackage = modelsProvider.findIdeModule(compilationData) ?: continue
|
||||
it.rootElement.addOrFindChild(ProductionModuleOutputPackagingElement(project, moduleToPackage.createPointer()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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
|
||||
|
||||
fun suggestNativeDebug(projectPath: String) {}
|
||||
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.gradle.execution
|
||||
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.toCanonicalPath
|
||||
import org.jetbrains.plugins.gradle.service.settings.GradleSettingsService
|
||||
import com.intellij.openapi.module.Module
|
||||
|
||||
fun isDelegatedBuild(module: Module): Boolean {
|
||||
val projectUrl = module.project.presentableUrl
|
||||
if (projectUrl == null || !GradleSettingsService.getInstance(module.project).isDelegatedBuildEnabled(toCanonicalPath(projectUrl))) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.gradle.testing
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
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.model.task.TaskData
|
||||
import com.intellij.openapi.externalSystem.util.Order
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.util.Consumer
|
||||
import org.gradle.tooling.model.idea.IdeaModule
|
||||
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModel
|
||||
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder
|
||||
import org.jetbrains.kotlin.idea.configuration.getMppModel
|
||||
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
|
||||
|
||||
@Order(Int.MIN_VALUE)
|
||||
open class KotlinTestTasksResolver : AbstractProjectResolverExtension() {
|
||||
companion object {
|
||||
private const val ENABLED_REGISTRY_KEY = "kotlin.gradle.testing.enabled"
|
||||
}
|
||||
|
||||
private val LOG by lazy { Logger.getInstance(KotlinTestTasksResolver::class.java) }
|
||||
|
||||
override fun getToolingExtensionsClasses(): Set<Class<out Any>> {
|
||||
return setOf(KotlinMPPGradleModelBuilder::class.java, Unit::class.java)
|
||||
}
|
||||
|
||||
override fun populateModuleTasks(
|
||||
gradleModule: IdeaModule,
|
||||
ideModule: DataNode<ModuleData>,
|
||||
ideProject: DataNode<ProjectData>
|
||||
): MutableCollection<TaskData> {
|
||||
if (!Registry.`is`(ENABLED_REGISTRY_KEY))
|
||||
return super.populateModuleTasks(gradleModule, ideModule, ideProject)
|
||||
|
||||
val mppModel = resolverCtx.getMppModel(gradleModule)
|
||||
?: return super.populateModuleTasks(gradleModule, ideModule, ideProject)
|
||||
|
||||
return postprocessTaskData(mppModel, ideModule, nextResolver.populateModuleTasks(gradleModule, ideModule, ideProject))
|
||||
}
|
||||
|
||||
private fun postprocessTaskData(
|
||||
mppModel: KotlinMPPGradleModel,
|
||||
ideModule: DataNode<ModuleData>,
|
||||
originalTaskData: MutableCollection<TaskData>
|
||||
): MutableCollection<TaskData> {
|
||||
val testTaskNames = mutableSetOf<String>().apply {
|
||||
mppModel.targets.forEach { target ->
|
||||
target.testRunTasks.forEach { testTaskModel ->
|
||||
add(testTaskModel.taskName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun buildNewTaskDataMarkedAsTest(original: TaskData): TaskData =
|
||||
TaskData(original.owner, original.name, original.linkedExternalProjectPath, original.description).apply {
|
||||
group = original.group
|
||||
type = original.type
|
||||
isInherited = original.isInherited
|
||||
|
||||
isTest = true
|
||||
}
|
||||
|
||||
val replacementMap: Map<TaskData, TaskData> = mutableMapOf<TaskData, TaskData>().apply {
|
||||
originalTaskData.forEach {
|
||||
if (it.name in testTaskNames && !it.isTest) {
|
||||
put(it, buildNewTaskDataMarkedAsTest(it))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ideModule.children.filter { it.data in replacementMap }.forEach { it.clear(true) }
|
||||
replacementMap.values.forEach { ideModule.createChild(ProjectKeys.TASK, it) }
|
||||
|
||||
return originalTaskData.mapTo(arrayListOf<TaskData>()) { replacementMap[it] ?: it }
|
||||
}
|
||||
|
||||
override fun enhanceTaskProcessing(taskNames: MutableList<String>, jvmAgentSetup: String?, initScriptConsumer: Consumer<String>) {
|
||||
if (!Registry.`is`(ENABLED_REGISTRY_KEY))
|
||||
return
|
||||
|
||||
try {
|
||||
//for 191 idea we can't check running task so add listener always
|
||||
val addTestListenerScript = javaClass
|
||||
.getResourceAsStream("/org/jetbrains/kotlin/idea/gradle/testing/addKotlinMppTestListener.groovy")
|
||||
.bufferedReader()
|
||||
.readText()
|
||||
val testLoggerScript = javaClass
|
||||
.getResourceAsStream("/org/jetbrains/kotlin/idea/gradle/testing/KotlinMppTestLogger.groovy")
|
||||
.bufferedReader()
|
||||
.readText()
|
||||
|
||||
initScriptConsumer.consume(buildString {
|
||||
append(addTestListenerScript)
|
||||
append('\n')
|
||||
append(testLoggerScript)
|
||||
})
|
||||
} catch (e: Exception) {
|
||||
LOG.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.actions.ConfigurationFromContext
|
||||
import com.intellij.execution.junit.JUnitConfigurationProducer
|
||||
import com.intellij.execution.testframework.AbstractPatternBasedConfigurationProducer
|
||||
import com.intellij.ide.plugins.PluginManager
|
||||
import com.intellij.openapi.extensions.PluginId.getId
|
||||
import com.intellij.openapi.util.component1
|
||||
import com.intellij.openapi.util.component2
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
|
||||
private val isJUnitEnabled by lazy { isPluginEnabled("JUnit") }
|
||||
private val isTestNgEnabled by lazy { isPluginEnabled("TestNG-J") }
|
||||
|
||||
private fun isPluginEnabled(id: String): Boolean {
|
||||
return PluginManager.isPluginInstalled(getId(id)) && id !in PluginManager.getDisabledPlugins()
|
||||
}
|
||||
|
||||
internal fun ConfigurationFromContext.isJpsJunitConfiguration(): Boolean {
|
||||
return isProducedBy(JUnitConfigurationProducer::class.java)
|
||||
|| isProducedBy(AbstractPatternBasedConfigurationProducer::class.java)
|
||||
}
|
||||
|
||||
internal fun canRunJvmTests() = isJUnitEnabled || isTestNgEnabled
|
||||
|
||||
internal fun getTestClassForJvm(location: Location<*>): PsiClass? {
|
||||
val leaf = location.psiElement ?: return null
|
||||
|
||||
if (leaf.language != KotlinLanguage.INSTANCE) return null
|
||||
|
||||
if (isJUnitEnabled) {
|
||||
KotlinJUnitRunConfigurationProducer.getTestClass(leaf)?.let { return it }
|
||||
}
|
||||
if (isTestNgEnabled) {
|
||||
KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.let { (testClass, testMethod) ->
|
||||
return if (testMethod == null) testClass else null
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
internal fun getTestMethodForJvm(location: Location<*>): PsiMethod? {
|
||||
val leaf = location.psiElement ?: return null
|
||||
|
||||
if (leaf.language != KotlinLanguage.INSTANCE) return null
|
||||
|
||||
if (isJUnitEnabled) {
|
||||
KotlinJUnitRunConfigurationProducer.getTestMethod(leaf)?.let { return it }
|
||||
}
|
||||
if (isTestNgEnabled) {
|
||||
KotlinTestNgConfigurationProducer.getTestClassAndMethod(leaf)?.second?.let { return it }
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.scripting.gradle
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||
import com.intellij.util.concurrency.SequentialTaskExecutor
|
||||
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
|
||||
|
||||
fun addVfsListener(
|
||||
watcher: GradleScriptListener,
|
||||
buildRootsManager: GradleBuildRootsManager
|
||||
) {
|
||||
watcher.project.messageBus.connect().subscribe(
|
||||
VirtualFileManager.VFS_CHANGES,
|
||||
object : BulkFileListener {
|
||||
private val executor =
|
||||
SequentialTaskExecutor.createSequentialApplicationPoolExecutor("GradleScriptInputsWatcherVfsChangesExecutor")
|
||||
|
||||
override fun after(events: List<VFileEvent>) {
|
||||
executor.submit(Runnable {
|
||||
if (watcher.project.isDisposed) return@Runnable
|
||||
for (event in events) {
|
||||
val file = event.file ?: continue
|
||||
if (buildRootsManager.maybeAffectedGradleProjectFile(event.path)) {
|
||||
watcher.fileChanged(event.path, file.timeStamp)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.importing
|
||||
|
||||
class KotlinGradleBuildScriptsResolver
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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("UNUSED_PARAMETER", "unused")
|
||||
|
||||
package org.jetbrains.kotlin.idea.scripting.gradle.importing
|
||||
|
||||
import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId
|
||||
import com.intellij.openapi.project.Project
|
||||
import java.io.File
|
||||
|
||||
class KotlinGradleDslErrorReporter(
|
||||
private val project: Project,
|
||||
private val task: ExternalSystemTaskId
|
||||
) {
|
||||
|
||||
fun reportError(
|
||||
scriptFile: File,
|
||||
model: KotlinDslScriptModel
|
||||
) {
|
||||
// KotlinDslModels aren't imported in 191
|
||||
}
|
||||
}
|
||||
@@ -1,262 +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.codeInsight.gradle;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.StreamUtil;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.codehaus.groovy.runtime.typehandling.ShortTypeHandling;
|
||||
import org.gradle.tooling.BuildActionExecuter;
|
||||
import org.gradle.tooling.GradleConnector;
|
||||
import org.gradle.tooling.ProjectConnection;
|
||||
import org.gradle.tooling.internal.consumer.DefaultGradleConnector;
|
||||
import org.gradle.tooling.model.DomainObjectSet;
|
||||
import org.gradle.tooling.model.idea.IdeaModule;
|
||||
import org.gradle.util.GradleVersion;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.gradle.model.ClassSetProjectImportExtraModelProvider;
|
||||
import org.jetbrains.plugins.gradle.model.ExternalProject;
|
||||
import org.jetbrains.plugins.gradle.model.ProjectImportAction;
|
||||
import org.jetbrains.plugins.gradle.service.execution.GradleExecutionHelper;
|
||||
import org.jetbrains.plugins.gradle.tooling.builder.ModelBuildScriptClasspathBuilderImpl;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.rules.TestName;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
|
||||
// part of org.jetbrains.plugins.gradle.tooling.builder.AbstractModelBuilderTest
|
||||
@RunWith(value = Parameterized.class)
|
||||
public abstract class AbstractModelBuilderTest {
|
||||
|
||||
public static final Object[][] SUPPORTED_GRADLE_VERSIONS = {{"4.9"}, {"5.6.4"}};
|
||||
|
||||
private static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*: with Gradle-.*)\\]");
|
||||
|
||||
private static File ourTempDir;
|
||||
|
||||
@NotNull
|
||||
private final String gradleVersion;
|
||||
private File testDir;
|
||||
private ProjectImportAction.AllModels allModels;
|
||||
|
||||
@Rule public TestName name = new TestName();
|
||||
@Rule public VersionMatcherRule versionMatcherRule = new VersionMatcherRule();
|
||||
|
||||
public AbstractModelBuilderTest(@NotNull String gradleVersion) {
|
||||
this.gradleVersion = gradleVersion;
|
||||
}
|
||||
|
||||
@Parameterized.Parameters(name = "{index}: with Gradle-{0}")
|
||||
public static Collection<Object[]> data() {
|
||||
return Arrays.asList(SUPPORTED_GRADLE_VERSIONS);
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
assumeThat(gradleVersion, versionMatcherRule.getMatcher());
|
||||
|
||||
ensureTempDirCreated();
|
||||
|
||||
String methodName = name.getMethodName();
|
||||
Matcher m = TEST_METHOD_NAME_PATTERN.matcher(methodName);
|
||||
if (m.matches()) {
|
||||
methodName = m.group(1);
|
||||
}
|
||||
|
||||
testDir = new File(ourTempDir, methodName);
|
||||
FileUtil.ensureExists(testDir);
|
||||
|
||||
InputStream buildScriptStream = getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.DEFAULT_SCRIPT_NAME);
|
||||
try {
|
||||
FileUtil.writeToFile(
|
||||
new File(testDir, GradleConstants.DEFAULT_SCRIPT_NAME),
|
||||
FileUtil.loadTextAndClose(buildScriptStream)
|
||||
);
|
||||
}
|
||||
finally {
|
||||
StreamUtil.closeStream(buildScriptStream);
|
||||
}
|
||||
|
||||
InputStream settingsStream = getClass().getResourceAsStream("/" + methodName + "/" + GradleConstants.SETTINGS_FILE_NAME);
|
||||
try {
|
||||
if (settingsStream != null) {
|
||||
FileUtil.writeToFile(
|
||||
new File(testDir, GradleConstants.SETTINGS_FILE_NAME),
|
||||
FileUtil.loadTextAndClose(settingsStream)
|
||||
);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
StreamUtil.closeStream(settingsStream);
|
||||
}
|
||||
|
||||
GradleConnector connector = GradleConnector.newConnector();
|
||||
|
||||
URI distributionUri = new DistributionLocator().getDistributionFor(GradleVersion.version(gradleVersion));
|
||||
connector.useDistribution(distributionUri);
|
||||
connector.forProjectDirectory(testDir);
|
||||
int daemonMaxIdleTime = 10;
|
||||
try {
|
||||
daemonMaxIdleTime = Integer.parseInt(System.getProperty("gradleDaemonMaxIdleTime", "10"));
|
||||
}
|
||||
catch (NumberFormatException ignore) {
|
||||
}
|
||||
|
||||
((DefaultGradleConnector) connector).daemonMaxIdleTime(daemonMaxIdleTime, TimeUnit.SECONDS);
|
||||
ProjectConnection connection = connector.connect();
|
||||
|
||||
try {
|
||||
ProjectImportAction projectImportAction = new ProjectImportAction(false);
|
||||
projectImportAction.addProjectImportExtraModelProvider(new ClassSetProjectImportExtraModelProvider(getModels()));
|
||||
BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
|
||||
File initScript = GradleExecutionHelper.generateInitScript(false, getToolingExtensionClasses());
|
||||
assertNotNull(initScript);
|
||||
String jdkHome = IdeaTestUtil.requireRealJdkHome();
|
||||
buildActionExecutor.setJavaHome(new File(jdkHome));
|
||||
buildActionExecutor.setJvmArguments("-Xmx128m", "-XX:MaxPermSize=64m");
|
||||
buildActionExecutor
|
||||
.withArguments("--info", "--recompile-scripts", GradleConstants.INIT_SCRIPT_CMD_OPTION, initScript.getAbsolutePath());
|
||||
allModels = buildActionExecutor.run();
|
||||
assertNotNull(allModels);
|
||||
}
|
||||
finally {
|
||||
connection.close();
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<Class> getToolingExtensionClasses() {
|
||||
Set<Class> classes = ContainerUtil.<Class>set(
|
||||
ExternalProject.class,
|
||||
// gradle-tooling-extension-api jar
|
||||
ProjectImportAction.class,
|
||||
// gradle-tooling-extension-impl jar
|
||||
ModelBuildScriptClasspathBuilderImpl.class,
|
||||
Multimap.class,
|
||||
ShortTypeHandling.class
|
||||
);
|
||||
|
||||
ContainerUtil.addAllNotNull(classes, doGetToolingExtensionClasses());
|
||||
return classes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<Class> doGetToolingExtensionClasses() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (testDir != null) {
|
||||
FileUtil.delete(testDir);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Set<Class> getModels();
|
||||
|
||||
|
||||
private <T> Map<String, T> getModulesMap(final Class<T> aClass) {
|
||||
DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
|
||||
|
||||
final String filterKey = "to_filter";
|
||||
Map<String, T> map = ContainerUtil.map2Map(ideaModules, new Function<IdeaModule, Pair<String, T>>() {
|
||||
@Override
|
||||
public Pair<String, T> fun(IdeaModule module) {
|
||||
T value = allModels.getExtraProject(module, aClass);
|
||||
String key = value != null ? module.getGradleProject().getPath() : filterKey;
|
||||
return Pair.create(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
map.remove(filterKey);
|
||||
return map;
|
||||
}
|
||||
|
||||
private static void ensureTempDirCreated() throws IOException {
|
||||
if (ourTempDir != null) return;
|
||||
|
||||
ourTempDir = new File(FileUtil.getTempDirectory(), "gradleTests");
|
||||
FileUtil.delete(ourTempDir);
|
||||
FileUtil.ensureExists(ourTempDir);
|
||||
}
|
||||
|
||||
public static class DistributionLocator {
|
||||
private static final String RELEASE_REPOSITORY_ENV = "GRADLE_RELEASE_REPOSITORY";
|
||||
private static final String SNAPSHOT_REPOSITORY_ENV = "GRADLE_SNAPSHOT_REPOSITORY";
|
||||
private static final String GRADLE_RELEASE_REPO = "https://services.gradle.org/distributions";
|
||||
private static final String GRADLE_SNAPSHOT_REPO = "https://services.gradle.org/distributions-snapshots";
|
||||
|
||||
@NotNull private final String myReleaseRepoUrl;
|
||||
@NotNull private final String mySnapshotRepoUrl;
|
||||
|
||||
public DistributionLocator() {
|
||||
this(DistributionLocator.getRepoUrl(false), DistributionLocator.getRepoUrl(true));
|
||||
}
|
||||
|
||||
public DistributionLocator(@NotNull String releaseRepoUrl, @NotNull String snapshotRepoUrl) {
|
||||
myReleaseRepoUrl = releaseRepoUrl;
|
||||
mySnapshotRepoUrl = snapshotRepoUrl;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public URI getDistributionFor(@NotNull GradleVersion version) throws URISyntaxException {
|
||||
return getDistribution(getDistributionRepository(version), version, "gradle", "bin");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getDistributionRepository(@NotNull GradleVersion version) {
|
||||
return version.isSnapshot() ? mySnapshotRepoUrl : myReleaseRepoUrl;
|
||||
}
|
||||
|
||||
private static URI getDistribution(
|
||||
@NotNull String repositoryUrl,
|
||||
@NotNull GradleVersion version,
|
||||
@NotNull String archiveName,
|
||||
@NotNull String archiveClassifier
|
||||
) throws URISyntaxException {
|
||||
return new URI(String.format("%s/%s-%s-%s.zip", repositoryUrl, archiveName, version.getVersion(), archiveClassifier));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String getRepoUrl(boolean isSnapshotUrl) {
|
||||
String envRepoUrl = System.getenv(isSnapshotUrl ? SNAPSHOT_REPOSITORY_ENV : RELEASE_REPOSITORY_ENV);
|
||||
if (envRepoUrl != null) return envRepoUrl;
|
||||
|
||||
return isSnapshotUrl ? GRADLE_SNAPSHOT_REPO : GRADLE_RELEASE_REPO;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.injection
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.util.PsiTreeUtil.getDeepestLast
|
||||
import com.intellij.util.Processor
|
||||
import org.intellij.plugins.intelliLang.Configuration
|
||||
import org.intellij.plugins.intelliLang.inject.*
|
||||
import org.intellij.plugins.intelliLang.inject.config.BaseInjection
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.idea.KotlinJvmBundle
|
||||
import org.jetbrains.kotlin.idea.patterns.KotlinPatterns
|
||||
import org.jetbrains.kotlin.idea.util.addAnnotation
|
||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||
import org.jetbrains.kotlin.idea.util.findAnnotation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.siblings
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
@NonNls
|
||||
val KOTLIN_SUPPORT_ID = "kotlin"
|
||||
|
||||
class KotlinLanguageInjectionSupport : AbstractLanguageInjectionSupport() {
|
||||
override fun getId(): String = KOTLIN_SUPPORT_ID
|
||||
|
||||
override fun getPatternClasses() = arrayOf(KotlinPatterns::class.java)
|
||||
|
||||
override fun isApplicableTo(host: PsiLanguageInjectionHost?) = host is KtElement
|
||||
|
||||
override fun useDefaultInjector(host: PsiLanguageInjectionHost?): Boolean = false
|
||||
|
||||
override fun addInjectionInPlace(language: Language?, host: PsiLanguageInjectionHost?): Boolean {
|
||||
if (language == null || host == null) return false
|
||||
|
||||
val configuration = Configuration.getProjectInstance(host.project).advancedConfiguration
|
||||
if (!configuration.isSourceModificationAllowed) {
|
||||
// It's not allowed to modify code without explicit permission. Postpone adding @Inject or comment till it granted.
|
||||
host.putUserData(InjectLanguageAction.FIX_KEY, Processor { fixHost: PsiLanguageInjectionHost? ->
|
||||
fixHost != null && addInjectionInstructionInCode(language, fixHost)
|
||||
})
|
||||
return false
|
||||
}
|
||||
|
||||
if (!addInjectionInstructionInCode(language, host)) {
|
||||
return false
|
||||
}
|
||||
|
||||
TemporaryPlacesRegistry.getInstance(host.project).addHostWithUndo(host, InjectedLanguage.create(language.id))
|
||||
return true
|
||||
}
|
||||
|
||||
override fun removeInjectionInPlace(psiElement: PsiLanguageInjectionHost?): Boolean {
|
||||
if (psiElement == null || psiElement !is KtElement) return false
|
||||
|
||||
val project = psiElement.getProject()
|
||||
|
||||
val injectInstructions = listOfNotNull(
|
||||
findAnnotationInjection(psiElement),
|
||||
findInjectionComment(psiElement)
|
||||
)
|
||||
|
||||
TemporaryPlacesRegistry.getInstance(project).removeHostWithUndo(project, psiElement)
|
||||
|
||||
project.executeWriteCommand(KotlinJvmBundle.message("command.action.remove.injection.in.code.instructions")) {
|
||||
injectInstructions.forEach(PsiElement::delete)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun findCommentInjection(host: PsiElement, commentRef: Ref<PsiElement>?): BaseInjection? {
|
||||
// Do not inject through CommentLanguageInjector, because it injects as simple injection.
|
||||
// We need to behave special for interpolated strings.
|
||||
return null
|
||||
}
|
||||
|
||||
fun findCommentInjection(host: KtElement): BaseInjection? {
|
||||
return InjectorUtils.findCommentInjection(host, "", null)
|
||||
}
|
||||
|
||||
private fun findInjectionComment(host: KtElement): PsiComment? {
|
||||
val commentRef = Ref.create<PsiElement>(null)
|
||||
InjectorUtils.findCommentInjection(host, "", commentRef) ?: return null
|
||||
|
||||
return commentRef.get() as? PsiComment
|
||||
}
|
||||
|
||||
internal fun findAnnotationInjectionLanguageId(host: KtElement): InjectionInfo? {
|
||||
val annotationEntry = findAnnotationInjection(host) ?: return null
|
||||
val extractLanguageFromInjectAnnotation = extractLanguageFromInjectAnnotation(annotationEntry) ?: return null
|
||||
val prefix = extractStringArgumentByName(annotationEntry, "prefix")
|
||||
val suffix = extractStringArgumentByName(annotationEntry, "suffix")
|
||||
return InjectionInfo(extractLanguageFromInjectAnnotation, prefix, suffix)
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractStringArgumentByName(annotationEntry: KtAnnotationEntry, name: String): String? {
|
||||
val namedArgument: ValueArgument = annotationEntry.valueArguments.firstOrNull { it.getArgumentName()?.asName?.asString() == name } ?: return null
|
||||
return extractStringValue(namedArgument)
|
||||
}
|
||||
|
||||
|
||||
private fun extractLanguageFromInjectAnnotation(annotationEntry: KtAnnotationEntry): String? {
|
||||
val firstArgument: ValueArgument = annotationEntry.valueArguments.firstOrNull() ?: return null
|
||||
return extractStringValue(firstArgument)
|
||||
}
|
||||
|
||||
private fun extractStringValue(valueArgument: ValueArgument): String? {
|
||||
val firstStringArgument = valueArgument.getArgumentExpression() as? KtStringTemplateExpression ?: return null
|
||||
val firstStringEntry = firstStringArgument.entries.singleOrNull() ?: return null
|
||||
|
||||
return firstStringEntry.text
|
||||
}
|
||||
|
||||
private fun findAnnotationInjection(host: KtElement): KtAnnotationEntry? {
|
||||
val modifierListOwner = findElementToInjectWithAnnotation(host) ?: return null
|
||||
|
||||
val modifierList = modifierListOwner.modifierList ?: return null
|
||||
|
||||
// Host can't be before annotation
|
||||
if (host.startOffset < modifierList.endOffset) return null
|
||||
|
||||
return modifierListOwner.findAnnotation(FqName(AnnotationUtil.LANGUAGE))
|
||||
}
|
||||
|
||||
private fun canInjectWithAnnotation(host: PsiElement): Boolean {
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(host) ?: return false
|
||||
val javaPsiFacade = JavaPsiFacade.getInstance(module.project)
|
||||
|
||||
return javaPsiFacade.findClass(AnnotationUtil.LANGUAGE, GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module)) != null
|
||||
}
|
||||
|
||||
private fun findElementToInjectWithAnnotation(host: KtElement): KtModifierListOwner? {
|
||||
return PsiTreeUtil.getParentOfType(
|
||||
host,
|
||||
KtModifierListOwner::class.java,
|
||||
false, /* strict */
|
||||
KtBlockExpression::class.java, KtParameterList::class.java, KtTypeParameterList::class.java /* Stop at */
|
||||
)
|
||||
}
|
||||
|
||||
private fun findElementToInjectWithComment(host: KtElement): KtExpression? {
|
||||
val parentBlockExpression = PsiTreeUtil.getParentOfType(
|
||||
host,
|
||||
KtBlockExpression::class.java,
|
||||
true, /* strict */
|
||||
KtDeclaration::class.java /* Stop at */
|
||||
) ?: return null
|
||||
|
||||
return parentBlockExpression.statements.firstOrNull { statement ->
|
||||
PsiTreeUtil.isAncestor(statement, host, false) && checkIsValidPlaceForInjectionWithLineComment(statement, host)
|
||||
}
|
||||
}
|
||||
|
||||
private fun addInjectionInstructionInCode(language: Language, host: PsiLanguageInjectionHost): Boolean {
|
||||
val ktHost = host as? KtElement ?: return false
|
||||
val project = ktHost.project
|
||||
|
||||
// Find the place where injection can be stated with annotation or comment
|
||||
val modifierListOwner = findElementToInjectWithAnnotation(ktHost)
|
||||
|
||||
if (modifierListOwner != null && canInjectWithAnnotation(ktHost)) {
|
||||
project.executeWriteCommand(KotlinJvmBundle.message("command.action.add.injection.annotation")) {
|
||||
modifierListOwner.addAnnotation(FqName(AnnotationUtil.LANGUAGE), "\"${language.id}\"")
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Find the place where injection can be done with one-line comment
|
||||
val commentBeforeAnchor: PsiElement =
|
||||
modifierListOwner?.firstNonCommentChild() ?:
|
||||
findElementToInjectWithComment(ktHost) ?:
|
||||
return false
|
||||
|
||||
val psiFactory = KtPsiFactory(project)
|
||||
val injectComment = psiFactory.createComment("//language=" + language.id)
|
||||
|
||||
project.executeWriteCommand(KotlinJvmBundle.message("command.action.add.injection.comment")) {
|
||||
commentBeforeAnchor.parent.addBefore(injectComment, commentBeforeAnchor)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Inspired with InjectorUtils.findCommentInjection()
|
||||
private fun checkIsValidPlaceForInjectionWithLineComment(statement: KtExpression, host: KtElement): Boolean {
|
||||
// make sure comment is close enough and ...
|
||||
val statementStartOffset = statement.startOffset
|
||||
val hostStart = host.startOffset
|
||||
if (hostStart < statementStartOffset || hostStart - statementStartOffset > 120) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (hostStart - statementStartOffset > 2) {
|
||||
// ... there's no non-empty valid host in between comment and e2
|
||||
if (prevWalker(host, statement).asSequence().takeWhile { it != null }.any {
|
||||
it is PsiLanguageInjectionHost && it.isValidHost && !StringUtil.isEmptyOrSpaces(it.text)
|
||||
}) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun PsiElement.firstNonCommentChild(): PsiElement? {
|
||||
return firstChild.siblings().dropWhile { it is PsiComment || it is PsiWhiteSpace }.firstOrNull()
|
||||
}
|
||||
|
||||
// Based on InjectorUtils.prevWalker
|
||||
private fun prevWalker(element: PsiElement, scope: PsiElement): Iterator<PsiElement?> {
|
||||
return object : Iterator<PsiElement?> {
|
||||
private var e: PsiElement? = element
|
||||
|
||||
override fun hasNext(): Boolean = true
|
||||
override fun next(): PsiElement? {
|
||||
val current = e
|
||||
|
||||
if (current == null || current === scope) return null
|
||||
val prev = current.prevSibling
|
||||
e = if (prev != null) {
|
||||
getDeepestLast(prev)
|
||||
}
|
||||
else {
|
||||
val parent = current.parent
|
||||
if (parent === scope || parent is PsiFile) null else parent
|
||||
}
|
||||
return e
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.compile
|
||||
|
||||
import com.intellij.execution.configurations.GeneralCommandLine
|
||||
import com.intellij.execution.process.CapturingProcessHandler
|
||||
import com.intellij.openapi.diagnostic.ControlFlowException
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.Task
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderFactories
|
||||
import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
|
||||
import org.jetbrains.kotlin.codegen.filterClassFiles
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.idea.KotlinJvmBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptConfigurationManager
|
||||
import org.jetbrains.kotlin.idea.debugger.DebuggerUtils
|
||||
import org.jetbrains.kotlin.idea.scratch.LOG
|
||||
import org.jetbrains.kotlin.idea.scratch.ScratchExpression
|
||||
import org.jetbrains.kotlin.idea.scratch.ScratchFile
|
||||
import org.jetbrains.kotlin.idea.scratch.printDebugMessage
|
||||
import org.jetbrains.kotlin.idea.util.JavaParametersBuilder
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import java.io.File
|
||||
|
||||
class KtScratchExecutionSession(
|
||||
private val file: ScratchFile,
|
||||
private val executor: KtCompilingExecutor
|
||||
) {
|
||||
companion object {
|
||||
private const val TIMEOUT_MS = 30000
|
||||
}
|
||||
|
||||
private var backgroundProcessIndicator: ProgressIndicator? = null
|
||||
|
||||
fun execute(callback: () -> Unit) {
|
||||
val psiFile = file.getPsiFile() as? KtFile ?: return executor.errorOccurs(KotlinJvmBundle.message("couldn.t.find.ktfile.for.current.editor"), isFatal = true)
|
||||
|
||||
val expressions = file.getExpressions()
|
||||
if (!executor.checkForErrors(psiFile, expressions)) return
|
||||
|
||||
when (val result = runReadAction { KtScratchSourceFileProcessor().process(expressions) }) {
|
||||
is KtScratchSourceFileProcessor.Result.Error -> return executor.errorOccurs(result.message, isFatal = true)
|
||||
is KtScratchSourceFileProcessor.Result.OK -> {
|
||||
LOG.printDebugMessage("After processing by KtScratchSourceFileProcessor:\n ${result.code}")
|
||||
|
||||
object : Task.Backgroundable(psiFile.project, KotlinJvmBundle.message("running.kotlin.scratch"), true) {
|
||||
override fun run(indicator: ProgressIndicator) {
|
||||
backgroundProcessIndicator = indicator
|
||||
|
||||
val modifiedScratchSourceFile = runReadAction {
|
||||
KtPsiFactory(psiFile.project).createFileWithLightClassSupport("tmp.kt", result.code, psiFile)
|
||||
}
|
||||
|
||||
try {
|
||||
val tempDir = DumbService.getInstance(project).runReadActionInSmartMode(
|
||||
Computable {
|
||||
compileFileToTempDir(modifiedScratchSourceFile, expressions)
|
||||
}
|
||||
) ?: return
|
||||
|
||||
try {
|
||||
val commandLine = createCommandLine(psiFile, file.module, result.mainClassName, tempDir.path)
|
||||
|
||||
LOG.printDebugMessage(commandLine.commandLineString)
|
||||
|
||||
val processHandler = CapturingProcessHandler(commandLine)
|
||||
val executionResult = processHandler.runProcessWithProgressIndicator(indicator, TIMEOUT_MS)
|
||||
when {
|
||||
executionResult.isTimeout -> {
|
||||
executor.errorOccurs(
|
||||
KotlinJvmBundle.message(
|
||||
"couldn.t.get.scratch.execution.result.stopped.by.timeout.0.ms",
|
||||
TIMEOUT_MS
|
||||
)
|
||||
)
|
||||
}
|
||||
executionResult.isCancelled -> {
|
||||
// ignore
|
||||
}
|
||||
else -> {
|
||||
executor.parseOutput(executionResult, expressions)
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
tempDir.delete()
|
||||
callback()
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
if (e is ControlFlowException) throw e
|
||||
|
||||
LOG.printDebugMessage(result.code)
|
||||
executor.errorOccurs(e.message ?: KotlinJvmBundle.message("couldn.t.compile.0", psiFile.name), e, isFatal = true)
|
||||
}
|
||||
}
|
||||
}.queue()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
backgroundProcessIndicator?.cancel()
|
||||
}
|
||||
|
||||
private fun compileFileToTempDir(psiFile: KtFile, expressions: List<ScratchExpression>): File? {
|
||||
if (!executor.checkForErrors(psiFile, expressions)) return null
|
||||
|
||||
val resolutionFacade = psiFile.getResolutionFacade()
|
||||
val (bindingContext, files) = DebuggerUtils.analyzeInlinedFunctions(resolutionFacade, psiFile, false)
|
||||
|
||||
LOG.printDebugMessage("Analyzed files: \n${files.joinToString("\n") { it.virtualFilePath }}")
|
||||
|
||||
val generateClassFilter = object : GenerationState.GenerateClassFilter() {
|
||||
override fun shouldGeneratePackagePart(ktFile: KtFile) = ktFile == psiFile
|
||||
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject) = true
|
||||
override fun shouldGenerateClass(processingClassOrObject: KtClassOrObject) = processingClassOrObject.containingKtFile == psiFile
|
||||
override fun shouldGenerateScript(script: KtScript) = false
|
||||
override fun shouldGenerateCodeFragment(script: KtCodeFragment) = false
|
||||
}
|
||||
|
||||
val state = GenerationState.Builder(
|
||||
file.project,
|
||||
ClassBuilderFactories.BINARIES,
|
||||
resolutionFacade.moduleDescriptor,
|
||||
bindingContext,
|
||||
files,
|
||||
CompilerConfiguration.EMPTY
|
||||
).generateDeclaredClassFilter(generateClassFilter).build()
|
||||
|
||||
KotlinCodegenFacade.compileCorrectFiles(state)
|
||||
|
||||
return writeClassFilesToTempDir(state)
|
||||
}
|
||||
|
||||
private fun writeClassFilesToTempDir(state: GenerationState): File {
|
||||
val classFiles = state.factory.asList().filterClassFiles()
|
||||
|
||||
val dir = FileUtil.createTempDirectory("compile", "scratch")
|
||||
|
||||
LOG.printDebugMessage("Temp output dir: ${dir.path}")
|
||||
|
||||
for (classFile in classFiles) {
|
||||
val tmpOutFile = File(dir, classFile.relativePath)
|
||||
tmpOutFile.parentFile.mkdirs()
|
||||
tmpOutFile.createNewFile()
|
||||
tmpOutFile.writeBytes(classFile.asByteArray())
|
||||
|
||||
LOG.printDebugMessage("Generated class file: ${classFile.relativePath}")
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
private fun createCommandLine(originalFile: KtFile, module: Module?, mainClassName: String, tempOutDir: String): GeneralCommandLine {
|
||||
val javaParameters = JavaParametersBuilder(originalFile.project)
|
||||
.withSdkFrom(module, true)
|
||||
.withMainClassName(mainClassName)
|
||||
.build()
|
||||
|
||||
javaParameters.classPath.add(tempOutDir)
|
||||
|
||||
if (module != null) {
|
||||
javaParameters.classPath.addAll(JavaParametersBuilder.getModuleDependencies(module))
|
||||
}
|
||||
|
||||
ScriptConfigurationManager.getInstance(originalFile.project)
|
||||
.getConfiguration(originalFile)?.let {
|
||||
javaParameters.classPath.addAll(it.dependenciesClassPath.map { f -> f.absolutePath })
|
||||
}
|
||||
|
||||
return javaParameters.toCommandLine()
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.ide.konan
|
||||
|
||||
import com.intellij.execution.actions.ConfigurationContext
|
||||
import com.intellij.execution.actions.LazyRunConfigurationProducer
|
||||
import com.intellij.execution.configurations.ConfigurationFactory
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.util.Ref
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.idea.facet.externalSystemNativeMainRunTasks
|
||||
import org.jetbrains.kotlin.idea.project.platform
|
||||
import org.jetbrains.kotlin.idea.util.module
|
||||
import org.jetbrains.kotlin.platform.konan.isNative
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.plugins.gradle.service.execution.GradleExternalTaskConfigurationType
|
||||
import org.jetbrains.plugins.gradle.service.execution.GradleRunConfiguration
|
||||
|
||||
|
||||
class KotlinNativeRunConfigurationProducer :
|
||||
LazyRunConfigurationProducer<GradleRunConfiguration>(),
|
||||
KotlinNativeRunConfigurationProvider {
|
||||
|
||||
override val isForTests = false
|
||||
|
||||
override fun getConfigurationFactory(): ConfigurationFactory =
|
||||
GradleExternalTaskConfigurationType.getInstance().factory
|
||||
|
||||
override fun isConfigurationFromContext(configuration: GradleRunConfiguration, context: ConfigurationContext): Boolean {
|
||||
val module = context.module.asNativeModule() ?: return false
|
||||
val location = context.location ?: return false
|
||||
val function = PsiTreeUtil.getParentOfType(location.psiElement, KtFunction::class.java) ?: return false
|
||||
|
||||
val mainRunTasks = getDebugMainRunTasks(function)
|
||||
if (mainRunTasks.isEmpty()) return false
|
||||
|
||||
return configuration.settings.externalProjectPath == ExternalSystemApiUtil.getExternalProjectPath(module)
|
||||
&& configuration.settings.taskNames == mainRunTasks
|
||||
}
|
||||
|
||||
override fun setupConfigurationFromContext(
|
||||
configuration: GradleRunConfiguration,
|
||||
context: ConfigurationContext,
|
||||
sourceElement: Ref<PsiElement>
|
||||
): Boolean {
|
||||
val module = context.module.asNativeModule() ?: return false
|
||||
val function = PsiTreeUtil.getParentOfType(sourceElement.get(), KtFunction::class.java) ?: return false
|
||||
|
||||
val mainRunTasks = getDebugMainRunTasks(function)
|
||||
if (mainRunTasks.isEmpty()) return false
|
||||
|
||||
configuration.settings.apply {
|
||||
externalProjectPath = ExternalSystemApiUtil.getExternalProjectPath(module)
|
||||
taskNames = mainRunTasks
|
||||
}
|
||||
configuration.name = mainRunTasks.first()
|
||||
configuration.isScriptDebugEnabled = false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun Module?.asNativeModule(): Module? = takeIf { it?.platform.isNative() }
|
||||
|
||||
private fun getDebugMainRunTasks(function: KtFunction): List<String> {
|
||||
val functionName = function.fqName?.asString() ?: return emptyList()
|
||||
val module = function.module ?: return emptyList()
|
||||
|
||||
return module.externalSystemNativeMainRunTasks()
|
||||
.filter { it.debuggable && it.entryPoint == functionName }
|
||||
.map { it.taskName }
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.tools.projectWizard.wizard.service
|
||||
|
||||
import com.intellij.execution.executors.DefaultRunExecutor
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.actionSystem.impl.SimpleDataContext
|
||||
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.Reader
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.andThen
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.safe
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.service.ProjectImportingWizardService
|
||||
import org.jetbrains.kotlin.tools.projectWizard.ir.buildsystem.ModuleIR
|
||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
|
||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
|
||||
import org.jetbrains.plugins.gradle.action.ImportProjectFromScriptAction
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import java.nio.file.Path
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
class IdeaGradleWizardService(private val project: Project) : ProjectImportingWizardService,
|
||||
IdeaWizardService {
|
||||
override fun isSuitableFor(buildSystemType: BuildSystemType): Boolean =
|
||||
buildSystemType.isGradle
|
||||
|
||||
// We have to call action directly as there is no common way
|
||||
// to import Gradle project in all IDEAs from 183 to 193
|
||||
override fun importProject(
|
||||
reader: Reader,
|
||||
path: Path,
|
||||
modulesIrs: List<ModuleIR>,
|
||||
buildSystem: BuildSystemType
|
||||
): TaskResult<Unit> = performImport(path) andThen createGradleWrapper(path)
|
||||
|
||||
private fun performImport(path: Path) = safe {
|
||||
val virtualFile = LocalFileSystem.getInstance().findFileByPath(path.toString())
|
||||
?: error("No virtual file found for path $path")
|
||||
val dataContext = SimpleDataContext.getSimpleContext(
|
||||
mapOf(
|
||||
CommonDataKeys.PROJECT.name to project,
|
||||
CommonDataKeys.VIRTUAL_FILE.name to virtualFile
|
||||
),
|
||||
null
|
||||
)
|
||||
val action = ImportProjectFromScriptAction()
|
||||
val event = AnActionEvent.createFromAnAction(
|
||||
action,
|
||||
/*event=*/ null,
|
||||
ActionPlaces.UNKNOWN,
|
||||
dataContext
|
||||
)
|
||||
action.actionPerformed(event)
|
||||
}
|
||||
|
||||
|
||||
private fun createGradleWrapper(path: Path) = safe {
|
||||
val settings = ExternalSystemTaskExecutionSettings().apply {
|
||||
externalProjectPath = path.toString()
|
||||
taskNames = listOf(WRAPPER_TASK_NAME)
|
||||
externalSystemIdString = GradleConstants.SYSTEM_ID.id
|
||||
}
|
||||
|
||||
ExternalSystemUtil.runTask(
|
||||
settings,
|
||||
DefaultRunExecutor.EXECUTOR_ID,
|
||||
project,
|
||||
GradleConstants.SYSTEM_ID,
|
||||
/*callback=*/ null,
|
||||
ProgressExecutionMode.NO_PROGRESS_ASYNC
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
@NonNls
|
||||
private const val WRAPPER_TASK_NAME = "wrapper"
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.tools.projectWizard.wizard.ui.firstStep
|
||||
|
||||
import com.intellij.ide.DataManager
|
||||
import com.intellij.openapi.actionSystem.ActionGroup
|
||||
import com.intellij.openapi.actionSystem.ex.ActionManagerEx
|
||||
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl
|
||||
import com.intellij.openapi.keymap.ex.KeymapManagerEx
|
||||
|
||||
// needed for <=192 to work correctly
|
||||
abstract class ActionToolbarImplWrapper(
|
||||
place: String,
|
||||
actionGroup: ActionGroup,
|
||||
horizontal: Boolean
|
||||
) : ActionToolbarImpl(
|
||||
place,
|
||||
actionGroup,
|
||||
horizontal,
|
||||
DataManager.getInstance(),
|
||||
ActionManagerEx.getInstanceEx(),
|
||||
KeymapManagerEx.getInstanceEx()
|
||||
)
|
||||
@@ -1,110 +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.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.testFramework.TempFiles;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.WithMutedInDatabaseRunTest;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collection;
|
||||
|
||||
@WithMutedInDatabaseRunTest
|
||||
public abstract class KotlinLightCodeInsightFixtureTestCaseBase extends LightCodeInsightFixtureTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
public Project getProject() {
|
||||
return super.getProject();
|
||||
}
|
||||
|
||||
public Module getModule() {
|
||||
return myModule;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Editor getEditor() {
|
||||
return super.getEditor();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiFile getFile() {
|
||||
return super.getFile();
|
||||
}
|
||||
|
||||
protected final Collection<File> myFilesToDelete = new THashSet<>();
|
||||
private final TempFiles myTempFiles = new TempFiles(myFilesToDelete);
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
myTempFiles.deleteAll();
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile createTempFile(
|
||||
@NonNls @NotNull String ext,
|
||||
@Nullable byte[] bom,
|
||||
@NonNls @NotNull String content,
|
||||
@NotNull Charset charset
|
||||
) throws IOException {
|
||||
File temp = FileUtil.createTempFile("copy", "." + ext);
|
||||
setContentOnDisk(temp, bom, content, charset);
|
||||
|
||||
myFilesToDelete.add(temp);
|
||||
final VirtualFile file = getVirtualFile(temp);
|
||||
assert file != null : temp;
|
||||
return file;
|
||||
}
|
||||
|
||||
public static void setContentOnDisk(@NotNull File file, @Nullable byte[] bom, @NotNull String content, @NotNull Charset charset)
|
||||
throws IOException {
|
||||
FileOutputStream stream = new FileOutputStream(file);
|
||||
if (bom != null) {
|
||||
stream.write(bom);
|
||||
}
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter(stream, charset)) {
|
||||
writer.write(content);
|
||||
}
|
||||
}
|
||||
|
||||
protected static VirtualFile getVirtualFile(@NotNull File file) {
|
||||
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTest() throws Throwable {
|
||||
//noinspection Convert2MethodRef
|
||||
KotlinTestUtils.runTestWithThrowable(this, () -> super.runTest());
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.test
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.testFramework.LightPlatformCodeInsightTestCase
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import com.intellij.util.ThrowableRunnable
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
abstract class KotlinLightPlatformCodeInsightTestCase : LightPlatformCodeInsightTestCase() {
|
||||
protected inline val project_: Project get() = LightPlatformTestCase.getProject()
|
||||
protected inline val editor_: Editor get() = LightPlatformCodeInsightTestCase.getEditor()
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
enableKotlinOfficialCodeStyle(project_)
|
||||
}
|
||||
|
||||
override fun tearDown() = runAll(
|
||||
ThrowableRunnable { disableKotlinOfficialCodeStyle(project_) },
|
||||
ThrowableRunnable { super.tearDown() },
|
||||
)
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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("unused", "IncompatibleAPI", "PropertyName")
|
||||
|
||||
package org.jetbrains.kotlin.idea.test
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.testFramework.LightIdeaTestCase
|
||||
import com.intellij.testFramework.LightPlatformCodeInsightTestCase
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
|
||||
// FIX ME WHEN BUNCH as36 REMOVED
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
@Suppress("DEPRECATION")
|
||||
@Deprecated("Use KotlinLightCodeInsightFixtureTestCase instead")
|
||||
abstract class KotlinLightCodeInsightTestCase : com.intellij.testFramework.LightCodeInsightTestCase() {
|
||||
protected inline val project_: Project get() = LightPlatformTestCase.getProject()
|
||||
protected inline val module_: Module get() = LightPlatformTestCase.getModule()
|
||||
protected inline val editor_: Editor get() = LightPlatformCodeInsightTestCase.getEditor()
|
||||
protected inline val file_: PsiFile get() = LightPlatformCodeInsightTestCase.getFile()
|
||||
protected inline val currentEditorDataContext_: DataContext get() = LightPlatformCodeInsightTestCase.getCurrentEditorDataContext()
|
||||
|
||||
protected fun configureFromFileText_(fileName: String, fileText: String): Document {
|
||||
return LightPlatformCodeInsightTestCase.configureFromFileText(fileName, fileText, false)
|
||||
}
|
||||
}
|
||||
|
||||
// FIX ME WHEN BUNCH as36 REMOVED
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
abstract class KotlinLightIdeaTestCase : LightIdeaTestCase() {
|
||||
protected inline val project_: Project get() = LightPlatformTestCase.getProject()
|
||||
protected inline val module_: Module get() = LightPlatformTestCase.getModule()
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.coroutine
|
||||
|
||||
import com.intellij.ui.components.JBLabel
|
||||
import org.jetbrains.kotlin.idea.debugger.coroutine.override.com.intellij.ui.SimpleListCellRenderer
|
||||
import javax.swing.ListCellRenderer
|
||||
|
||||
class VersionedImplementationProvider {
|
||||
fun comboboxListCellRenderer(): ListCellRenderer<in String>? =
|
||||
SimpleListCellRenderer.create { label: JBLabel, value: String?, index: Int ->
|
||||
if (value != null) {
|
||||
label.text = value
|
||||
} else if (index >= 0) {
|
||||
label.text = KotlinDebuggerCoroutinesBundle.message("coroutine.dump.threads.loading")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.coroutine.override.com.intellij.ui;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import sun.swing.DefaultLookup;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.plaf.basic.BasicHTML;
|
||||
import java.awt.*;
|
||||
|
||||
public abstract class SimpleListCellRenderer<T> extends JBLabel implements ListCellRenderer<T> {
|
||||
|
||||
@NotNull
|
||||
public static <T> SimpleListCellRenderer<T> create(@NotNull String nullValue, @NotNull Function<? super T, String> getText) {
|
||||
return new SimpleListCellRenderer<T>() {
|
||||
@Override
|
||||
public void customize(JList<? extends T> list, T value, int index, boolean selected, boolean hasFocus) {
|
||||
setText(value == null ? nullValue : getText.fun(value));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static <T> SimpleListCellRenderer<T> create(@NotNull Customizer<? super T> customizer) {
|
||||
return new SimpleListCellRenderer<T>() {
|
||||
@Override
|
||||
public void customize(JList<? extends T> list, T value, int index, boolean selected, boolean hasFocus) {
|
||||
customizer.customize(this, value, index);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList<? extends T> list, T value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
setComponentOrientation(list.getComponentOrientation());
|
||||
setBorder(JBUI.Borders.empty(1));
|
||||
Color bg, fg;
|
||||
JList.DropLocation dropLocation = list.getDropLocation();
|
||||
if (dropLocation != null && !dropLocation.isInsert() && dropLocation.getIndex() == index) {
|
||||
bg = DefaultLookup.getColor(this, ui, "List.dropCellBackground");
|
||||
fg = DefaultLookup.getColor(this, ui, "List.dropCellForeground");
|
||||
isSelected = true;
|
||||
}
|
||||
else {
|
||||
bg = isSelected ? list.getSelectionBackground() : list.getBackground();
|
||||
fg = isSelected ? list.getSelectionForeground() : list.getForeground();
|
||||
}
|
||||
setBackground(bg);
|
||||
setForeground(fg);
|
||||
setFont(list.getFont());
|
||||
setText("");
|
||||
setIcon(null);
|
||||
customize(list, value, index, isSelected, cellHasFocus);
|
||||
setOpaque(isSelected);
|
||||
return this;
|
||||
}
|
||||
|
||||
public abstract void customize(JList<? extends T> list, T value, int index, boolean selected, boolean hasFocus);
|
||||
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
if (StringUtil.isNotEmpty(getText())) {
|
||||
return super.getPreferredSize();
|
||||
}
|
||||
setText(" ");
|
||||
Dimension size = super.getPreferredSize();
|
||||
setText("");
|
||||
return size;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Customizer<T> {
|
||||
void customize(@NotNull JBLabel label, T value, int index);
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
@Override public void validate() {}
|
||||
@Override public void invalidate() {}
|
||||
@Override public void repaint() {}
|
||||
@Override public void revalidate() {}
|
||||
@Override public void repaint(long tm, int x, int y, int width, int height) {}
|
||||
@Override public void repaint(Rectangle r) {}
|
||||
@Override public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {}
|
||||
@Override public void firePropertyChange(String propertyName, char oldValue, char newValue) {}
|
||||
@Override public void firePropertyChange(String propertyName, short oldValue, short newValue) {}
|
||||
@Override public void firePropertyChange(String propertyName, int oldValue, int newValue) {}
|
||||
@Override public void firePropertyChange(String propertyName, long oldValue, long newValue) {}
|
||||
@Override public void firePropertyChange(String propertyName, float oldValue, float newValue) {}
|
||||
@Override public void firePropertyChange(String propertyName, double oldValue, double newValue) {}
|
||||
@Override public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {}
|
||||
|
||||
@Override
|
||||
protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
|
||||
if (propertyName == "text"
|
||||
|| ((propertyName == "font" || propertyName == "foreground")
|
||||
&& oldValue != newValue
|
||||
&& getClientProperty(BasicHTML.propertyKey) != null)) {
|
||||
super.firePropertyChange(propertyName, oldValue, newValue);
|
||||
}
|
||||
}
|
||||
// @formatter:on
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.test.sequence
|
||||
|
||||
import com.intellij.debugger.streams.test.StreamChainBuilderTestCase
|
||||
import com.intellij.debugger.streams.wrapper.StreamChain
|
||||
import com.intellij.debugger.streams.wrapper.StreamChainBuilder
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.projectRoots.Sdk
|
||||
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable
|
||||
import com.intellij.testFramework.LightPlatformTestCase
|
||||
import com.intellij.testFramework.PsiTestUtil
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||
import org.jetbrains.kotlin.idea.caches.project.LibraryModificationTracker
|
||||
import org.jetbrains.kotlin.idea.debugger.test.DEBUGGER_TESTDATA_PATH_BASE
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||
|
||||
abstract class KotlinPsiChainBuilderTestCase(private val relativePath: String) : StreamChainBuilderTestCase() {
|
||||
override fun getTestDataPath(): String = "$DEBUGGER_TESTDATA_PATH_BASE/sequence/psi/$relativeTestPath"
|
||||
|
||||
override fun getFileExtension(): String = ".kt"
|
||||
abstract val kotlinChainBuilder: StreamChainBuilder
|
||||
override fun getChainBuilder(): StreamChainBuilder = kotlinChainBuilder
|
||||
private val stdLibName = "kotlin-stdlib"
|
||||
|
||||
protected abstract fun doTest()
|
||||
|
||||
final override fun getRelativeTestPath(): String = relativePath
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
ApplicationManager.getApplication().runWriteAction {
|
||||
@Suppress("UnstableApiUsage")
|
||||
if (ProjectLibraryTable.getInstance(LightPlatformTestCase.getProject()).getLibraryByName(stdLibName) == null) {
|
||||
val stdLibPath = ForTestCompileRuntime.runtimeJarForTests()
|
||||
PsiTestUtil.addLibrary(
|
||||
testRootDisposable,
|
||||
LightPlatformTestCase.getModule(),
|
||||
stdLibName,
|
||||
stdLibPath.parent,
|
||||
stdLibPath.name
|
||||
)
|
||||
}
|
||||
}
|
||||
LibraryModificationTracker.getInstance(LightPlatformTestCase.getProject()).incModificationCount()
|
||||
}
|
||||
|
||||
|
||||
override fun getProjectJDK(): Sdk {
|
||||
return PluginTestCaseBase.mockJdk9()
|
||||
}
|
||||
|
||||
abstract class Positive(relativePath: String) : KotlinPsiChainBuilderTestCase(relativePath) {
|
||||
override fun doTest() {
|
||||
val chains = buildChains()
|
||||
checkChains(chains)
|
||||
}
|
||||
|
||||
private fun checkChains(chains: MutableList<StreamChain>) {
|
||||
TestCase.assertFalse(chains.isEmpty())
|
||||
}
|
||||
}
|
||||
|
||||
abstract class Negative(relativePath: String) : KotlinPsiChainBuilderTestCase(relativePath) {
|
||||
override fun doTest() {
|
||||
val elementAtCaret = configureAndGetElementAtCaret()
|
||||
TestCase.assertFalse(chainBuilder.isChainExists(elementAtCaret))
|
||||
TestCase.assertTrue(chainBuilder.build(elementAtCaret).isEmpty())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
org.jetbrains.kotlin.gradle.KotlinGradleModelBuilder
|
||||
org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.testFramework
|
||||
|
||||
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.plugins.gradle.service.project.GradleProjectOpenProcessor
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import java.nio.file.Paths
|
||||
|
||||
fun refreshGradleProject(projectPath: String, project: Project) {
|
||||
GradleProjectOpenProcessor.openGradleProject(project, null, Paths.get(projectPath))
|
||||
|
||||
StatefulTestGradleProjectRefreshCallback(projectPath, project).use { callback ->
|
||||
ExternalSystemUtil.refreshProjects(
|
||||
ImportSpecBuilder(project, GradleConstants.SYSTEM_ID)
|
||||
.use(ProgressExecutionMode.MODAL_SYNC)
|
||||
.forceWhenUptodate()
|
||||
.withArguments(System.getProperty("kotlin.test.gradle.import.arguments"))
|
||||
.callback(callback)
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
dispatchAllInvocationEvents()
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.testFramework
|
||||
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl
|
||||
import com.intellij.lang.LanguageAnnotators
|
||||
import com.intellij.lang.LanguageExtensionPoint
|
||||
import com.intellij.lang.annotation.Annotator
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorImpl
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx
|
||||
import com.intellij.openapi.startup.StartupManager
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.impl.PsiDocumentManagerBase
|
||||
import com.intellij.testFramework.PlatformTestUtil
|
||||
import com.intellij.testFramework.runInEdtAndWait
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import org.jetbrains.kotlin.idea.parameterInfo.HintType
|
||||
import org.jetbrains.kotlin.idea.perf.TestApplicationManager
|
||||
import org.jetbrains.kotlin.idea.test.runPostStartupActivitiesOnce
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeoutException
|
||||
import java.io.PrintWriter
|
||||
import java.io.StringWriter
|
||||
|
||||
fun commitAllDocuments() {
|
||||
val fileDocumentManager = FileDocumentManager.getInstance()
|
||||
runInEdtAndWait {
|
||||
fileDocumentManager.saveAllDocuments()
|
||||
}
|
||||
|
||||
ProjectManagerEx.getInstanceEx().openProjects.forEach { project ->
|
||||
val psiDocumentManagerBase = PsiDocumentManager.getInstance(project) as PsiDocumentManagerBase
|
||||
|
||||
runInEdtAndWait {
|
||||
psiDocumentManagerBase.clearUncommittedDocuments()
|
||||
psiDocumentManagerBase.commitAllDocuments()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun commitDocument(project: Project, document: Document) {
|
||||
val psiDocumentManagerBase = PsiDocumentManager.getInstance(project) as PsiDocumentManagerBase
|
||||
runInEdtAndWait {
|
||||
psiDocumentManagerBase.commitDocument(document)
|
||||
}
|
||||
}
|
||||
|
||||
fun saveDocument(document: Document) {
|
||||
val fileDocumentManager = FileDocumentManager.getInstance()
|
||||
|
||||
runInEdtAndWait {
|
||||
fileDocumentManager.saveDocument(document)
|
||||
}
|
||||
}
|
||||
|
||||
fun enableHints(enable: Boolean) =
|
||||
HintType.values().forEach { it.option.set(enable) }
|
||||
|
||||
fun dispatchAllInvocationEvents() {
|
||||
runInEdtAndWait {
|
||||
UIUtil.dispatchAllInvocationEvents()
|
||||
}
|
||||
}
|
||||
|
||||
fun loadProjectWithName(path: String, name: String): Project? =
|
||||
ProjectManagerEx.getInstanceEx().loadProject(name, path)
|
||||
|
||||
fun TestApplicationManager.closeProject(project: Project) {
|
||||
dispatchAllInvocationEvents()
|
||||
val projectManagerEx = ProjectManagerEx.getInstanceEx()
|
||||
projectManagerEx.forceCloseProjectEx(project, true)
|
||||
}
|
||||
|
||||
fun runStartupActivities(project: Project) {
|
||||
with(StartupManager.getInstance(project) as StartupManagerImpl) {
|
||||
scheduleInitialVfsRefresh()
|
||||
runStartupActivities()
|
||||
}
|
||||
runPostStartupActivitiesOnce(project)
|
||||
}
|
||||
|
||||
fun waitForAllEditorsFinallyLoaded(project: Project) {
|
||||
waitForAllEditorsFinallyLoaded(project, 5, TimeUnit.MINUTES)
|
||||
}
|
||||
|
||||
fun waitForAllEditorsFinallyLoaded(project: Project, timeout: Long, unit: TimeUnit) {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread()
|
||||
val deadline = unit.toMillis(timeout) + System.currentTimeMillis()
|
||||
while (true) {
|
||||
if (System.currentTimeMillis() > deadline) throw TimeoutException()
|
||||
if (waitABitForEditorLoading(project)) break
|
||||
UIUtil.dispatchAllInvocationEvents()
|
||||
}
|
||||
}
|
||||
|
||||
private fun waitABitForEditorLoading(project: Project): Boolean {
|
||||
for (editor in FileEditorManager.getInstance(project).allEditors) {
|
||||
if (editor is TextEditorImpl) {
|
||||
try {
|
||||
editor.waitForLoaded(100, TimeUnit.MILLISECONDS)
|
||||
} catch (ignored: TimeoutException) {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun replaceWithCustomHighlighter(parentDisposable: Disposable, fromImplementationClass: String, toImplementationClass: String) {
|
||||
val pointName = ExtensionPointName.create<LanguageExtensionPoint<Annotator>>(LanguageAnnotators.EP_NAME)
|
||||
val extensionPoint = pointName.getPoint(null)
|
||||
|
||||
val point = LanguageExtensionPoint<Annotator>()
|
||||
point.language = "kotlin"
|
||||
point.implementationClass = toImplementationClass
|
||||
|
||||
val extensions = extensionPoint.extensions
|
||||
val filteredExtensions =
|
||||
extensions.filter { it.language != "kotlin" || it.implementationClass != fromImplementationClass }
|
||||
.toList()
|
||||
// custom highlighter is already registered if filteredExtensions has the same size as extensions
|
||||
if (filteredExtensions.size < extensions.size) {
|
||||
PlatformTestUtil.maskExtensions(pointName, filteredExtensions + listOf(point), parentDisposable)
|
||||
}
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPSourceSetsFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinMPPFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
<pluginDescriptions implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradlePluginDescription"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectResolverExtension" order="first"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.kapt.idea.KaptProjectResolverExtension" order="last"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.allopen.ide.AllOpenProjectResolverExtension" order="last"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.noarg.ide.NoArgProjectResolverExtension" order="last"/>
|
||||
<projectResolve implementation="org.jetbrains.kotlin.samWithReceiver.ide.SamWithReceiverProjectResolverExtension" order="last"/>
|
||||
</extensions>
|
||||
|
||||
<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.KotlinTargetDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.KotlinJavaMPPSourceSetDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.klib.KotlinNativeLibraryDataService"/>
|
||||
<externalSystemTaskNotificationListener
|
||||
implementation="org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslSyncListener"
|
||||
/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.MissingGradleScriptConfigurationNotificationProvider"/>
|
||||
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinJvmTestClassGradleConfigurationProducer"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinMultiplatformJvmTestClassGradleConfigurationProducer"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinJvmTestMethodGradleConfigurationProducer"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinMultiplatformJvmTestMethodGradleConfigurationProducer"/>
|
||||
|
||||
</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.scripting.gradle.GradleScriptDefinitionsContributor" order="first"/>
|
||||
<scriptAdditionalIdeaDependenciesProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptAdditionalIdeaDependenciesProvider"/>
|
||||
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -1,139 +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="191.5109.14" until-build="191.*"/>
|
||||
|
||||
<depends>com.intellij.modules.platform</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="gradle-java.xml">org.jetbrains.plugins.gradle.java</depends>
|
||||
<depends optional="true" config-file="kotlin-gradle-testing.xml">org.jetbrains.plugins.gradle.java</depends>
|
||||
<depends optional="true" config-file="gradle-groovy.xml">org.intellij.groovy</depends>
|
||||
<depends optional="true" config-file="maven-common.xml">org.jetbrains.idea.maven</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="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.idea</depends>
|
||||
<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-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="jvm.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<!-- CIDR-PLUGIN-EXCLUDE-END -->
|
||||
|
||||
<xi:include href="native-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="native.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="tipsAndTricks.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="extensions/ide.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="kotlinx-serialization.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="scripting-support.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.versions.KotlinUpdatePluginComponent</implementation-class>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
<project-components>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.completion.LookupCancelWatcher</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.caches.KotlinPackageContentModificationListener</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.configuration.KotlinMigrationProjectComponent</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.parameterInfo.custom.KotlinCodeHintsPass$Companion$Factory</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory</implementation-class>
|
||||
<skipForDefaultProject/>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.highlighter.ScriptExternalHighlightingPass$Factory</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener</implementation-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.PluginStartupComponent</implementation-class>
|
||||
</component>
|
||||
</application-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.jvm">
|
||||
<declarationSearcher language="kotlin" implementationClass="org.jetbrains.kotlin.idea.jvm.KotlinDeclarationSearcher"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="2"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.library" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.refactoring" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.newFileTempl" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.npwizards" version="2"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.debugger" version="2"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.j2k" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.editor" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.migrationTool" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.ide.new.wizard" version="1"/>
|
||||
<statistics.counterUsagesCollector groupId="kotlin.gradle.performance" version="1"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.formatter.KotlinFormatterUsageCollector"/>
|
||||
<statistics.projectUsagesCollector implementation="org.jetbrains.kotlin.idea.statistics.ProjectConfigurationCollector"/>
|
||||
|
||||
<defaultLiveTemplatesProvider implementation="org.jetbrains.kotlin.idea.liveTemplates.KotlinLiveTemplatesProvider"/>
|
||||
|
||||
<fileTypeFactory implementation="org.jetbrains.kotlin.idea.core.KotlinFileTypeFactory"/>
|
||||
<fileTypeFactory implementation="org.jetbrains.kotlin.idea.KotlinJavaScriptMetaFileTypeFactory"/>
|
||||
<fileTypeFactory implementation="org.jetbrains.kotlin.idea.KotlinBuiltInFileTypeFactory"/>
|
||||
<fileTypeFactory implementation="org.jetbrains.kotlin.idea.KotlinModuleFileFactory"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -1,3 +0,0 @@
|
||||
class IDESettingsFUSCollector {
|
||||
// Not supported in 2019.1
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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
|
||||
|
||||
import com.intellij.openapi.util.IconLoader
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import com.intellij.psi.impl.ElementPresentationUtil
|
||||
import com.intellij.util.PlatformIcons
|
||||
import javax.swing.Icon
|
||||
|
||||
class KotlinIdeFileIconProviderService : KotlinIconProviderService() {
|
||||
override fun getFileIcon(): Icon = KOTLIN_FILE
|
||||
|
||||
override fun getLightVariableIcon(element: PsiModifierListOwner, flags: Int): Icon {
|
||||
val baseIcon = ElementPresentationUtil.createLayeredIcon(PlatformIcons.VARIABLE_ICON, element, false)
|
||||
return ElementPresentationUtil.addVisibilityIcon(element, flags, baseIcon)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val KOTLIN_FILE = IconLoader.getIcon("/org/jetbrains/kotlin/idea/icons/kotlin_file.svg")
|
||||
}
|
||||
}
|
||||
@@ -1,131 +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.generate
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle
|
||||
import com.intellij.codeInsight.CodeInsightSettings
|
||||
import com.intellij.codeInsight.generation.ui.AbstractGenerateEqualsWizard
|
||||
import com.intellij.ide.wizard.StepAdapter
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.VerticalFlowLayout
|
||||
import com.intellij.refactoring.classMembers.AbstractMemberInfoModel
|
||||
import com.intellij.ui.NonFocusableCheckBox
|
||||
import com.intellij.util.containers.HashMap
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.core.isInheritable
|
||||
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberInfo
|
||||
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KotlinMemberSelectionPanel
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.JPanel
|
||||
|
||||
class KotlinGenerateEqualsWizard(
|
||||
project: Project,
|
||||
klass: KtClass,
|
||||
properties: List<KtNamedDeclaration>,
|
||||
needEquals: Boolean,
|
||||
needHashCode: Boolean
|
||||
) : AbstractGenerateEqualsWizard<KtClass, KtNamedDeclaration, KotlinMemberInfo>(
|
||||
project, BuilderImpl(klass, properties, needEquals, needHashCode)
|
||||
) {
|
||||
private object MemberInfoModelImpl : AbstractMemberInfoModel<KtNamedDeclaration, KotlinMemberInfo>()
|
||||
|
||||
private class BuilderImpl(
|
||||
private val klass: KtClass,
|
||||
properties: List<KtNamedDeclaration>,
|
||||
needEquals: Boolean,
|
||||
needHashCode: Boolean
|
||||
) : AbstractGenerateEqualsWizard.Builder<KtClass, KtNamedDeclaration, KotlinMemberInfo>() {
|
||||
private val equalsPanel: KotlinMemberSelectionPanel?
|
||||
private val hashCodePanel: KotlinMemberSelectionPanel?
|
||||
|
||||
private val memberInfos = properties.map { createMemberInfo(it) }
|
||||
|
||||
private val membersToHashCode = HashMap(properties.keysToMap { createMemberInfo(it) })
|
||||
|
||||
init {
|
||||
equalsPanel = if (needEquals) {
|
||||
KotlinMemberSelectionPanel(KotlinBundle.message("action.generate.equals.choose.equals"), memberInfos, null).apply {
|
||||
table.memberInfoModel = MemberInfoModelImpl
|
||||
}
|
||||
} else null
|
||||
|
||||
hashCodePanel = if (needHashCode) {
|
||||
KotlinMemberSelectionPanel(KotlinBundle.message("action.generate.equals.choose.hashcode"), memberInfos, null).apply {
|
||||
table.memberInfoModel = MemberInfoModelImpl
|
||||
}
|
||||
} else null
|
||||
}
|
||||
|
||||
private fun createMemberInfo(it: KtNamedDeclaration) = KotlinMemberInfo(it).apply { isChecked = true }
|
||||
|
||||
override fun getPsiClass() = klass
|
||||
|
||||
override fun getClassFields() = memberInfos
|
||||
|
||||
override fun getFieldsToHashCode() = membersToHashCode
|
||||
|
||||
override fun getFieldsToNonNull() = HashMap<KtNamedDeclaration, KotlinMemberInfo>()
|
||||
|
||||
override fun getEqualsPanel() = equalsPanel
|
||||
|
||||
override fun getHashCodePanel() = hashCodePanel
|
||||
|
||||
override fun getNonNullPanel() = null
|
||||
|
||||
override fun updateHashCodeMemberInfos(equalsMemberInfos: MutableCollection<KotlinMemberInfo>) {
|
||||
hashCodePanel?.table?.setMemberInfos(equalsMemberInfos.map { membersToHashCode[it.member] })
|
||||
}
|
||||
|
||||
override fun updateNonNullMemberInfos(equalsMemberInfos: MutableCollection<KotlinMemberInfo>?) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private object OptionsStep : StepAdapter() {
|
||||
private val panel = JPanel(VerticalFlowLayout())
|
||||
|
||||
init {
|
||||
with(NonFocusableCheckBox(CodeInsightBundle.message("generate.equals.hashcode.accept.sublcasses"))) {
|
||||
isSelected = CodeInsightSettings.getInstance().USE_INSTANCEOF_ON_EQUALS_PARAMETER
|
||||
addActionListener { CodeInsightSettings.getInstance().USE_INSTANCEOF_ON_EQUALS_PARAMETER = isSelected }
|
||||
panel.add(this)
|
||||
}
|
||||
panel.add(JLabel(CodeInsightBundle.message("generate.equals.hashcode.accept.sublcasses.explanation")))
|
||||
}
|
||||
|
||||
override fun getComponent() = panel
|
||||
}
|
||||
|
||||
override fun addSteps() {
|
||||
if (myEqualsPanel != null && myClass.isInheritable()) {
|
||||
addStep(OptionsStep)
|
||||
}
|
||||
super.addSteps()
|
||||
}
|
||||
|
||||
override fun doOKAction() {
|
||||
myEqualsPanel?.let { updateHashCodeMemberInfos(it.table.selectedMemberInfos) }
|
||||
super.doOKAction()
|
||||
}
|
||||
|
||||
fun getPropertiesForEquals() = myEqualsPanel?.table?.selectedMemberInfos?.map { it.member } ?: emptyList()
|
||||
|
||||
fun getPropertiesForHashCode() = myHashCodePanel?.table?.selectedMemberInfos?.map { it.member } ?: emptyList()
|
||||
}
|
||||
@@ -1,739 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.compiler.configuration;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.options.Configurable;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.SearchableConfigurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.TextComponentAccessor;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.ListCellRendererWrapper;
|
||||
import com.intellij.ui.RawCommandLineEditor;
|
||||
import com.intellij.util.text.VersionComparatorUtil;
|
||||
import com.intellij.util.ui.ThreeStateCheckBox;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import kotlin.collections.ArraysKt;
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments;
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants;
|
||||
import org.jetbrains.kotlin.config.*;
|
||||
import org.jetbrains.kotlin.idea.PluginStartupComponent;
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle;
|
||||
import org.jetbrains.kotlin.idea.facet.DescriptionListCellRenderer;
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet;
|
||||
import org.jetbrains.kotlin.idea.roots.RootUtilsKt;
|
||||
import org.jetbrains.kotlin.idea.util.CidrUtil;
|
||||
import org.jetbrains.kotlin.idea.util.application.ApplicationUtilsKt;
|
||||
import org.jetbrains.kotlin.platform.IdePlatformKind;
|
||||
import org.jetbrains.kotlin.platform.PlatformUtilKt;
|
||||
import org.jetbrains.kotlin.platform.impl.JsIdePlatformUtil;
|
||||
import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind;
|
||||
import org.jetbrains.kotlin.platform.impl.JvmIdePlatformUtil;
|
||||
import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.platform.jvm.JdkPlatform;
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
|
||||
public class KotlinCompilerConfigurableTab implements SearchableConfigurable {
|
||||
private static final Map<String, String> moduleKindDescriptions = new LinkedHashMap<>();
|
||||
private static final Map<String, String> soruceMapSourceEmbeddingDescriptions = new LinkedHashMap<>();
|
||||
private static final List<LanguageFeature.State> languageFeatureStates = Arrays.asList(
|
||||
LanguageFeature.State.ENABLED, LanguageFeature.State.ENABLED_WITH_WARNING, LanguageFeature.State.ENABLED_WITH_ERROR
|
||||
);
|
||||
private static final int MAX_WARNING_SIZE = 75;
|
||||
|
||||
static {
|
||||
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_PLAIN, KotlinBundle.message("configuration.description.plain.put.to.global.scope"));
|
||||
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_AMD, KotlinBundle.message("configuration.description.amd"));
|
||||
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_COMMONJS, KotlinBundle.message("configuration.description.commonjs"));
|
||||
moduleKindDescriptions.put(K2JsArgumentConstants.MODULE_UMD, KotlinBundle.message("configuration.description.umd.detect.amd.or.commonjs.if.available.fallback.to.plain"));
|
||||
|
||||
soruceMapSourceEmbeddingDescriptions.put(K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_NEVER, KotlinBundle.message("configuration.description.never"));
|
||||
soruceMapSourceEmbeddingDescriptions.put(K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_ALWAYS, KotlinBundle.message("configuration.description.always"));
|
||||
soruceMapSourceEmbeddingDescriptions.put(K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_INLINING, KotlinBundle.message("configuration.description.when.inlining.a.function.from.other.module.with.embedded.sources"));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private final KotlinCompilerWorkspaceSettings compilerWorkspaceSettings;
|
||||
private final Project project;
|
||||
private final boolean isProjectSettings;
|
||||
private CommonCompilerArguments commonCompilerArguments;
|
||||
private K2JSCompilerArguments k2jsCompilerArguments;
|
||||
private K2JVMCompilerArguments k2jvmCompilerArguments;
|
||||
private CompilerSettings compilerSettings;
|
||||
private JPanel contentPane;
|
||||
private ThreeStateCheckBox reportWarningsCheckBox;
|
||||
private RawCommandLineEditor additionalArgsOptionsField;
|
||||
private JLabel additionalArgsLabel;
|
||||
private ThreeStateCheckBox generateSourceMapsCheckBox;
|
||||
private TextFieldWithBrowseButton outputPrefixFile;
|
||||
private TextFieldWithBrowseButton outputPostfixFile;
|
||||
private JLabel labelForOutputDirectory;
|
||||
private TextFieldWithBrowseButton outputDirectory;
|
||||
private ThreeStateCheckBox copyRuntimeFilesCheckBox;
|
||||
private ThreeStateCheckBox keepAliveCheckBox;
|
||||
private JCheckBox enableIncrementalCompilationForJvmCheckBox;
|
||||
private JCheckBox enableIncrementalCompilationForJsCheckBox;
|
||||
private JComboBox moduleKindComboBox;
|
||||
private JTextField scriptTemplatesField;
|
||||
private JTextField scriptTemplatesClasspathField;
|
||||
private JLabel scriptTemplatesLabel;
|
||||
private JLabel scriptTemplatesClasspathLabel;
|
||||
private JPanel k2jvmPanel;
|
||||
private JPanel k2jsPanel;
|
||||
private JComboBox jvmVersionComboBox;
|
||||
private JComboBox<VersionView> languageVersionComboBox;
|
||||
private JComboBox coroutineSupportComboBox;
|
||||
private JComboBox<VersionView> apiVersionComboBox;
|
||||
private JPanel scriptPanel;
|
||||
private JLabel labelForOutputPrefixFile;
|
||||
private JLabel labelForOutputPostfixFile;
|
||||
private JLabel warningLabel;
|
||||
private JTextField sourceMapPrefix;
|
||||
private JLabel labelForSourceMapPrefix;
|
||||
private JComboBox sourceMapEmbedSources;
|
||||
private JPanel coroutinesPanel;
|
||||
private boolean isEnabled = true;
|
||||
|
||||
public KotlinCompilerConfigurableTab(
|
||||
Project project,
|
||||
@NotNull CommonCompilerArguments commonCompilerArguments,
|
||||
@NotNull K2JSCompilerArguments k2jsCompilerArguments,
|
||||
@NotNull K2JVMCompilerArguments k2jvmCompilerArguments, CompilerSettings compilerSettings,
|
||||
@Nullable KotlinCompilerWorkspaceSettings compilerWorkspaceSettings,
|
||||
boolean isProjectSettings,
|
||||
boolean isMultiEditor
|
||||
) {
|
||||
this.project = project;
|
||||
this.commonCompilerArguments = commonCompilerArguments;
|
||||
this.k2jsCompilerArguments = k2jsCompilerArguments;
|
||||
this.compilerSettings = compilerSettings;
|
||||
this.compilerWorkspaceSettings = compilerWorkspaceSettings;
|
||||
this.k2jvmCompilerArguments = k2jvmCompilerArguments;
|
||||
this.isProjectSettings = isProjectSettings;
|
||||
|
||||
warningLabel.setIcon(AllIcons.General.WarningDialog);
|
||||
|
||||
if (isProjectSettings) {
|
||||
languageVersionComboBox.addActionListener(e -> onLanguageLevelChanged(getSelectedLanguageVersionView()));
|
||||
}
|
||||
|
||||
additionalArgsOptionsField.attachLabel(additionalArgsLabel);
|
||||
|
||||
fillLanguageAndAPIVersionList();
|
||||
fillCoroutineSupportList();
|
||||
|
||||
if (CidrUtil.isRunningInCidrIde()) {
|
||||
keepAliveCheckBox.setVisible(false);
|
||||
k2jvmPanel.setVisible(false);
|
||||
k2jsPanel.setVisible(false);
|
||||
}
|
||||
else {
|
||||
initializeNonCidrSettings(isMultiEditor);
|
||||
}
|
||||
|
||||
reportWarningsCheckBox.setThirdStateEnabled(isMultiEditor);
|
||||
|
||||
if (isProjectSettings) {
|
||||
List<String> modulesOverridingProjectSettings = ArraysKt.mapNotNull(
|
||||
ModuleManager.getInstance(project).getModules(),
|
||||
module -> {
|
||||
KotlinFacet facet = KotlinFacet.Companion.get(module);
|
||||
if (facet == null) return null;
|
||||
KotlinFacetSettings facetSettings = facet.getConfiguration().getSettings();
|
||||
if (facetSettings.getUseProjectSettings()) return null;
|
||||
return module.getName();
|
||||
}
|
||||
);
|
||||
CollectionsKt.sort(modulesOverridingProjectSettings);
|
||||
if (!modulesOverridingProjectSettings.isEmpty()) {
|
||||
warningLabel.setVisible(true);
|
||||
warningLabel.setText(buildOverridingModulesWarning(modulesOverridingProjectSettings));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public KotlinCompilerConfigurableTab(Project project) {
|
||||
this(project,
|
||||
(CommonCompilerArguments) KotlinCommonCompilerArgumentsHolder.Companion.getInstance(project).getSettings().unfrozen(),
|
||||
(K2JSCompilerArguments) Kotlin2JsCompilerArgumentsHolder.Companion.getInstance(project).getSettings().unfrozen(),
|
||||
(K2JVMCompilerArguments) Kotlin2JvmCompilerArgumentsHolder.Companion.getInstance(project).getSettings().unfrozen(),
|
||||
(CompilerSettings) KotlinCompilerSettings.Companion.getInstance(project).getSettings().unfrozen(),
|
||||
KotlinCompilerWorkspaceSettings.getInstance(project),
|
||||
true,
|
||||
false);
|
||||
}
|
||||
|
||||
private void initializeNonCidrSettings(boolean isMultiEditor) {
|
||||
setupFileChooser(labelForOutputPrefixFile, outputPrefixFile,
|
||||
KotlinBundle.message("configuration.title.kotlin.compiler.js.option.output.prefix.browse.title"),
|
||||
true);
|
||||
setupFileChooser(labelForOutputPostfixFile, outputPostfixFile,
|
||||
KotlinBundle.message("configuration.title.kotlin.compiler.js.option.output.postfix.browse.title"),
|
||||
true);
|
||||
setupFileChooser(labelForOutputDirectory, outputDirectory,
|
||||
KotlinBundle.message("configuration.title.choose.output.directory"),
|
||||
false);
|
||||
|
||||
fillModuleKindList();
|
||||
fillSourceMapSourceEmbeddingList();
|
||||
fillJvmVersionList();
|
||||
|
||||
generateSourceMapsCheckBox.setThirdStateEnabled(isMultiEditor);
|
||||
generateSourceMapsCheckBox.addActionListener(event -> sourceMapPrefix.setEnabled(generateSourceMapsCheckBox.isSelected()));
|
||||
|
||||
copyRuntimeFilesCheckBox.setThirdStateEnabled(isMultiEditor);
|
||||
keepAliveCheckBox.setThirdStateEnabled(isMultiEditor);
|
||||
|
||||
if (compilerWorkspaceSettings == null) {
|
||||
keepAliveCheckBox.setVisible(false);
|
||||
k2jvmPanel.setVisible(false);
|
||||
enableIncrementalCompilationForJsCheckBox.setVisible(false);
|
||||
}
|
||||
|
||||
updateOutputDirEnabled();
|
||||
}
|
||||
|
||||
private static int calculateNameCountToShowInWarning(List<String> allNames) {
|
||||
int lengthSoFar = 0;
|
||||
int size = allNames.size();
|
||||
for (int i = 0; i < size; i++) {
|
||||
lengthSoFar = (i > 0 ? lengthSoFar + 2 : 0) + allNames.get(i).length();
|
||||
if (lengthSoFar > MAX_WARNING_SIZE) return i;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String buildOverridingModulesWarning(List<String> modulesOverridingProjectSettings) {
|
||||
int nameCountToShow = calculateNameCountToShowInWarning(modulesOverridingProjectSettings);
|
||||
int allNamesCount = modulesOverridingProjectSettings.size();
|
||||
if (nameCountToShow == 0) {
|
||||
return KotlinBundle.message("configuration.warning.text.modules.override.project.settings", String.valueOf(allNamesCount));
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("<html>");
|
||||
builder.append(KotlinBundle.message("configuration.warning.text.following.modules.override.project.settings")).append(" ");
|
||||
CollectionsKt.joinTo(
|
||||
modulesOverridingProjectSettings.subList(0, nameCountToShow),
|
||||
builder,
|
||||
", ",
|
||||
"",
|
||||
"",
|
||||
-1,
|
||||
"",
|
||||
new Function1<String, CharSequence>() {
|
||||
@Override
|
||||
public CharSequence invoke(String s) {
|
||||
return "<strong>" + s + "</strong>";
|
||||
}
|
||||
}
|
||||
);
|
||||
if (nameCountToShow < allNamesCount) {
|
||||
builder.append(" ").append(KotlinBundle.message("configuration.text.and")).append(" ").append(allNamesCount - nameCountToShow).append(" ").append(KotlinBundle.message("configuration.text.other.s"));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getModuleKindDescription(@Nullable String moduleKind) {
|
||||
if (moduleKind == null) return "";
|
||||
String result = moduleKindDescriptions.get(moduleKind);
|
||||
assert result != null : "Module kind " + moduleKind + " was not added to combobox, therefore it should not be here";
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getSourceMapSourceEmbeddingDescription(@Nullable String sourceMapSourceEmbeddingId) {
|
||||
if (sourceMapSourceEmbeddingId == null) return "";
|
||||
String result = soruceMapSourceEmbeddingDescriptions.get(sourceMapSourceEmbeddingId);
|
||||
assert result != null : "Source map source embedding mode " + sourceMapSourceEmbeddingId +
|
||||
" was not added to combobox, therefore it should not be here";
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getModuleKindOrDefault(@Nullable String moduleKindId) {
|
||||
if (moduleKindId == null) {
|
||||
moduleKindId = K2JsArgumentConstants.MODULE_PLAIN;
|
||||
}
|
||||
return moduleKindId;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getSourceMapSourceEmbeddingOrDefault(@Nullable String sourceMapSourceEmbeddingId) {
|
||||
if (sourceMapSourceEmbeddingId == null) {
|
||||
sourceMapSourceEmbeddingId = K2JsArgumentConstants.SOURCE_MAP_SOURCE_CONTENT_INLINING;
|
||||
}
|
||||
return sourceMapSourceEmbeddingId;
|
||||
}
|
||||
|
||||
private static String getJvmVersionOrDefault(@Nullable String jvmVersion) {
|
||||
return jvmVersion != null ? jvmVersion : JvmTarget.DEFAULT.getDescription();
|
||||
}
|
||||
|
||||
private static void setupFileChooser(
|
||||
@NotNull JLabel label,
|
||||
@NotNull TextFieldWithBrowseButton fileChooser,
|
||||
@NotNull String title,
|
||||
boolean forFiles
|
||||
) {
|
||||
label.setLabelFor(fileChooser);
|
||||
|
||||
fileChooser.addBrowseFolderListener(title, null, null,
|
||||
new FileChooserDescriptor(forFiles, !forFiles, false, false, false, false),
|
||||
TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT);
|
||||
}
|
||||
|
||||
private static boolean isModifiedWithNullize(@NotNull TextFieldWithBrowseButton chooser, @Nullable String currentValue) {
|
||||
return !StringUtil.equals(
|
||||
StringUtil.nullize(chooser.getText(), true),
|
||||
StringUtil.nullize(currentValue, true));
|
||||
}
|
||||
|
||||
private static boolean isModified(@NotNull TextFieldWithBrowseButton chooser, @NotNull String currentValue) {
|
||||
return !StringUtil.equals(chooser.getText(), currentValue);
|
||||
}
|
||||
|
||||
private void updateOutputDirEnabled() {
|
||||
if (isEnabled && copyRuntimeFilesCheckBox != null) {
|
||||
outputDirectory.setEnabled(copyRuntimeFilesCheckBox.isSelected());
|
||||
labelForOutputDirectory.setEnabled(copyRuntimeFilesCheckBox.isSelected());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isLessOrEqual(LanguageVersion version, LanguageVersion upperBound) {
|
||||
return VersionComparatorUtil.compare(version.getVersionString(), upperBound.getVersionString()) <= 0;
|
||||
}
|
||||
|
||||
public void onLanguageLevelChanged(VersionView languageLevel) {
|
||||
restrictAPIVersions(languageLevel);
|
||||
coroutinesPanel.setVisible(languageLevel.getVersion().compareTo(LanguageVersion.KOTLIN_1_3) < 0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void restrictAPIVersions(VersionView upperBoundView) {
|
||||
VersionView selectedAPIView = getSelectedAPIVersionView();
|
||||
LanguageVersion selectedAPIVersion = selectedAPIView.getVersion();
|
||||
LanguageVersion upperBound = upperBoundView.getVersion();
|
||||
List<VersionView> permittedAPIVersions = new ArrayList<>(LanguageVersion.values().length + 1);
|
||||
if (isLessOrEqual(VersionView.LatestStable.INSTANCE.getVersion(), upperBound)) {
|
||||
permittedAPIVersions.add(VersionView.LatestStable.INSTANCE);
|
||||
}
|
||||
ArraysKt.mapNotNullTo(
|
||||
LanguageVersion.values(),
|
||||
permittedAPIVersions,
|
||||
version -> isLessOrEqual(version, upperBound) && !version.isUnsupported() ? new VersionView.Specific(version) : null
|
||||
);
|
||||
apiVersionComboBox.setModel(
|
||||
new DefaultComboBoxModel(permittedAPIVersions.toArray())
|
||||
);
|
||||
apiVersionComboBox.setSelectedItem(
|
||||
VersionComparatorUtil.compare(selectedAPIVersion.getVersionString(), upperBound.getVersionString()) <= 0
|
||||
? selectedAPIView
|
||||
: upperBoundView
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void fillJvmVersionList() {
|
||||
for (TargetPlatform jvm : JvmIdePlatformKind.INSTANCE.getPlatforms()) {
|
||||
jvmVersionComboBox.addItem(PlatformUtilKt.subplatformsOfType(jvm, JdkPlatform.class).get(0).getTargetVersion().getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
private void fillLanguageAndAPIVersionList() {
|
||||
languageVersionComboBox.addItem(VersionView.LatestStable.INSTANCE);
|
||||
apiVersionComboBox.addItem(VersionView.LatestStable.INSTANCE);
|
||||
|
||||
for (LanguageVersion version : LanguageVersion.values()) {
|
||||
if (version.isUnsupported() || !version.isStable() && !ApplicationManager.getApplication().isInternal()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
VersionView.Specific specificVersion = new VersionView.Specific(version);
|
||||
languageVersionComboBox.addItem(specificVersion);
|
||||
apiVersionComboBox.addItem(specificVersion);
|
||||
}
|
||||
languageVersionComboBox.setRenderer(new DescriptionListCellRenderer());
|
||||
apiVersionComboBox.setRenderer(new DescriptionListCellRenderer());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void fillCoroutineSupportList() {
|
||||
for (LanguageFeature.State coroutineSupport : languageFeatureStates) {
|
||||
coroutineSupportComboBox.addItem(coroutineSupport);
|
||||
}
|
||||
coroutineSupportComboBox.setRenderer(new DescriptionListCellRenderer());
|
||||
}
|
||||
|
||||
public void setTargetPlatform(@Nullable IdePlatformKind<?> targetPlatform) {
|
||||
k2jsPanel.setVisible(JsIdePlatformUtil.isJavaScript(targetPlatform));
|
||||
scriptPanel.setVisible(JvmIdePlatformUtil.isJvm(targetPlatform));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void fillModuleKindList() {
|
||||
for (String moduleKind : moduleKindDescriptions.keySet()) {
|
||||
moduleKindComboBox.addItem(moduleKind);
|
||||
}
|
||||
moduleKindComboBox.setRenderer(new ListCellRendererWrapper<String>() {
|
||||
@Override
|
||||
public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
|
||||
setText(getModuleKindDescription(value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void fillSourceMapSourceEmbeddingList() {
|
||||
for (String moduleKind : soruceMapSourceEmbeddingDescriptions.keySet()) {
|
||||
sourceMapEmbedSources.addItem(moduleKind);
|
||||
}
|
||||
sourceMapEmbedSources.setRenderer(new ListCellRendererWrapper<String>() {
|
||||
@Override
|
||||
public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
|
||||
setText(value != null ? getSourceMapSourceEmbeddingDescription(value) : "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getId() {
|
||||
return "project.kotlinCompiler";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Runnable enableSearch(String option) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createComponent() {
|
||||
return contentPane;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModified() {
|
||||
return isModified(reportWarningsCheckBox, !commonCompilerArguments.getSuppressWarnings()) ||
|
||||
!getSelectedLanguageVersionView().equals(KotlinFacetSettingsKt.getLanguageVersionView(commonCompilerArguments)) ||
|
||||
!getSelectedAPIVersionView().equals(KotlinFacetSettingsKt.getApiVersionView(commonCompilerArguments)) ||
|
||||
!getSelectedCoroutineState().equals(commonCompilerArguments.getCoroutinesState()) ||
|
||||
!additionalArgsOptionsField.getText().equals(compilerSettings.getAdditionalArguments()) ||
|
||||
isModified(scriptTemplatesField, compilerSettings.getScriptTemplates()) ||
|
||||
isModified(scriptTemplatesClasspathField, compilerSettings.getScriptTemplatesClasspath()) ||
|
||||
isModified(copyRuntimeFilesCheckBox, compilerSettings.getCopyJsLibraryFiles()) ||
|
||||
isModified(outputDirectory, compilerSettings.getOutputDirectoryForJsLibraryFiles()) ||
|
||||
|
||||
(compilerWorkspaceSettings != null &&
|
||||
(isModified(enableIncrementalCompilationForJvmCheckBox, compilerWorkspaceSettings.getPreciseIncrementalEnabled()) ||
|
||||
isModified(enableIncrementalCompilationForJsCheckBox, compilerWorkspaceSettings.getIncrementalCompilationForJsEnabled()) ||
|
||||
isModified(keepAliveCheckBox, compilerWorkspaceSettings.getEnableDaemon()))) ||
|
||||
|
||||
isModified(generateSourceMapsCheckBox, k2jsCompilerArguments.getSourceMap()) ||
|
||||
isModifiedWithNullize(outputPrefixFile, k2jsCompilerArguments.getOutputPrefix()) ||
|
||||
isModifiedWithNullize(outputPostfixFile, k2jsCompilerArguments.getOutputPostfix()) ||
|
||||
!getSelectedModuleKind().equals(getModuleKindOrDefault(k2jsCompilerArguments.getModuleKind())) ||
|
||||
isModified(sourceMapPrefix, StringUtil.notNullize(k2jsCompilerArguments.getSourceMapPrefix())) ||
|
||||
!getSelectedSourceMapSourceEmbedding().equals(
|
||||
getSourceMapSourceEmbeddingOrDefault(k2jsCompilerArguments.getSourceMapEmbedSources())) ||
|
||||
!getSelectedJvmVersion().equals(getJvmVersionOrDefault(k2jvmCompilerArguments.getJvmTarget()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getSelectedModuleKind() {
|
||||
return getModuleKindOrDefault((String) moduleKindComboBox.getSelectedItem());
|
||||
}
|
||||
|
||||
private String getSelectedSourceMapSourceEmbedding() {
|
||||
return getSourceMapSourceEmbeddingOrDefault((String) sourceMapEmbedSources.getSelectedItem());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getSelectedJvmVersion() {
|
||||
return getJvmVersionOrDefault((String) jvmVersionComboBox.getSelectedItem());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VersionView getSelectedLanguageVersionView() {
|
||||
Object item = languageVersionComboBox.getSelectedItem();
|
||||
return item != null ? (VersionView) item : VersionView.LatestStable.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private VersionView getSelectedAPIVersionView() {
|
||||
Object item = apiVersionComboBox.getSelectedItem();
|
||||
return item != null ? (VersionView) item : VersionView.LatestStable.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String getSelectedCoroutineState() {
|
||||
if (getSelectedLanguageVersionView().getVersion().compareTo(LanguageVersion.KOTLIN_1_3) >= 0) {
|
||||
return CommonCompilerArguments.DEFAULT;
|
||||
}
|
||||
|
||||
LanguageFeature.State state = (LanguageFeature.State) coroutineSupportComboBox.getSelectedItem();
|
||||
if (state == null) return CommonCompilerArguments.DEFAULT;
|
||||
switch (state) {
|
||||
case ENABLED: return CommonCompilerArguments.ENABLE;
|
||||
case ENABLED_WITH_WARNING: return CommonCompilerArguments.WARN;
|
||||
case ENABLED_WITH_ERROR: return CommonCompilerArguments.ERROR;
|
||||
default: return CommonCompilerArguments.DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
public void applyTo(
|
||||
CommonCompilerArguments commonCompilerArguments,
|
||||
K2JVMCompilerArguments k2jvmCompilerArguments,
|
||||
K2JSCompilerArguments k2jsCompilerArguments,
|
||||
CompilerSettings compilerSettings
|
||||
) throws ConfigurationException {
|
||||
if (isProjectSettings) {
|
||||
boolean shouldInvalidateCaches =
|
||||
!getSelectedLanguageVersionView().equals(KotlinFacetSettingsKt.getLanguageVersionView(commonCompilerArguments)) ||
|
||||
!getSelectedAPIVersionView().equals(KotlinFacetSettingsKt.getApiVersionView(commonCompilerArguments)) ||
|
||||
!getSelectedCoroutineState().equals(commonCompilerArguments.getCoroutinesState()) ||
|
||||
!additionalArgsOptionsField.getText().equals(compilerSettings.getAdditionalArguments());
|
||||
|
||||
if (shouldInvalidateCaches) {
|
||||
ApplicationUtilsKt.runWriteAction(
|
||||
new Function0<Object>() {
|
||||
@Override
|
||||
public Object invoke() {
|
||||
RootUtilsKt.invalidateProjectRoots(project);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
commonCompilerArguments.setSuppressWarnings(!reportWarningsCheckBox.isSelected());
|
||||
KotlinFacetSettingsKt.setLanguageVersionView(commonCompilerArguments, getSelectedLanguageVersionView());
|
||||
KotlinFacetSettingsKt.setApiVersionView(commonCompilerArguments, getSelectedAPIVersionView());
|
||||
|
||||
commonCompilerArguments.setCoroutinesState(getSelectedCoroutineState());
|
||||
|
||||
compilerSettings.setAdditionalArguments(additionalArgsOptionsField.getText());
|
||||
compilerSettings.setScriptTemplates(scriptTemplatesField.getText());
|
||||
compilerSettings.setScriptTemplatesClasspath(scriptTemplatesClasspathField.getText());
|
||||
compilerSettings.setCopyJsLibraryFiles(copyRuntimeFilesCheckBox.isSelected());
|
||||
compilerSettings.setOutputDirectoryForJsLibraryFiles(outputDirectory.getText());
|
||||
|
||||
if (compilerWorkspaceSettings != null) {
|
||||
compilerWorkspaceSettings.setPreciseIncrementalEnabled(enableIncrementalCompilationForJvmCheckBox.isSelected());
|
||||
compilerWorkspaceSettings.setIncrementalCompilationForJsEnabled(enableIncrementalCompilationForJsCheckBox.isSelected());
|
||||
|
||||
boolean oldEnableDaemon = compilerWorkspaceSettings.getEnableDaemon();
|
||||
compilerWorkspaceSettings.setEnableDaemon(keepAliveCheckBox.isSelected());
|
||||
if (keepAliveCheckBox.isSelected() != oldEnableDaemon) {
|
||||
PluginStartupComponent.getInstance().resetAliveFlag();
|
||||
}
|
||||
}
|
||||
|
||||
k2jsCompilerArguments.setSourceMap(generateSourceMapsCheckBox.isSelected());
|
||||
k2jsCompilerArguments.setOutputPrefix(StringUtil.nullize(outputPrefixFile.getText(), true));
|
||||
k2jsCompilerArguments.setOutputPostfix(StringUtil.nullize(outputPostfixFile.getText(), true));
|
||||
k2jsCompilerArguments.setModuleKind(getSelectedModuleKind());
|
||||
|
||||
k2jsCompilerArguments.setSourceMapPrefix(sourceMapPrefix.getText());
|
||||
k2jsCompilerArguments.setSourceMapEmbedSources(generateSourceMapsCheckBox.isSelected() ? getSelectedSourceMapSourceEmbedding() : null);
|
||||
|
||||
k2jvmCompilerArguments.setJvmTarget(getSelectedJvmVersion());
|
||||
|
||||
if (isProjectSettings) {
|
||||
KotlinCommonCompilerArgumentsHolder.Companion.getInstance(project).setSettings(commonCompilerArguments);
|
||||
Kotlin2JvmCompilerArgumentsHolder.Companion.getInstance(project).setSettings(k2jvmCompilerArguments);
|
||||
Kotlin2JsCompilerArgumentsHolder.Companion.getInstance(project).setSettings(k2jsCompilerArguments);
|
||||
KotlinCompilerSettings.Companion.getInstance(project).setSettings(compilerSettings);
|
||||
}
|
||||
|
||||
for (ClearBuildStateExtension extension : ClearBuildStateExtension.getExtensions()) {
|
||||
extension.clearState(project);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply() throws ConfigurationException {
|
||||
applyTo(commonCompilerArguments, k2jvmCompilerArguments, k2jsCompilerArguments, compilerSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
reportWarningsCheckBox.setSelected(!commonCompilerArguments.getSuppressWarnings());
|
||||
languageVersionComboBox.setSelectedItem(KotlinFacetSettingsKt.getLanguageVersionView(commonCompilerArguments));
|
||||
onLanguageLevelChanged(getSelectedLanguageVersionView());
|
||||
apiVersionComboBox.setSelectedItem(KotlinFacetSettingsKt.getApiVersionView(commonCompilerArguments));
|
||||
coroutineSupportComboBox.setSelectedItem(CoroutineSupport.byCompilerArguments(commonCompilerArguments));
|
||||
additionalArgsOptionsField.setText(compilerSettings.getAdditionalArguments());
|
||||
scriptTemplatesField.setText(compilerSettings.getScriptTemplates());
|
||||
scriptTemplatesClasspathField.setText(compilerSettings.getScriptTemplatesClasspath());
|
||||
copyRuntimeFilesCheckBox.setSelected(compilerSettings.getCopyJsLibraryFiles());
|
||||
outputDirectory.setText(compilerSettings.getOutputDirectoryForJsLibraryFiles());
|
||||
|
||||
if (compilerWorkspaceSettings != null) {
|
||||
enableIncrementalCompilationForJvmCheckBox.setSelected(compilerWorkspaceSettings.getPreciseIncrementalEnabled());
|
||||
enableIncrementalCompilationForJsCheckBox.setSelected(compilerWorkspaceSettings.getIncrementalCompilationForJsEnabled());
|
||||
keepAliveCheckBox.setSelected(compilerWorkspaceSettings.getEnableDaemon());
|
||||
}
|
||||
|
||||
generateSourceMapsCheckBox.setSelected(k2jsCompilerArguments.getSourceMap());
|
||||
outputPrefixFile.setText(k2jsCompilerArguments.getOutputPrefix());
|
||||
outputPostfixFile.setText(k2jsCompilerArguments.getOutputPostfix());
|
||||
|
||||
moduleKindComboBox.setSelectedItem(getModuleKindOrDefault(k2jsCompilerArguments.getModuleKind()));
|
||||
sourceMapPrefix.setText(k2jsCompilerArguments.getSourceMapPrefix());
|
||||
sourceMapPrefix.setEnabled(k2jsCompilerArguments.getSourceMap());
|
||||
sourceMapEmbedSources.setSelectedItem(getSourceMapSourceEmbeddingOrDefault(k2jsCompilerArguments.getSourceMapEmbedSources()));
|
||||
|
||||
jvmVersionComboBox.setSelectedItem(getJvmVersionOrDefault(k2jvmCompilerArguments.getJvmTarget()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
}
|
||||
|
||||
@Nls
|
||||
@Override
|
||||
public String getDisplayName() {
|
||||
return KotlinBundle.message("configuration.name.kotlin.compiler");
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getHelpTopic() {
|
||||
return "reference.compiler.kotlin";
|
||||
}
|
||||
|
||||
public JPanel getContentPane() {
|
||||
return contentPane;
|
||||
}
|
||||
|
||||
public ThreeStateCheckBox getReportWarningsCheckBox() {
|
||||
return reportWarningsCheckBox;
|
||||
}
|
||||
|
||||
public RawCommandLineEditor getAdditionalArgsOptionsField() {
|
||||
return additionalArgsOptionsField;
|
||||
}
|
||||
|
||||
public ThreeStateCheckBox getGenerateSourceMapsCheckBox() {
|
||||
return generateSourceMapsCheckBox;
|
||||
}
|
||||
|
||||
public TextFieldWithBrowseButton getOutputPrefixFile() {
|
||||
return outputPrefixFile;
|
||||
}
|
||||
|
||||
public TextFieldWithBrowseButton getOutputPostfixFile() {
|
||||
return outputPostfixFile;
|
||||
}
|
||||
|
||||
public TextFieldWithBrowseButton getOutputDirectory() {
|
||||
return outputDirectory;
|
||||
}
|
||||
|
||||
public ThreeStateCheckBox getCopyRuntimeFilesCheckBox() {
|
||||
return copyRuntimeFilesCheckBox;
|
||||
}
|
||||
|
||||
public ThreeStateCheckBox getKeepAliveCheckBox() {
|
||||
return keepAliveCheckBox;
|
||||
}
|
||||
|
||||
public JComboBox getModuleKindComboBox() {
|
||||
return moduleKindComboBox;
|
||||
}
|
||||
|
||||
public JTextField getScriptTemplatesField() {
|
||||
return scriptTemplatesField;
|
||||
}
|
||||
|
||||
public JTextField getScriptTemplatesClasspathField() {
|
||||
return scriptTemplatesClasspathField;
|
||||
}
|
||||
|
||||
public JComboBox getLanguageVersionComboBox() {
|
||||
return languageVersionComboBox;
|
||||
}
|
||||
|
||||
public JComboBox getApiVersionComboBox() {
|
||||
return apiVersionComboBox;
|
||||
}
|
||||
|
||||
public JComboBox getCoroutineSupportComboBox() {
|
||||
return coroutineSupportComboBox;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean value) {
|
||||
isEnabled = value;
|
||||
UIUtil.setEnabled(getContentPane(), value, true);
|
||||
}
|
||||
|
||||
public CommonCompilerArguments getCommonCompilerArguments() {
|
||||
return commonCompilerArguments;
|
||||
}
|
||||
|
||||
public void setCommonCompilerArguments(CommonCompilerArguments commonCompilerArguments) {
|
||||
this.commonCompilerArguments = commonCompilerArguments;
|
||||
}
|
||||
|
||||
public K2JSCompilerArguments getK2jsCompilerArguments() {
|
||||
return k2jsCompilerArguments;
|
||||
}
|
||||
|
||||
public void setK2jsCompilerArguments(K2JSCompilerArguments k2jsCompilerArguments) {
|
||||
this.k2jsCompilerArguments = k2jsCompilerArguments;
|
||||
}
|
||||
|
||||
public K2JVMCompilerArguments getK2jvmCompilerArguments() {
|
||||
return k2jvmCompilerArguments;
|
||||
}
|
||||
|
||||
public void setK2jvmCompilerArguments(K2JVMCompilerArguments k2jvmCompilerArguments) {
|
||||
this.k2jvmCompilerArguments = k2jvmCompilerArguments;
|
||||
}
|
||||
|
||||
public CompilerSettings getCompilerSettings() {
|
||||
return compilerSettings;
|
||||
}
|
||||
|
||||
public void setCompilerSettings(CompilerSettings compilerSettings) {
|
||||
this.compilerSettings = compilerSettings;
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
// Workaround: ThreeStateCheckBox doesn't send suitable notification on state change
|
||||
// TODO: replace with PropertyChangerListener after fix is available in IDEA
|
||||
copyRuntimeFilesCheckBox = new ThreeStateCheckBox() {
|
||||
@Override
|
||||
public void setState(State state) {
|
||||
super.setState(state);
|
||||
updateOutputDirEnabled();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.formatter
|
||||
|
||||
import com.intellij.application.options.CodeStyle
|
||||
import com.intellij.internal.statistic.beans.UsageDescriptor
|
||||
import com.intellij.internal.statistic.utils.getEnumUsage
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
|
||||
import org.jetbrains.kotlin.idea.formatter.KotlinFormatterUsageCollector.KotlinFormatterKind.*
|
||||
import org.jetbrains.kotlin.idea.util.isDefaultOfficialCodeStyle
|
||||
|
||||
//todo: convert to FUS?
|
||||
class KotlinFormatterUsageCollector {
|
||||
fun getProjectUsages(project: Project): Set<UsageDescriptor> {
|
||||
val usedFormatter = getKotlinFormatterKind(project)
|
||||
|
||||
val settings = CodeStyle.getSettings(project)
|
||||
val kotlinCommonSettings = settings.kotlinCommonSettings
|
||||
val kotlinCustomSettings = settings.kotlinCustomSettings
|
||||
|
||||
return setOf(
|
||||
getEnumUsage("kotlin.formatter.kind", usedFormatter),
|
||||
getEnumStringPropertyUsage(
|
||||
"kotlin.formatter.defaults",
|
||||
kotlinCustomSettings.CODE_STYLE_DEFAULTS ?: kotlinCommonSettings.CODE_STYLE_DEFAULTS
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun getEnumStringPropertyUsage(key: String, value: String?): UsageDescriptor {
|
||||
return UsageDescriptor(key + "." + value.toString().toLowerCase(java.util.Locale.ENGLISH), 1)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val GROUP_ID = "kotlin.formatter"
|
||||
|
||||
private val KOTLIN_DEFAULT_COMMON = KotlinLanguageCodeStyleSettingsProvider().defaultCommonSettings
|
||||
.also { KotlinStyleGuideCodeStyle.applyToCommonSettings(it) }
|
||||
|
||||
private val KOTLIN_DEFAULT_CUSTOM by lazy {
|
||||
KotlinCodeStyleSettings.defaultSettings().cloneSettings()
|
||||
.also { KotlinStyleGuideCodeStyle.applyToKotlinCustomSettings(it) }
|
||||
}
|
||||
|
||||
private val KOTLIN_OBSOLETE_DEFAULT_COMMON = KotlinLanguageCodeStyleSettingsProvider().defaultCommonSettings
|
||||
.also { KotlinObsoleteCodeStyle.applyToCommonSettings(it) }
|
||||
|
||||
private val KOTLIN_OBSOLETE_DEFAULT_CUSTOM by lazy {
|
||||
KotlinCodeStyleSettings.defaultSettings().cloneSettings()
|
||||
.also { KotlinObsoleteCodeStyle.applyToKotlinCustomSettings(it) }
|
||||
}
|
||||
|
||||
fun getKotlinFormatterKind(project: Project): KotlinFormatterKind {
|
||||
val isProject = CodeStyleSettingsManager.getInstance(project).USE_PER_PROJECT_SETTINGS
|
||||
val isDefaultOfficialCodeStyle = isDefaultOfficialCodeStyle
|
||||
|
||||
val settings = CodeStyle.getSettings(project)
|
||||
val kotlinCommonSettings = settings.kotlinCommonSettings
|
||||
val kotlinCustomSettings = settings.kotlinCustomSettings
|
||||
|
||||
val isDefaultKotlinCommonSettings = kotlinCommonSettings == KotlinLanguageCodeStyleSettingsProvider().defaultCommonSettings
|
||||
val isDefaultKotlinCustomSettings = kotlinCustomSettings == KotlinCodeStyleSettings.defaultSettings()
|
||||
|
||||
if (isDefaultKotlinCommonSettings && isDefaultKotlinCustomSettings) {
|
||||
return if (isDefaultOfficialCodeStyle) {
|
||||
paired(IDEA_OFFICIAL_DEFAULT, isProject)
|
||||
} else {
|
||||
paired(IDEA_DEFAULT, isProject)
|
||||
}
|
||||
}
|
||||
|
||||
if (kotlinCommonSettings == KOTLIN_OBSOLETE_DEFAULT_COMMON && kotlinCustomSettings == KOTLIN_OBSOLETE_DEFAULT_CUSTOM) {
|
||||
return paired(IDEA_OBSOLETE_KOTLIN, isProject)
|
||||
}
|
||||
|
||||
if (kotlinCommonSettings == KOTLIN_DEFAULT_COMMON && kotlinCustomSettings == KOTLIN_DEFAULT_CUSTOM) {
|
||||
return paired(IDEA_KOTLIN, isProject)
|
||||
}
|
||||
|
||||
val isKotlinOfficialLikeSettings = settings == settings.clone().also {
|
||||
KotlinStyleGuideCodeStyle.apply(it)
|
||||
}
|
||||
if (isKotlinOfficialLikeSettings) {
|
||||
return paired(IDEA_OFFICIAL_KOTLIN_WITH_CUSTOM, isProject)
|
||||
}
|
||||
|
||||
val isKotlinObsoleteLikeSettings = settings == settings.clone().also {
|
||||
KotlinObsoleteCodeStyle.apply(it)
|
||||
}
|
||||
if (isKotlinObsoleteLikeSettings) {
|
||||
return paired(IDEA_KOTLIN_WITH_CUSTOM, isProject)
|
||||
}
|
||||
|
||||
return paired(IDEA_CUSTOM, isProject)
|
||||
}
|
||||
|
||||
private fun paired(kind: KotlinFormatterKind, isProject: Boolean): KotlinFormatterKind {
|
||||
if (!isProject) return kind
|
||||
|
||||
return when (kind) {
|
||||
IDEA_DEFAULT -> PROJECT_DEFAULT
|
||||
IDEA_OFFICIAL_DEFAULT -> PROJECT_OFFICIAL_DEFAULT
|
||||
IDEA_CUSTOM -> PROJECT_CUSTOM
|
||||
IDEA_KOTLIN_WITH_CUSTOM -> PROJECT_KOTLIN_WITH_CUSTOM
|
||||
IDEA_KOTLIN -> PROJECT_KOTLIN
|
||||
IDEA_OBSOLETE_KOTLIN -> PROJECT_OBSOLETE_KOTLIN
|
||||
IDEA_OFFICIAL_KOTLIN_WITH_CUSTOM -> PROJECT_OBSOLETE_KOTLIN_WITH_CUSTOM
|
||||
else -> kind
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum class KotlinFormatterKind {
|
||||
IDEA_DEFAULT,
|
||||
IDEA_CUSTOM,
|
||||
IDEA_KOTLIN_WITH_CUSTOM,
|
||||
IDEA_KOTLIN,
|
||||
|
||||
PROJECT_DEFAULT,
|
||||
PROJECT_CUSTOM,
|
||||
PROJECT_KOTLIN_WITH_CUSTOM,
|
||||
PROJECT_KOTLIN,
|
||||
|
||||
IDEA_OFFICIAL_DEFAULT,
|
||||
IDEA_OBSOLETE_KOTLIN,
|
||||
IDEA_OFFICIAL_KOTLIN_WITH_CUSTOM,
|
||||
PROJECT_OFFICIAL_DEFAULT,
|
||||
PROJECT_OBSOLETE_KOTLIN,
|
||||
PROJECT_OBSOLETE_KOTLIN_WITH_CUSTOM
|
||||
}
|
||||
}
|
||||
@@ -1,31 +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.highlighter.markers
|
||||
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.ui.LayeredIcon
|
||||
import com.intellij.util.ui.ColorsIcon
|
||||
import com.intellij.util.ui.JBUI
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.highlighter.dsl.DslHighlighterExtension
|
||||
import javax.swing.Icon
|
||||
|
||||
// FIX ME WHEN BUNCH as35 REMOVED
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
internal fun createDslStyleIcon(styleId: Int): Icon {
|
||||
val globalScheme = EditorColorsManager.getInstance().globalScheme
|
||||
val markersColor = globalScheme.getAttributes(DslHighlighterExtension.styleById(styleId)).foregroundColor
|
||||
val icon = LayeredIcon(2)
|
||||
val defaultIcon = KotlinIcons.DSL_MARKER_ANNOTATION
|
||||
icon.setIcon(defaultIcon, 0)
|
||||
icon.setIcon(
|
||||
ColorsIcon(defaultIcon.iconHeight / 2, markersColor).scale(JBUI.pixScale()),
|
||||
1,
|
||||
defaultIcon.iconHeight / 2,
|
||||
defaultIcon.iconWidth / 2
|
||||
)
|
||||
return icon
|
||||
}
|
||||
@@ -1,60 +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.inspections
|
||||
|
||||
import com.intellij.codeInsight.daemon.HighlightDisplayKey
|
||||
import com.intellij.codeInsight.daemon.QuickFixActionRegistrar
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider
|
||||
import com.intellij.openapi.util.Condition
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.SmartPsiElementPointer
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinIntentionActionFactoryWithDelegate
|
||||
import org.jetbrains.kotlin.idea.quickfix.QuickFixWithDelegateFactory
|
||||
import org.jetbrains.kotlin.idea.quickfix.detectPriority
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import java.util.*
|
||||
|
||||
object PlatformUnresolvedProvider : KotlinIntentionActionFactoryWithDelegate<KtNameReferenceExpression, String>() {
|
||||
override fun getElementOfInterest(diagnostic: Diagnostic) = QuickFixUtil.getParentElementOfType(diagnostic, KtNameReferenceExpression::class.java)
|
||||
override fun extractFixData(element: KtNameReferenceExpression, diagnostic: Diagnostic) = element.getReferencedName()
|
||||
|
||||
override fun createFixes(originalElementPointer: SmartPsiElementPointer<KtNameReferenceExpression>, diagnostic: Diagnostic, quickFixDataFactory: () -> String?): List<QuickFixWithDelegateFactory> {
|
||||
val result = ArrayList<QuickFixWithDelegateFactory>()
|
||||
|
||||
originalElementPointer.element?.references?.filterIsInstance<KtSimpleNameReference>()?.firstOrNull()?.let { reference ->
|
||||
UnresolvedReferenceQuickFixProvider.registerReferenceFixes(reference, object: QuickFixActionRegistrar {
|
||||
override fun register(action: IntentionAction) {
|
||||
result.add(QuickFixWithDelegateFactory(action.detectPriority()) { action })
|
||||
}
|
||||
|
||||
override fun register(fixRange: TextRange, action: IntentionAction, key: HighlightDisplayKey?) {
|
||||
register(action)
|
||||
}
|
||||
|
||||
override fun unregister(condition: Condition<IntentionAction>) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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 org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
|
||||
internal class ImportFix(expression: KtSimpleNameExpression): AbstractImportFix(expression, MyFactory) {
|
||||
companion object MyFactory : Factory() {
|
||||
override fun createImportAction(diagnostic: Diagnostic) =
|
||||
(diagnostic.psiElement as? KtSimpleNameExpression)?.let(::ImportFix)
|
||||
}
|
||||
}
|
||||
@@ -1,131 +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.ReferenceImporter
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerEx
|
||||
import com.intellij.codeInsight.daemon.impl.DaemonListeners
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.idea.actions.createSingleImportAction
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference
|
||||
import org.jetbrains.kotlin.idea.codeInsight.KotlinCodeInsightSettings
|
||||
import org.jetbrains.kotlin.idea.core.targetDescriptors
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class KotlinReferenceImporter : ReferenceImporter {
|
||||
override fun autoImportReferenceAtCursor(editor: Editor, file: PsiFile)
|
||||
= autoImportReferenceAtCursor(editor, file, allowCaretNearRef = false)
|
||||
|
||||
override fun autoImportReferenceAt(editor: Editor, file: PsiFile, offset: Int): Boolean {
|
||||
if (file !is KtFile) return false
|
||||
|
||||
val nameExpression = file.findElementAt(offset)?.parent as? KtSimpleNameExpression ?: return false
|
||||
|
||||
if (!KotlinCodeInsightSettings.getInstance().addUnambiguousImportsOnTheFly) return false
|
||||
|
||||
val importFix: ImportFixBase<out KtExpression>? = findImportFixAt(editor, file, offset)
|
||||
if (importFix != null && !importFix.isOutdated()) {
|
||||
val addImportAction = importFix.createAction(file.project, editor, nameExpression)
|
||||
if (addImportAction.isUnambiguous()) {
|
||||
addImportAction.execute()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun findImportFixAt(
|
||||
editor: Editor,
|
||||
file: KtFile,
|
||||
offset: Int
|
||||
): ImportFixBase<out KtExpression>? {
|
||||
var importFix: ImportFixBase<out KtExpression>? = null
|
||||
DaemonCodeAnalyzerEx.processHighlights(editor.document, file.project, null, offset, offset) { info ->
|
||||
importFix = info.quickFixActionRanges?.asSequence()
|
||||
?.map { it.first.action }?.filterIsInstance<ImportFixBase<*>>()?.firstOrNull()
|
||||
importFix == null
|
||||
}
|
||||
return importFix
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
// TODO: use in table cell
|
||||
fun autoImportReferenceAtCursor(editor: Editor, file: PsiFile, allowCaretNearRef: Boolean): Boolean {
|
||||
if (file !is KtFile) return false
|
||||
|
||||
val caretOffset = editor.caretModel.offset
|
||||
val document = editor.document
|
||||
val lineNumber = document.getLineNumber(caretOffset)
|
||||
val startOffset = document.getLineStartOffset(lineNumber)
|
||||
val endOffset = document.getLineEndOffset(lineNumber)
|
||||
|
||||
val elements = file.elementsInRange(TextRange(startOffset, endOffset))
|
||||
.flatMap { it.collectDescendantsOfType<KtSimpleNameExpression>() }
|
||||
for (element in elements) {
|
||||
if (!allowCaretNearRef && element.endOffset == caretOffset) continue
|
||||
|
||||
if (element.autoImport(editor, file)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun hasUnresolvedImportWhichCanImport(file: KtFile, name: String): Boolean {
|
||||
return file.importDirectives.any {
|
||||
it.targetDescriptors().isEmpty() && (it.isAllUnder || it.importPath?.importedName?.asString() == name)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtSimpleNameExpression.autoImport(editor: Editor, file: KtFile): Boolean {
|
||||
if (!KotlinCodeInsightSettings.getInstance().addUnambiguousImportsOnTheFly) return false
|
||||
if (!DaemonListeners.canChangeFileSilently(file)) return false
|
||||
if (hasUnresolvedImportWhichCanImport(file, getReferencedName())) return false
|
||||
|
||||
val bindingContext = analyze(BodyResolveMode.PARTIAL)
|
||||
if (mainReference.resolveToDescriptors(bindingContext).isNotEmpty()) return false
|
||||
|
||||
val suggestions = ImportFix(this).collectSuggestions()
|
||||
if (suggestions.size != 1) return false
|
||||
val descriptors = file.resolveImportReference(suggestions.single())
|
||||
|
||||
// we do not auto-import nested classes because this will probably add qualification into the text and this will confuse the user
|
||||
if (descriptors.any { it is ClassDescriptor && it.containingDeclaration is ClassDescriptor }) return false
|
||||
|
||||
var result = false
|
||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
||||
result = createSingleImportAction(project, editor, this, suggestions).execute()
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.crossLanguage
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle
|
||||
import com.intellij.lang.jvm.actions.ChangeParametersRequest
|
||||
import com.intellij.lang.jvm.actions.ExpectedParameter
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.JvmPsiConversionHelper
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||
import org.jetbrains.kotlin.idea.util.resolveToKotlinType
|
||||
import org.jetbrains.kotlin.load.java.NOT_NULL_ANNOTATIONS
|
||||
import org.jetbrains.kotlin.load.java.NULLABLE_ANNOTATIONS
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtParameterList
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
internal class ChangeMethodParameters(
|
||||
target: KtNamedFunction,
|
||||
val request: ChangeParametersRequest
|
||||
) : KotlinQuickFixAction<KtNamedFunction>(target) {
|
||||
|
||||
|
||||
override fun getText(): String {
|
||||
val target = element ?: return KotlinBundle.message("fix.change.signature.unavailable")
|
||||
|
||||
val helper = JvmPsiConversionHelper.getInstance(target.project)
|
||||
|
||||
val parametersString = request.expectedParameters.joinToString(", ", "(", ")") { ep ->
|
||||
val kotlinType =
|
||||
ep.expectedTypes.firstOrNull()?.theType?.let { helper.convertType(it).resolveToKotlinType(target.getResolutionFacade()) }
|
||||
val parameterName = ep.semanticNames.firstOrNull() ?: KotlinBundle.message("fix.change.signature.unnamed.parameter")
|
||||
"$parameterName: ${kotlinType?.let {
|
||||
IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_NO_ANNOTATIONS.renderType(it)
|
||||
} ?: KotlinBundle.message("fix.change.signature.error")}"
|
||||
}
|
||||
|
||||
val shortenParameterString = StringUtil.shortenTextWithEllipsis(parametersString, 30, 5)
|
||||
return QuickFixBundle.message("change.method.parameters.text", shortenParameterString)
|
||||
}
|
||||
|
||||
override fun getFamilyName(): String = QuickFixBundle.message("change.method.parameters.family")
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: KtFile): Boolean = element != null && request.isValid
|
||||
|
||||
private data class ParameterModification(
|
||||
val name: String,
|
||||
val ktType: KotlinType
|
||||
)
|
||||
|
||||
private fun getParametersModifications(
|
||||
target: KtNamedFunction,
|
||||
expectedParameters: List<ExpectedParameter>
|
||||
): List<ParameterModification> {
|
||||
val helper = JvmPsiConversionHelper.getInstance(target.project)
|
||||
|
||||
return expectedParameters.mapIndexed { index, expectedParameter ->
|
||||
val theType = expectedParameter.expectedTypes.firstOrNull()?.theType
|
||||
val kotlinType = theType
|
||||
?.let { helper.convertType(it).resolveToKotlinType(target.getResolutionFacade()) }
|
||||
?: ErrorUtils.createErrorType("unknown type")
|
||||
|
||||
ParameterModification(
|
||||
expectedParameter.semanticNames.firstOrNull() ?: "param$index", kotlinType
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
if (!request.isValid) return
|
||||
|
||||
val target = element ?: return
|
||||
val functionDescriptor = target.resolveToDescriptorIfAny(BodyResolveMode.FULL) ?: return
|
||||
|
||||
target.valueParameterList!!.parameters.forEach { target.valueParameterList!!.removeParameter(it) }
|
||||
val parameterActions = getParametersModifications(target, request.expectedParameters)
|
||||
|
||||
val parametersGenerated = parameterActions.let {
|
||||
it zip generateParameterList(project, functionDescriptor, it).parameters
|
||||
}.toMap()
|
||||
|
||||
for (action in parameterActions) {
|
||||
val parameter = parametersGenerated.getValue(action)
|
||||
target.valueParameterList!!.addParameter(parameter)
|
||||
}
|
||||
|
||||
ShortenReferences.DEFAULT.process(target.valueParameterList!!)
|
||||
}
|
||||
|
||||
private fun generateParameterList(
|
||||
project: Project,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
paramsToAdd: List<ParameterModification>
|
||||
): KtParameterList {
|
||||
val newFunctionDescriptor = SimpleFunctionDescriptorImpl.create(
|
||||
functionDescriptor.containingDeclaration,
|
||||
functionDescriptor.annotations,
|
||||
functionDescriptor.name,
|
||||
functionDescriptor.kind,
|
||||
SourceElement.NO_SOURCE
|
||||
).apply {
|
||||
initialize(
|
||||
functionDescriptor.extensionReceiverParameter?.copy(this),
|
||||
functionDescriptor.dispatchReceiverParameter,
|
||||
functionDescriptor.typeParameters,
|
||||
paramsToAdd.mapIndexed { index, parameter ->
|
||||
ValueParameterDescriptorImpl(
|
||||
this, null, index, Annotations.EMPTY,
|
||||
Name.identifier(parameter.name),
|
||||
parameter.ktType, declaresDefaultValue = false,
|
||||
isCrossinline = false, isNoinline = false, varargElementType = null, source = SourceElement.NO_SOURCE
|
||||
)
|
||||
},
|
||||
functionDescriptor.returnType,
|
||||
functionDescriptor.modality,
|
||||
functionDescriptor.visibility
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
val renderer = IdeDescriptorRenderers.SOURCE_CODE.withOptions {
|
||||
defaultParameterValueRenderer = null
|
||||
}
|
||||
|
||||
val newFunction = KtPsiFactory(project).createFunction(renderer.render(newFunctionDescriptor)).apply {
|
||||
valueParameters.forEach { param ->
|
||||
param.annotationEntries.forEach { a ->
|
||||
a.typeReference?.run {
|
||||
val fqName = FqName(this.text)
|
||||
if (fqName in (NULLABLE_ANNOTATIONS + NOT_NULL_ANNOTATIONS)) a.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newFunction.valueParameterList!!
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(ktNamedFunction: KtNamedFunction, request: ChangeParametersRequest): ChangeMethodParameters? =
|
||||
ChangeMethodParameters(ktNamedFunction, request)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,499 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.crossLanguage
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory
|
||||
import com.intellij.lang.java.beans.PropertyKind
|
||||
import com.intellij.lang.jvm.*
|
||||
import com.intellij.lang.jvm.actions.*
|
||||
import com.intellij.lang.jvm.types.JvmType
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.text.StringUtilRt
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo
|
||||
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl
|
||||
import com.intellij.psi.util.PropertyUtil
|
||||
import com.intellij.psi.util.PropertyUtilBase
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
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.resolveToKotlinType
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
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.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
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(
|
||||
contextElement: KtElement,
|
||||
propertyInfo: PropertyInfo,
|
||||
private val classOrFileName: String?
|
||||
) : CreateCallableFromUsageFix<KtElement>(contextElement, listOf(propertyInfo)) {
|
||||
override fun getFamilyName() = KotlinBundle.message("add.property")
|
||||
override fun getText(): String {
|
||||
val info = callableInfos.first() as PropertyInfo
|
||||
return buildString {
|
||||
append(KotlinBundle.message("text.add"))
|
||||
if (info.isLateinitPreferred || info.modifierList?.hasModifier(KtTokens.LATEINIT_KEYWORD) == true) {
|
||||
append("lateinit ")
|
||||
}
|
||||
append(if (info.writable) "var" else "val")
|
||||
append(KotlinBundle.message("property.0.to.1", info.name, classOrFileName.toString()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 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: ChangeModifierRequest): List<IntentionAction> {
|
||||
val kModifierOwner = target.toKtElement<KtModifierListOwner>() ?: return emptyList()
|
||||
|
||||
val modifier = request.modifier
|
||||
val shouldPresent = request.shouldBePresent()
|
||||
//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 createChangeModifierActions(target: JvmModifiersOwner, request: MemberRequest.Modifier): List<IntentionAction> =
|
||||
createChangeModifierActions(target, modifierRequest(request.modifier, request.shouldPresent))
|
||||
|
||||
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() = KotlinBundle.message("add.method")
|
||||
override fun getText() = KotlinBundle.message(
|
||||
"add.0.constructor.to.1",
|
||||
if (needPrimary) KotlinBundle.message("text.primary") else KotlinBundle.message("text.secondary"),
|
||||
targetClassName.toString()
|
||||
)
|
||||
}
|
||||
|
||||
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()
|
||||
return createAddPropertyActions(
|
||||
targetContainer, listOf(request.visibilityModifier),
|
||||
request.propertyType, request.propertyName, request.setterRequired, targetClass.name
|
||||
)
|
||||
}
|
||||
|
||||
private fun createAddPropertyActions(
|
||||
targetContainer: KtElement,
|
||||
modifiers: Iterable<JvmModifier>,
|
||||
propertyType: JvmType,
|
||||
propertyName: String,
|
||||
setterRequired: Boolean,
|
||||
classOrFileName: String?
|
||||
): List<IntentionAction> {
|
||||
val modifierBuilder = ModifierBuilder(targetContainer).apply { addJvmModifiers(modifiers) }
|
||||
if (!modifierBuilder.isValid) return emptyList()
|
||||
|
||||
val resolutionFacade = targetContainer.getResolutionFacade()
|
||||
val nullableAnyType = resolutionFacade.moduleDescriptor.builtIns.nullableAnyType
|
||||
|
||||
val ktType = (propertyType as? PsiType)?.resolveToKotlinType(resolutionFacade) ?: nullableAnyType
|
||||
val propertyInfo = PropertyInfo(
|
||||
propertyName,
|
||||
TypeInfo.Empty,
|
||||
TypeInfo(ktType, Variance.INVARIANT),
|
||||
setterRequired,
|
||||
listOf(targetContainer),
|
||||
modifierList = modifierBuilder.modifierList,
|
||||
withInitializer = true
|
||||
)
|
||||
val propertyInfos = if (setterRequired) {
|
||||
listOf(propertyInfo, propertyInfo.copyProperty(isLateinitPreferred = true))
|
||||
}
|
||||
else {
|
||||
listOf(propertyInfo)
|
||||
}
|
||||
return propertyInfos.map { CreatePropertyFix(targetContainer, it, classOrFileName) }
|
||||
}
|
||||
|
||||
override fun createAddFieldActions(targetClass: JvmClass, request: CreateFieldRequest): List<IntentionAction> {
|
||||
val targetContainer = targetClass.toKtClassOrFile() ?: return emptyList()
|
||||
|
||||
val resolutionFacade = targetContainer.getResolutionFacade()
|
||||
val typeInfo = request.fieldType.toKotlinTypeInfo(resolutionFacade)
|
||||
val writable = JvmModifier.FINAL !in request.modifiers
|
||||
|
||||
fun propertyInfo(lateinit: Boolean) = PropertyInfo(
|
||||
request.fieldName,
|
||||
TypeInfo.Empty,
|
||||
typeInfo,
|
||||
writable,
|
||||
listOf(targetContainer),
|
||||
isLateinitPreferred = false, // Dont set it to `lateinit` because it works via templates that brings issues in batch field adding
|
||||
isForCompanion = JvmModifier.STATIC in request.modifiers,
|
||||
modifierList = ModifierBuilder(targetContainer, allowJvmStatic = false).apply {
|
||||
addJvmModifiers(request.modifiers)
|
||||
if (modifierList.children.none { it.node.elementType in KtTokens.VISIBILITY_MODIFIERS })
|
||||
addJvmModifier(JvmModifier.PUBLIC)
|
||||
if (lateinit)
|
||||
modifierList.appendModifier(KtTokens.LATEINIT_KEYWORD)
|
||||
if (!request.modifiers.contains(JvmModifier.PRIVATE) && !lateinit)
|
||||
addAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME)
|
||||
}.modifierList,
|
||||
withInitializer = !lateinit
|
||||
)
|
||||
|
||||
val propertyInfos = if (writable) {
|
||||
listOf(propertyInfo(false), propertyInfo(true))
|
||||
}
|
||||
else {
|
||||
listOf(propertyInfo(false))
|
||||
}
|
||||
return propertyInfos.map { CreatePropertyFix(targetContainer, it, targetClass.name) }
|
||||
}
|
||||
|
||||
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, JvmPlatforms.unspecifiedJvmPlatform) ?: 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() = KotlinBundle.message("add.method")
|
||||
override fun getText() = KotlinBundle.message("add.method.0.to.1", methodName, targetClassName.toString())
|
||||
}
|
||||
|
||||
val nameAndKind = PropertyUtilBase.getPropertyNameAndKind(methodName) ?: return listOf(action)
|
||||
|
||||
val propertyType = (request.expectedParameters.singleOrNull()?.expectedTypes ?: request.returnType)
|
||||
.firstOrNull { JvmPsiConversionHelper.getInstance(targetContainer.project).convertType(it.theType) != PsiType.VOID }
|
||||
?: return listOf(action)
|
||||
|
||||
return createAddPropertyActions(
|
||||
targetContainer,
|
||||
request.modifiers,
|
||||
propertyType.theType,
|
||||
nameAndKind.first,
|
||||
nameAndKind.second == PropertyKind.SETTER,
|
||||
targetClass.name
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
override fun createAddAnnotationActions(target: JvmModifiersOwner, request: AnnotationRequest): List<IntentionAction> {
|
||||
val declaration = (target as? KtLightElement<*, *>)?.kotlinOrigin as? KtModifierListOwner ?: return emptyList()
|
||||
if (declaration.language != KotlinLanguage.INSTANCE) return emptyList()
|
||||
val annotationUseSiteTarget = when (target) {
|
||||
is JvmField -> AnnotationUseSiteTarget.FIELD
|
||||
is JvmMethod -> when {
|
||||
PropertyUtil.isSimplePropertySetter(target as? PsiMethod) -> AnnotationUseSiteTarget.PROPERTY_SETTER
|
||||
PropertyUtil.isSimplePropertyGetter(target as? PsiMethod) -> AnnotationUseSiteTarget.PROPERTY_GETTER
|
||||
else -> null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
return listOf(CreateAnnotationAction(declaration, annotationUseSiteTarget, request))
|
||||
}
|
||||
|
||||
private class CreateAnnotationAction(
|
||||
target: KtModifierListOwner,
|
||||
val annotationTarget: AnnotationUseSiteTarget?,
|
||||
val request: AnnotationRequest
|
||||
) : IntentionAction {
|
||||
|
||||
private val pointer = target.createSmartPointer()
|
||||
|
||||
override fun startInWriteAction(): Boolean = true
|
||||
|
||||
override fun getText(): String =
|
||||
QuickFixBundle.message("create.annotation.text", StringUtilRt.getShortName(request.qualifiedName))
|
||||
|
||||
override fun getFamilyName(): String = QuickFixBundle.message("create.annotation.family")
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean = pointer.element != null
|
||||
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
|
||||
val target = pointer.element ?: return
|
||||
val entry = addAnnotationEntry(target, request, annotationTarget)
|
||||
ShortenReferences.DEFAULT.process(entry)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun createChangeParametersActions(target: JvmMethod, request: ChangeParametersRequest): List<IntentionAction> {
|
||||
val ktNamedFunction = (target as? KtLightElement<*, *>)?.kotlinOrigin as? KtNamedFunction ?: return emptyList()
|
||||
return listOfNotNull(ChangeMethodParameters.create(ktNamedFunction, request))
|
||||
}
|
||||
}
|
||||
|
||||
internal fun addAnnotationEntry(
|
||||
target: KtModifierListOwner,
|
||||
request: AnnotationRequest,
|
||||
annotationTarget: AnnotationUseSiteTarget?
|
||||
): KtAnnotationEntry {
|
||||
val annotationClass = JavaPsiFacade.getInstance(target.project).findClass(request.qualifiedName, target.resolveScope)
|
||||
|
||||
val kotlinAnnotation = annotationClass?.language == KotlinLanguage.INSTANCE
|
||||
|
||||
val annotationUseSiteTargetPrefix = run prefixEvaluation@{
|
||||
if (annotationTarget == null) return@prefixEvaluation ""
|
||||
|
||||
val moduleDescriptor = (target as? KtDeclaration)?.resolveToDescriptorIfAny()?.module ?: return@prefixEvaluation ""
|
||||
val annotationClassDescriptor = moduleDescriptor.resolveClassByFqName(
|
||||
FqName(request.qualifiedName), NoLookupLocation.FROM_IDE
|
||||
) ?: return@prefixEvaluation ""
|
||||
|
||||
val applicableTargetSet =
|
||||
AnnotationChecker.applicableTargetSet(annotationClassDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
|
||||
|
||||
if (KotlinTarget.PROPERTY !in applicableTargetSet) return@prefixEvaluation ""
|
||||
|
||||
"${annotationTarget.renderName}:"
|
||||
}
|
||||
|
||||
// could be generated via descriptor when KT-30478 is fixed
|
||||
val entry = target.addAnnotationEntry(
|
||||
KtPsiFactory(target)
|
||||
.createAnnotationEntry(
|
||||
"@$annotationUseSiteTargetPrefix${request.qualifiedName}${
|
||||
request.attributes.takeIf { it.isNotEmpty() }?.mapIndexed { i, p ->
|
||||
if (!kotlinAnnotation && i == 0 && p.name == "value")
|
||||
renderAttributeValue(p.value).toString()
|
||||
else
|
||||
"${p.name} = ${renderAttributeValue(p.value)}"
|
||||
}?.joinToString(", ", "(", ")") ?: ""
|
||||
}"
|
||||
)
|
||||
)
|
||||
return entry
|
||||
}
|
||||
|
||||
private fun renderAttributeValue(annotationAttributeRequest: AnnotationAttributeValueRequest) =
|
||||
when (annotationAttributeRequest) {
|
||||
is AnnotationAttributeValueRequest.PrimitiveValue -> annotationAttributeRequest.value
|
||||
is AnnotationAttributeValueRequest.StringValue -> "\"" + annotationAttributeRequest.value + "\""
|
||||
}
|
||||
|
||||
|
||||
private fun JvmPsiConversionHelper.asPsiType(param: Pair<SuggestedNameInfo, List<ExpectedType>>): PsiType? =
|
||||
param.second.firstOrNull()?.theType?.let { convertType(it) }
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate
|
||||
import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesHandler
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
abstract class MoveHandlerDelegateCompat : MoveHandlerDelegate() {
|
||||
override fun canMove(elements: Array<PsiElement>, targetContainer: PsiElement?): Boolean =
|
||||
canMove(elements, targetContainer, null)
|
||||
|
||||
open fun canMove(elements: Array<out PsiElement>, targetContainer: PsiElement?, reference: PsiReference?): Boolean =
|
||||
super.canMove(elements, targetContainer)
|
||||
}
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
abstract class MoveFilesOrDirectoriesHandlerCompat : MoveFilesOrDirectoriesHandler() {
|
||||
override fun canMove(elements: Array<PsiElement>, targetContainer: PsiElement?): Boolean =
|
||||
canMove(elements, targetContainer, null)
|
||||
|
||||
open fun canMove(elements: Array<out PsiElement>, targetContainer: PsiElement?, reference: PsiReference?): Boolean =
|
||||
super.canMove(elements, targetContainer)
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.refactoring.rename.RenameJavaMethodProcessor
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.idea.references.SyntheticPropertyAccessorReference
|
||||
import org.jetbrains.kotlin.idea.statistics.FUSEventGroups
|
||||
import org.jetbrains.kotlin.idea.statistics.KotlinFUSLogger
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
import org.jetbrains.kotlin.utils.ifEmpty
|
||||
|
||||
class KotlinAwareJavaGetterRenameProcessor : RenameJavaMethodProcessor() {
|
||||
override fun canProcessElement(element: PsiElement) = element is PsiMethod && element !is KtLightMethod && JvmAbi.isGetterName(element.name)
|
||||
|
||||
override fun findReferences(element: PsiElement): MutableCollection<PsiReference> {
|
||||
val getterReferences = super.findReferences(element)
|
||||
val getter = element as? PsiMethod ?: return getterReferences
|
||||
val propertyName = SyntheticJavaPropertyDescriptor.propertyNameByGetMethodName(Name.identifier(getter.name)) ?: return getterReferences
|
||||
val setterName = JvmAbi.setterName(propertyName.asString())
|
||||
val containingClass = getter.containingClass ?: return getterReferences
|
||||
val setterReferences = containingClass
|
||||
.findMethodsByName(setterName, true)
|
||||
.filter { it.parameters.size == 1 && it.returnType == PsiType.VOID }
|
||||
.flatMap { super.findReferences(it).filterIsInstance<SyntheticPropertyAccessorReference.Setter>() }
|
||||
.ifEmpty { return getterReferences }
|
||||
return ArrayList<PsiReference>(getterReferences.size + setterReferences.size).apply {
|
||||
addAll(getterReferences)
|
||||
setterReferences.mapTo(this) { SyntheticPropertyAccessorReference.Getter(it.expression) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.search.SearchScope
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
class RenameKotlinClassifierProcessor : RenameKotlinClassifierProcessorCompat() {
|
||||
|
||||
override fun findReferences(element: PsiElement): Collection<PsiReference> {
|
||||
val references = super.findReferences(element)
|
||||
return processFoundReferences(element, references)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
class RenameKotlinFunctionProcessor : RenameKotlinFunctionProcessorCompat() {
|
||||
|
||||
override fun findReferences(element: PsiElement): Collection<PsiReference> {
|
||||
val references = super.findReferences(element)
|
||||
return processFoundReferences(element, references)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.psi.PsiElement
|
||||
import com.intellij.refactoring.listeners.RefactoringElementListener
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
|
||||
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringSettings
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
class RenameKotlinParameterProcessor : RenameKotlinPsiProcessor() {
|
||||
override fun canProcessElement(element: PsiElement) = element is KtParameter && element.ownerFunction is KtFunction
|
||||
|
||||
override fun isToSearchInComments(psiElement: PsiElement) = KotlinRefactoringSettings.instance.RENAME_SEARCH_IN_COMMENTS_FOR_VARIABLE
|
||||
|
||||
override fun setToSearchInComments(element: PsiElement, enabled: Boolean) {
|
||||
KotlinRefactoringSettings.instance.RENAME_SEARCH_IN_COMMENTS_FOR_VARIABLE = enabled
|
||||
}
|
||||
|
||||
override fun findCollisions(
|
||||
element: PsiElement,
|
||||
newName: String,
|
||||
allRenames: MutableMap<out PsiElement, String>,
|
||||
result: MutableList<UsageInfo>
|
||||
) {
|
||||
val declaration = element.namedUnwrappedElement as? KtNamedDeclaration ?: return
|
||||
|
||||
val collisions = SmartList<UsageInfo>()
|
||||
checkRedeclarations(declaration, newName, collisions)
|
||||
checkOriginalUsagesRetargeting(declaration, newName, result, collisions)
|
||||
checkNewNameUsagesRetargeting(declaration, newName, collisions)
|
||||
result += collisions
|
||||
}
|
||||
|
||||
override fun renameElement(element: PsiElement, newName: String, usages: Array<UsageInfo>, listener: RefactoringElementListener?) {
|
||||
super.renameElement(element, newName, usages, listener)
|
||||
|
||||
usages.forEach { (it as? KtResolvableCollisionUsageInfo)?.apply() }
|
||||
}
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.refactoring.listeners.RefactoringElementListener
|
||||
import com.intellij.refactoring.util.MoveRenameUsageInfo
|
||||
import com.intellij.usageView.UsageInfo
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.propertyNameByAccessor
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.idea.core.isEnumCompanionPropertyWithEntryConflict
|
||||
import org.jetbrains.kotlin.idea.core.unquote
|
||||
import org.jetbrains.kotlin.idea.refactoring.dropOverrideKeywordIfNecessary
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded
|
||||
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
class RenameKotlinPropertyProcessor : RenameKotlinPropertyProcessorCompat() {
|
||||
|
||||
override fun findReferences(element: PsiElement): Collection<PsiReference> {
|
||||
val references = super.findReferences(element)
|
||||
return processFoundReferences(element, references)
|
||||
}
|
||||
|
||||
//TODO: a very long and complicated method, even recursive. mb refactor it somehow? at least split by PsiElement types?
|
||||
override tailrec fun renameElement(
|
||||
element: PsiElement,
|
||||
newName: String,
|
||||
usages: Array<UsageInfo>,
|
||||
listener: RefactoringElementListener?
|
||||
) {
|
||||
val newNameUnquoted = newName.unquote()
|
||||
if (element is KtLightMethod) {
|
||||
if (element.modifierList.findAnnotation(DescriptorUtils.JVM_NAME.asString()) != null) {
|
||||
return super.renameElement(element, newName, usages, listener)
|
||||
}
|
||||
|
||||
val origin = element.kotlinOrigin
|
||||
val newPropertyName = propertyNameByAccessor(newNameUnquoted, element)
|
||||
// Kotlin references to Kotlin property should not use accessor name
|
||||
if (newPropertyName != null && (origin is KtProperty || origin is KtParameter)) {
|
||||
val (ktUsages, otherUsages) = usages.partition { it.reference is KtSimpleNameReference }
|
||||
super.renameElement(element, newName, otherUsages.toTypedArray(), listener)
|
||||
renameElement(origin, newPropertyName.quoteIfNeeded(), ktUsages.toTypedArray(), listener)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (element !is KtProperty && element !is KtParameter) {
|
||||
super.renameElement(element, newName, usages, listener)
|
||||
return
|
||||
}
|
||||
|
||||
val name = (element as KtNamedDeclaration).name!!
|
||||
val oldGetterName = JvmAbi.getterName(name)
|
||||
val oldSetterName = JvmAbi.setterName(name)
|
||||
|
||||
if (isEnumCompanionPropertyWithEntryConflict(element, newNameUnquoted)) {
|
||||
for ((i, usage) in usages.withIndex()) {
|
||||
if (usage !is MoveRenameUsageInfo) continue
|
||||
val ref = usage.reference ?: continue
|
||||
// TODO: Enum value can't be accessed from Java in case of conflict with companion member
|
||||
if (ref is KtReference) {
|
||||
val newRef = (ref.bindToElement(element) as? KtSimpleNameExpression)?.mainReference ?: continue
|
||||
usages[i] = MoveRenameUsageInfo(newRef, usage.referencedElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val adjustedUsages = if (element is KtParameter) usages.filterNot {
|
||||
val refTarget = it.reference?.resolve()
|
||||
refTarget is KtLightMethod && DataClassDescriptorResolver.isComponentLike(Name.guessByFirstCharacter(refTarget.name))
|
||||
} else usages.toList()
|
||||
|
||||
val refKindUsages = adjustedUsages.groupBy { usage: UsageInfo ->
|
||||
val refElement = usage.reference?.resolve()
|
||||
if (refElement is PsiMethod) {
|
||||
val refElementName = refElement.name
|
||||
val refElementNameToCheck =
|
||||
(if (usage is MangledJavaRefUsageInfo) KotlinTypeMapper.InternalNameMapper.demangleInternalName(refElementName) else null) ?: refElementName
|
||||
when (refElementNameToCheck) {
|
||||
oldGetterName -> UsageKind.GETTER_USAGE
|
||||
oldSetterName -> UsageKind.SETTER_USAGE
|
||||
else -> UsageKind.SIMPLE_PROPERTY_USAGE
|
||||
}
|
||||
} else {
|
||||
UsageKind.SIMPLE_PROPERTY_USAGE
|
||||
}
|
||||
}
|
||||
|
||||
super.renameElement(
|
||||
element.copy(), JvmAbi.setterName(newNameUnquoted).quoteIfNeeded(),
|
||||
refKindUsages[UsageKind.SETTER_USAGE]?.toTypedArray() ?: arrayOf<UsageInfo>(),
|
||||
null
|
||||
)
|
||||
|
||||
super.renameElement(
|
||||
element.copy(), JvmAbi.getterName(newNameUnquoted).quoteIfNeeded(),
|
||||
refKindUsages[UsageKind.GETTER_USAGE]?.toTypedArray() ?: arrayOf<UsageInfo>(),
|
||||
null
|
||||
)
|
||||
|
||||
super.renameElement(
|
||||
element, newName,
|
||||
refKindUsages[UsageKind.SIMPLE_PROPERTY_USAGE]?.toTypedArray() ?: arrayOf<UsageInfo>(),
|
||||
null
|
||||
)
|
||||
|
||||
usages.forEach { (it as? KtResolvableCollisionUsageInfo)?.apply() }
|
||||
|
||||
dropOverrideKeywordIfNecessary(element)
|
||||
|
||||
listener?.elementRenamed(element)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchOptions
|
||||
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
|
||||
import org.jetbrains.kotlin.idea.search.or
|
||||
import org.jetbrains.kotlin.idea.search.projectScope
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
abstract class RenameKotlinPsiProcessor : RenameKotlinPsiProcessorCompat() {
|
||||
|
||||
override fun findReferences(element: PsiElement): Collection<PsiReference> {
|
||||
val searchParameters = KotlinReferencesSearchParameters(
|
||||
element,
|
||||
element.project.projectScope() or element.useScope,
|
||||
kotlinOptions = KotlinReferencesSearchOptions(
|
||||
searchForComponentConventions = false,
|
||||
acceptImportAlias = false
|
||||
)
|
||||
)
|
||||
return findReferences(element, searchParameters)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +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.psi.PsiElement
|
||||
import com.intellij.slicer.SliceUsage
|
||||
import com.intellij.usages.UsagePresentation
|
||||
import com.intellij.util.Processor
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
|
||||
class KotlinSliceDereferenceUsage(
|
||||
element: PsiElement,
|
||||
parent: KotlinSliceUsage,
|
||||
mode: KotlinSliceAnalysisMode
|
||||
) : KotlinSliceUsage(element, parent, mode, false) {
|
||||
override fun processChildren(processor: Processor<SliceUsage>) {
|
||||
// no children
|
||||
}
|
||||
|
||||
override fun getPresentation() = object : UsagePresentation by super.getPresentation() {
|
||||
override fun getTooltipText() = KotlinBundle.message("slicer.tool.tip.text.variable.dereferenced")
|
||||
}
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.Disposable
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.progress.ProcessCanceledException
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.progress.util.BackgroundTaskUtil
|
||||
import com.intellij.openapi.project.DumbService
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Computable
|
||||
import com.intellij.openapi.util.ThrowableComputable
|
||||
import org.jetbrains.annotations.Nls
|
||||
import org.jetbrains.kotlin.idea.util.application.runReadAction
|
||||
import java.util.concurrent.Future
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.TimeoutException
|
||||
|
||||
object ProgressIndicatorUtils {
|
||||
private val LOG = Logger.getInstance(ProgressIndicatorUtils::class.java)
|
||||
|
||||
@JvmStatic
|
||||
fun <T> underModalProgress(
|
||||
project: Project,
|
||||
@Nls progressTitle: String,
|
||||
computable: () -> T
|
||||
): T {
|
||||
val dumbService = DumbService.getInstance(project)
|
||||
val useAlternativeResolve = dumbService.isAlternativeResolveEnabled
|
||||
val inReadAction =
|
||||
ThrowableComputable<T, RuntimeException> { runReadAction { return@runReadAction computable() } }
|
||||
val process =
|
||||
if (useAlternativeResolve) ThrowableComputable { dumbService.computeWithAlternativeResolveEnabled(inReadAction) } else inReadAction
|
||||
return ProgressManager.getInstance().runProcessWithProgressSynchronously(process, progressTitle, true, project)
|
||||
}
|
||||
|
||||
fun <T> runUnderDisposeAwareIndicator(
|
||||
parent: Disposable,
|
||||
computable: () -> T
|
||||
): T = BackgroundTaskUtil.runUnderDisposeAwareIndicator(parent, Computable { computable() })
|
||||
|
||||
@JvmStatic
|
||||
fun <T> awaitWithCheckCanceled(future: Future<T>): T {
|
||||
while (true) {
|
||||
ProgressManager.checkCanceled()
|
||||
try {
|
||||
return future.get(50, TimeUnit.MILLISECONDS)
|
||||
} catch (e: TimeoutException) {
|
||||
// ignore
|
||||
} catch (e: Exception) {
|
||||
LOG.warn(e)
|
||||
throw ProcessCanceledException(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
// INTENTION_TEXT: "Import members from 'javax.swing.SwingUtilities'"
|
||||
// WITH_RUNTIME
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: <br>public open fun convertPoint(source: Component!, aPoint: Point!, destination: Component!): Point! defined in javax.swing.SwingUtilities<br>public open fun convertPoint(source: Component!, x: Int, y: Int, destination: Component!): Point! defined in javax.swing.SwingUtilities
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: <br>public open fun convertPoint(source: Component!, aPoint: Point!, destination: Component!): Point! defined in javax.swing.SwingUtilities<br>public open fun convertPoint(source: Component!, x: Int, y: Int, destination: Component!): Point! defined in javax.swing.SwingUtilities
|
||||
// ERROR: Unresolved reference: unresolved
|
||||
|
||||
import javax.swing.SwingUtilities
|
||||
|
||||
fun foo() {
|
||||
<caret>SwingUtilities.convertPoint()
|
||||
|
||||
val bottom = SwingUtilities.BOTTOM
|
||||
|
||||
SwingUtilities.convertPoint()
|
||||
|
||||
SwingUtilities.unresolved
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// INTENTION_TEXT: "Import members from 'javax.swing.SwingUtilities'"
|
||||
// WITH_RUNTIME
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: <br>public open fun convertPoint(source: Component!, aPoint: Point!, destination: Component!): Point! defined in javax.swing.SwingUtilities<br>public open fun convertPoint(source: Component!, x: Int, y: Int, destination: Component!): Point! defined in javax.swing.SwingUtilities
|
||||
// ERROR: None of the following functions can be called with the arguments supplied: <br>public open fun convertPoint(source: Component!, aPoint: Point!, destination: Component!): Point! defined in javax.swing.SwingUtilities<br>public open fun convertPoint(source: Component!, x: Int, y: Int, destination: Component!): Point! defined in javax.swing.SwingUtilities
|
||||
// ERROR: Unresolved reference: unresolved
|
||||
|
||||
import javax.swing.SwingUtilities
|
||||
import javax.swing.SwingUtilities.*
|
||||
|
||||
fun foo() {
|
||||
<caret>convertPoint()
|
||||
|
||||
val bottom = BOTTOM
|
||||
|
||||
convertPoint()
|
||||
|
||||
SwingUtilities.unresolved
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
// WITH_RUNTIME
|
||||
|
||||
lateinit var x: java.lang.Readable
|
||||
|
||||
val file = x.read(<caret>)
|
||||
|
||||
/*
|
||||
Text: (<highlight>CharBuffer!</highlight>), Disabled: false, Strikeout: false, Green: true
|
||||
*/
|
||||
@@ -1,5 +0,0 @@
|
||||
// "Add constructor parameters from DataInputStream(InputStream!)" "true"
|
||||
import java.io.DataInputStream
|
||||
import java.io.InputStream
|
||||
|
||||
class C(`in`: InputStream?) : DataInputStream(`in`)
|
||||
@@ -1,5 +0,0 @@
|
||||
// "Add constructor parameters from ArrayList((MutableCollection<out String!>..Collection<String!>?))" "true"
|
||||
// ACTION: Add constructor parameters from ArrayList(Int)
|
||||
import java.util.ArrayList
|
||||
|
||||
class C(c: MutableCollection<out String>?) : ArrayList<String>(c)
|
||||
@@ -1,12 +0,0 @@
|
||||
// "Surround with lambda" "false"
|
||||
// ERROR: Type mismatch: inferred type is Object but () -> String was expected
|
||||
// ACTION: Annotate constructor 'Object'...
|
||||
// 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,125 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.codeInsight.moveUpDown
|
||||
|
||||
import com.intellij.application.options.CodeStyle
|
||||
import com.intellij.codeInsight.editorActions.moveLeftRight.MoveElementLeftAction
|
||||
import com.intellij.codeInsight.editorActions.moveLeftRight.MoveElementRightAction
|
||||
import com.intellij.codeInsight.editorActions.moveUpDown.MoveStatementDownAction
|
||||
import com.intellij.codeInsight.editorActions.moveUpDown.MoveStatementUpAction
|
||||
import com.intellij.codeInsight.editorActions.moveUpDown.StatementUpDownMover
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.editor.actionSystem.EditorAction
|
||||
import com.intellij.openapi.extensions.Extensions
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.testFramework.LightPlatformCodeInsightTestCase
|
||||
import junit.framework.ComparisonFailure
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.formatter.FormatSettingsUtil
|
||||
import org.jetbrains.kotlin.idea.codeInsight.upDownMover.KotlinDeclarationMover
|
||||
import org.jetbrains.kotlin.idea.codeInsight.upDownMover.KotlinExpressionMover
|
||||
import org.jetbrains.kotlin.idea.core.script.isScriptChangesNotifierDisabled
|
||||
import org.jetbrains.kotlin.idea.formatter.kotlinCustomSettings
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightTestCase
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractMoveStatementTest : AbstractCodeMoverTest() {
|
||||
protected fun doTestClassBodyDeclaration(path: String) {
|
||||
doTest(path, KotlinDeclarationMover::class.java)
|
||||
}
|
||||
|
||||
protected fun doTestExpression(path: String) {
|
||||
doTest(path, KotlinExpressionMover::class.java)
|
||||
}
|
||||
|
||||
protected fun doTestExpressionWithTrailingComma(path: String) {
|
||||
doTest(path, KotlinExpressionMover::class.java, true)
|
||||
}
|
||||
|
||||
private fun doTest(path: String, defaultMoverClass: Class<out StatementUpDownMover>, trailingComma: Boolean = false) {
|
||||
doTest(path, trailingComma) { isApplicableExpected, direction ->
|
||||
val movers = Extensions.getExtensions(StatementUpDownMover.STATEMENT_UP_DOWN_MOVER_EP)
|
||||
val info = StatementUpDownMover.MoveInfo()
|
||||
val actualMover = movers.firstOrNull {
|
||||
it.checkAvailable(LightPlatformCodeInsightTestCase.getEditor(), LightPlatformCodeInsightTestCase.getFile(), info, direction == "down")
|
||||
} ?: error("No mover found")
|
||||
|
||||
assertEquals("Unmatched movers", defaultMoverClass.name, actualMover::class.java.name)
|
||||
assertEquals("Invalid applicability", isApplicableExpected, info.toMove2 != null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractMoveLeftRightTest : AbstractCodeMoverTest() {
|
||||
protected fun doTest(path: String) {
|
||||
doTest(path) { _, _ -> }
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
abstract class AbstractCodeMoverTest : KotlinLightCodeInsightTestCase() {
|
||||
protected fun doTest(
|
||||
path: String,
|
||||
trailingComma: Boolean = false,
|
||||
isApplicableChecker: (isApplicableExpected: Boolean, direction: String) -> Unit
|
||||
) {
|
||||
configureByFile(path)
|
||||
|
||||
val fileText = FileUtil.loadFile(File(path), true)
|
||||
val direction = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// MOVE: ") ?: error("No MOVE directive found")
|
||||
|
||||
val action = when (direction) {
|
||||
"up" -> MoveStatementUpAction()
|
||||
"down" -> MoveStatementDownAction()
|
||||
"left" -> MoveElementLeftAction()
|
||||
"right" -> MoveElementRightAction()
|
||||
else -> error("Unknown direction: $direction")
|
||||
}
|
||||
|
||||
val isApplicableString = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// IS_APPLICABLE: ")
|
||||
val isApplicableExpected = isApplicableString == null || isApplicableString == "true"
|
||||
|
||||
isApplicableChecker(isApplicableExpected, direction)
|
||||
|
||||
val codeStyleSettings = CodeStyle.getSettings(editor_.project!!)
|
||||
try {
|
||||
val configurator = FormatSettingsUtil.createConfigurator(fileText, codeStyleSettings)
|
||||
configurator.configureSettings()
|
||||
|
||||
if (trailingComma) codeStyleSettings.kotlinCustomSettings.ALLOW_TRAILING_COMMA = true
|
||||
invokeAndCheck(path, action, isApplicableExpected)
|
||||
} finally {
|
||||
codeStyleSettings.clearCodeStyleSettings()
|
||||
}
|
||||
}
|
||||
|
||||
private fun invokeAndCheck(path: String, action: EditorAction, isApplicableExpected: Boolean) {
|
||||
val editor = editor_
|
||||
val dataContext = currentEditorDataContext_
|
||||
|
||||
val before = editor.document.text
|
||||
runWriteAction { action.actionPerformed(editor, dataContext) }
|
||||
|
||||
val after = editor.document.text
|
||||
val actionDoesNothing = after == before
|
||||
|
||||
TestCase.assertEquals(isApplicableExpected, !actionDoesNothing)
|
||||
|
||||
if (isApplicableExpected) {
|
||||
val afterFilePath = "$path.after"
|
||||
try {
|
||||
checkResultByFile(afterFilePath)
|
||||
} catch (e: ComparisonFailure) {
|
||||
KotlinTestUtils.assertEqualsToFile(File(afterFilePath), editor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getTestDataPath() = ""
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.decompiler.navigation
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
|
||||
abstract class AbstractNavigateFromLibrarySourcesTest : LightCodeInsightFixtureTestCase() {
|
||||
val module: Module get() = myModule
|
||||
|
||||
protected fun navigationElementForReferenceInLibrarySource(filePath: String, referenceText: String): PsiElement {
|
||||
val libraryOrderEntry = ModuleRootManager.getInstance(module!!).orderEntries.first { it is LibraryOrderEntry }
|
||||
val libSourcesRoot = libraryOrderEntry.getUrls(OrderRootType.SOURCES)[0]
|
||||
val libUrl = "$libSourcesRoot/$filePath"
|
||||
val vf = VirtualFileManager.getInstance().refreshAndFindFileByUrl(libUrl)
|
||||
?: error("Can't find library: $libUrl")
|
||||
val psiFile = psiManager.findFile(vf)!!
|
||||
val indexOf = psiFile.text!!.indexOf(referenceText)
|
||||
val reference = psiFile.findReferenceAt(indexOf)
|
||||
return reference.sure { "Couldn't find reference" }.resolve().sure { "Couldn't resolve reference" }.navigationElement!!
|
||||
}
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.decompiler.stubBuilder
|
||||
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.findTestLibraryRoot
|
||||
import org.jetbrains.kotlin.idea.test.KotlinJdkAndLibraryProjectDescriptor
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.junit.runner.RunWith
|
||||
import java.io.File
|
||||
|
||||
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
||||
class ClsStubBuilderForWrongAbiVersionTest : AbstractClsStubBuilderTest() {
|
||||
val module: Module get() = myModule
|
||||
|
||||
fun testPackage() = testStubsForFileWithWrongAbiVersion("Wrong_packageKt")
|
||||
|
||||
fun testClass() = testStubsForFileWithWrongAbiVersion("ClassWithWrongAbiVersion")
|
||||
|
||||
private fun testStubsForFileWithWrongAbiVersion(className: String) {
|
||||
val root = findTestLibraryRoot(module!!)!!
|
||||
val result = root.findClassFileByName(className)
|
||||
testClsStubsForFile(result, null)
|
||||
}
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor {
|
||||
return KotlinJdkAndLibraryProjectDescriptor(File(KotlinTestUtils.getTestDataPathBase() + "/cli/jvm/wrongAbiVersionLib/bin"))
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.parameterInfo
|
||||
|
||||
import com.intellij.codeInsight.hints.HintInfo
|
||||
import com.intellij.codeInsight.hints.InlayParameterHintsExtension
|
||||
import com.intellij.codeInsight.hints.isOwnsInlayInEditor
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
|
||||
import org.junit.Assert
|
||||
|
||||
internal fun JavaCodeInsightTestFixture.checkHintType(text: String, hintType: HintType) {
|
||||
configureByText("A.kt", text.trimIndent())
|
||||
doHighlighting()
|
||||
|
||||
checkHintType(hintType)
|
||||
}
|
||||
|
||||
internal fun JavaCodeInsightTestFixture.checkHintType(hintType: HintType) {
|
||||
val hintInfo = getHintInfoFromProvider(caretOffset, file, editor)
|
||||
Assert.assertNotNull("No hint available at caret", hintInfo)
|
||||
Assert.assertEquals(hintType.option.name, (hintInfo as HintInfo.OptionInfo).optionName)
|
||||
}
|
||||
|
||||
// It's crucial for this method to be conformable with IDEA internals.
|
||||
// Originally copied from com.intellij.codeInsight.hints.getHintInfoFromProvider()
|
||||
private fun getHintInfoFromProvider(offset: Int, file: PsiFile, editor: Editor): HintInfo? {
|
||||
val element = file.findElementAt(offset) ?: return null
|
||||
val provider = InlayParameterHintsExtension.forLanguage(file.language) ?: return null
|
||||
|
||||
val isHintOwnedByElement: (PsiElement) -> Boolean = { e -> provider.getHintInfo(e) != null && e.isOwnsInlayInEditor(editor) }
|
||||
val method = PsiTreeUtil.findFirstParent(element, isHintOwnedByElement) ?: return null
|
||||
|
||||
return provider.getHintInfo(method)
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.lang.jvm.actions.createChangeParametersActions
|
||||
import com.intellij.lang.jvm.actions.setMethodParametersRequest
|
||||
import com.intellij.lang.jvm.types.JvmType
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.jetbrains.uast.UMethod
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
||||
class CommonIntentionActionsParametersTest : LightPlatformCodeInsightFixtureTestCase() {
|
||||
|
||||
override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
|
||||
|
||||
fun testSetParameters() {
|
||||
myFixture.configureByText(
|
||||
"foo.kt",
|
||||
"""
|
||||
class Foo {
|
||||
fun ba<caret>r() {}
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createChangeParametersActions(
|
||||
myFixture.atCaret<UMethod>().javaPsi,
|
||||
setMethodParametersRequest(
|
||||
linkedMapOf<String, JvmType>(
|
||||
"i" to PsiType.INT,
|
||||
"file" to PsiType.getTypeByName("java.io.File", project, myFixture.file.resolveScope)
|
||||
).entries
|
||||
)
|
||||
).findWithText("Change method parameters to '(i: Int, file: File)'")
|
||||
)
|
||||
myFixture.checkResult(
|
||||
"""
|
||||
import java.io.File
|
||||
|
||||
class Foo {
|
||||
fun bar(i: Int, file: File) {}
|
||||
}
|
||||
""".trimIndent(),
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,236 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.facet.FacetManager
|
||||
import com.intellij.facet.impl.FacetUtil
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil.updateModel
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.roots.ui.configuration.libraryEditor.NewLibraryEditor
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.vfs.JarFileSystem
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments.Companion.DEFAULT
|
||||
import org.jetbrains.kotlin.config.CompilerSettings.Companion.DEFAULT_ADDITIONAL_ARGUMENTS
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgumentsHolder
|
||||
import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings
|
||||
import org.jetbrains.kotlin.idea.configuration.KotlinJavaModuleConfigurator
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacetType
|
||||
import org.jetbrains.kotlin.idea.facet.getRuntimeLibraryVersion
|
||||
import org.jetbrains.kotlin.idea.project.getLanguageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
|
||||
import org.jetbrains.kotlin.idea.test.configureKotlinFacet
|
||||
import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.junit.runner.RunWith
|
||||
import java.io.File
|
||||
|
||||
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
||||
class UpdateConfigurationQuickFixTest : LightPlatformCodeInsightFixtureTestCase() {
|
||||
|
||||
val module: Module get() = myModule
|
||||
|
||||
fun testDisableInlineClasses() {
|
||||
configureRuntime("mockRuntime11")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_3)
|
||||
myFixture.configureByText("foo.kt", "inline class My(val n: Int)")
|
||||
|
||||
assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, inlineClassesSupport)
|
||||
assertTrue(myFixture.availableIntentions.none { it.text == "Disable inline classes support in the project" })
|
||||
}
|
||||
|
||||
fun testEnableInlineClasses() {
|
||||
configureRuntime("mockRuntime11")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_3)
|
||||
myFixture.configureByText("foo.kt", "inline class My(val n: Int)")
|
||||
|
||||
assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, inlineClassesSupport)
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Enable inline classes support in the project"))
|
||||
assertEquals(LanguageFeature.State.ENABLED, inlineClassesSupport)
|
||||
}
|
||||
|
||||
fun testEnableCoroutines() {
|
||||
configureRuntime("mockRuntime11")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_1)
|
||||
myFixture.configureByText("foo.kt", "suspend fun foo()")
|
||||
|
||||
assertEquals(DEFAULT, KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.coroutinesState)
|
||||
assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, coroutineSupport)
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Enable coroutine support in the project"))
|
||||
assertEquals(LanguageFeature.State.ENABLED, coroutineSupport)
|
||||
}
|
||||
|
||||
fun testDisableCoroutines() {
|
||||
configureRuntime("mockRuntime11")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_1)
|
||||
myFixture.configureByText("foo.kt", "suspend fun foo()")
|
||||
|
||||
assertEquals(DEFAULT, KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.coroutinesState)
|
||||
assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, coroutineSupport)
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Disable coroutine support in the project"))
|
||||
assertEquals(LanguageFeature.State.ENABLED_WITH_ERROR, coroutineSupport)
|
||||
}
|
||||
|
||||
fun testEnableCoroutinesFacet() {
|
||||
configureRuntime("mockRuntime11")
|
||||
val facet = configureKotlinFacet(module) {
|
||||
settings.languageLevel = LanguageVersion.KOTLIN_1_1
|
||||
}
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_1)
|
||||
myFixture.configureByText("foo.kt", "suspend fun foo()")
|
||||
|
||||
assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, facet.configuration.settings.coroutineSupport)
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Enable coroutine support in the current module"))
|
||||
assertEquals(LanguageFeature.State.ENABLED, facet.configuration.settings.coroutineSupport)
|
||||
}
|
||||
|
||||
fun testEnableCoroutines_UpdateRuntime() {
|
||||
configureRuntime("mockRuntime106")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_1)
|
||||
myFixture.configureByText("foo.kt", "suspend fun foo()")
|
||||
|
||||
assertEquals(LanguageFeature.State.ENABLED_WITH_WARNING, coroutineSupport)
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Enable coroutine support in the project"))
|
||||
assertEquals(LanguageFeature.State.ENABLED, coroutineSupport)
|
||||
assertEquals(bundledRuntimeVersion(), getRuntimeLibraryVersion(myFixture.module))
|
||||
}
|
||||
|
||||
fun testIncreaseLangLevel() {
|
||||
configureRuntime("mockRuntime11")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_0)
|
||||
myFixture.configureByText("foo.kt", "val x get() = 1")
|
||||
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Set project language version to 1.1"))
|
||||
|
||||
assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.languageVersion)
|
||||
assertEquals("1.0", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.apiVersion)
|
||||
}
|
||||
|
||||
fun testIncreaseLangLevelFacet() {
|
||||
configureRuntime("mockRuntime11")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_0)
|
||||
configureKotlinFacet(module) {
|
||||
settings.languageLevel = LanguageVersion.KOTLIN_1_0
|
||||
settings.apiLevel = LanguageVersion.KOTLIN_1_0
|
||||
}
|
||||
myFixture.configureByText("foo.kt", "val x get() = 1")
|
||||
|
||||
assertEquals(LanguageVersion.KOTLIN_1_0, module.languageVersionSettings.languageVersion)
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Set module language version to 1.1"))
|
||||
assertEquals(LanguageVersion.KOTLIN_1_1, module.languageVersionSettings.languageVersion)
|
||||
}
|
||||
|
||||
fun testIncreaseLangAndApiLevel() {
|
||||
configureRuntime("mockRuntime11")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_0)
|
||||
myFixture.configureByText("foo.kt", "val x = <caret>\"s\"::length")
|
||||
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Set project language version to 1.1"))
|
||||
|
||||
assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.languageVersion)
|
||||
assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.apiVersion)
|
||||
}
|
||||
|
||||
fun testIncreaseLangAndApiLevel_10() {
|
||||
configureRuntime("mockRuntime106")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_0)
|
||||
myFixture.configureByText("foo.kt", "val x = <caret>\"s\"::length")
|
||||
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Set project language version to 1.1"))
|
||||
|
||||
assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.languageVersion)
|
||||
assertEquals("1.1", KotlinCommonCompilerArgumentsHolder.getInstance(project).settings.apiVersion)
|
||||
|
||||
assertEquals(bundledRuntimeVersion(), getRuntimeLibraryVersion(myFixture.module))
|
||||
}
|
||||
|
||||
fun testIncreaseLangLevelFacet_10() {
|
||||
configureRuntime("mockRuntime106")
|
||||
resetProjectSettings(LanguageVersion.KOTLIN_1_0)
|
||||
configureKotlinFacet(module) {
|
||||
settings.languageLevel = LanguageVersion.KOTLIN_1_0
|
||||
settings.apiLevel = LanguageVersion.KOTLIN_1_0
|
||||
}
|
||||
myFixture.configureByText("foo.kt", "val x = <caret>\"s\"::length")
|
||||
|
||||
assertEquals(LanguageVersion.KOTLIN_1_0, module.languageVersionSettings.languageVersion)
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Set module language version to 1.1"))
|
||||
assertEquals(LanguageVersion.KOTLIN_1_1, module.languageVersionSettings.languageVersion)
|
||||
|
||||
assertEquals(bundledRuntimeVersion(), getRuntimeLibraryVersion(myFixture.module))
|
||||
}
|
||||
|
||||
fun testAddKotlinReflect() {
|
||||
configureRuntime("actualRuntime")
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo(val prop: Any) {
|
||||
fun func() {}
|
||||
}
|
||||
|
||||
fun y01() = Foo::prop.gett<caret>er
|
||||
"""
|
||||
)
|
||||
myFixture.launchAction(myFixture.findSingleIntention("Add 'kotlin-reflect.jar' to the classpath"))
|
||||
val kotlinRuntime = KotlinJavaModuleConfigurator.instance.getKotlinLibrary(module)!!
|
||||
val classes = kotlinRuntime.getFiles(OrderRootType.CLASSES).map { it.name }
|
||||
assertContainsElements(classes, "kotlin-reflect.jar")
|
||||
val sources = kotlinRuntime.getFiles(OrderRootType.SOURCES)
|
||||
assertContainsElements(sources.map { it.name }, "kotlin-reflect-sources.jar")
|
||||
}
|
||||
|
||||
private fun configureRuntime(path: String) {
|
||||
val name = if (path == "mockRuntime106") "kotlin-runtime.jar" else "kotlin-stdlib.jar"
|
||||
val sourcePath = when (path) {
|
||||
"actualRuntime" -> PathUtil.kotlinPathsForIdeaPlugin.jar(KotlinPaths.Jar.StdLib)
|
||||
else -> File("idea/testData/configuration/$path/$name")
|
||||
}
|
||||
val tempFile = File(FileUtil.createTempDirectory("kotlin-update-configuration", null), name)
|
||||
FileUtil.copy(sourcePath, tempFile)
|
||||
val tempVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile) ?: error("Can't find file: $tempFile")
|
||||
|
||||
updateModel(myFixture.module) { model ->
|
||||
val editor = NewLibraryEditor()
|
||||
editor.name = "KotlinJavaRuntime"
|
||||
|
||||
editor.addRoot(JarFileSystem.getInstance().getJarRootForLocalFile(tempVFile)!!, OrderRootType.CLASSES)
|
||||
|
||||
ConfigLibraryUtil.addLibrary(editor, model)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetProjectSettings(version: LanguageVersion) {
|
||||
KotlinCompilerSettings.getInstance(project).update {
|
||||
additionalArguments = DEFAULT_ADDITIONAL_ARGUMENTS
|
||||
}
|
||||
KotlinCommonCompilerArgumentsHolder.getInstance(project).update {
|
||||
languageVersion = version.versionString
|
||||
apiVersion = version.versionString
|
||||
coroutinesState = DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
private val coroutineSupport: LanguageFeature.State
|
||||
get() = project.getLanguageVersionSettings().getFeatureSupport(LanguageFeature.Coroutines)
|
||||
|
||||
private val inlineClassesSupport: LanguageFeature.State
|
||||
get() = project.getLanguageVersionSettings().getFeatureSupport(LanguageFeature.InlineClasses)
|
||||
|
||||
override fun tearDown() {
|
||||
resetProjectSettings(LanguageVersion.LATEST_STABLE)
|
||||
FacetManager.getInstance(module).getFacetByType(KotlinFacetType.TYPE_ID)?.let {
|
||||
FacetUtil.deleteFacet(it)
|
||||
}
|
||||
ConfigLibraryUtil.removeLibrary(module, "KotlinJavaRuntime")
|
||||
super.tearDown()
|
||||
}
|
||||
}
|
||||
@@ -1,258 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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
|
||||
|
||||
import com.intellij.codeInsight.TargetElementUtil
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||
import com.intellij.openapi.actionSystem.impl.SimpleDataContext
|
||||
import com.intellij.openapi.command.WriteCommandAction
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler
|
||||
import com.intellij.testFramework.LightPlatformCodeInsightTestCase
|
||||
import com.intellij.testFramework.fixtures.CodeInsightTestUtil
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.idea.liveTemplates.setTemplateTestingCompat
|
||||
import org.jetbrains.kotlin.idea.refactoring.rename.KotlinMemberInplaceRenameHandler
|
||||
import org.jetbrains.kotlin.idea.refactoring.rename.KotlinVariableInplaceRenameHandler
|
||||
import org.jetbrains.kotlin.idea.refactoring.rename.RenameKotlinImplicitLambdaParameter
|
||||
import org.jetbrains.kotlin.idea.refactoring.rename.findElementForRename
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.junit.runner.RunWith
|
||||
import kotlin.test.assertFalse
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
||||
class InplaceRenameTest : LightPlatformCodeInsightTestCase() {
|
||||
override fun isRunInWriteAction(): Boolean = false
|
||||
override fun getTestDataPath(): String = PluginTestCaseBase.getTestDataPathBase() + "/refactoring/rename/inplace/"
|
||||
|
||||
fun testLocalVal() {
|
||||
doTestMemberInplaceRename("y")
|
||||
}
|
||||
|
||||
fun testForLoop() {
|
||||
doTestInplaceRename("j")
|
||||
}
|
||||
|
||||
fun testTryCatch() {
|
||||
doTestInplaceRename("e1")
|
||||
}
|
||||
|
||||
fun testFunctionLiteral() {
|
||||
doTestInplaceRename("y")
|
||||
}
|
||||
|
||||
fun testFunctionLiteralIt() {
|
||||
doTestImplicitLambdaParameter("y")
|
||||
}
|
||||
|
||||
fun testFunctionLiteralItEndCaret() {
|
||||
doTestImplicitLambdaParameter("y")
|
||||
}
|
||||
|
||||
fun testFunctionLiteralParenthesis() {
|
||||
doTestInplaceRename("y")
|
||||
}
|
||||
|
||||
fun testLocalFunction() {
|
||||
doTestMemberInplaceRename("bar")
|
||||
}
|
||||
|
||||
fun testFunctionParameterNotInplace() {
|
||||
doTestInplaceRename(null)
|
||||
}
|
||||
|
||||
fun testGlobalFunctionNotInplace() {
|
||||
doTestInplaceRename(null)
|
||||
}
|
||||
|
||||
fun testTopLevelValNotInplace() {
|
||||
doTestInplaceRename(null)
|
||||
}
|
||||
|
||||
fun testLabelFromFunction() {
|
||||
doTestMemberInplaceRename("foo")
|
||||
}
|
||||
|
||||
fun testMultiDeclaration() {
|
||||
doTestInplaceRename("foo")
|
||||
}
|
||||
|
||||
fun testLocalVarShadowingMemberProperty() {
|
||||
doTestMemberInplaceRename("name1")
|
||||
}
|
||||
|
||||
fun testNoReformat() {
|
||||
doTestMemberInplaceRename("subject2")
|
||||
}
|
||||
|
||||
fun testInvokeToFoo() {
|
||||
doTestMemberInplaceRename("foo")
|
||||
}
|
||||
|
||||
fun testInvokeToGet() {
|
||||
doTestMemberInplaceRename("get")
|
||||
}
|
||||
|
||||
fun testInvokeToGetWithQualifiedExpr() {
|
||||
doTestMemberInplaceRename("get")
|
||||
}
|
||||
|
||||
fun testInvokeToGetWithSafeQualifiedExpr() {
|
||||
doTestMemberInplaceRename("get")
|
||||
}
|
||||
|
||||
fun testInvokeToPlus() {
|
||||
doTestMemberInplaceRename("plus")
|
||||
}
|
||||
|
||||
fun testGetToFoo() {
|
||||
doTestMemberInplaceRename("foo")
|
||||
}
|
||||
|
||||
fun testGetToInvoke() {
|
||||
doTestMemberInplaceRename("invoke")
|
||||
}
|
||||
|
||||
fun testGetToInvokeWithQualifiedExpr() {
|
||||
doTestMemberInplaceRename("invoke")
|
||||
}
|
||||
|
||||
fun testGetToInvokeWithSafeQualifiedExpr() {
|
||||
doTestMemberInplaceRename("invoke")
|
||||
}
|
||||
|
||||
fun testGetToPlus() {
|
||||
doTestMemberInplaceRename("plus")
|
||||
}
|
||||
|
||||
fun testAddQuotes() {
|
||||
doTestMemberInplaceRename("is")
|
||||
}
|
||||
|
||||
fun testAddThis() {
|
||||
doTestMemberInplaceRename("foo")
|
||||
}
|
||||
|
||||
fun testExtensionAndNoReceiver() {
|
||||
doTestMemberInplaceRename("b")
|
||||
}
|
||||
|
||||
fun testTwoExtensions() {
|
||||
doTestMemberInplaceRename("example")
|
||||
}
|
||||
|
||||
fun testQuotedLocalVar() {
|
||||
doTestMemberInplaceRename("x")
|
||||
}
|
||||
|
||||
fun testQuotedParameter() {
|
||||
doTestMemberInplaceRename("x")
|
||||
}
|
||||
|
||||
fun testEraseCompanionName() {
|
||||
doTestMemberInplaceRename("")
|
||||
}
|
||||
|
||||
fun testLocalVarRedeclaration() {
|
||||
doTestMemberInplaceRename("localValB")
|
||||
}
|
||||
|
||||
fun testLocalFunRedeclaration() {
|
||||
doTestMemberInplaceRename("localFunB")
|
||||
}
|
||||
|
||||
fun testLocalClassRedeclaration() {
|
||||
doTestMemberInplaceRename("LocalClassB")
|
||||
}
|
||||
|
||||
fun testBacktickedWithAccessors() {
|
||||
doTestMemberInplaceRename("`object`")
|
||||
}
|
||||
|
||||
fun testNoTextUsagesForLocalVar() {
|
||||
doTestMemberInplaceRename("w")
|
||||
}
|
||||
|
||||
private fun doTestImplicitLambdaParameter(newName: String) {
|
||||
configureByFile(getTestName(false) + ".kt")
|
||||
|
||||
// This code is copy-pasted from CodeInsightTestUtil.doInlineRename() and slightly modified.
|
||||
// Original method was not suitable because it expects renamed element to be reference to other or referrable
|
||||
|
||||
val file = getFile()!!
|
||||
val editor = getEditor()!!
|
||||
val element = file.findElementForRename<KtNameReferenceExpression>(editor.caretModel.offset)!!
|
||||
assertNotNull(element)
|
||||
|
||||
val dataContext = SimpleDataContext.getSimpleContext(CommonDataKeys.PSI_ELEMENT.name, element,
|
||||
getCurrentEditorDataContext())
|
||||
val handler = RenameKotlinImplicitLambdaParameter()
|
||||
|
||||
assertTrue(handler.isRenaming(dataContext), "In-place rename not allowed for " + element)
|
||||
|
||||
val project = editor.project!!
|
||||
|
||||
setTemplateTestingCompat(project, testRootDisposable)
|
||||
|
||||
object : WriteCommandAction.Simple<Any>(project) {
|
||||
override fun run() {
|
||||
handler.invoke(project, editor, file, dataContext)
|
||||
}
|
||||
}.execute()
|
||||
|
||||
var state = TemplateManagerImpl.getTemplateState(editor)
|
||||
assert(state != null)
|
||||
val range = state!!.currentVariableRange
|
||||
assert(range != null)
|
||||
object : WriteCommandAction.Simple<Any>(project) {
|
||||
override fun run() {
|
||||
editor.document.replaceString(range!!.startOffset, range.endOffset, newName)
|
||||
}
|
||||
}.execute().throwException()
|
||||
|
||||
state = TemplateManagerImpl.getTemplateState(editor)
|
||||
assert(state != null)
|
||||
state!!.gotoEnd(false)
|
||||
|
||||
checkResultByFile(getTestName(false) + ".kt.after")
|
||||
}
|
||||
|
||||
private fun doTestMemberInplaceRename(newName: String?) {
|
||||
doTestInplaceRename(newName, KotlinMemberInplaceRenameHandler())
|
||||
}
|
||||
|
||||
private fun doTestInplaceRename(newName: String?, handler: VariableInplaceRenameHandler = KotlinVariableInplaceRenameHandler()) {
|
||||
configureByFile(getTestName(false) + ".kt")
|
||||
val element = TargetElementUtil.findTargetElement(
|
||||
myEditor,
|
||||
TargetElementUtil.ELEMENT_NAME_ACCEPTED or TargetElementUtil.REFERENCED_ELEMENT_ACCEPTED
|
||||
)
|
||||
|
||||
assertNotNull(element)
|
||||
|
||||
val dataContext = SimpleDataContext.getSimpleContext(CommonDataKeys.PSI_ELEMENT.name, element!!,
|
||||
getCurrentEditorDataContext())
|
||||
|
||||
if (newName == null) {
|
||||
assertFalse(handler.isRenaming(dataContext), "In-place rename is allowed for " + element)
|
||||
}
|
||||
else {
|
||||
try {
|
||||
assertTrue(handler.isRenaming(dataContext), "In-place rename not allowed for " + element)
|
||||
CodeInsightTestUtil.doInlineRename(handler, newName, getEditor(), element)
|
||||
checkResultByFile(getTestName(false) + ".kt.after")
|
||||
} catch (e: BaseRefactoringProcessor.ConflictsInTestsException) {
|
||||
val expectedMessage = InTextDirectivesUtils.findStringWithPrefixes(myFile.text, "// SHOULD_FAIL_WITH: ")
|
||||
TestCase.assertEquals(expectedMessage, e.messages.joinToString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.refactoring.move.MoveHandlerDelegate
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
internal fun MoveHandlerDelegate.canMoveCompat(
|
||||
elements: Array<out PsiElement>,
|
||||
targetContainer: PsiElement?,
|
||||
reference: PsiReference?
|
||||
): Boolean = canMove(elements, targetContainer)
|
||||
@@ -1,137 +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.NullableNotNullManagerImpl
|
||||
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.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 : NullableNotNullManagerImpl(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 getNullables() = emptyList<String>()
|
||||
override fun setNullables(vararg p0: String) = Unit
|
||||
override fun getNotNulls() = emptyList<String>()
|
||||
override fun setNotNulls(vararg p0: String) = Unit
|
||||
override fun getDefaultNullable() = ""
|
||||
override fun setDefaultNullable(defaultNullable: String) = Unit
|
||||
override fun getDefaultNotNull() = ""
|
||||
override fun setDefaultNotNull(p0: String) = Unit
|
||||
override fun setInstrumentedNotNulls(p0: List<String>) = Unit
|
||||
override fun getInstrumentedNotNulls() = emptyList<String>()
|
||||
override fun isJsr305Default(psiAnnotation: PsiAnnotation, p1: Array<PsiAnnotation.TargetType>) = null
|
||||
})
|
||||
|
||||
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, 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. and Kotlin Programming Language contributors.
|
||||
* 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)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.nj2k.postProcessing.processings
|
||||
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.refactoring.rename.RenamePsiElementProcessor
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
|
||||
// FIX ME WHEN BUNCH 191 REMOVED
|
||||
|
||||
internal fun KtParameter.findReferences(renamer: RenamePsiElementProcessor): MutableCollection<PsiReference> {
|
||||
return renamer.findReferences(this, false)
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiRecursiveElementWalkingVisitor
|
||||
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.uast.*
|
||||
import java.util.*
|
||||
|
||||
class KotlinUFile(
|
||||
override val psi: KtFile,
|
||||
override val languagePlugin: UastLanguagePlugin = kotlinUastPlugin
|
||||
) : UFile {
|
||||
override val packageName: String
|
||||
get() = psi.packageFqName.asString()
|
||||
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = psi.annotationEntries.map { KotlinUAnnotation(it, this) }
|
||||
|
||||
override val javaPsi: PsiElement? = null
|
||||
|
||||
override val sourcePsi: PsiElement? = psi
|
||||
|
||||
override val allCommentsInFile by lz {
|
||||
val comments = ArrayList<UComment>(0)
|
||||
psi.accept(object : PsiRecursiveElementWalkingVisitor() {
|
||||
override fun visitComment(comment: PsiComment) {
|
||||
comments += UComment(comment, this@KotlinUFile)
|
||||
}
|
||||
})
|
||||
comments
|
||||
}
|
||||
|
||||
override val imports by lz { psi.importDirectives.map { KotlinUImportStatement(it, this) } }
|
||||
|
||||
override val classes by lz {
|
||||
val facadeOrScriptClass = if (psi.isScript()) psi.script?.toLightClass() else psi.findFacadeClass()
|
||||
val classes = psi.declarations.mapNotNull { (it as? KtClassOrObject)?.toLightClass()?.toUClass() }
|
||||
|
||||
(facadeOrScriptClass?.toUClass()?.let { listOf(it) } ?: emptyList()) + classes
|
||||
}
|
||||
|
||||
private fun PsiClass.toUClass() = languagePlugin.convertOpt<UClass>(this, this@KotlinUFile)
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin.declarations
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.java.internal.JavaUElementWithComments
|
||||
import org.jetbrains.uast.kotlin.*
|
||||
import org.jetbrains.uast.kotlin.psi.UastFakeLightMethod
|
||||
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
|
||||
|
||||
open class KotlinUMethod(
|
||||
psi: PsiMethod,
|
||||
final override val sourcePsi: KtDeclaration?,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUElement(givenParent), UMethodTypeSpecific, UAnchorOwner, JavaUElementWithComments, PsiMethod by psi {
|
||||
|
||||
constructor(psi: KtLightMethod, givenParent: UElement?) : this(psi, getKotlinMemberOrigin(psi), givenParent)
|
||||
|
||||
override val comments: List<UComment>
|
||||
get() = super<KotlinAbstractUElement>.comments
|
||||
|
||||
override val psi: PsiMethod = unwrap<UMethod, PsiMethod>(psi)
|
||||
|
||||
override val javaPsi = psi
|
||||
|
||||
override fun getSourceElement() = sourcePsi ?: this
|
||||
|
||||
private val kotlinOrigin = getKotlinMemberOrigin(psi.originalElement) ?: sourcePsi
|
||||
|
||||
override fun getContainingFile(): PsiFile? {
|
||||
kotlinOrigin?.containingFile?.let { return it }
|
||||
return unwrapFakeFileForLightClass(psi.containingFile)
|
||||
}
|
||||
|
||||
override fun getNameIdentifier() = UastLightIdentifier(psi, kotlinOrigin as? KtDeclaration)
|
||||
|
||||
override val annotations: List<UAnnotation> by lz {
|
||||
psi.annotations
|
||||
.mapNotNull { (it as? KtLightElement<*, *>)?.kotlinOrigin as? KtAnnotationEntry }
|
||||
.map { KotlinUAnnotation(it, this) }
|
||||
}
|
||||
|
||||
private val receiver by lz { (sourcePsi as? KtCallableDeclaration)?.receiverTypeReference }
|
||||
|
||||
override val uastParameters by lz {
|
||||
|
||||
fun parameterOrigin(psiParameter: PsiParameter?): KtElement? = when (psiParameter) {
|
||||
is KtLightElement<*, *> -> psiParameter.kotlinOrigin
|
||||
is UastKotlinPsiParameter -> psiParameter.ktParameter
|
||||
else -> null
|
||||
}
|
||||
|
||||
val lightParams = psi.parameterList.parameters
|
||||
val receiver = receiver ?: return@lz lightParams.map { KotlinUParameter(it, parameterOrigin(it), this) }
|
||||
val receiverLight = lightParams.firstOrNull() ?: return@lz emptyList<UParameter>()
|
||||
val uParameters = SmartList<UParameter>(KotlinReceiverUParameter(receiverLight, receiver, this))
|
||||
lightParams.drop(1).mapTo(uParameters) { KotlinUParameter(it, parameterOrigin(it), this) }
|
||||
uParameters
|
||||
}
|
||||
|
||||
override val uastAnchor by lazy {
|
||||
KotlinUIdentifier(
|
||||
nameIdentifier,
|
||||
sourcePsi.let { sourcePsi ->
|
||||
when (sourcePsi) {
|
||||
is PsiNameIdentifierOwner -> sourcePsi.nameIdentifier
|
||||
is KtObjectDeclaration -> sourcePsi.getObjectKeyword()
|
||||
is KtPropertyAccessor -> sourcePsi.namePlaceholder
|
||||
else -> sourcePsi?.navigationElement
|
||||
}
|
||||
},
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
override val uastBody by lz {
|
||||
if (kotlinOrigin?.canAnalyze() != true) return@lz null // EA-137193
|
||||
val bodyExpression = when (kotlinOrigin) {
|
||||
is KtFunction -> kotlinOrigin.bodyExpression
|
||||
is KtPropertyAccessor -> kotlinOrigin.bodyExpression
|
||||
is KtProperty -> when {
|
||||
psi is KtLightMethod && psi.isGetter -> kotlinOrigin.getter?.bodyExpression
|
||||
psi is KtLightMethod && psi.isSetter -> kotlinOrigin.setter?.bodyExpression
|
||||
else -> null
|
||||
}
|
||||
else -> null
|
||||
} ?: return@lz null
|
||||
|
||||
wrapExpressionBody(this, bodyExpression)
|
||||
}
|
||||
|
||||
override val isOverride: Boolean
|
||||
get() = (kotlinOrigin as? KtCallableDeclaration)?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false
|
||||
|
||||
override val returnTypeReference: UTypeReferenceExpression? by lz {
|
||||
(sourcePsi as? KtCallableDeclaration)?.typeReference?.let {
|
||||
LazyKotlinUTypeReferenceExpression(it, this) { javaPsi.returnType ?: UastErrorType }
|
||||
}
|
||||
}
|
||||
|
||||
override fun equals(other: Any?) = other is KotlinUMethod && psi == other.psi
|
||||
|
||||
companion object {
|
||||
private fun getKotlinMemberOrigin(element: PsiElement?): KtDeclaration? {
|
||||
(element as? KtLightMember<*>)?.lightMemberOrigin?.auxiliaryOriginalElement?.let { return it }
|
||||
(element as? KtLightElement<*, *>)?.kotlinOrigin?.let { return it as? KtDeclaration }
|
||||
return null
|
||||
}
|
||||
|
||||
fun create(psi: KtLightMethod, containingElement: UElement?): KotlinUMethod {
|
||||
val kotlinOrigin = psi.kotlinOrigin
|
||||
return if (kotlinOrigin is KtConstructor<*>) {
|
||||
KotlinConstructorUMethod(
|
||||
kotlinOrigin.containingClassOrObject,
|
||||
psi,
|
||||
containingElement
|
||||
)
|
||||
} else if (kotlinOrigin is KtParameter && kotlinOrigin.getParentOfType<KtClass>(true)?.isAnnotation() == true)
|
||||
KotlinUAnnotationMethod(psi, containingElement)
|
||||
else
|
||||
KotlinUMethod(psi, containingElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class KotlinUAnnotationMethod(
|
||||
psi: KtLightMethod,
|
||||
givenParent: UElement?
|
||||
) : KotlinUMethod(psi, psi.kotlinOrigin, givenParent), UAnnotationMethod {
|
||||
|
||||
override val psi: KtLightMethod = unwrap<UMethod, KtLightMethod>(psi)
|
||||
|
||||
override val uastDefaultValue by lz {
|
||||
val annotationParameter = sourcePsi as? KtParameter ?: return@lz null
|
||||
val defaultValue = annotationParameter.defaultValue ?: return@lz null
|
||||
getLanguagePlugin().convertElement(defaultValue, this) as? UExpression
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class KotlinUMethodWithFakeLightDelegate internal constructor(
|
||||
val original: KtFunction,
|
||||
fakePsi: UastFakeLightMethod,
|
||||
givenParent: UElement?
|
||||
) : KotlinUMethod(fakePsi, original, givenParent) {
|
||||
|
||||
constructor(original: KtFunction, containingLightClass: PsiClass, givenParent: UElement?)
|
||||
: this(original, UastFakeLightMethod(original, containingLightClass), givenParent)
|
||||
|
||||
override val annotations: List<UAnnotation>
|
||||
get() = original.annotationEntries.mapNotNull { it.toUElementOfType<UAnnotation>() }
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
other as KotlinUMethodWithFakeLightDelegate
|
||||
if (original != other.original) return false
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = original.hashCode()
|
||||
}
|
||||
|
||||
internal fun wrapExpressionBody(function: UElement, bodyExpression: KtExpression): UExpression? = when (bodyExpression) {
|
||||
!is KtBlockExpression -> {
|
||||
KotlinUBlockExpression.KotlinLazyUBlockExpression(function) { block ->
|
||||
val implicitReturn = KotlinUImplicitReturnExpression(block)
|
||||
val uBody = function.getLanguagePlugin().convertElement(bodyExpression, implicitReturn) as? UExpression
|
||||
?: return@KotlinLazyUBlockExpression emptyList()
|
||||
listOf(implicitReturn.apply { returnExpression = uBody })
|
||||
}
|
||||
|
||||
}
|
||||
else -> function.getLanguagePlugin().convertElement(bodyExpression, function) as? UExpression
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.test.common.UElementToParentMap
|
||||
import org.jetbrains.uast.test.common.kotlin.IdentifiersTestBase
|
||||
import org.jetbrains.uast.test.env.assertEqualsToFile
|
||||
import java.io.File
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
|
||||
abstract class AbstractKotlinIdentifiersTest : AbstractKotlinUastTest(), IdentifiersTestBase {
|
||||
|
||||
private fun getTestFile(testName: String, ext: String) =
|
||||
File(File(TEST_KOTLIN_MODEL_DIR, testName).canonicalPath + '.' + ext)
|
||||
|
||||
override fun getIdentifiersFile(testName: String): File = getTestFile(testName, "identifiers.txt")
|
||||
|
||||
override fun check(testName: String, file: UFile) {
|
||||
super.check(testName, file)
|
||||
assertEqualsToFile("refNames", getTestFile(testName, "refNames.txt"), file.asRefNames())
|
||||
}
|
||||
}
|
||||
|
||||
private fun refNameRetriever(psiElement: PsiElement): UElement? =
|
||||
when (val uElement = psiElement.toUElementOfExpectedTypes(UCallExpression::class.java, UReferenceExpression::class.java)) {
|
||||
is UReferenceExpression -> uElement.referenceNameElement
|
||||
is UCallExpression -> uElement.classReference?.referenceNameElement
|
||||
else -> null
|
||||
}?.also {
|
||||
assertNotNull(it.sourcePsi, "referenceNameElement should have physical source, origin = $psiElement")
|
||||
}
|
||||
|
||||
fun UFile.asRefNames() = object : UElementToParentMap(::refNameRetriever) {
|
||||
override fun renderSource(element: PsiElement): String = element.javaClass.simpleName
|
||||
}.visitUFileAndGetResult(this)
|
||||
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.uast.test.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.test.common.kotlin.IndentedPrintingVisitor
|
||||
import org.jetbrains.uast.test.common.kotlin.visitUFileAndGetResult
|
||||
import org.jetbrains.uast.test.env.kotlin.assertEqualsToFile
|
||||
import java.io.File
|
||||
|
||||
|
||||
abstract class AbstractKotlinResolveEverythingTest : AbstractKotlinUastTest() {
|
||||
|
||||
private fun getTestFile(testName: String, ext: String) =
|
||||
File(File(TEST_KOTLIN_MODEL_DIR, testName).canonicalPath + '.' + ext)
|
||||
|
||||
|
||||
private fun UFile.resolvableWithTargets() = object : IndentedPrintingVisitor(KtBlockExpression::class) {
|
||||
override fun render(element: PsiElement) =
|
||||
sequenceOf(element.toUElementOfType<UReferenceExpression>(), element.toUElementOfType<UCallExpression>()).filterNotNull()
|
||||
.filter {
|
||||
when (it) {
|
||||
is UCallExpression -> it.sourcePsi.safeAs<KtCallElement>()?.calleeExpression !is KtSimpleNameExpression
|
||||
else -> true
|
||||
}
|
||||
}.takeIf { it.any() }
|
||||
?.joinTo(StringBuilder(), "\n") { ref ->
|
||||
StringBuilder().apply {
|
||||
val parent = ref.uastParent
|
||||
append(parent?.asLogString())
|
||||
if (parent is UCallExpression) {
|
||||
append("(resolves to ${parent.resolve()})")
|
||||
}
|
||||
append(" -> ")
|
||||
append(ref.asLogString())
|
||||
append(" -> ")
|
||||
append(ref.cast<UResolvable>().resolve())
|
||||
append(": ")
|
||||
append(
|
||||
when (ref) {
|
||||
is UReferenceExpression -> ref.resolvedName
|
||||
is UCallExpression -> ""
|
||||
else -> "<none>"
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}.visitUFileAndGetResult(this)
|
||||
|
||||
override fun check(testName: String, file: UFile) {
|
||||
assertEqualsToFile("resolved", getTestFile(testName, "resolved.txt"), file.resolvableWithTargets())
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.uast.test.kotlin
|
||||
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import com.intellij.util.io.URLUtil
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.uast.UFile
|
||||
import org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractKotlinUastLightCodeInsightFixtureTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor =
|
||||
KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
|
||||
|
||||
fun getVirtualFile(testName: String): VirtualFile {
|
||||
val testFile = TEST_KOTLIN_MODEL_DIR.listFiles { pathname -> pathname.nameWithoutExtension == testName }.first()
|
||||
val vfs = VirtualFileManager.getInstance().getFileSystem(URLUtil.FILE_PROTOCOL)
|
||||
return vfs.findFileByPath(testFile.canonicalPath)!!
|
||||
}
|
||||
|
||||
abstract fun check(testName: String, file: UFile)
|
||||
|
||||
fun doTest(testName: String, checkCallback: (String, UFile) -> Unit = { testName, file -> check(testName, file) }) {
|
||||
val virtualFile = getVirtualFile(testName)
|
||||
|
||||
val psiFile = myFixture.configureByText(virtualFile.name, File(virtualFile.canonicalPath!!).readText())
|
||||
val uFile = KotlinUastLanguagePlugin().convertElementWithParent(psiFile, null) ?: error("Can't get UFile for $testName")
|
||||
checkCallback(testName, uFile as UFile)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +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.uast.test.common.kotlin
|
||||
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.uast.UFile
|
||||
import org.jetbrains.uast.UResolvable
|
||||
import org.jetbrains.uast.test.env.kotlin.findElementByText
|
||||
import org.junit.Assert.assertEquals
|
||||
|
||||
interface ResolveTestBase {
|
||||
fun check(testName: String, file: UFile) {
|
||||
val refComment = file.allCommentsInFile.find { it.text.startsWith("// REF:") } ?: throw IllegalArgumentException("No // REF tag in file")
|
||||
val resultComment = file.allCommentsInFile.find { it.text.startsWith("// RESULT:") } ?: throw IllegalArgumentException("No // RESULT tag in file")
|
||||
|
||||
val refText = refComment.text.substringAfter("REF:")
|
||||
val parent = refComment.uastParent
|
||||
val matchingElement = parent.findElementByText<UResolvable>(refText)
|
||||
val resolveResult = matchingElement.resolve() ?: throw IllegalArgumentException("Unresolved reference")
|
||||
val resultText = resolveResult.javaClass.simpleName + (if (resolveResult is PsiNamedElement) ":${resolveResult.name}" else "")
|
||||
assertEquals(resultComment.text.substringAfter("RESULT:"), resultText)
|
||||
}
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
-dontnote **
|
||||
-dontwarn com.intellij.util.ui.IsRetina*
|
||||
-dontwarn com.intellij.util.ui.UIUtilities
|
||||
-dontwarn com.intellij.util.RetinaImage*
|
||||
-dontwarn apple.awt.*
|
||||
-dontwarn dk.brics.automaton.*
|
||||
-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 kotlinx.collections.immutable.*
|
||||
-dontwarn kotlinx.collections.immutable.**
|
||||
-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
|
||||
-dontwarn com.intellij.util.io.Compressor$Tar
|
||||
|
||||
# Annotations from intellijCore/annotations.jar that not presented in org.jetbrains.annotations
|
||||
-dontwarn org.jetbrains.annotations.Async*
|
||||
-dontwarn org.jetbrains.annotations.Nls$Capitalization
|
||||
|
||||
# Nullability annotations used in Guava
|
||||
-dontwarn org.checkerframework.checker.nullness.compatqual.NullableDecl
|
||||
-dontwarn org.checkerframework.checker.nullness.compatqual.MonotonicNonNullDecl
|
||||
-dontwarn org.checkerframework.checker.nullness.qual.Nullable
|
||||
-dontwarn org.checkerframework.checker.nullness.qual.MonotonicNonNull
|
||||
|
||||
# Depends on apache batick which has lots of dependencies
|
||||
-dontwarn com.intellij.util.SVGLoader*
|
||||
-dontwarn org.apache.batik.script.rhino.RhinoInterpreter
|
||||
-dontwarn org.apache.batik.script.rhino.RhinoInterpreterFactory
|
||||
|
||||
# The appropriate jar is either loaded separately or added explicitly to the classpath then needed
|
||||
-dontwarn org.jetbrains.kotlin.scripting.compiler.plugin.ScriptingCompilerConfigurationComponentRegistrar
|
||||
|
||||
-dontwarn org.jdom.xpath.jaxen.*
|
||||
-dontwarn com.intellij.util.io.Decompressor*
|
||||
-dontwarn org.w3c.dom.Location
|
||||
-dontwarn org.w3c.dom.Window
|
||||
-dontwarn org.slf4j.**
|
||||
|
||||
|
||||
#-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(...); }
|
||||
# Without this class PluginManagerCore.loadDescriptorFromJar fails
|
||||
-keep class org.jdom.output.XMLOutputter { *; }
|
||||
|
||||
# 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.tree.InsnList { *; }
|
||||
|
||||
-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 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 { *; }
|
||||
|
||||
-keep class com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem { *; }
|
||||
|
||||
# used in REPL
|
||||
# TODO: pack jline directly to scripting-compiler jars instead
|
||||
-keep class org.jline.reader.LineReaderBuilder { *; }
|
||||
-keep class org.jline.reader.LineReader { *; }
|
||||
-keep class org.jline.reader.History { *; }
|
||||
-keep class org.jline.reader.EndOfFileException { *; }
|
||||
-keep class org.jline.reader.UserInterruptException { *; }
|
||||
-keep class org.jline.terminal.impl.jna.JnaSupportImpl { *; }
|
||||
-keep class org.jline.terminal.impl.jansi.JansiSupportImpl { *; }
|
||||
|
||||
-keepclassmembers class * implements java.io.Serializable {
|
||||
static final long serialVersionUID;
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
Test key, Issue, State (optional: MUTE or FAIL), Status (optional: FLAKY)
|
||||
org.jetbrains.kotlin.idea.caches.resolve.MultiModuleHighlightingTest.testLazyResolvers,,,
|
||||
org.jetbrains.kotlin.idea.caches.resolve.MultiModuleHighlightingTest.testRecomputeResolversOnChange,,,
|
||||
org.jetbrains.kotlin.idea.completion.test.weighers.BasicCompletionWeigherTestGenerated.testPreferFromJdk, KT-35709 Class from JDK is not prioritized,,
|
||||
org.jetbrains.kotlin.idea.quickfix.QuickFixMultiFileTestGenerated.AutoImports.testAmbiguousNamePreferFromJdk, KT-35709 Class from JDK is not prioritized,,
|
||||
org.jetbrains.kotlin.j2k.JavaToKotlinConverterSingleFileTestGenerated.ToKotlinClasses.testIterableAndIterator,,,
|
||||
org.jetbrains.kotlin.j2k.JavaToKotlinConverterSingleFileTestGenerated.ToKotlinClasses.testIterableAndIterator2,,,
|
||||
org.jetbrains.kotlin.j2k.JavaToKotlinConverterSingleFileTestGenerated.ToKotlinClasses.testIterableAndIterator3,,,
|
||||
Reference in New Issue
Block a user