Compare commits

...

11 Commits

Author SHA1 Message Date
Nikolay Krasko
3f9421f9bd Update idea.plugins.compatible.build in compiler 2020-06-05 23:47:26 +03:00
Nikolay Krasko
e844f15ec9 Disable check for broken plugins in tests
Otherwise is is an exception in PluginManagerCore
because of brokenPlugins.txt file.
2020-06-05 23:40:41 +03:00
Nikolay Krasko
266c705ad9 -- temp 2020-06-05 16:49:47 +03:00
Nikolay Krasko
9169d2da05 Add fastutil dependency to compiler 2020-06-05 16:49:47 +03:00
Nikita Bobko
220a5f49c7 Fix compilation 2020-06-05 01:04:55 +03:00
Nikita Bobko
0e58df18c1 Fix compilation
CoreJarVirtualFile is now package private. And seems that
most of VirtualFiles return system independent path
2020-06-04 21:09:09 +03:00
Nikolay Krasko
0a31cf8e2e ~~~~ cleanup 202 ~~~~ 2020-06-04 20:00:44 +03:00
Nikolay Krasko
bde8603fe4 -- pretend to be 202 based 2020-06-04 19:51:14 +03:00
Nikolay Krasko
f2fe2940ac ~~~~ switch 202 ~~~~ 2020-06-04 18:08:02 +03:00
Nikolay Krasko
5eac69fdda 202: Update dependencies 2020-06-04 18:07:50 +03:00
Nikolay Krasko
063be2fa1c 202: Update to the latest EAP 2020-06-03 21:02:45 +03:00
216 changed files with 10777 additions and 1073 deletions

8
.bunch
View File

@@ -1,7 +1,3 @@
193
202
201
202_201
192
as36_192
as40
as41_201
193_201

1
.idea/vcs.xml generated
View File

@@ -32,5 +32,6 @@
</component>
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/kotlin-ultimate" vcs="Git" />
</component>
</project>

View File

@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.incremental.storage
import com.intellij.util.io.DataExternalizer
import com.intellij.util.io.KeyDescriptor
import com.intellij.util.io.JpsPersistentHashMap
import com.intellij.util.io.PersistentHashMap
import java.io.File
@@ -28,10 +28,10 @@ class NonCachingLazyStorage<K, V>(
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
@Volatile
private var storage: JpsPersistentHashMap<K, V>? = null
private var storage: PersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): JpsPersistentHashMap<K, V>? {
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
if (storage != null) return storage
if (storageFile.exists()) {
@@ -43,7 +43,7 @@ class NonCachingLazyStorage<K, V>(
}
@Synchronized
private fun getStorageOrCreateNew(): JpsPersistentHashMap<K, V> {
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
}
@@ -69,7 +69,7 @@ class NonCachingLazyStorage<K, V>(
}
override fun append(key: K, value: V) {
getStorageOrCreateNew().appendDataWithoutCache(key, value)
getStorageOrCreateNew().appendData(key) { dataOutput -> valueExternalizer.save(dataOutput, value) }
}
@Synchronized
@@ -79,7 +79,7 @@ class NonCachingLazyStorage<K, V>(
} catch (ignored: Throwable) {
}
JpsPersistentHashMap.deleteFilesStartingWith(storageFile)
PersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
}
@@ -101,6 +101,6 @@ class NonCachingLazyStorage<K, V>(
storage?.close()
}
private fun createMap(): JpsPersistentHashMap<K, V> =
JpsPersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
private fun createMap(): PersistentHashMap<K, V> =
PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
}

View File

@@ -0,0 +1,106 @@
/*
* 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.KeyDescriptor
import com.intellij.util.io.JpsPersistentHashMap
import java.io.File
class NonCachingLazyStorage<K, V>(
private val storageFile: File,
private val keyDescriptor: KeyDescriptor<K>,
private val valueExternalizer: DataExternalizer<V>
) : LazyStorage<K, V> {
@Volatile
private var storage: JpsPersistentHashMap<K, V>? = null
@Synchronized
private fun getStorageIfExists(): JpsPersistentHashMap<K, V>? {
if (storage != null) return storage
if (storageFile.exists()) {
storage = createMap()
return storage
}
return null
}
@Synchronized
private fun getStorageOrCreateNew(): JpsPersistentHashMap<K, V> {
if (storage == null) {
storage = createMap()
}
return storage!!
}
override val keys: Collection<K>
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
override operator fun contains(key: K): Boolean =
getStorageIfExists()?.containsMapping(key) ?: false
override operator fun get(key: K): V? =
getStorageIfExists()?.get(key)
override operator fun set(key: K, value: V) {
getStorageOrCreateNew().put(key, value)
}
override fun remove(key: K) {
getStorageIfExists()?.remove(key)
}
override fun append(key: K, value: V) {
getStorageOrCreateNew().appendDataWithoutCache(key, value)
}
@Synchronized
override fun clean() {
try {
storage?.close()
} catch (ignored: Throwable) {
}
JpsPersistentHashMap.deleteFilesStartingWith(storageFile)
storage = null
}
@Synchronized
override fun flush(memoryCachesOnly: Boolean) {
val existingStorage = storage ?: return
if (memoryCachesOnly) {
if (existingStorage.isDirty) {
existingStorage.dropMemoryCaches()
}
} else {
existingStorage.force()
}
}
@Synchronized
override fun close() {
storage?.close()
}
private fun createMap(): JpsPersistentHashMap<K, V> =
JpsPersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
}

View File

@@ -200,7 +200,11 @@ extra["intellijSeparateSdks"] = intellijSeparateSdks
extra["IntellijCoreDependencies"] =
listOf(
if (Platform[191].orHigher()) "asm-all-7.0.1" else "asm-all",
when {
Platform[202].orHigher() -> "asm-all-8.0.1"
Platform[191].orHigher() -> "asm-all-7.0.1"
else -> "asm-all"
},
"guava",
"jdom",
"jna",

View File

@@ -105,7 +105,7 @@ dependencies {
implementation("com.github.jengelman.gradle.plugins:shadow:${rootProject.extra["versions.shadow"]}")
implementation("net.sf.proguard:proguard-gradle:6.2.2")
implementation("org.jetbrains.intellij.deps:asm-all:7.0.1")
implementation("org.jetbrains.intellij.deps:asm-all:8.0.1")
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:0.5")
}

View File

@@ -107,6 +107,7 @@ fun Project.projectTest(
systemProperty("jps.kotlin.home", rootProject.extra["distKotlinHomeDir"]!!)
systemProperty("kotlin.ni", if (rootProject.hasProperty("newInferenceTests")) "true" else "false")
systemProperty("org.jetbrains.kotlin.skip.muted.tests", if (rootProject.hasProperty("skipMutedTests")) "true" else "false")
systemProperty("idea.ignore.disabled.plugins", "true")
var subProjectTempRoot: Path? = null
doFirst {

View File

@@ -29,7 +29,14 @@ dependencies {
testCompile(intellijDep()) { includeJars("openapi", rootProject = rootProject) }
}
testCompile(intellijDep()) { includeJars("util", "idea", "idea_rt", "groovy-all", rootProject = rootProject) }
testCompile(intellijDep()) { includeJars("util", "idea", "idea_rt", rootProject = rootProject) }
Platform[202].orHigher {
testCompile(intellijDep()) { includeJars("groovy", rootProject = rootProject) }
}
Platform[201].orLower {
testCompile(intellijDep()) { includeJars("groovy-all", rootProject = rootProject) }
}
Platform[191].orLower {
testCompile(intellijDep()) { includeJars("jps-builders") }
}

View File

@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.codegen.coroutines
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
typealias SourceFrames = Array<Frame<SourceValue>?>
typealias SourceFrames = Array<Frame<SourceValue>>

View File

@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.codegen.coroutines
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceValue
typealias SourceFrames = Array<Frame<SourceValue>>
typealias SourceFrames = Array<Frame<SourceValue>?>

View File

@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.codegen.optimization.common
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>?>
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>>

View File

@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.codegen.optimization.common
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>>
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>?>

View File

@@ -5,4 +5,4 @@
package org.jetbrains.kotlin.codegen.state
typealias JvmMethodExceptionTypes = Array<out String>?
typealias JvmMethodExceptionTypes = Array<out String?>?

View File

@@ -5,4 +5,4 @@
package org.jetbrains.kotlin.codegen.state
typealias JvmMethodExceptionTypes = Array<out String?>?
typealias JvmMethodExceptionTypes = Array<out String>?

View File

@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.cli.common.messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.impl.jar.CoreJarVirtualFile;
import com.intellij.openapi.vfs.local.CoreLocalVirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
@@ -51,10 +49,6 @@ public class MessageUtil {
@NotNull
public static String virtualFileToPath(@NotNull VirtualFile virtualFile) {
// Convert path to platform-dependent format when virtualFile is local file.
if (virtualFile instanceof CoreLocalVirtualFile || virtualFile instanceof CoreJarVirtualFile) {
return toSystemDependentName(virtualFile.getPath());
}
return virtualFile.getPath();
return toSystemDependentName(virtualFile.getPath());
}
}

View File

@@ -4,147 +4,52 @@
*/
package org.jetbrains.kotlin.cli.jvm.compiler;
import com.intellij.DynamicBundle;
import com.intellij.codeInsight.ContainerProvider;
import com.intellij.codeInsight.JavaContainerProvider;
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
import com.intellij.codeInsight.folding.impl.JavaCodeFoldingSettingsBase;
import com.intellij.codeInsight.folding.impl.JavaFoldingBuilderBase;
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
import com.intellij.core.CoreApplicationEnvironment;
import com.intellij.core.CoreJavaDirectoryService;
import com.intellij.core.CorePsiPackageImplementationHelper;
import com.intellij.ide.highlighter.ArchiveFileType;
import com.intellij.ide.highlighter.JavaClassFileType;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.lang.LanguageASTFactory;
import com.intellij.core.JavaCoreApplicationEnvironment;
import com.intellij.lang.MetaLanguage;
import com.intellij.lang.folding.LanguageFolding;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.lang.java.JavaParserDefinition;
import com.intellij.navigation.ItemPresentationProviders;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.fileTypes.FileTypeExtensionPoint;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.fileTypes.PlainTextLanguage;
import com.intellij.openapi.fileTypes.PlainTextParserDefinition;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.vfs.VirtualFileSystem;
import com.intellij.psi.*;
import com.intellij.psi.FileContextProvider;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.augment.TypeAnnotationModifier;
import com.intellij.psi.compiled.ClassFileDecompilers;
import com.intellij.psi.impl.LanguageConstantExpressionEvaluator;
import com.intellij.psi.impl.PsiExpressionEvaluator;
import com.intellij.psi.impl.PsiSubstitutorFactoryImpl;
import com.intellij.psi.impl.compiled.ClassFileStubBuilder;
import com.intellij.psi.impl.file.PsiPackageImplementationHelper;
import com.intellij.psi.impl.search.MethodSuperSearcher;
import com.intellij.psi.impl.source.tree.JavaASTFactory;
import com.intellij.psi.impl.source.tree.PlainTextASTFactory;
import com.intellij.psi.meta.MetaDataContributor;
import com.intellij.psi.presentation.java.*;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.stubs.BinaryFileStubBuilders;
import com.intellij.util.QueryExecutor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
/**
* adapted from com.intellij.core.JavaCoreApplicationEnvironment
* TODO: initiate removal original from com.intellij.core since it seems that there are no usages left
*/
public class KotlinCoreApplicationEnvironment extends CoreApplicationEnvironment {
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
registerExtensionPoints();
return environment;
}
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
return new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
}
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
super(parentDisposable, unitTestMode);
}
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
super(parentDisposable, unitTestMode);
private static void registerExtensionPoints() {
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
registerExtensionPoints();
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
registerExtensions();
}
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
registerApplicationExtensionPoint(ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
private void registerExtensionPoints() {
ExtensionsArea area = Extensions.getRootArea();
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
CoreApplicationEnvironment.registerExtensionPoint(area, BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint.class);
CoreApplicationEnvironment.registerExtensionPoint(area, FileContextProvider.EP_NAME, FileContextProvider.class);
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
}
CoreApplicationEnvironment.registerExtensionPoint(area, MetaDataContributor.EP_NAME, MetaDataContributor.class);
CoreApplicationEnvironment.registerExtensionPoint(area, PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(area, JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(area, ContainerProvider.EP_NAME, ContainerProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(area, ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
CoreApplicationEnvironment.registerExtensionPoint(area, TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier.class);
CoreApplicationEnvironment.registerExtensionPoint(area, MetaLanguage.EP_NAME, MetaLanguage.class);
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(area);
}
private void registerExtensions() {
registerFileType(JavaClassFileType.INSTANCE, "class");
registerFileType(JavaFileType.INSTANCE, "java");
registerFileType(ArchiveFileType.INSTANCE, "jar;zip");
registerFileType(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess");
addExplicitExtension(LanguageASTFactory.INSTANCE, PlainTextLanguage.INSTANCE, new PlainTextASTFactory());
registerParserDefinition(new PlainTextParserDefinition());
addExplicitExtension(FileTypeFileViewProviders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileViewProviderFactory());
addExplicitExtension(BinaryFileStubBuilders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileStubBuilder());
addExplicitExtension(LanguageASTFactory.INSTANCE, JavaLanguage.INSTANCE, new JavaASTFactory());
registerParserDefinition(new JavaParserDefinition());
addExplicitExtension(LanguageConstantExpressionEvaluator.INSTANCE, JavaLanguage.INSTANCE, new PsiExpressionEvaluator());
addExtension(ContainerProvider.EP_NAME, new JavaContainerProvider());
myApplication.registerService(PsiPackageImplementationHelper.class, new CorePsiPackageImplementationHelper());
myApplication.registerService(PsiSubstitutorFactory.class, new PsiSubstitutorFactoryImpl());
myApplication.registerService(JavaDirectoryService.class, createJavaDirectoryService());
myApplication.registerService(JavaVersionService.class, new JavaVersionService());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiPackage.class, new PackagePresentationProvider());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiClass.class, new ClassPresentationProvider());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiMethod.class, new MethodPresentationProvider());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiField.class, new FieldPresentationProvider());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiLocalVariable.class, new VariablePresentationProvider());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiParameter.class, new VariablePresentationProvider());
registerApplicationService(JavaCodeFoldingSettings.class, new JavaCodeFoldingSettingsBase());
addExplicitExtension(LanguageFolding.INSTANCE, JavaLanguage.INSTANCE, new JavaFoldingBuilderBase() {
@Override
protected boolean shouldShowExplicitLambdaType(@NotNull PsiAnonymousClass anonymousClass, @NotNull PsiNewExpression expression) {
return false;
}
@Override
protected boolean isBelowRightMargin(@NotNull PsiFile file, int lineLength) {
return false;
}
});
registerApplicationExtensionPoint(SuperMethodsSearch.EP_NAME, QueryExecutor.class);
addExtension(SuperMethodsSearch.EP_NAME, new MethodSuperSearcher());
}
// overridden in upsource
protected CoreJavaDirectoryService createJavaDirectoryService() {
return new CoreJavaDirectoryService();
}
@Nullable
@Override
protected VirtualFileSystem createJrtFileSystem() {
return new CoreJrtFileSystem();
}
@Nullable
@Override
protected VirtualFileSystem createJrtFileSystem() {
return new CoreJrtFileSystem();
}
}

View File

@@ -0,0 +1,150 @@
/*
* 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.cli.jvm.compiler;
import com.intellij.codeInsight.ContainerProvider;
import com.intellij.codeInsight.JavaContainerProvider;
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
import com.intellij.codeInsight.folding.impl.JavaCodeFoldingSettingsBase;
import com.intellij.codeInsight.folding.impl.JavaFoldingBuilderBase;
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
import com.intellij.core.CoreApplicationEnvironment;
import com.intellij.core.CoreJavaDirectoryService;
import com.intellij.core.CorePsiPackageImplementationHelper;
import com.intellij.ide.highlighter.ArchiveFileType;
import com.intellij.ide.highlighter.JavaClassFileType;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.lang.LanguageASTFactory;
import com.intellij.lang.MetaLanguage;
import com.intellij.lang.folding.LanguageFolding;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.lang.java.JavaParserDefinition;
import com.intellij.navigation.ItemPresentationProviders;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.extensions.ExtensionsArea;
import com.intellij.openapi.fileTypes.FileTypeExtensionPoint;
import com.intellij.openapi.fileTypes.PlainTextFileType;
import com.intellij.openapi.fileTypes.PlainTextLanguage;
import com.intellij.openapi.fileTypes.PlainTextParserDefinition;
import com.intellij.openapi.projectRoots.JavaVersionService;
import com.intellij.openapi.vfs.VirtualFileSystem;
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.LanguageConstantExpressionEvaluator;
import com.intellij.psi.impl.PsiExpressionEvaluator;
import com.intellij.psi.impl.PsiSubstitutorFactoryImpl;
import com.intellij.psi.impl.compiled.ClassFileStubBuilder;
import com.intellij.psi.impl.file.PsiPackageImplementationHelper;
import com.intellij.psi.impl.search.MethodSuperSearcher;
import com.intellij.psi.impl.source.tree.JavaASTFactory;
import com.intellij.psi.impl.source.tree.PlainTextASTFactory;
import com.intellij.psi.meta.MetaDataContributor;
import com.intellij.psi.presentation.java.*;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.stubs.BinaryFileStubBuilders;
import com.intellij.util.QueryExecutor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
/**
* adapted from com.intellij.core.JavaCoreApplicationEnvironment
* TODO: initiate removal original from com.intellij.core since it seems that there are no usages left
*/
public class KotlinCoreApplicationEnvironment extends CoreApplicationEnvironment {
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
return new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
}
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
super(parentDisposable, unitTestMode);
registerExtensionPoints();
registerExtensions();
}
private void registerExtensionPoints() {
ExtensionsArea area = Extensions.getRootArea();
CoreApplicationEnvironment.registerExtensionPoint(area, BinaryFileStubBuilders.EP_NAME, FileTypeExtensionPoint.class);
CoreApplicationEnvironment.registerExtensionPoint(area, FileContextProvider.EP_NAME, FileContextProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(area, MetaDataContributor.EP_NAME, MetaDataContributor.class);
CoreApplicationEnvironment.registerExtensionPoint(area, PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(area, JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(area, ContainerProvider.EP_NAME, ContainerProvider.class);
CoreApplicationEnvironment.registerExtensionPoint(area, ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
CoreApplicationEnvironment.registerExtensionPoint(area, TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier.class);
CoreApplicationEnvironment.registerExtensionPoint(area, MetaLanguage.EP_NAME, MetaLanguage.class);
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(area);
}
private void registerExtensions() {
registerFileType(JavaClassFileType.INSTANCE, "class");
registerFileType(JavaFileType.INSTANCE, "java");
registerFileType(ArchiveFileType.INSTANCE, "jar;zip");
registerFileType(PlainTextFileType.INSTANCE, "txt;sh;bat;cmd;policy;log;cgi;MF;jad;jam;htaccess");
addExplicitExtension(LanguageASTFactory.INSTANCE, PlainTextLanguage.INSTANCE, new PlainTextASTFactory());
registerParserDefinition(new PlainTextParserDefinition());
addExplicitExtension(FileTypeFileViewProviders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileViewProviderFactory());
addExplicitExtension(BinaryFileStubBuilders.INSTANCE, JavaClassFileType.INSTANCE, new ClassFileStubBuilder());
addExplicitExtension(LanguageASTFactory.INSTANCE, JavaLanguage.INSTANCE, new JavaASTFactory());
registerParserDefinition(new JavaParserDefinition());
addExplicitExtension(LanguageConstantExpressionEvaluator.INSTANCE, JavaLanguage.INSTANCE, new PsiExpressionEvaluator());
addExtension(ContainerProvider.EP_NAME, new JavaContainerProvider());
myApplication.registerService(PsiPackageImplementationHelper.class, new CorePsiPackageImplementationHelper());
myApplication.registerService(PsiSubstitutorFactory.class, new PsiSubstitutorFactoryImpl());
myApplication.registerService(JavaDirectoryService.class, createJavaDirectoryService());
myApplication.registerService(JavaVersionService.class, new JavaVersionService());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiPackage.class, new PackagePresentationProvider());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiClass.class, new ClassPresentationProvider());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiMethod.class, new MethodPresentationProvider());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiField.class, new FieldPresentationProvider());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiLocalVariable.class, new VariablePresentationProvider());
addExplicitExtension(ItemPresentationProviders.INSTANCE, PsiParameter.class, new VariablePresentationProvider());
registerApplicationService(JavaCodeFoldingSettings.class, new JavaCodeFoldingSettingsBase());
addExplicitExtension(LanguageFolding.INSTANCE, JavaLanguage.INSTANCE, new JavaFoldingBuilderBase() {
@Override
protected boolean shouldShowExplicitLambdaType(@NotNull PsiAnonymousClass anonymousClass, @NotNull PsiNewExpression expression) {
return false;
}
@Override
protected boolean isBelowRightMargin(@NotNull PsiFile file, int lineLength) {
return false;
}
});
registerApplicationExtensionPoint(SuperMethodsSearch.EP_NAME, QueryExecutor.class);
addExtension(SuperMethodsSearch.EP_NAME, new MethodSuperSearcher());
}
// overridden in upsource
protected CoreJavaDirectoryService createJavaDirectoryService() {
return new CoreJavaDirectoryService();
}
@Nullable
@Override
protected VirtualFileSystem createJrtFileSystem() {
return new CoreJrtFileSystem();
}
}

View File

@@ -22,6 +22,7 @@ import com.intellij.psi.*
class MockExternalAnnotationsManager : ExternalAnnotationsManager() {
override fun chooseAnnotationsPlace(element: PsiElement): AnnotationPlace = AnnotationPlace.NOWHERE
override fun chooseAnnotationsPlaceNoUi(element: PsiElement): AnnotationPlace = AnnotationPlace.NOWHERE
override fun isExternalAnnotationWritable(listOwner: PsiModifierListOwner, annotationFQN: String): Boolean = false
override fun isExternalAnnotation(annotation: PsiAnnotation): Boolean = false

View File

@@ -0,0 +1,61 @@
/*
* 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.cli.jvm.compiler
import com.intellij.codeInsight.ExternalAnnotationsManager
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.*
class MockExternalAnnotationsManager : ExternalAnnotationsManager() {
override fun chooseAnnotationsPlace(element: PsiElement): AnnotationPlace = AnnotationPlace.NOWHERE
override fun isExternalAnnotationWritable(listOwner: PsiModifierListOwner, annotationFQN: String): Boolean = false
override fun isExternalAnnotation(annotation: PsiAnnotation): Boolean = false
override fun findExternalAnnotationsFiles(listOwner: PsiModifierListOwner): List<PsiFile>? = null
override fun findExternalAnnotation(listOwner: PsiModifierListOwner, annotationFQN: String): PsiAnnotation? = null
override fun findExternalAnnotations(listOwner: PsiModifierListOwner): Array<out PsiAnnotation>? = null
override fun annotateExternally(
listOwner: PsiModifierListOwner,
annotationFQName: String,
fromFile: PsiFile,
value: Array<out PsiNameValuePair>?
) {
throw UnsupportedOperationException("not implemented")
}
override fun deannotate(listOwner: PsiModifierListOwner, annotationFQN: String): Boolean {
throw UnsupportedOperationException("not implemented")
}
override fun editExternalAnnotation(
listOwner: PsiModifierListOwner,
annotationFQN: String,
value: Array<out PsiNameValuePair>?
): Boolean {
throw UnsupportedOperationException("not implemented")
}
override fun hasAnnotationRootsForFile(file: VirtualFile): Boolean = false
override fun findDefaultConstructorExternalAnnotations(aClass: PsiClass, annotationFQN: String): List<PsiAnnotation> = emptyList()
override fun findDefaultConstructorExternalAnnotations(aClass: PsiClass): List<PsiAnnotation> = emptyList()
override fun findExternalAnnotations(listOwner: PsiModifierListOwner, annotationFQN: String): List<PsiAnnotation> = emptyList()
}

View File

@@ -6,4 +6,10 @@
package org.jetbrains.kotlin.cli.jvm.compiler
fun setupIdeaStandaloneExecution() {
System.getProperties().setProperty("idea.plugins.compatible.build", "202.5103")
System.getProperties().setProperty("project.structure.add.tools.jar.to.new.jdk", "false")
System.getProperties().setProperty("psi.track.invalidation", "true")
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
System.getProperties().setProperty("ide.hide.excluded.files", "false")
System.getProperties().setProperty("ast.loading.filter", "false")
}

View File

@@ -0,0 +1,9 @@
/*
* 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.cli.jvm.compiler
fun setupIdeaStandaloneExecution() {
}

View File

@@ -8,9 +8,11 @@ package org.jetbrains.kotlin.cli.jvm.compiler
import com.intellij.core.CoreApplicationEnvironment
import com.intellij.openapi.extensions.ExtensionsArea
import java.io.File
import java.nio.file.FileSystems
// FIX ME WHEN BUNCH 193 REMOVED
fun registerExtensionPointAndExtensionsEx(pluginFile: File, fileName: String, area: ExtensionsArea) {
val pluginRoot = FileSystems.getDefault().getPath(pluginFile.path)
@Suppress("MissingRecentApi")
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginFile, fileName, area)
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginRoot, fileName, area)
}

View File

@@ -0,0 +1,16 @@
/*
* 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.cli.jvm.compiler
import com.intellij.core.CoreApplicationEnvironment
import com.intellij.openapi.extensions.ExtensionsArea
import java.io.File
// FIX ME WHEN BUNCH 193 REMOVED
fun registerExtensionPointAndExtensionsEx(pluginFile: File, fileName: String, area: ExtensionsArea) {
@Suppress("MissingRecentApi")
CoreApplicationEnvironment.registerExtensionPointAndExtensions(pluginFile, fileName, area)
}

View File

@@ -140,7 +140,6 @@ public abstract class KtParsingTestCase extends KtPlatformLiteFixture {
// That's for reparse routines
final PomModelImpl pomModel = new PomModelImpl(myProject);
myProject.registerService(PomModel.class, pomModel);
new TreeAspect(pomModel);
}
public void configureFromParserDefinition(ParserDefinition definition, String extension) {

View File

@@ -140,6 +140,7 @@ public abstract class KtParsingTestCase extends KtPlatformLiteFixture {
// That's for reparse routines
final PomModelImpl pomModel = new PomModelImpl(myProject);
myProject.registerService(PomModel.class, pomModel);
new TreeAspect(pomModel);
}
public void configureFromParserDefinition(ParserDefinition definition, String extension) {

View File

@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.test.testFramework;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory;
import com.intellij.diagnostic.PerformanceWatcher;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
@@ -23,20 +25,33 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.impl.DocumentCommitProcessor;
import com.intellij.psi.impl.DocumentCommitThread;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.rt.execution.junit.FileComparisonFailure;
import com.intellij.testFramework.*;
import com.intellij.testFramework.exceptionCases.AbstractExceptionCase;
import com.intellij.util.Consumer;
import com.intellij.util.ReflectionUtil;
import com.intellij.testFramework.fixtures.IdeaTestExecutionPolicy;
import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.containers.PeekableIterator;
import com.intellij.util.containers.PeekableIteratorWrapper;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.indexing.FileBasedIndexImpl;
import com.intellij.util.lang.CompoundRuntimeException;
import com.intellij.util.ui.UIUtil;
import gnu.trove.Equality;
@@ -47,11 +62,11 @@ import org.jdom.Element;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.test.IdeaSystemPropertiesForParallelRunConfigurator;
import org.jetbrains.kotlin.testFramework.MockComponentManagerCreationTracer;
import org.jetbrains.kotlin.types.AbstractTypeChecker;
import org.jetbrains.kotlin.types.FlexibleTypeImpl;
import org.junit.Assert;
import org.junit.ComparisonFailure;
import java.io.File;
import java.io.FileNotFoundException;
@@ -61,14 +76,19 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
@SuppressWarnings("UseOfSystemOutOrSystemErr")
/**
* @author peter
*/
@SuppressWarnings("ALL")
public abstract class KtUsefulTestCase extends TestCase {
public static final boolean IS_UNDER_TEAMCITY = System.getenv("TEAMCITY_VERSION") != null;
private static final String TEMP_DIR_MARKER = "unitTest_";
public static final String TEMP_DIR_MARKER = "unitTest_";
public static final boolean OVERWRITE_TESTDATA = Boolean.getBoolean("idea.tests.overwrite.data");
private static final String ORIGINAL_TEMP_DIR = FileUtil.getTempDirectory();
@@ -79,24 +99,34 @@ public abstract class KtUsefulTestCase extends TestCase {
private Application application;
static {
IdeaSystemPropertiesForParallelRunConfigurator.setProperties();
//TODO: investigate and enable
//IdeaForkJoinWorkerThreadFactory.setupPoisonFactory();
IdeaForkJoinWorkerThreadFactory.setupPoisonFactory();
Logger.setFactory(TestLoggerFactory.class);
}
protected static final Logger LOG = Logger.getInstance(KtUsefulTestCase.class);
@NotNull
protected final Disposable myTestRootDisposable = new TestDisposable();
private final Disposable myTestRootDisposable = new TestDisposable();
private static final String ourPathToKeep = null;
static Path ourPathToKeep;
private final List<String> myPathsToKeep = new ArrayList<>();
private File myTempDir;
private String myTempDir;
private static final String DEFAULT_SETTINGS_EXTERNALIZED;
private static final CodeInsightSettings defaultSettings = new CodeInsightSettings();
static {
// Radar #5755208: Command line Java applications need a way to launch without a Dock icon.
System.setProperty("apple.awt.UIElement", "true");
try {
Element oldS = new Element("temp");
defaultSettings.writeExternal(oldS);
DEFAULT_SETTINGS_EXTERNALIZED = JDOMUtil.writeElement(oldS);
}
catch (Exception e) {
throw new RuntimeException(e);
}
// -- KOTLIN ADDITIONAL START --
FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true;
@@ -105,6 +135,42 @@ public abstract class KtUsefulTestCase extends TestCase {
// -- KOTLIN ADDITIONAL END --
}
/**
* Pass here the exception you want to be thrown first
* E.g.<pre>
* {@code
* void tearDown() {
* try {
* doTearDowns();
* }
* catch(Exception e) {
* addSuppressedException(e);
* }
* finally {
* super.tearDown();
* }
* }
* }
* </pre>
*
*/
protected void addSuppressedException(@NotNull Throwable e) {
List<Throwable> list = mySuppressedExceptions;
if (list == null) {
mySuppressedExceptions = list = new SmartList<>();
}
list.add(e);
}
private List<Throwable> mySuppressedExceptions;
public KtUsefulTestCase() {
}
public KtUsefulTestCase(@NotNull String name) {
super(name);
}
protected boolean shouldContainTempFiles() {
return true;
}
@@ -122,11 +188,17 @@ public abstract class KtUsefulTestCase extends TestCase {
super.setUp();
if (shouldContainTempFiles()) {
String testName = FileUtil.sanitizeFileName(getTestName(true));
if (StringUtil.isEmptyOrSpaces(testName)) testName = "";
IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
String testName = null;
if (policy != null) {
testName = policy.getPerTestTempDirName();
}
if (testName == null) {
testName = FileUtil.sanitizeFileName(getTestName(true));
}
testName = new File(testName).getName(); // in case the test name contains file separators
myTempDir = FileUtil.createTempDirectory(TEMP_DIR_MARKER, testName, false);
FileUtil.resetCanonicalTempPathCache(myTempDir.getPath());
myTempDir = FileUtil.createTempDirectory(TEMP_DIR_MARKER + testName, "", false).getPath();
FileUtil.resetCanonicalTempPathCache(myTempDir);
}
boolean isStressTest = isStressTest();
@@ -137,6 +209,16 @@ public abstract class KtUsefulTestCase extends TestCase {
// turn off Disposer debugging for performance tests
Disposer.setDebugMode(!isStressTest);
if (isIconRequired()) {
// ensure that IconLoader will use dummy empty icon
IconLoader.deactivate();
//IconManager.activate();
}
}
protected boolean isIconRequired() {
return false;
}
@Override
@@ -145,6 +227,11 @@ public abstract class KtUsefulTestCase extends TestCase {
// don't use method references here to make stack trace reading easier
//noinspection Convert2MethodRef
new RunAll(
() -> {
if (isIconRequired()) {
//IconManager.deactivate();
}
},
() -> disposeRootDisposable(),
() -> cleanupSwingDataStructures(),
() -> cleanupDeleteOnExitHookList(),
@@ -153,7 +240,7 @@ public abstract class KtUsefulTestCase extends TestCase {
if (shouldContainTempFiles()) {
FileUtil.resetCanonicalTempPathCache(ORIGINAL_TEMP_DIR);
if (hasTmpFilesToKeep()) {
File[] files = myTempDir.listFiles();
File[] files = new File(myTempDir).listFiles();
if (files != null) {
for (File file : files) {
if (!shouldKeepTmpFile(file)) {
@@ -163,15 +250,14 @@ public abstract class KtUsefulTestCase extends TestCase {
}
}
else {
FileUtil.delete(myTempDir);
FileUtil.delete(new File(myTempDir));
}
}
},
() -> UIUtil.removeLeakingAppleListeners()
).run();
() -> waitForAppLeakingThreads(10, TimeUnit.SECONDS)
).run(ObjectUtils.notNull(mySuppressedExceptions, Collections.emptyList()));
}
finally {
super.tearDown();
// -- KOTLIN ADDITIONAL START --
TestApplicationUtilKt.resetApplicationToNull(application);
application = null;
@@ -188,12 +274,12 @@ public abstract class KtUsefulTestCase extends TestCase {
}
private boolean hasTmpFilesToKeep() {
return ourPathToKeep != null && FileUtil.isAncestor(myTempDir.getPath(), ourPathToKeep, false) || !myPathsToKeep.isEmpty();
return ourPathToKeep != null && FileUtil.isAncestor(myTempDir, ourPathToKeep.toString(), false) || !myPathsToKeep.isEmpty();
}
private boolean shouldKeepTmpFile(@NotNull File file) {
String path = file.getPath();
if (FileUtil.pathsEqual(path, ourPathToKeep)) return true;
if (FileUtil.pathsEqual(path, ourPathToKeep.toString())) return true;
for (String pathToKeep : myPathsToKeep) {
if (FileUtil.pathsEqual(path, pathToKeep)) return true;
}
@@ -201,7 +287,7 @@ public abstract class KtUsefulTestCase extends TestCase {
}
private static final Set<String> DELETE_ON_EXIT_HOOK_DOT_FILES;
private static final Class DELETE_ON_EXIT_HOOK_CLASS;
private static final Class<?> DELETE_ON_EXIT_HOOK_CLASS;
static {
Class<?> aClass;
try {
@@ -237,12 +323,45 @@ public abstract class KtUsefulTestCase extends TestCase {
@SuppressWarnings("ConstantConditions")
private static void cleanupSwingDataStructures() throws Exception {
Object manager = ReflectionUtil.getDeclaredMethod(Class.forName("javax.swing.KeyboardManager"), "getCurrentManager").invoke(null);
Map componentKeyStrokeMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "componentKeyStrokeMap");
Map<?, ?> componentKeyStrokeMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "componentKeyStrokeMap");
componentKeyStrokeMap.clear();
Map containerMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "containerMap");
Map<?, ?> containerMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "containerMap");
containerMap.clear();
}
static void doCheckForSettingsDamage(@NotNull CodeStyleSettings oldCodeStyleSettings, @NotNull CodeStyleSettings currentCodeStyleSettings) {
final CodeInsightSettings settings = CodeInsightSettings.getInstance();
// don't use method references here to make stack trace reading easier
//noinspection Convert2MethodRef
new RunAll()
.append(() -> {
try {
checkCodeInsightSettingsEqual(defaultSettings, settings);
}
catch (AssertionError error) {
CodeInsightSettings clean = new CodeInsightSettings();
for (Field field : clean.getClass().getFields()) {
try {
ReflectionUtil.copyFieldValue(clean, settings, field);
}
catch (Exception ignored) {
}
}
throw error;
}
})
.append(() -> {
currentCodeStyleSettings.getIndentOptions(StdFileTypes.JAVA);
try {
checkCodeStyleSettingsEqual(oldCodeStyleSettings, currentCodeStyleSettings);
}
finally {
currentCodeStyleSettings.clearCodeStyleSettings();
}
})
.run();
}
@NotNull
public Disposable getTestRootDisposable() {
return myTestRootDisposable;
@@ -252,13 +371,11 @@ public abstract class KtUsefulTestCase extends TestCase {
protected void runTest() throws Throwable {
final Throwable[] throwables = new Throwable[1];
AtomicBoolean completed = new AtomicBoolean(false);
Runnable runnable = () -> {
try {
//TestLoggerFactory.onTestStarted();
TestLoggerFactory.onTestStarted();
super.runTest();
TestLoggerFactory.onTestFinished(true);
completed.set(true);
}
catch (InvocationTargetException e) {
TestLoggerFactory.onTestFinished(false);
@@ -281,9 +398,6 @@ public abstract class KtUsefulTestCase extends TestCase {
if (throwables[0] != null) {
throw throwables[0];
}
if (!completed.get()) {
throw new IllegalStateException("test didn't start");
}
}
protected boolean shouldRunTest() {
@@ -291,19 +405,18 @@ public abstract class KtUsefulTestCase extends TestCase {
}
protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
//IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
//if (policy != null && !policy.runInDispatchThread()) {
// runnable.run();
//}
//else {
if (runInDispatchThread()) {
EdtTestUtilKt.runInEdtAndWait(() -> {
runnable.run();
return null;
});
//}
}
else {
runnable.run();
}
}
private void defaultRunBare() throws Throwable {
protected void defaultRunBare() throws Throwable {
Throwable exception = null;
try {
long setupStart = System.nanoTime();
@@ -324,11 +437,17 @@ public abstract class KtUsefulTestCase extends TestCase {
logPerClassCost(teardownCost, TOTAL_TEARDOWN_COST_MILLIS);
}
catch (Throwable tearingDown) {
if (exception == null) exception = tearingDown;
else exception = new CompoundRuntimeException(Arrays.asList(exception, tearingDown));
if (exception == null) {
exception = tearingDown;
}
else {
exception = new CompoundRuntimeException(Arrays.asList(exception, tearingDown));
}
}
}
if (exception != null) throw exception;
if (exception != null) {
throw exception;
}
}
/**
@@ -368,7 +487,7 @@ public abstract class KtUsefulTestCase extends TestCase {
if (runInDispatchThread()) {
TestRunnerUtil.replaceIdeEventQueueSafely();
com.intellij.testFramework.EdtTestUtil.runInEdtAndWait(this::defaultRunBare);
EdtTestUtil.runInEdtAndWait(this::defaultRunBare);
}
else {
defaultRunBare();
@@ -376,13 +495,20 @@ public abstract class KtUsefulTestCase extends TestCase {
}
protected boolean runInDispatchThread() {
//IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
//if (policy != null) {
// return policy.runInDispatchThread();
//}
IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
if (policy != null) {
return policy.runInDispatchThread();
}
return true;
}
/**
* If you want a more shorter name than runInEdtAndWait.
*/
protected void edt(@NotNull ThrowableRunnable<Throwable> runnable) {
EdtTestUtil.runInEdtAndWait(runnable);
}
@NotNull
public static String toString(@NotNull Iterable<?> collection) {
if (!collection.iterator().hasNext()) {
@@ -515,9 +641,20 @@ public abstract class KtUsefulTestCase extends TestCase {
}
public static <T> void assertContainsOrdered(@NotNull Collection<? extends T> collection, @NotNull Collection<? extends T> expected) {
ArrayList<T> copy = new ArrayList<>(collection);
copy.retainAll(expected);
assertOrderedEquals(toString(collection), copy, expected);
PeekableIterator<T> expectedIt = new PeekableIteratorWrapper<>(expected.iterator());
PeekableIterator<T> actualIt = new PeekableIteratorWrapper<>(collection.iterator());
while (actualIt.hasNext() && expectedIt.hasNext()) {
T expectedElem = expectedIt.peek();
T actualElem = actualIt.peek();
if (expectedElem.equals(actualElem)) {
expectedIt.next();
}
actualIt.next();
}
if (expectedIt.hasNext()) {
throw new ComparisonFailure("", toString(expected), toString(collection));
}
}
@SafeVarargs
@@ -592,7 +729,7 @@ public abstract class KtUsefulTestCase extends TestCase {
if (collection.size() != checkers.length) {
Assert.fail(toString(collection));
}
Set<Consumer<T>> checkerSet = new HashSet<>(Arrays.asList(checkers));
Set<Consumer<T>> checkerSet = ContainerUtil.set(checkers);
int i = 0;
Throwable lastError = null;
for (final T actual : collection) {
@@ -767,7 +904,7 @@ public abstract class KtUsefulTestCase extends TestCase {
//noinspection UseOfSystemOutOrSystemErr
System.out.println("File " + filePath + " created.");
}
fileText = FileUtil.loadFile(new File(filePath), CharsetToolkit.UTF8_CHARSET);
fileText = FileUtil.loadFile(new File(filePath), StandardCharsets.UTF_8);
}
catch (FileNotFoundException e) {
VfsTestUtil.overwriteTestData(filePath, actualText);
@@ -784,14 +921,14 @@ public abstract class KtUsefulTestCase extends TestCase {
}
protected static void clearFields(@NotNull Object test) throws IllegalAccessException {
Class aClass = test.getClass();
Class<?> aClass = test.getClass();
while (aClass != null) {
clearDeclaredFields(test, aClass);
aClass = aClass.getSuperclass();
}
}
public static void clearDeclaredFields(@NotNull Object test, @NotNull Class aClass) throws IllegalAccessException {
public static void clearDeclaredFields(@NotNull Object test, @NotNull Class<?> aClass) throws IllegalAccessException {
for (final Field field : aClass.getDeclaredFields()) {
final String name = field.getDeclaringClass().getName();
if (!name.startsWith("junit.framework.") && !name.startsWith("com.intellij.testFramework.")) {
@@ -817,6 +954,14 @@ public abstract class KtUsefulTestCase extends TestCase {
}
}
private static void checkCodeInsightSettingsEqual(@NotNull CodeInsightSettings oldSettings, @NotNull CodeInsightSettings settings) {
if (!oldSettings.equals(settings)) {
Element newS = new Element("temp");
settings.writeExternal(newS);
Assert.assertEquals("Code insight settings damaged", DEFAULT_SETTINGS_EXTERNALIZED, JDOMUtil.writeElement(newS));
}
}
public boolean isPerformanceTest() {
String testName = getName();
String className = getClass().getSimpleName();
@@ -843,6 +988,21 @@ public abstract class KtUsefulTestCase extends TestCase {
return name != null && (name.contains("Stress") || name.contains("Slow"));
}
public static void doPostponedFormatting(@NotNull Project project) {
DocumentUtil.writeInRunUndoTransparentAction(() -> {
PsiDocumentManager.getInstance(project).commitAllDocuments();
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting();
});
}
/**
* Checks that code block throw corresponding exception.
*
* @param exceptionCase Block annotated with some exception type
*/
protected void assertException(@NotNull AbstractExceptionCase<?> exceptionCase) {
assertException(exceptionCase, null);
}
/**
* Checks that code block throw corresponding exception with expected error msg.
@@ -856,6 +1016,42 @@ public abstract class KtUsefulTestCase extends TestCase {
assertExceptionOccurred(true, exceptionCase, expectedErrorMsg);
}
/**
* Checks that the code block throws an exception of the specified class.
*
* @param exceptionClass Expected exception type
* @param runnable Block annotated with some exception type
*/
public static <T extends Throwable> void assertThrows(@NotNull Class<? extends Throwable> exceptionClass,
@NotNull ThrowableRunnable<T> runnable) {
assertThrows(exceptionClass, null, runnable);
}
/**
* Checks that the code block throws an exception of the specified class with expected error msg.
* If expected error message is null it will not be checked.
*
* @param exceptionClass Expected exception type
* @param expectedErrorMsgPart expected error message, of any
* @param runnable Block annotated with some exception type
*/
@SuppressWarnings({"unchecked", "SameParameterValue"})
public static <T extends Throwable> void assertThrows(@NotNull Class<? extends Throwable> exceptionClass,
@Nullable String expectedErrorMsgPart,
@NotNull ThrowableRunnable<T> runnable) {
assertExceptionOccurred(true, new AbstractExceptionCase() {
@Override
public Class<Throwable> getExpectedExceptionClass() {
return (Class<Throwable>)exceptionClass;
}
@Override
public void tryClosure() throws Throwable {
runnable.run();
}
}, expectedErrorMsgPart);
}
/**
* Checks that code block doesn't throw corresponding exception.
*
@@ -878,21 +1074,22 @@ public abstract class KtUsefulTestCase extends TestCase {
private static <T extends Throwable> void assertExceptionOccurred(boolean shouldOccur,
@NotNull AbstractExceptionCase<T> exceptionCase,
String expectedErrorMsg) throws T {
String expectedErrorMsgPart) throws T {
boolean wasThrown = false;
try {
exceptionCase.tryClosure();
}
catch (Throwable e) {
Throwable cause = e;
if (shouldOccur) {
wasThrown = true;
final String errorMessage = exceptionCase.getAssertionErrorMessage();
assertEquals(errorMessage, exceptionCase.getExpectedExceptionClass(), e.getClass());
if (expectedErrorMsg != null) {
assertEquals("Compare error messages", expectedErrorMsg, e.getMessage());
assertInstanceOf(cause, exceptionCase.getExpectedExceptionClass());
if (expectedErrorMsgPart != null) {
assertTrue(cause.getMessage(), cause.getMessage().contains(expectedErrorMsgPart));
}
}
else if (exceptionCase.getExpectedExceptionClass().equals(e.getClass())) {
else if (exceptionCase.getExpectedExceptionClass().equals(cause.getClass())) {
wasThrown = true;
//noinspection UseOfSystemOutOrSystemErr
@@ -900,7 +1097,7 @@ public abstract class KtUsefulTestCase extends TestCase {
//noinspection UseOfSystemOutOrSystemErr
e.printStackTrace(System.out);
fail("Exception isn't expected here. Exception message: " + e.getMessage());
fail("Exception isn't expected here. Exception message: " + cause.getMessage());
}
else {
throw e;
@@ -908,7 +1105,7 @@ public abstract class KtUsefulTestCase extends TestCase {
}
finally {
if (shouldOccur && !wasThrown) {
fail(exceptionCase.getAssertionErrorMessage());
fail(exceptionCase.getExpectedExceptionClass().getName() + " must be thrown.");
}
}
}
@@ -937,7 +1134,7 @@ public abstract class KtUsefulTestCase extends TestCase {
}
public static void refreshRecursively(@NotNull VirtualFile file) {
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() {
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor<Void>() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
file.getChildren();
@@ -947,11 +1144,27 @@ public abstract class KtUsefulTestCase extends TestCase {
file.refresh(false, true);
}
@Nullable
public static VirtualFile refreshAndFindFile(@NotNull final File file) {
return UIUtil.invokeAndWaitIfNeeded(() -> LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file));
}
public static void waitForAppLeakingThreads(long timeout, @NotNull TimeUnit timeUnit) {
EdtTestUtil.runInEdtAndWait(() -> {
Application app = ApplicationManager.getApplication();
if (app != null && !app.isDisposed()) {
FileBasedIndexImpl index = (FileBasedIndexImpl)app.getServiceIfCreated(FileBasedIndex.class);
if (index != null) {
index.getChangedFilesCollector().waitForVfsEventsExecuted(timeout, timeUnit);
}
DocumentCommitThread commitThread = (DocumentCommitThread)app.getServiceIfCreated(DocumentCommitProcessor.class);
if (commitThread != null) {
commitThread.waitForAllCommits(timeout, timeUnit);
}
}
});
}
protected class TestDisposable implements Disposable {
private volatile boolean myDisposed;
@@ -972,5 +1185,5 @@ public abstract class KtUsefulTestCase extends TestCase {
String testName = getTestName(false);
return KtUsefulTestCase.this.getClass() + (StringUtil.isEmpty(testName) ? "" : ".test" + testName);
}
};
}
}
}

View File

@@ -16,8 +16,6 @@
package org.jetbrains.kotlin.test.testFramework;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.concurrency.IdeaForkJoinWorkerThreadFactory;
import com.intellij.diagnostic.PerformanceWatcher;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
@@ -25,33 +23,20 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.impl.DocumentCommitProcessor;
import com.intellij.psi.impl.DocumentCommitThread;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.rt.execution.junit.FileComparisonFailure;
import com.intellij.testFramework.*;
import com.intellij.testFramework.exceptionCases.AbstractExceptionCase;
import com.intellij.testFramework.fixtures.IdeaTestExecutionPolicy;
import com.intellij.util.*;
import com.intellij.util.Consumer;
import com.intellij.util.ReflectionUtil;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.PeekableIterator;
import com.intellij.util.containers.PeekableIteratorWrapper;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.indexing.FileBasedIndexImpl;
import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.lang.CompoundRuntimeException;
import com.intellij.util.ui.UIUtil;
import gnu.trove.Equality;
@@ -62,11 +47,11 @@ import org.jdom.Element;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.test.IdeaSystemPropertiesForParallelRunConfigurator;
import org.jetbrains.kotlin.testFramework.MockComponentManagerCreationTracer;
import org.jetbrains.kotlin.types.AbstractTypeChecker;
import org.jetbrains.kotlin.types.FlexibleTypeImpl;
import org.junit.Assert;
import org.junit.ComparisonFailure;
import java.io.File;
import java.io.FileNotFoundException;
@@ -76,19 +61,14 @@ import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
/**
* @author peter
*/
@SuppressWarnings("ALL")
@SuppressWarnings("UseOfSystemOutOrSystemErr")
public abstract class KtUsefulTestCase extends TestCase {
public static final boolean IS_UNDER_TEAMCITY = System.getenv("TEAMCITY_VERSION") != null;
public static final String TEMP_DIR_MARKER = "unitTest_";
private static final String TEMP_DIR_MARKER = "unitTest_";
public static final boolean OVERWRITE_TESTDATA = Boolean.getBoolean("idea.tests.overwrite.data");
private static final String ORIGINAL_TEMP_DIR = FileUtil.getTempDirectory();
@@ -99,34 +79,24 @@ public abstract class KtUsefulTestCase extends TestCase {
private Application application;
static {
IdeaForkJoinWorkerThreadFactory.setupPoisonFactory();
IdeaSystemPropertiesForParallelRunConfigurator.setProperties();
//TODO: investigate and enable
//IdeaForkJoinWorkerThreadFactory.setupPoisonFactory();
Logger.setFactory(TestLoggerFactory.class);
}
protected static final Logger LOG = Logger.getInstance(KtUsefulTestCase.class);
@NotNull
private final Disposable myTestRootDisposable = new TestDisposable();
protected final Disposable myTestRootDisposable = new TestDisposable();
static Path ourPathToKeep;
private static final String ourPathToKeep = null;
private final List<String> myPathsToKeep = new ArrayList<>();
private String myTempDir;
private File myTempDir;
private static final String DEFAULT_SETTINGS_EXTERNALIZED;
private static final CodeInsightSettings defaultSettings = new CodeInsightSettings();
static {
// Radar #5755208: Command line Java applications need a way to launch without a Dock icon.
System.setProperty("apple.awt.UIElement", "true");
try {
Element oldS = new Element("temp");
defaultSettings.writeExternal(oldS);
DEFAULT_SETTINGS_EXTERNALIZED = JDOMUtil.writeElement(oldS);
}
catch (Exception e) {
throw new RuntimeException(e);
}
// -- KOTLIN ADDITIONAL START --
FlexibleTypeImpl.RUN_SLOW_ASSERTIONS = true;
@@ -135,42 +105,6 @@ public abstract class KtUsefulTestCase extends TestCase {
// -- KOTLIN ADDITIONAL END --
}
/**
* Pass here the exception you want to be thrown first
* E.g.<pre>
* {@code
* void tearDown() {
* try {
* doTearDowns();
* }
* catch(Exception e) {
* addSuppressedException(e);
* }
* finally {
* super.tearDown();
* }
* }
* }
* </pre>
*
*/
protected void addSuppressedException(@NotNull Throwable e) {
List<Throwable> list = mySuppressedExceptions;
if (list == null) {
mySuppressedExceptions = list = new SmartList<>();
}
list.add(e);
}
private List<Throwable> mySuppressedExceptions;
public KtUsefulTestCase() {
}
public KtUsefulTestCase(@NotNull String name) {
super(name);
}
protected boolean shouldContainTempFiles() {
return true;
}
@@ -188,17 +122,11 @@ public abstract class KtUsefulTestCase extends TestCase {
super.setUp();
if (shouldContainTempFiles()) {
IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
String testName = null;
if (policy != null) {
testName = policy.getPerTestTempDirName();
}
if (testName == null) {
testName = FileUtil.sanitizeFileName(getTestName(true));
}
String testName = FileUtil.sanitizeFileName(getTestName(true));
if (StringUtil.isEmptyOrSpaces(testName)) testName = "";
testName = new File(testName).getName(); // in case the test name contains file separators
myTempDir = FileUtil.createTempDirectory(TEMP_DIR_MARKER + testName, "", false).getPath();
FileUtil.resetCanonicalTempPathCache(myTempDir);
myTempDir = FileUtil.createTempDirectory(TEMP_DIR_MARKER, testName, false);
FileUtil.resetCanonicalTempPathCache(myTempDir.getPath());
}
boolean isStressTest = isStressTest();
@@ -209,16 +137,6 @@ public abstract class KtUsefulTestCase extends TestCase {
// turn off Disposer debugging for performance tests
Disposer.setDebugMode(!isStressTest);
if (isIconRequired()) {
// ensure that IconLoader will use dummy empty icon
IconLoader.deactivate();
//IconManager.activate();
}
}
protected boolean isIconRequired() {
return false;
}
@Override
@@ -227,11 +145,6 @@ public abstract class KtUsefulTestCase extends TestCase {
// don't use method references here to make stack trace reading easier
//noinspection Convert2MethodRef
new RunAll(
() -> {
if (isIconRequired()) {
//IconManager.deactivate();
}
},
() -> disposeRootDisposable(),
() -> cleanupSwingDataStructures(),
() -> cleanupDeleteOnExitHookList(),
@@ -240,7 +153,7 @@ public abstract class KtUsefulTestCase extends TestCase {
if (shouldContainTempFiles()) {
FileUtil.resetCanonicalTempPathCache(ORIGINAL_TEMP_DIR);
if (hasTmpFilesToKeep()) {
File[] files = new File(myTempDir).listFiles();
File[] files = myTempDir.listFiles();
if (files != null) {
for (File file : files) {
if (!shouldKeepTmpFile(file)) {
@@ -250,14 +163,15 @@ public abstract class KtUsefulTestCase extends TestCase {
}
}
else {
FileUtil.delete(new File(myTempDir));
FileUtil.delete(myTempDir);
}
}
},
() -> waitForAppLeakingThreads(10, TimeUnit.SECONDS)
).run(ObjectUtils.notNull(mySuppressedExceptions, Collections.emptyList()));
() -> UIUtil.removeLeakingAppleListeners()
).run();
}
finally {
super.tearDown();
// -- KOTLIN ADDITIONAL START --
TestApplicationUtilKt.resetApplicationToNull(application);
application = null;
@@ -274,12 +188,12 @@ public abstract class KtUsefulTestCase extends TestCase {
}
private boolean hasTmpFilesToKeep() {
return ourPathToKeep != null && FileUtil.isAncestor(myTempDir, ourPathToKeep.toString(), false) || !myPathsToKeep.isEmpty();
return ourPathToKeep != null && FileUtil.isAncestor(myTempDir.getPath(), ourPathToKeep, false) || !myPathsToKeep.isEmpty();
}
private boolean shouldKeepTmpFile(@NotNull File file) {
String path = file.getPath();
if (FileUtil.pathsEqual(path, ourPathToKeep.toString())) return true;
if (FileUtil.pathsEqual(path, ourPathToKeep)) return true;
for (String pathToKeep : myPathsToKeep) {
if (FileUtil.pathsEqual(path, pathToKeep)) return true;
}
@@ -287,7 +201,7 @@ public abstract class KtUsefulTestCase extends TestCase {
}
private static final Set<String> DELETE_ON_EXIT_HOOK_DOT_FILES;
private static final Class<?> DELETE_ON_EXIT_HOOK_CLASS;
private static final Class DELETE_ON_EXIT_HOOK_CLASS;
static {
Class<?> aClass;
try {
@@ -323,45 +237,12 @@ public abstract class KtUsefulTestCase extends TestCase {
@SuppressWarnings("ConstantConditions")
private static void cleanupSwingDataStructures() throws Exception {
Object manager = ReflectionUtil.getDeclaredMethod(Class.forName("javax.swing.KeyboardManager"), "getCurrentManager").invoke(null);
Map<?, ?> componentKeyStrokeMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "componentKeyStrokeMap");
Map componentKeyStrokeMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "componentKeyStrokeMap");
componentKeyStrokeMap.clear();
Map<?, ?> containerMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "containerMap");
Map containerMap = ReflectionUtil.getField(manager.getClass(), manager, Hashtable.class, "containerMap");
containerMap.clear();
}
static void doCheckForSettingsDamage(@NotNull CodeStyleSettings oldCodeStyleSettings, @NotNull CodeStyleSettings currentCodeStyleSettings) {
final CodeInsightSettings settings = CodeInsightSettings.getInstance();
// don't use method references here to make stack trace reading easier
//noinspection Convert2MethodRef
new RunAll()
.append(() -> {
try {
checkCodeInsightSettingsEqual(defaultSettings, settings);
}
catch (AssertionError error) {
CodeInsightSettings clean = new CodeInsightSettings();
for (Field field : clean.getClass().getFields()) {
try {
ReflectionUtil.copyFieldValue(clean, settings, field);
}
catch (Exception ignored) {
}
}
throw error;
}
})
.append(() -> {
currentCodeStyleSettings.getIndentOptions(StdFileTypes.JAVA);
try {
checkCodeStyleSettingsEqual(oldCodeStyleSettings, currentCodeStyleSettings);
}
finally {
currentCodeStyleSettings.clearCodeStyleSettings();
}
})
.run();
}
@NotNull
public Disposable getTestRootDisposable() {
return myTestRootDisposable;
@@ -371,11 +252,13 @@ public abstract class KtUsefulTestCase extends TestCase {
protected void runTest() throws Throwable {
final Throwable[] throwables = new Throwable[1];
AtomicBoolean completed = new AtomicBoolean(false);
Runnable runnable = () -> {
try {
TestLoggerFactory.onTestStarted();
//TestLoggerFactory.onTestStarted();
super.runTest();
TestLoggerFactory.onTestFinished(true);
completed.set(true);
}
catch (InvocationTargetException e) {
TestLoggerFactory.onTestFinished(false);
@@ -398,6 +281,9 @@ public abstract class KtUsefulTestCase extends TestCase {
if (throwables[0] != null) {
throw throwables[0];
}
if (!completed.get()) {
throw new IllegalStateException("test didn't start");
}
}
protected boolean shouldRunTest() {
@@ -405,18 +291,19 @@ public abstract class KtUsefulTestCase extends TestCase {
}
protected void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
if (runInDispatchThread()) {
//IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
//if (policy != null && !policy.runInDispatchThread()) {
// runnable.run();
//}
//else {
EdtTestUtilKt.runInEdtAndWait(() -> {
runnable.run();
return null;
});
}
else {
runnable.run();
}
//}
}
protected void defaultRunBare() throws Throwable {
private void defaultRunBare() throws Throwable {
Throwable exception = null;
try {
long setupStart = System.nanoTime();
@@ -437,17 +324,11 @@ public abstract class KtUsefulTestCase extends TestCase {
logPerClassCost(teardownCost, TOTAL_TEARDOWN_COST_MILLIS);
}
catch (Throwable tearingDown) {
if (exception == null) {
exception = tearingDown;
}
else {
exception = new CompoundRuntimeException(Arrays.asList(exception, tearingDown));
}
if (exception == null) exception = tearingDown;
else exception = new CompoundRuntimeException(Arrays.asList(exception, tearingDown));
}
}
if (exception != null) {
throw exception;
}
if (exception != null) throw exception;
}
/**
@@ -487,7 +368,7 @@ public abstract class KtUsefulTestCase extends TestCase {
if (runInDispatchThread()) {
TestRunnerUtil.replaceIdeEventQueueSafely();
EdtTestUtil.runInEdtAndWait(this::defaultRunBare);
com.intellij.testFramework.EdtTestUtil.runInEdtAndWait(this::defaultRunBare);
}
else {
defaultRunBare();
@@ -495,20 +376,13 @@ public abstract class KtUsefulTestCase extends TestCase {
}
protected boolean runInDispatchThread() {
IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
if (policy != null) {
return policy.runInDispatchThread();
}
//IdeaTestExecutionPolicy policy = IdeaTestExecutionPolicy.current();
//if (policy != null) {
// return policy.runInDispatchThread();
//}
return true;
}
/**
* If you want a more shorter name than runInEdtAndWait.
*/
protected void edt(@NotNull ThrowableRunnable<Throwable> runnable) {
EdtTestUtil.runInEdtAndWait(runnable);
}
@NotNull
public static String toString(@NotNull Iterable<?> collection) {
if (!collection.iterator().hasNext()) {
@@ -641,20 +515,9 @@ public abstract class KtUsefulTestCase extends TestCase {
}
public static <T> void assertContainsOrdered(@NotNull Collection<? extends T> collection, @NotNull Collection<? extends T> expected) {
PeekableIterator<T> expectedIt = new PeekableIteratorWrapper<>(expected.iterator());
PeekableIterator<T> actualIt = new PeekableIteratorWrapper<>(collection.iterator());
while (actualIt.hasNext() && expectedIt.hasNext()) {
T expectedElem = expectedIt.peek();
T actualElem = actualIt.peek();
if (expectedElem.equals(actualElem)) {
expectedIt.next();
}
actualIt.next();
}
if (expectedIt.hasNext()) {
throw new ComparisonFailure("", toString(expected), toString(collection));
}
ArrayList<T> copy = new ArrayList<>(collection);
copy.retainAll(expected);
assertOrderedEquals(toString(collection), copy, expected);
}
@SafeVarargs
@@ -729,7 +592,7 @@ public abstract class KtUsefulTestCase extends TestCase {
if (collection.size() != checkers.length) {
Assert.fail(toString(collection));
}
Set<Consumer<T>> checkerSet = ContainerUtil.set(checkers);
Set<Consumer<T>> checkerSet = new HashSet<>(Arrays.asList(checkers));
int i = 0;
Throwable lastError = null;
for (final T actual : collection) {
@@ -904,7 +767,7 @@ public abstract class KtUsefulTestCase extends TestCase {
//noinspection UseOfSystemOutOrSystemErr
System.out.println("File " + filePath + " created.");
}
fileText = FileUtil.loadFile(new File(filePath), StandardCharsets.UTF_8);
fileText = FileUtil.loadFile(new File(filePath), CharsetToolkit.UTF8_CHARSET);
}
catch (FileNotFoundException e) {
VfsTestUtil.overwriteTestData(filePath, actualText);
@@ -921,14 +784,14 @@ public abstract class KtUsefulTestCase extends TestCase {
}
protected static void clearFields(@NotNull Object test) throws IllegalAccessException {
Class<?> aClass = test.getClass();
Class aClass = test.getClass();
while (aClass != null) {
clearDeclaredFields(test, aClass);
aClass = aClass.getSuperclass();
}
}
public static void clearDeclaredFields(@NotNull Object test, @NotNull Class<?> aClass) throws IllegalAccessException {
public static void clearDeclaredFields(@NotNull Object test, @NotNull Class aClass) throws IllegalAccessException {
for (final Field field : aClass.getDeclaredFields()) {
final String name = field.getDeclaringClass().getName();
if (!name.startsWith("junit.framework.") && !name.startsWith("com.intellij.testFramework.")) {
@@ -954,14 +817,6 @@ public abstract class KtUsefulTestCase extends TestCase {
}
}
private static void checkCodeInsightSettingsEqual(@NotNull CodeInsightSettings oldSettings, @NotNull CodeInsightSettings settings) {
if (!oldSettings.equals(settings)) {
Element newS = new Element("temp");
settings.writeExternal(newS);
Assert.assertEquals("Code insight settings damaged", DEFAULT_SETTINGS_EXTERNALIZED, JDOMUtil.writeElement(newS));
}
}
public boolean isPerformanceTest() {
String testName = getName();
String className = getClass().getSimpleName();
@@ -988,21 +843,6 @@ public abstract class KtUsefulTestCase extends TestCase {
return name != null && (name.contains("Stress") || name.contains("Slow"));
}
public static void doPostponedFormatting(@NotNull Project project) {
DocumentUtil.writeInRunUndoTransparentAction(() -> {
PsiDocumentManager.getInstance(project).commitAllDocuments();
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting();
});
}
/**
* Checks that code block throw corresponding exception.
*
* @param exceptionCase Block annotated with some exception type
*/
protected void assertException(@NotNull AbstractExceptionCase<?> exceptionCase) {
assertException(exceptionCase, null);
}
/**
* Checks that code block throw corresponding exception with expected error msg.
@@ -1016,42 +856,6 @@ public abstract class KtUsefulTestCase extends TestCase {
assertExceptionOccurred(true, exceptionCase, expectedErrorMsg);
}
/**
* Checks that the code block throws an exception of the specified class.
*
* @param exceptionClass Expected exception type
* @param runnable Block annotated with some exception type
*/
public static <T extends Throwable> void assertThrows(@NotNull Class<? extends Throwable> exceptionClass,
@NotNull ThrowableRunnable<T> runnable) {
assertThrows(exceptionClass, null, runnable);
}
/**
* Checks that the code block throws an exception of the specified class with expected error msg.
* If expected error message is null it will not be checked.
*
* @param exceptionClass Expected exception type
* @param expectedErrorMsgPart expected error message, of any
* @param runnable Block annotated with some exception type
*/
@SuppressWarnings({"unchecked", "SameParameterValue"})
public static <T extends Throwable> void assertThrows(@NotNull Class<? extends Throwable> exceptionClass,
@Nullable String expectedErrorMsgPart,
@NotNull ThrowableRunnable<T> runnable) {
assertExceptionOccurred(true, new AbstractExceptionCase() {
@Override
public Class<Throwable> getExpectedExceptionClass() {
return (Class<Throwable>)exceptionClass;
}
@Override
public void tryClosure() throws Throwable {
runnable.run();
}
}, expectedErrorMsgPart);
}
/**
* Checks that code block doesn't throw corresponding exception.
*
@@ -1074,22 +878,21 @@ public abstract class KtUsefulTestCase extends TestCase {
private static <T extends Throwable> void assertExceptionOccurred(boolean shouldOccur,
@NotNull AbstractExceptionCase<T> exceptionCase,
String expectedErrorMsgPart) throws T {
String expectedErrorMsg) throws T {
boolean wasThrown = false;
try {
exceptionCase.tryClosure();
}
catch (Throwable e) {
Throwable cause = e;
if (shouldOccur) {
wasThrown = true;
assertInstanceOf(cause, exceptionCase.getExpectedExceptionClass());
if (expectedErrorMsgPart != null) {
assertTrue(cause.getMessage(), cause.getMessage().contains(expectedErrorMsgPart));
final String errorMessage = exceptionCase.getAssertionErrorMessage();
assertEquals(errorMessage, exceptionCase.getExpectedExceptionClass(), e.getClass());
if (expectedErrorMsg != null) {
assertEquals("Compare error messages", expectedErrorMsg, e.getMessage());
}
}
else if (exceptionCase.getExpectedExceptionClass().equals(cause.getClass())) {
else if (exceptionCase.getExpectedExceptionClass().equals(e.getClass())) {
wasThrown = true;
//noinspection UseOfSystemOutOrSystemErr
@@ -1097,7 +900,7 @@ public abstract class KtUsefulTestCase extends TestCase {
//noinspection UseOfSystemOutOrSystemErr
e.printStackTrace(System.out);
fail("Exception isn't expected here. Exception message: " + cause.getMessage());
fail("Exception isn't expected here. Exception message: " + e.getMessage());
}
else {
throw e;
@@ -1105,7 +908,7 @@ public abstract class KtUsefulTestCase extends TestCase {
}
finally {
if (shouldOccur && !wasThrown) {
fail(exceptionCase.getExpectedExceptionClass().getName() + " must be thrown.");
fail(exceptionCase.getAssertionErrorMessage());
}
}
}
@@ -1134,7 +937,7 @@ public abstract class KtUsefulTestCase extends TestCase {
}
public static void refreshRecursively(@NotNull VirtualFile file) {
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor<Void>() {
VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() {
@Override
public boolean visitFile(@NotNull VirtualFile file) {
file.getChildren();
@@ -1144,27 +947,11 @@ public abstract class KtUsefulTestCase extends TestCase {
file.refresh(false, true);
}
@Nullable
public static VirtualFile refreshAndFindFile(@NotNull final File file) {
return UIUtil.invokeAndWaitIfNeeded(() -> LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file));
}
public static void waitForAppLeakingThreads(long timeout, @NotNull TimeUnit timeUnit) {
EdtTestUtil.runInEdtAndWait(() -> {
Application app = ApplicationManager.getApplication();
if (app != null && !app.isDisposed()) {
FileBasedIndexImpl index = (FileBasedIndexImpl)app.getServiceIfCreated(FileBasedIndex.class);
if (index != null) {
index.getChangedFilesCollector().waitForVfsEventsExecuted(timeout, timeUnit);
}
DocumentCommitThread commitThread = (DocumentCommitThread)app.getServiceIfCreated(DocumentCommitProcessor.class);
if (commitThread != null) {
commitThread.waitForAllCommits(timeout, timeUnit);
}
}
});
}
protected class TestDisposable implements Disposable {
private volatile boolean myDisposed;
@@ -1185,5 +972,5 @@ public abstract class KtUsefulTestCase extends TestCase {
String testName = getTestName(false);
return KtUsefulTestCase.this.getClass() + (StringUtil.isEmpty(testName) ? "" : ".test" + testName);
}
}
}
};
}

View File

@@ -1,18 +1,18 @@
versions.intellijSdk=193.6494.35
versions.intellijSdk=202.5103-EAP-CANDIDATE-SNAPSHOT
versions.androidBuildTools=r23.0.1
versions.idea.NodeJS=181.3494.12
versions.jar.asm-all=7.0.1
versions.jar.guava=27.1-jre
versions.jar.groovy-all=2.4.17
versions.idea.NodeJS=193.6494.7
versions.jar.asm-all=8.0.1
versions.jar.guava=29.0-jre
versions.jar.groovy=2.5.11
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.8
versions.jar.gson=2.8.5
versions.jar.streamex=0.7.2
versions.jar.gson=2.8.6
versions.jar.oro=2.0.8
versions.jar.picocontainer=1.2
versions.jar.serviceMessages=2019.1.4
versions.jar.lz4-java=1.6.0
versions.jar.lz4-java=1.7.1
ignore.jar.snappy-in-java=true
versions.gradle-api=4.5.1
versions.shadow=5.2.0

View File

@@ -1,18 +1,18 @@
versions.intellijSdk=202.3567-SNAPSHOT
versions.intellijSdk=193.6494.35
versions.androidBuildTools=r23.0.1
versions.idea.NodeJS=193.6494.7
versions.idea.NodeJS=181.3494.12
versions.jar.asm-all=7.0.1
versions.jar.guava=29.0-jre
versions.jar.guava=27.1-jre
versions.jar.groovy-all=2.4.17
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.7.2
versions.jar.gson=2.8.6
versions.jar.streamex=0.6.8
versions.jar.gson=2.8.5
versions.jar.oro=2.0.8
versions.jar.picocontainer=1.2
versions.jar.serviceMessages=2019.1.4
versions.jar.lz4-java=1.7.1
versions.jar.lz4-java=1.6.0
ignore.jar.snappy-in-java=true
versions.gradle-api=4.5.1
versions.shadow=5.2.0

View File

@@ -5,8 +5,8 @@
package org.jetbrains.kotlin.util
import com.intellij.AbstractBundle
import com.intellij.DynamicBundle
abstract class AbstractKotlinBundle protected constructor(pathToBundle: String) : AbstractBundle(pathToBundle) {
abstract class AbstractKotlinBundle protected constructor(pathToBundle: String) : DynamicBundle(pathToBundle) {
protected fun String.withHtml(): String = "<html>$this</html>"
}

View File

@@ -0,0 +1,12 @@
/*
* 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.util
import com.intellij.AbstractBundle
abstract class AbstractKotlinBundle protected constructor(pathToBundle: String) : AbstractBundle(pathToBundle) {
protected fun String.withHtml(): String = "<html>$this</html>"
}

View File

@@ -9,6 +9,6 @@ import com.intellij.psi.PsiMethod
import com.intellij.util.Processor
// FIX ME WHEN BUNCH 193 REMOVED
typealias StringProcessor = Processor<String>
typealias PsiMethodProcessor = Processor<PsiMethod>
typealias StringProcessor = Processor<in String>
typealias PsiMethodProcessor = Processor<in PsiMethod>

View File

@@ -0,0 +1,14 @@
/*
* 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.caches
import com.intellij.psi.PsiMethod
import com.intellij.util.Processor
// FIX ME WHEN BUNCH 193 REMOVED
typealias StringProcessor = Processor<String>
typealias PsiMethodProcessor = Processor<PsiMethod>

View File

@@ -1,83 +1,50 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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.openapi.project.Project
import com.intellij.openapi.util.SimpleModificationTracker
import com.intellij.pom.tree.TreeAspect
import com.intellij.psi.impl.PsiTreeChangeEventImpl
import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.util.application.getServiceSafe
import org.jetbrains.kotlin.psi.KtFile
/**
* Tested in OutOfBlockModificationTestGenerated
*/
// FIX ME WHEN BUNCH 193 REMOVED
class KotlinCodeBlockModificationListener(
project: Project,
treeAspect: TreeAspect
) : KotlinCodeBlockModificationListenerCompat(project) {
@Suppress("UnstableApiUsage")
private val isLanguageTrackerEnabled = modificationTrackerImpl.isEnableLanguageTrackerCompat
// FIX ME WHEN BUNCH 191 REMOVED
// When there're we no per-language trackers we had to increment global tracker first and process result afterward
private val customIncrement = if (isLanguageTrackerEnabled) 0 else 1
class KotlinCodeBlockModificationListener(project: Project) : KotlinCodeBlockModificationListenerCompat(project) {
init {
init(
treeAspect,
TreeAspect.getInstance(project),
incOCBCounter = { ktFile ->
if (isLanguageTrackerEnabled) {
kotlinOutOfCodeBlockTrackerImpl.incModificationCount()
perModuleOutOfCodeBlockTrackerUpdater.onKotlinPhysicalFileOutOfBlockChange(ktFile, true)
} else {
perModuleOutOfCodeBlockTrackerUpdater.onKotlinPhysicalFileOutOfBlockChange(ktFile, false)
// Increment counter and process changes in PsiModificationTracker.Listener
modificationTrackerImpl.incCounter()
}
kotlinOutOfCodeBlockTrackerImpl.incModificationCount()
perModuleOutOfCodeBlockTrackerUpdater.onKotlinPhysicalFileOutOfBlockChange(ktFile, true)
},
kotlinOutOfCodeBlockTrackerProducer = {
if (isLanguageTrackerEnabled) {
SimpleModificationTracker()
} else {
object : SimpleModificationTracker() {
override fun getModificationCount(): Long {
@Suppress("DEPRECATION")
return modificationTrackerImpl.outOfCodeBlockModificationCount
}
}
}
SimpleModificationTracker()
},
psiModificationTrackerListener = {
@Suppress("UnstableApiUsage")
if (isLanguageTrackerEnabled) {
val kotlinTrackerInternalIDECount =
modificationTrackerImpl.forLanguage(KotlinLanguage.INSTANCE).modificationCount
if (kotlinModificationTracker == kotlinTrackerInternalIDECount) {
// Some update that we are not sure is from Kotlin language, as Kotlin language tracker wasn't changed
kotlinOutOfCodeBlockTrackerImpl.incModificationCount()
} else {
kotlinModificationTracker = kotlinTrackerInternalIDECount
}
val kotlinTrackerInternalIDECount =
modificationTrackerImpl.forLanguage(KotlinLanguage.INSTANCE).modificationCount
if (kotlinModificationTracker == kotlinTrackerInternalIDECount) {
// Some update that we are not sure is from Kotlin language, as Kotlin language tracker wasn't changed
kotlinOutOfCodeBlockTrackerImpl.incModificationCount()
} else {
kotlinModificationTracker = kotlinTrackerInternalIDECount
}
perModuleOutOfCodeBlockTrackerUpdater.onPsiModificationTrackerUpdate(customIncrement)
perModuleOutOfCodeBlockTrackerUpdater.onPsiModificationTrackerUpdate()
}
)
}
override fun treeChanged(event: PsiTreeChangeEventImpl) {
assert(isLanguageTrackerEnabled)
super.treeChanged(event)
}
companion object {
fun getInstance(project: Project): KotlinCodeBlockModificationListener =
project.getComponent(KotlinCodeBlockModificationListener::class.java)
fun getInstance(project: Project): KotlinCodeBlockModificationListener = project.getServiceSafe()
}
}
}

View File

@@ -0,0 +1,83 @@
/*
* 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.caches.trackers
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.SimpleModificationTracker
import com.intellij.pom.tree.TreeAspect
import com.intellij.psi.impl.PsiTreeChangeEventImpl
import org.jetbrains.kotlin.idea.KotlinLanguage
/**
* Tested in OutOfBlockModificationTestGenerated
*/
// FIX ME WHEN BUNCH 193 REMOVED
class KotlinCodeBlockModificationListener(
project: Project,
treeAspect: TreeAspect
) : KotlinCodeBlockModificationListenerCompat(project) {
@Suppress("UnstableApiUsage")
private val isLanguageTrackerEnabled = modificationTrackerImpl.isEnableLanguageTrackerCompat
// FIX ME WHEN BUNCH 191 REMOVED
// When there're we no per-language trackers we had to increment global tracker first and process result afterward
private val customIncrement = if (isLanguageTrackerEnabled) 0 else 1
init {
init(
treeAspect,
incOCBCounter = { ktFile ->
if (isLanguageTrackerEnabled) {
kotlinOutOfCodeBlockTrackerImpl.incModificationCount()
perModuleOutOfCodeBlockTrackerUpdater.onKotlinPhysicalFileOutOfBlockChange(ktFile, true)
} else {
perModuleOutOfCodeBlockTrackerUpdater.onKotlinPhysicalFileOutOfBlockChange(ktFile, false)
// Increment counter and process changes in PsiModificationTracker.Listener
modificationTrackerImpl.incCounter()
}
},
kotlinOutOfCodeBlockTrackerProducer = {
if (isLanguageTrackerEnabled) {
SimpleModificationTracker()
} else {
object : SimpleModificationTracker() {
override fun getModificationCount(): Long {
@Suppress("DEPRECATION")
return modificationTrackerImpl.outOfCodeBlockModificationCount
}
}
}
},
psiModificationTrackerListener = {
@Suppress("UnstableApiUsage")
if (isLanguageTrackerEnabled) {
val kotlinTrackerInternalIDECount =
modificationTrackerImpl.forLanguage(KotlinLanguage.INSTANCE).modificationCount
if (kotlinModificationTracker == kotlinTrackerInternalIDECount) {
// Some update that we are not sure is from Kotlin language, as Kotlin language tracker wasn't changed
kotlinOutOfCodeBlockTrackerImpl.incModificationCount()
} else {
kotlinModificationTracker = kotlinTrackerInternalIDECount
}
}
perModuleOutOfCodeBlockTrackerUpdater.onPsiModificationTrackerUpdate(customIncrement)
}
)
}
override fun treeChanged(event: PsiTreeChangeEventImpl) {
assert(isLanguageTrackerEnabled)
super.treeChanged(event)
}
companion object {
fun getInstance(project: Project): KotlinCodeBlockModificationListener =
project.getComponent(KotlinCodeBlockModificationListener::class.java)
}
}

View File

@@ -8,8 +8,9 @@ package org.jetbrains.kotlin.idea.highlighter
import com.intellij.codeInsight.intention.EmptyIntentionAction
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.lang.annotation.Annotation
import com.intellij.lang.annotation.AnnotationBuilder
import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.lang.annotation.HighlightSeverity
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.colors.TextAttributesKey
import com.intellij.openapi.util.TextRange
@@ -31,53 +32,43 @@ class AnnotationPresentationInfo(
for (range in ranges) {
for (diagnostic in diagnostics) {
val fixes = fixesMap[diagnostic]
val annotation = create(diagnostic, range, holder)
fixes.forEach {
when (it) {
is KotlinUniversalQuickFix -> annotation.registerUniversalFix(it, null, null)
is IntentionAction -> annotation.registerFix(it)
create(diagnostic, range, holder) { annotation ->
fixes.forEach {
when (it) {
is KotlinUniversalQuickFix -> annotation.newFix(it).universal().registerFix()
is IntentionAction -> annotation.newFix(it).registerFix()
}
}
}
if (diagnostic.severity == Severity.WARNING) {
annotation.problemGroup = KotlinSuppressableWarningProblemGroup(diagnostic.factory)
if (diagnostic.severity == Severity.WARNING) {
annotation.problemGroup(KotlinSuppressableWarningProblemGroup(diagnostic.factory))
if (fixes.isEmpty()) {
// if there are no quick fixes we need to register an EmptyIntentionAction to enable 'suppress' actions
annotation.registerFix(EmptyIntentionAction(diagnostic.factory.name))
if (fixes.isEmpty()) {
// if there are no quick fixes we need to register an EmptyIntentionAction to enable 'suppress' actions
annotation.newFix(EmptyIntentionAction(diagnostic.factory.name)).registerFix()
}
}
}
}
}
}
private fun create(diagnostic: Diagnostic, range: TextRange, holder: AnnotationHolder): Annotation {
val defaultMessage = nonDefaultMessage ?: getDefaultMessage(diagnostic)
val annotation = when (diagnostic.severity) {
Severity.ERROR -> holder.createErrorAnnotation(range, defaultMessage)
Severity.WARNING -> {
if (highlightType == ProblemHighlightType.WEAK_WARNING) {
holder.createWeakWarningAnnotation(range, defaultMessage)
} else {
holder.createWarningAnnotation(range, defaultMessage)
}
}
Severity.INFO -> holder.createInfoAnnotation(range, defaultMessage)
private fun create(diagnostic: Diagnostic, range: TextRange, holder: AnnotationHolder, consumer: (AnnotationBuilder) -> Unit) {
val severity = when (diagnostic.severity) {
Severity.ERROR -> HighlightSeverity.ERROR
Severity.WARNING -> if (highlightType == ProblemHighlightType.WEAK_WARNING) {
HighlightSeverity.WEAK_WARNING
} else HighlightSeverity.WARNING
Severity.INFO -> HighlightSeverity.WEAK_WARNING
}
annotation.tooltip = getMessage(diagnostic)
if (highlightType != null) {
annotation.highlightType = highlightType
}
if (textAttributes != null) {
annotation.textAttributes = textAttributes
}
return annotation
holder.newAnnotation(severity, nonDefaultMessage ?: getDefaultMessage(diagnostic))
.range(range)
.tooltip(getMessage(diagnostic))
.also { builder -> highlightType?.let { builder.highlightType(it) } }
.also { builder -> textAttributes?.let { builder.textAttributes(it) } }
.also { consumer(it) }
.create()
}
private fun getMessage(diagnostic: Diagnostic): String {
@@ -103,4 +94,5 @@ class AnnotationPresentationInfo(
}
return message
}
}

View File

@@ -0,0 +1,106 @@
/*
* 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.highlighter
import com.intellij.codeInsight.intention.EmptyIntentionAction
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.lang.annotation.Annotation
import com.intellij.lang.annotation.AnnotationHolder
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.editor.colors.TextAttributesKey
import com.intellij.openapi.util.TextRange
import com.intellij.util.containers.MultiMap
import com.intellij.xml.util.XmlStringUtil
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.idea.inspections.KotlinUniversalQuickFix
class AnnotationPresentationInfo(
val ranges: List<TextRange>,
val nonDefaultMessage: String? = null,
val highlightType: ProblemHighlightType? = null,
val textAttributes: TextAttributesKey? = null
) {
fun processDiagnostics(holder: AnnotationHolder, diagnostics: List<Diagnostic>, fixesMap: MultiMap<Diagnostic, IntentionAction>) {
for (range in ranges) {
for (diagnostic in diagnostics) {
val fixes = fixesMap[diagnostic]
val annotation = create(diagnostic, range, holder)
fixes.forEach {
when (it) {
is KotlinUniversalQuickFix -> annotation.registerUniversalFix(it, null, null)
is IntentionAction -> annotation.registerFix(it)
}
}
if (diagnostic.severity == Severity.WARNING) {
annotation.problemGroup = KotlinSuppressableWarningProblemGroup(diagnostic.factory)
if (fixes.isEmpty()) {
// if there are no quick fixes we need to register an EmptyIntentionAction to enable 'suppress' actions
annotation.registerFix(EmptyIntentionAction(diagnostic.factory.name))
}
}
}
}
}
private fun create(diagnostic: Diagnostic, range: TextRange, holder: AnnotationHolder): Annotation {
val defaultMessage = nonDefaultMessage ?: getDefaultMessage(diagnostic)
val annotation = when (diagnostic.severity) {
Severity.ERROR -> holder.createErrorAnnotation(range, defaultMessage)
Severity.WARNING -> {
if (highlightType == ProblemHighlightType.WEAK_WARNING) {
holder.createWeakWarningAnnotation(range, defaultMessage)
} else {
holder.createWarningAnnotation(range, defaultMessage)
}
}
Severity.INFO -> holder.createInfoAnnotation(range, defaultMessage)
}
annotation.tooltip = getMessage(diagnostic)
if (highlightType != null) {
annotation.highlightType = highlightType
}
if (textAttributes != null) {
annotation.textAttributes = textAttributes
}
return annotation
}
private fun getMessage(diagnostic: Diagnostic): String {
var message = IdeErrorMessages.render(diagnostic)
if (ApplicationManager.getApplication().isInternal || ApplicationManager.getApplication().isUnitTestMode) {
val factoryName = diagnostic.factory.name
message = if (message.startsWith("<html>")) {
"<html>[$factoryName] ${message.substring("<html>".length)}"
} else {
"[$factoryName] $message"
}
}
if (!message.startsWith("<html>")) {
message = "<html><body>${XmlStringUtil.escapeString(message)}</body></html>"
}
return message
}
private fun getDefaultMessage(diagnostic: Diagnostic): String {
val message = DefaultErrorMessages.render(diagnostic)
if (ApplicationManager.getApplication().isInternal || ApplicationManager.getApplication().isUnitTestMode) {
return "[${diagnostic.factory.name}] $message"
}
return message
}
}

View File

@@ -64,7 +64,7 @@ public class ModuleHighlightUtil2 {
}
}
else if (root.getFileSystem() instanceof JarFileSystem && "jar".equalsIgnoreCase(root.getExtension())) {
return LightJavaModule.getModule(PsiManager.getInstance(project), root);
return LightJavaModule.findModule(PsiManager.getInstance(project), root);
}
}
else if ((root = index.getSourceRootForFile(file)) != null) {

View File

@@ -0,0 +1,114 @@
/*
* 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;
}
}

View File

@@ -6,12 +6,9 @@
package org.jetbrains.kotlin.idea.search.ideaExtensions
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.cache.CacheManager
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ScopeOptimizer
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.UsageSearchContext
import com.intellij.psi.search.*
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.search.excludeFileTypes
@@ -31,19 +28,22 @@ class KotlinReferenceScopeOptimizer : ScopeOptimizer {
val file = callable.parent as KtFile
val packageName = file.packageFqName.takeUnless { it.isRoot } ?: return null
val project = file.project
val cacheManager = CacheManager.SERVICE.getInstance(project)
val searchHelper = PsiSearchHelper.getInstance(project)
val kotlinScope = GlobalSearchScope.getScopeRestrictedByFileTypes(useScope, KotlinFileType.INSTANCE)
val javaScope = GlobalSearchScope.getScopeRestrictedByFileTypes(useScope, JavaFileType.INSTANCE)
val restScope = useScope.excludeFileTypes(KotlinFileType.INSTANCE, JavaFileType.INSTANCE) as GlobalSearchScope
//TODO: use all components of package name?
val shortPackageName = packageName.shortName().identifier
val kotlinFiles = cacheManager.getVirtualFilesWithWord(shortPackageName, UsageSearchContext.IN_CODE, kotlinScope, true)
val kotlinFiles = mutableListOf<VirtualFile>()
searchHelper.processCandidateFilesForText(kotlinScope, UsageSearchContext.IN_CODE, true, packageName.asString()) {
kotlinFiles.add(it)
}
val javaFacadeName = file.javaFileFacadeFqName.shortName().identifier
val javaFiles = cacheManager.getVirtualFilesWithWord(javaFacadeName, UsageSearchContext.IN_CODE, javaScope, true)
val javaFiles = mutableListOf<VirtualFile>()
searchHelper.processCandidateFilesForText(javaScope, UsageSearchContext.IN_CODE, true, file.javaFileFacadeFqName.asString()) {
javaFiles.add(it)
}
return GlobalSearchScope.filesScope(project, (kotlinFiles + javaFiles).asList()).uniteWith(restScope)
return GlobalSearchScope.filesScope(project, kotlinFiles + javaFiles).uniteWith(restScope)
}
}

View File

@@ -0,0 +1,49 @@
/*
* 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.search.ideaExtensions
import com.intellij.ide.highlighter.JavaFileType
import com.intellij.psi.PsiElement
import com.intellij.psi.impl.cache.CacheManager
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ScopeOptimizer
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.UsageSearchContext
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.search.excludeFileTypes
import org.jetbrains.kotlin.psi.KtCallableDeclaration
import org.jetbrains.kotlin.psi.KtFile
class KotlinReferenceScopeOptimizer : ScopeOptimizer {
override fun getRestrictedUseScope(element: PsiElement): SearchScope? {
if (element is KtCallableDeclaration && element.parent is KtFile) {
return getRestrictedScopeForTopLevelCallable(element)
}
return null
}
private fun getRestrictedScopeForTopLevelCallable(callable: KtCallableDeclaration): GlobalSearchScope? {
val useScope = callable.useScope as? GlobalSearchScope ?: return null
val file = callable.parent as KtFile
val packageName = file.packageFqName.takeUnless { it.isRoot } ?: return null
val project = file.project
val cacheManager = CacheManager.SERVICE.getInstance(project)
val kotlinScope = GlobalSearchScope.getScopeRestrictedByFileTypes(useScope, KotlinFileType.INSTANCE)
val javaScope = GlobalSearchScope.getScopeRestrictedByFileTypes(useScope, JavaFileType.INSTANCE)
val restScope = useScope.excludeFileTypes(KotlinFileType.INSTANCE, JavaFileType.INSTANCE) as GlobalSearchScope
//TODO: use all components of package name?
val shortPackageName = packageName.shortName().identifier
val kotlinFiles = cacheManager.getVirtualFilesWithWord(shortPackageName, UsageSearchContext.IN_CODE, kotlinScope, true)
val javaFacadeName = file.javaFileFacadeFqName.shortName().identifier
val javaFiles = cacheManager.getVirtualFilesWithWord(javaFacadeName, UsageSearchContext.IN_CODE, javaScope, true)
return GlobalSearchScope.filesScope(project, (kotlinFiles + javaFiles).asList()).uniteWith(restScope)
}
}

View File

@@ -19,8 +19,8 @@ package org.jetbrains.kotlin.idea.util.application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.components.ComponentManager
import com.intellij.openapi.progress.impl.CancellationCheck
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.Nls
fun <T> runReadAction(action: () -> T): T {
return ApplicationManager.getApplication().runReadAction<T>(action)
@@ -30,22 +30,22 @@ fun <T> runWriteAction(action: () -> T): T {
return ApplicationManager.getApplication().runWriteAction<T>(action)
}
fun Project.executeWriteCommand(@Nls name: String, command: () -> Unit) {
fun Project.executeWriteCommand(name: String, command: () -> Unit) {
CommandProcessor.getInstance().executeCommand(this, { runWriteAction(command) }, name, null)
}
fun <T> Project.executeWriteCommand(@Nls name: String, groupId: Any? = null, command: () -> T): T {
fun <T> Project.executeWriteCommand(name: String, groupId: Any? = null, command: () -> T): T {
return executeCommand<T>(name, groupId) { runWriteAction(command) }
}
fun <T> Project.executeCommand(@Nls name: String, groupId: Any? = null, command: () -> T): T {
fun <T> Project.executeCommand(name: String, groupId: Any? = null, command: () -> T): T {
@Suppress("UNCHECKED_CAST") var result: T = null as T
CommandProcessor.getInstance().executeCommand(this, { result = command() }, name, groupId)
@Suppress("USELESS_CAST")
return result as T
}
fun <T> runWithCancellationCheck(block: () -> T): T = block()
fun <T> runWithCancellationCheck(block: () -> T): T = CancellationCheck.runWithCancellationCheck(block)
inline fun executeOnPooledThread(crossinline action: () -> Unit) =
ApplicationManager.getApplication().executeOnPooledThread { action() }

View File

@@ -0,0 +1,59 @@
/*
* 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.util.application
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.command.CommandProcessor
import com.intellij.openapi.components.ComponentManager
import com.intellij.openapi.project.Project
import org.jetbrains.annotations.Nls
fun <T> runReadAction(action: () -> T): T {
return ApplicationManager.getApplication().runReadAction<T>(action)
}
fun <T> runWriteAction(action: () -> T): T {
return ApplicationManager.getApplication().runWriteAction<T>(action)
}
fun Project.executeWriteCommand(@Nls name: String, command: () -> Unit) {
CommandProcessor.getInstance().executeCommand(this, { runWriteAction(command) }, name, null)
}
fun <T> Project.executeWriteCommand(@Nls name: String, groupId: Any? = null, command: () -> T): T {
return executeCommand<T>(name, groupId) { runWriteAction(command) }
}
fun <T> Project.executeCommand(@Nls name: String, groupId: Any? = null, command: () -> T): T {
@Suppress("UNCHECKED_CAST") var result: T = null as T
CommandProcessor.getInstance().executeCommand(this, { result = command() }, name, groupId)
@Suppress("USELESS_CAST")
return result as T
}
fun <T> runWithCancellationCheck(block: () -> T): T = block()
inline fun executeOnPooledThread(crossinline action: () -> Unit) =
ApplicationManager.getApplication().executeOnPooledThread { action() }
inline fun invokeLater(crossinline action: () -> Unit) =
ApplicationManager.getApplication().invokeLater { action() }
inline fun isUnitTestMode(): Boolean = ApplicationManager.getApplication().isUnitTestMode
inline fun <reified T : Any> ComponentManager.getServiceSafe(): T =
this.getService(T::class.java) ?: error("Unable to locate service ${T::class.java.name}")

View File

@@ -5,9 +5,10 @@
package org.jetbrains.kotlin.idea.completion.test.handlers
import com.intellij.codeInsight.lookup.LookupFocusDegree
import com.intellij.codeInsight.lookup.impl.LookupImpl
// FIX ME WHEN BUNCH 193 REMOVED
fun LookupImpl.setFocusedFocusDegree() {
focusDegree = LookupImpl.FocusDegree.FOCUSED
this.lookupFocusDegree = LookupFocusDegree.FOCUSED
}

View File

@@ -0,0 +1,13 @@
/*
* 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.completion.test.handlers
import com.intellij.codeInsight.lookup.impl.LookupImpl
// FIX ME WHEN BUNCH 193 REMOVED
fun LookupImpl.setFocusedFocusDegree() {
focusDegree = LookupImpl.FocusDegree.FOCUSED
}

View File

@@ -45,7 +45,7 @@ class ShowKotlinGradleDslLogs : IntentionAction, AnAction(), DumbAware {
RevealFileAction.openDirectory(logsDir)
} else {
val parent = WindowManager.getInstance().getStatusBar(project)?.component
?: WindowManager.getInstance().findVisibleFrame().rootPane
?: WindowManager.getInstance().findVisibleFrame()?.rootPane
JBPopupFactory.getInstance()
.createHtmlTextBalloonBuilder(
KotlinIdeaGradleBundle.message(

View File

@@ -13,8 +13,8 @@ import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExten
// FIX ME WHEN BUNCH 193 REMOVED
abstract class AbstractProjectResolverExtensionCompat : AbstractProjectResolverExtension() {
override fun createModule(gradleModule: IdeaModule, projectDataNode: DataNode<ProjectData>): DataNode<ModuleData> {
return super.createModule(gradleModule, projectDataNode).also {
override fun createModule(gradleModule: IdeaModule, projectDataNode: DataNode<ProjectData>): DataNode<ModuleData>? {
return super.createModule(gradleModule, projectDataNode)?.also {
initializeModuleNode(gradleModule, it, projectDataNode)
}
}

View File

@@ -0,0 +1,28 @@
/*
* 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.configuration
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.project.ModuleData
import com.intellij.openapi.externalSystem.model.project.ProjectData
import org.gradle.tooling.model.idea.IdeaModule
import org.jetbrains.plugins.gradle.service.project.AbstractProjectResolverExtension
// FIX ME WHEN BUNCH 193 REMOVED
abstract class AbstractProjectResolverExtensionCompat : AbstractProjectResolverExtension() {
override fun createModule(gradleModule: IdeaModule, projectDataNode: DataNode<ProjectData>): DataNode<ModuleData> {
return super.createModule(gradleModule, projectDataNode).also {
initializeModuleNode(gradleModule, it, projectDataNode)
}
}
// Inline after class remove
abstract fun initializeModuleNode(
gradleModule: IdeaModule,
moduleDataNode: DataNode<ModuleData>,
projectDataNode: DataNode<ProjectData>,
)
}

View File

@@ -5,7 +5,8 @@
package org.jetbrains.kotlin.idea.scripting.gradle
import com.intellij.openapi.externalSystem.service.project.autoimport.AsyncFileChangeListenerBase
import com.intellij.openapi.externalSystem.autoimport.AsyncFileChangeListenerBase
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
@@ -17,19 +18,27 @@ fun addVfsListener(
) {
VirtualFileManager.getInstance().addAsyncFileListener(
object : AsyncFileChangeListenerBase() {
val changedFiles = mutableListOf<String>()
override fun init() {
changedFiles.clear()
}
override fun isRelevant(path: String): Boolean {
return buildRootsManager.maybeAffectedGradleProjectFile(path)
}
override fun updateFile(file: VirtualFile, event: VFileEvent) {
watcher.fileChanged(event.path, file.timeStamp)
changedFiles.add(event.path)
}
// do nothing
override fun prepareFileDeletion(file: VirtualFile) {}
override fun apply() {}
override fun reset() {}
override fun apply() {
changedFiles.forEach {
LocalFileSystem.getInstance().findFileByPath(it)?.let { f ->
watcher.fileChanged(f.path, f.timeStamp)
}
}
}
},
watcher.project
)

View File

@@ -0,0 +1,36 @@
/*
* 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.externalSystem.service.project.autoimport.AsyncFileChangeListenerBase
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.VirtualFileManager
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
fun addVfsListener(
watcher: GradleScriptListener,
buildRootsManager: GradleBuildRootsManager
) {
VirtualFileManager.getInstance().addAsyncFileListener(
object : AsyncFileChangeListenerBase() {
override fun isRelevant(path: String): Boolean {
return buildRootsManager.maybeAffectedGradleProjectFile(path)
}
override fun updateFile(file: VirtualFile, event: VFileEvent) {
watcher.fileChanged(event.path, file.timeStamp)
}
// do nothing
override fun prepareFileDeletion(file: VirtualFile) {}
override fun apply() {}
override fun reset() {}
},
watcher.project
)
}

View File

@@ -7,113 +7,100 @@
package org.jetbrains.kotlin.idea.scripting.gradle
import com.intellij.notification.*
import com.intellij.diff.util.DiffUtil
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.testFramework.LightVirtualFileBase
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
import org.jetbrains.kotlin.psi.UserDataProperty
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
import org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelResolver
import org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager
import org.jetbrains.plugins.gradle.service.project.GradlePartialResolverPolicy
import org.jetbrains.plugins.gradle.util.GradleConstants
fun runPartialGradleImport(project: Project) {
getGradleProjectSettings(project).forEach {
getGradleProjectSettings(project).forEach { gradleProjectSettings ->
ExternalSystemUtil.refreshProject(
it.externalProjectPath,
gradleProjectSettings.externalProjectPath,
ImportSpecBuilder(project, GradleConstants.SYSTEM_ID)
.build()
.projectResolverPolicy(
GradlePartialResolverPolicy { it is KotlinDslScriptModelResolver }
)
)
}
}
fun getMissingConfigurationNotificationText() = KotlinIdeaGradleBundle.message("script.configurations.will.be.available.after.import")
fun getMissingConfigurationActionText() = KotlinIdeaGradleBundle.message("action.label.import.project")
fun getMissingConfigurationNotificationText() = KotlinIdeaGradleBundle.message("script.configurations.will.be.available.after.load.changes")
fun getMissingConfigurationActionText() = KotlinIdeaGradleBundle.message("action.text.load.script.configurations")
fun autoReloadScriptConfigurations(project: Project): Boolean {
val gradleSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
val projectSettings = gradleSettings.getLinkedProjectsSettings()
.filterIsInstance<GradleProjectSettings>()
.firstOrNull()
if (projectSettings != null) {
return projectSettings.isUseAutoImport
return GradleScriptDefinitionsContributor.getDefinitions(project).any {
KotlinScriptingSettings.getInstance(project).autoReloadConfigurations(it)
}
return false
}
private const val kotlinDslNotificationGroupId = "Gradle Kotlin DSL Scripts"
private var Project.notificationPanel: ScriptConfigurationChangedNotification?
by UserDataProperty<Project, ScriptConfigurationChangedNotification>(Key.create("load.script.configuration.panel"))
fun scriptConfigurationsNeedToBeUpdated(project: Project) {
if (autoReloadScriptConfigurations(project)) {
// import should be run automatically by Gradle plugin
return
runPartialGradleImport(project)
} else {
// notification is shown in LoadConfigurationAction
}
val existingPanel = project.notificationPanel
if (existingPanel != null) {
return
}
val notificationGroup = NotificationGroup.findRegisteredGroup(kotlinDslNotificationGroupId)
if (notificationGroup == null) {
NotificationsConfiguration.getNotificationsConfiguration().register(
kotlinDslNotificationGroupId, NotificationDisplayType.STICKY_BALLOON, false
)
}
val notification = ScriptConfigurationChangedNotification(project)
project.notificationPanel = notification
notification.notify(project)
}
fun scriptConfigurationsAreUpToDate(project: Project): Boolean {
if (project.notificationPanel == null) return false
project.notificationPanel?.expire()
return true
}
fun scriptConfigurationsAreUpToDate(project: Project): Boolean = true
private class ScriptConfigurationChangedNotification(val project: Project) :
Notification(
kotlinDslNotificationGroupId,
KotlinIcons.LOAD_SCRIPT_CONFIGURATION,
KotlinIdeaGradleBundle.message("notification.title.script.configuration.has.been.changed"),
null,
KotlinIdeaGradleBundle.message("notification.text.script.configuration.has.been.changed"),
NotificationType.INFORMATION,
null
) {
init {
addAction(LoadConfigurationAction())
addAction(NotificationAction.createSimple(KotlinIdeaGradleBundle.message("action.label.enable.auto.import")) {
val gradleSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
val projectSettings = gradleSettings.getLinkedProjectsSettings()
.filterIsInstance<GradleProjectSettings>()
.firstOrNull()
if (projectSettings != null) {
projectSettings.isUseAutoImport = true
}
runPartialGradleImport(project)
})
class LoadConfigurationAction : AnAction(
KotlinIdeaGradleBundle.message("action.text.load.script.configurations"),
KotlinIdeaGradleBundle.message("action.description.load.script.configurations"),
KotlinIcons.LOAD_SCRIPT_CONFIGURATION
) {
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
runPartialGradleImport(project)
}
override fun expire() {
super.expire()
project.notificationPanel = null
override fun update(e: AnActionEvent) {
ensureValidActionVisibility(e)
}
private class LoadConfigurationAction : AnAction(KotlinIdeaGradleBundle.message("action.label.import.project")) {
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
runPartialGradleImport(project)
private fun ensureValidActionVisibility(e: AnActionEvent) {
val editor = e.getData(CommonDataKeys.EDITOR) ?: return
e.presentation.isVisible = getNotificationVisibility(editor)
}
private fun getNotificationVisibility(editor: Editor): Boolean {
if (DiffUtil.isDiffEditor(editor)) {
return false
}
val project = editor.project ?: return false
val file = getKotlinScriptFile(editor) ?: return false
if (autoReloadScriptConfigurations(project)) {
return false
}
return GradleBuildRootsManager.getInstance(project).isConfigurationOutOfDate(file)
}
private fun getKotlinScriptFile(editor: Editor): VirtualFile? {
return FileDocumentManager.getInstance()
.getFile(editor.document)
?.takeIf {
it !is LightVirtualFileBase
&& it.isValid
&& it.fileType != KotlinFileType.INSTANCE
&& isGradleKotlinScript(it)
}
}
}

View File

@@ -0,0 +1,119 @@
/*
* 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("UnstableApiUsage")
package org.jetbrains.kotlin.idea.scripting.gradle
import com.intellij.notification.*
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.externalSystem.importing.ImportSpecBuilder
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Key
import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.idea.KotlinIdeaGradleBundle
import org.jetbrains.kotlin.psi.UserDataProperty
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
fun runPartialGradleImport(project: Project) {
getGradleProjectSettings(project).forEach {
ExternalSystemUtil.refreshProject(
it.externalProjectPath,
ImportSpecBuilder(project, GradleConstants.SYSTEM_ID)
.build()
)
}
}
fun getMissingConfigurationNotificationText() = KotlinIdeaGradleBundle.message("script.configurations.will.be.available.after.import")
fun getMissingConfigurationActionText() = KotlinIdeaGradleBundle.message("action.label.import.project")
fun autoReloadScriptConfigurations(project: Project): Boolean {
val gradleSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
val projectSettings = gradleSettings.getLinkedProjectsSettings()
.filterIsInstance<GradleProjectSettings>()
.firstOrNull()
if (projectSettings != null) {
return projectSettings.isUseAutoImport
}
return false
}
private const val kotlinDslNotificationGroupId = "Gradle Kotlin DSL Scripts"
private var Project.notificationPanel: ScriptConfigurationChangedNotification?
by UserDataProperty<Project, ScriptConfigurationChangedNotification>(Key.create("load.script.configuration.panel"))
fun scriptConfigurationsNeedToBeUpdated(project: Project) {
if (autoReloadScriptConfigurations(project)) {
// import should be run automatically by Gradle plugin
return
}
val existingPanel = project.notificationPanel
if (existingPanel != null) {
return
}
val notificationGroup = NotificationGroup.findRegisteredGroup(kotlinDslNotificationGroupId)
if (notificationGroup == null) {
NotificationsConfiguration.getNotificationsConfiguration().register(
kotlinDslNotificationGroupId, NotificationDisplayType.STICKY_BALLOON, false
)
}
val notification = ScriptConfigurationChangedNotification(project)
project.notificationPanel = notification
notification.notify(project)
}
fun scriptConfigurationsAreUpToDate(project: Project): Boolean {
if (project.notificationPanel == null) return false
project.notificationPanel?.expire()
return true
}
private class ScriptConfigurationChangedNotification(val project: Project) :
Notification(
kotlinDslNotificationGroupId,
KotlinIcons.LOAD_SCRIPT_CONFIGURATION,
KotlinIdeaGradleBundle.message("notification.title.script.configuration.has.been.changed"),
null,
KotlinIdeaGradleBundle.message("notification.text.script.configuration.has.been.changed"),
NotificationType.INFORMATION,
null
) {
init {
addAction(LoadConfigurationAction())
addAction(NotificationAction.createSimple(KotlinIdeaGradleBundle.message("action.label.enable.auto.import")) {
val gradleSettings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
val projectSettings = gradleSettings.getLinkedProjectsSettings()
.filterIsInstance<GradleProjectSettings>()
.firstOrNull()
if (projectSettings != null) {
projectSettings.isUseAutoImport = true
}
runPartialGradleImport(project)
})
}
override fun expire() {
super.expire()
project.notificationPanel = null
}
private class LoadConfigurationAction : AnAction(KotlinIdeaGradleBundle.message("action.label.import.project")) {
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
runPartialGradleImport(project)
}
}
}

View File

@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
import org.jetbrains.kotlin.scripting.resolve.KotlinScriptDefinitionFromAnnotatedTemplate
import kotlin.script.experimental.api.*
import kotlin.script.experimental.host.ScriptingHostConfiguration
import kotlin.script.experimental.location.ScriptExpectedLocation
class GradleKotlinScriptDefinitionWrapper(
hostConfiguration: ScriptingHostConfiguration,
@@ -25,6 +26,5 @@ class GradleKotlinScriptDefinitionWrapper(
}
}
override val canAutoReloadScriptConfigurationsBeSwitchedOff = !kotlinDslScriptsModelImportSupported(gradleVersion)
override val canDefinitionBeSwitchedOff: Boolean = false
}

View File

@@ -0,0 +1,30 @@
/*
* 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 org.jetbrains.kotlin.scripting.definitions.ScriptCompilationConfigurationFromDefinition
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
import org.jetbrains.kotlin.scripting.resolve.KotlinScriptDefinitionFromAnnotatedTemplate
import kotlin.script.experimental.api.*
import kotlin.script.experimental.host.ScriptingHostConfiguration
class GradleKotlinScriptDefinitionWrapper(
hostConfiguration: ScriptingHostConfiguration,
legacyDefinition: KotlinScriptDefinitionFromAnnotatedTemplate,
gradleVersion: String,
) : ScriptDefinition.FromLegacy(hostConfiguration, legacyDefinition) {
override val compilationConfiguration by lazy {
ScriptCompilationConfigurationFromDefinition(
hostConfiguration,
legacyDefinition
).with {
ScriptCompilationConfiguration.ide.acceptedLocations.put(listOf(ScriptAcceptedLocation.Project))
}
}
override val canAutoReloadScriptConfigurationsBeSwitchedOff = !kotlinDslScriptsModelImportSupported(gradleVersion)
override val canDefinitionBeSwitchedOff: Boolean = false
}

View File

@@ -5,16 +5,16 @@
package org.jetbrains.kotlin.idea.scripting.gradle.importing
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.project.ProjectData
import org.gradle.tooling.model.idea.IdeaProject
import org.gradle.tooling.model.kotlin.dsl.KotlinDslScriptsModel
import org.jetbrains.kotlin.gradle.KotlinDslScriptAdditionalTask
import org.jetbrains.kotlin.gradle.KotlinDslScriptModelProvider
import org.jetbrains.kotlin.idea.scripting.gradle.kotlinDslScriptsModelImportSupported
import org.jetbrains.plugins.gradle.model.Build
import org.jetbrains.plugins.gradle.model.ClassSetImportModelProvider
import org.jetbrains.plugins.gradle.model.ProjectImportModelProvider
import org.jetbrains.kotlin.gradle.KotlinDslScriptAdditionalTask
import org.jetbrains.kotlin.gradle.KotlinDslScriptModelProvider
import org.gradle.tooling.model.kotlin.dsl.KotlinDslScriptsModel
import org.jetbrains.kotlin.idea.scripting.gradle.kotlinDslScriptsModelImportSupported
import org.jetbrains.plugins.gradle.service.project.ModifiableGradleProjectModel
import org.jetbrains.plugins.gradle.service.project.ProjectModelContributor
import org.jetbrains.plugins.gradle.service.project.ProjectResolverContext
import org.jetbrains.plugins.gradle.service.project.ToolingModelsProvider
class KotlinDslScriptModelResolver : KotlinDslScriptModelResolverCommon() {
override fun requiresTaskRunning() = true
@@ -27,27 +27,23 @@ class KotlinDslScriptModelResolver : KotlinDslScriptModelResolverCommon() {
setOf(KotlinDslScriptAdditionalTask::class.java)
)
}
}
override fun populateProjectExtraModels(gradleProject: IdeaProject, ideProject: DataNode<ProjectData>) {
super.populateProjectExtraModels(gradleProject, ideProject)
if (kotlinDslScriptsModelImportSupported(resolverCtx.projectGradleVersion)) {
populateBuildModels(resolverCtx.models.mainBuild, ideProject)
resolverCtx.models.includedBuilds.forEach { includedRoot ->
populateBuildModels(includedRoot, ideProject)
}
}
}
private fun populateBuildModels(
root: Build,
ideProject: DataNode<ProjectData>
@Suppress("UnstableApiUsage")
class KotlinDslScriptModelContributor : ProjectModelContributor {
override fun accept(
projectModelBuilder: ModifiableGradleProjectModel,
toolingModelsProvider: ToolingModelsProvider,
resolverContext: ProjectResolverContext
) {
root.projects.forEach {
if (it.projectIdentifier.projectPath == ":") {
resolverCtx.models.getModel(it, KotlinDslScriptsModel::class.java)?.let { model ->
processScriptModel(resolverCtx, model, it.projectIdentifier.projectPath)
if (!kotlinDslScriptsModelImportSupported(resolverContext.projectGradleVersion)) return
toolingModelsProvider.projects().forEach {
val projectIdentifier = it.projectIdentifier.projectPath
if (projectIdentifier == ":") {
val model = toolingModelsProvider.getProjectModel(it, KotlinDslScriptsModel::class.java)
if (model != null) {
processScriptModel(resolverContext, model, projectIdentifier)
}
}
}

View File

@@ -0,0 +1,55 @@
/*
* 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.scripting.gradle.importing
import com.intellij.openapi.externalSystem.model.DataNode
import com.intellij.openapi.externalSystem.model.project.ProjectData
import org.gradle.tooling.model.idea.IdeaProject
import org.gradle.tooling.model.kotlin.dsl.KotlinDslScriptsModel
import org.jetbrains.kotlin.gradle.KotlinDslScriptAdditionalTask
import org.jetbrains.kotlin.gradle.KotlinDslScriptModelProvider
import org.jetbrains.kotlin.idea.scripting.gradle.kotlinDslScriptsModelImportSupported
import org.jetbrains.plugins.gradle.model.Build
import org.jetbrains.plugins.gradle.model.ClassSetImportModelProvider
import org.jetbrains.plugins.gradle.model.ProjectImportModelProvider
class KotlinDslScriptModelResolver : KotlinDslScriptModelResolverCommon() {
override fun requiresTaskRunning() = true
override fun getModelProvider() = KotlinDslScriptModelProvider()
override fun getProjectsLoadedModelProvider(): ProjectImportModelProvider? {
return ClassSetImportModelProvider(
emptySet(),
setOf(KotlinDslScriptAdditionalTask::class.java)
)
}
override fun populateProjectExtraModels(gradleProject: IdeaProject, ideProject: DataNode<ProjectData>) {
super.populateProjectExtraModels(gradleProject, ideProject)
if (kotlinDslScriptsModelImportSupported(resolverCtx.projectGradleVersion)) {
populateBuildModels(resolverCtx.models.mainBuild, ideProject)
resolverCtx.models.includedBuilds.forEach { includedRoot ->
populateBuildModels(includedRoot, ideProject)
}
}
}
private fun populateBuildModels(
root: Build,
ideProject: DataNode<ProjectData>
) {
root.projects.forEach {
if (it.projectIdentifier.projectPath == ":") {
resolverCtx.models.getModel(it, KotlinDslScriptsModel::class.java)?.let { model ->
processScriptModel(resolverCtx, model, it.projectIdentifier.projectPath)
}
}
}
}
}

View File

@@ -147,8 +147,8 @@ public abstract class AbstractModelBuilderTest {
}
@NotNull
private static Set<Class> getToolingExtensionClasses() {
Set<Class> classes = ContainerUtil.<Class>set(
private static Set<Class<?>> getToolingExtensionClasses() {
Set<Class<?>> classes = ContainerUtil.set(
ExternalProject.class,
// gradle-tooling-extension-api jar
ProjectImportAction.class,
@@ -163,7 +163,7 @@ public abstract class AbstractModelBuilderTest {
}
@NotNull
private static Set<Class> doGetToolingExtensionClasses() {
private static Set<Class<?>> doGetToolingExtensionClasses() {
return Collections.emptySet();
}
@@ -174,7 +174,7 @@ public abstract class AbstractModelBuilderTest {
}
}
protected abstract Set<Class> getModels();
protected abstract Set<Class<?>> getModels();
private static void ensureTempDirCreated() throws IOException {

View File

@@ -0,0 +1,233 @@
/*
* 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.codeInsight.gradle;
import com.google.common.collect.Multimap;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.io.StreamUtil;
import com.intellij.testFramework.IdeaTestUtil;
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.util.GradleVersion;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.gradle.model.ClassSetProjectImportModelProvider;
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.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
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.addProjectImportModelProvider(new ClassSetProjectImportModelProvider(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 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;
}
}
}

View File

@@ -30,15 +30,18 @@ class ShowKotlinBytecodeAction : AnAction() {
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
val toolWindowManager = ToolWindowManager.getInstance(project)
var toolWindow = toolWindowManager.getToolWindow(TOOLWINDOW_ID)
if (toolWindow == null) {
toolWindow = toolWindowManager.registerToolWindow(TOOLWINDOW_ID, false, ToolWindowAnchor.RIGHT)
toolWindow.icon = KotlinIcons.SMALL_LOGO_13
val contentManager = toolWindow.contentManager
val contentFactory = ContentFactory.SERVICE.getInstance()
contentManager.addContent(contentFactory.createContent(KotlinBytecodeToolWindow(project, toolWindow), "", false))
}
val toolWindow = toolWindowManager.getToolWindow(TOOLWINDOW_ID) ?: toolWindowManager.registerToolWindow(
TOOLWINDOW_ID,
false,
ToolWindowAnchor.RIGHT,
)
.apply {
setIcon(KotlinIcons.SMALL_LOGO_13)
val contentFactory = ContentFactory.SERVICE.getInstance()
contentManager.addContent(contentFactory.createContent(KotlinBytecodeToolWindow(project, this), "", false))
}
toolWindow.activate(null)
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.idea.actions
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.wm.ToolWindowAnchor
import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.ui.content.ContentFactory
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.idea.internal.KotlinBytecodeToolWindow
class ShowKotlinBytecodeAction : AnAction() {
override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return
val toolWindowManager = ToolWindowManager.getInstance(project)
var toolWindow = toolWindowManager.getToolWindow(TOOLWINDOW_ID)
if (toolWindow == null) {
toolWindow = toolWindowManager.registerToolWindow(TOOLWINDOW_ID, false, ToolWindowAnchor.RIGHT)
toolWindow.icon = KotlinIcons.SMALL_LOGO_13
val contentManager = toolWindow.contentManager
val contentFactory = ContentFactory.SERVICE.getInstance()
contentManager.addContent(contentFactory.createContent(KotlinBytecodeToolWindow(project, toolWindow), "", false))
}
toolWindow.activate(null)
}
override fun update(e: AnActionEvent) {
val file = e.getData(CommonDataKeys.PSI_FILE)
e.presentation.isEnabled = e.project != null && file?.fileType == KotlinFileType.INSTANCE
}
companion object {
const val TOOLWINDOW_ID = "Kotlin Bytecode"
}
}

View File

@@ -20,12 +20,12 @@ import com.intellij.execution.filters.OpenFileHyperlinkInfo
import com.intellij.execution.impl.ConsoleViewImpl
import com.intellij.execution.runners.ExecutionUtil
import com.intellij.execution.ui.ConsoleViewContentType
import com.intellij.ide.scratch.ScratchFileType
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.TransactionGuard
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.editor.ex.EditorEx
import com.intellij.openapi.fileTypes.PlainTextFileType
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.wm.ToolWindow
@@ -113,8 +113,8 @@ private class ToolWindowScratchOutputHandler(private val parentDisposable: Dispo
OpenFileHyperlinkInfo(
project,
psiFile.virtualFile,
expression.lineStart,
),
expression.lineStart
)
)
print(" ", ConsoleViewContentType.NORMAL_OUTPUT)
}
@@ -149,7 +149,7 @@ private class ToolWindowScratchOutputHandler(private val parentDisposable: Dispo
toolWindow.show(null)
}
toolWindow.icon = ExecutionUtil.getLiveIndicator(scratchIcon())
toolWindow.setIcon(ExecutionUtil.getLiveIndicator(ScratchFileType.INSTANCE.icon))
}
}
@@ -168,7 +168,7 @@ private class ToolWindowScratchOutputHandler(private val parentDisposable: Dispo
toolWindow.hide(null)
}
toolWindow.icon = scratchIcon()
toolWindow.setIcon(ScratchFileType.INSTANCE.icon ?: error("Text icon is expected to be present"))
}
}
@@ -187,22 +187,18 @@ private class ToolWindowScratchOutputHandler(private val parentDisposable: Dispo
val project = file.project
val toolWindowManager = ToolWindowManager.getInstance(project)
toolWindowManager.registerToolWindow(ScratchToolWindowFactory.ID, true, ToolWindowAnchor.BOTTOM)
val window = toolWindowManager.getToolWindow(ScratchToolWindowFactory.ID)
val window =
toolWindowManager.getToolWindow(ScratchToolWindowFactory.ID) ?: error("ScratchToolWindowFactory.ID should be registered")
ScratchToolWindowFactory().createToolWindowContent(project, window)
Disposer.register(
parentDisposable,
Disposable {
toolWindowManager.unregisterToolWindow(ScratchToolWindowFactory.ID)
},
)
Disposer.register(parentDisposable, Disposable {
toolWindowManager.unregisterToolWindow(ScratchToolWindowFactory.ID)
})
return window
}
}
private fun scratchIcon() = PlainTextFileType.INSTANCE.icon
private fun getLineInfo(psiFile: PsiFile, expression: ScratchExpression) =
"${psiFile.name}:${expression.lineStart + 1}"
@@ -213,8 +209,8 @@ private class ScratchToolWindowFactory : ToolWindowFactory {
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
val consoleView = ConsoleViewImpl(project, true)
toolWindow.isToHideOnEmptyContent = true
toolWindow.icon = scratchIcon()
toolWindow.setToHideOnEmptyContent(true)
toolWindow.setIcon(ScratchFileType.INSTANCE.icon ?: error("Text icon should be present"))
toolWindow.hide(null)
val contentManager = toolWindow.contentManager
@@ -242,33 +238,27 @@ private object TestOutputHandler : ScratchOutputHandlerAdapter() {
}
override fun onFinish(file: ScratchFile) {
TransactionGuard.submitTransaction(
file.project,
Runnable {
val psiFile = file.getPsiFile()
?: error(
"PsiFile cannot be found for scratch to render inlays in tests:\n" +
"project.isDisposed = ${file.project.isDisposed}\n" +
"inlays = ${inlays.joinToString { it.second }}\n" +
"errors = ${errors.joinToString()}",
)
TransactionGuard.submitTransaction(file.project, Runnable {
val psiFile = file.getPsiFile()
?: error(
"PsiFile cannot be found for scratch to render inlays in tests:\n" +
"project.isDisposed = ${file.project.isDisposed}\n" +
"inlays = ${inlays.joinToString { it.second }}\n" +
"errors = ${errors.joinToString()}"
)
if (inlays.isNotEmpty()) {
testPrint(
psiFile,
inlays.map { (expression, text) ->
"/** ${getLineInfo(psiFile, expression)} $text */"
},
)
inlays.clear()
}
if (inlays.isNotEmpty()) {
testPrint(psiFile, inlays.map { (expression, text) ->
"/** ${getLineInfo(psiFile, expression)} $text */"
})
inlays.clear()
}
if (errors.isNotEmpty()) {
testPrint(psiFile, listOf(errors.joinToString(prefix = "/** ", postfix = " */")))
errors.clear()
}
},
)
if (errors.isNotEmpty()) {
testPrint(psiFile, listOf(errors.joinToString(prefix = "/** ", postfix = " */")))
errors.clear()
}
})
}
private fun testPrint(file: PsiFile, comments: List<String>) {
@@ -276,7 +266,7 @@ private object TestOutputHandler : ScratchOutputHandlerAdapter() {
for (comment in comments) {
file.addAfter(
KtPsiFactory(file.project).createComment(comment),
file.lastChild,
file.lastChild
)
}
}

View File

@@ -0,0 +1,284 @@
/*
* 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.scratch.output
import com.intellij.execution.filters.OpenFileHyperlinkInfo
import com.intellij.execution.impl.ConsoleViewImpl
import com.intellij.execution.runners.ExecutionUtil
import com.intellij.execution.ui.ConsoleViewContentType
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.TransactionGuard
import com.intellij.openapi.command.WriteCommandAction
import com.intellij.openapi.editor.ex.EditorEx
import com.intellij.openapi.fileTypes.PlainTextFileType
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer
import com.intellij.openapi.wm.ToolWindow
import com.intellij.openapi.wm.ToolWindowAnchor
import com.intellij.openapi.wm.ToolWindowFactory
import com.intellij.openapi.wm.ToolWindowManager
import com.intellij.psi.PsiFile
import org.jetbrains.kotlin.idea.scratch.ScratchExpression
import org.jetbrains.kotlin.idea.scratch.ScratchFile
import org.jetbrains.kotlin.psi.KtPsiFactory
/**
* Method to retrieve shared instance of scratches ToolWindow output handler.
*
* [releaseToolWindowHandler] must be called for every output handler received from this method.
*
* Can be called from EDT only.
*
* @return new toolWindow output handler if one does not exist, otherwise returns the existing one. When application in test mode,
* returns [TestOutputHandler].
*/
fun requestToolWindowHandler(): ScratchOutputHandler {
return if (ApplicationManager.getApplication().isUnitTestMode) {
TestOutputHandler
} else {
ScratchToolWindowHandlerKeeper.requestOutputHandler()
}
}
/**
* Should be called once with the output handler received from the [requestToolWindowHandler] call.
*
* When release is called for every request, the output handler is actually disposed.
*
* When application in test mode, does nothing.
*
* Can be called from EDT only.
*/
fun releaseToolWindowHandler(scratchOutputHandler: ScratchOutputHandler) {
if (!ApplicationManager.getApplication().isUnitTestMode) {
ScratchToolWindowHandlerKeeper.releaseOutputHandler(scratchOutputHandler)
}
}
/**
* Implements logic of shared pointer for the toolWindow output handler.
*
* Not thread safe! Can be used only from the EDT.
*/
private object ScratchToolWindowHandlerKeeper {
private var toolWindowHandler: ScratchOutputHandler? = null
private var toolWindowDisposable = Disposer.newDisposable()
private var counter = 0
fun requestOutputHandler(): ScratchOutputHandler {
if (counter == 0) {
toolWindowHandler = ToolWindowScratchOutputHandler(toolWindowDisposable)
}
counter += 1
return toolWindowHandler!!
}
fun releaseOutputHandler(scratchOutputHandler: ScratchOutputHandler) {
require(counter > 0) { "Counter is $counter, nothing to release!" }
require(toolWindowHandler === scratchOutputHandler) { "$scratchOutputHandler differs from stored $toolWindowHandler" }
counter -= 1
if (counter == 0) {
Disposer.dispose(toolWindowDisposable)
toolWindowDisposable = Disposer.newDisposable()
toolWindowHandler = null
}
}
}
private class ToolWindowScratchOutputHandler(private val parentDisposable: Disposable) : ScratchOutputHandlerAdapter() {
override fun handle(file: ScratchFile, expression: ScratchExpression, output: ScratchOutput) {
printToConsole(file) {
val psiFile = file.getPsiFile()
if (psiFile != null) {
printHyperlink(
getLineInfo(psiFile, expression),
OpenFileHyperlinkInfo(
project,
psiFile.virtualFile,
expression.lineStart,
),
)
print(" ", ConsoleViewContentType.NORMAL_OUTPUT)
}
print(output.text, output.type.convert())
}
}
override fun error(file: ScratchFile, message: String) {
printToConsole(file) {
print(message, ConsoleViewContentType.ERROR_OUTPUT)
}
}
private fun printToConsole(file: ScratchFile, print: ConsoleViewImpl.() -> Unit) {
ApplicationManager.getApplication().invokeLater {
val project = file.project.takeIf { !it.isDisposed } ?: return@invokeLater
val toolWindow = getToolWindow(project) ?: createToolWindow(file)
val contents = toolWindow.contentManager.contents
for (content in contents) {
val component = content.component
if (component is ConsoleViewImpl) {
component.print()
component.print("\n", ConsoleViewContentType.NORMAL_OUTPUT)
}
}
toolWindow.setAvailable(true, null)
if (!file.options.isInteractiveMode) {
toolWindow.show(null)
}
toolWindow.icon = ExecutionUtil.getLiveIndicator(scratchIcon())
}
}
override fun clear(file: ScratchFile) {
ApplicationManager.getApplication().invokeLater {
val toolWindow = getToolWindow(file.project) ?: return@invokeLater
val contents = toolWindow.contentManager.contents
for (content in contents) {
val component = content.component
if (component is ConsoleViewImpl) {
component.clear()
}
}
if (!file.options.isInteractiveMode) {
toolWindow.hide(null)
}
toolWindow.icon = scratchIcon()
}
}
private fun ScratchOutputType.convert() = when (this) {
ScratchOutputType.OUTPUT -> ConsoleViewContentType.SYSTEM_OUTPUT
ScratchOutputType.RESULT -> ConsoleViewContentType.NORMAL_OUTPUT
ScratchOutputType.ERROR -> ConsoleViewContentType.ERROR_OUTPUT
}
private fun getToolWindow(project: Project): ToolWindow? {
val toolWindowManager = ToolWindowManager.getInstance(project)
return toolWindowManager.getToolWindow(ScratchToolWindowFactory.ID)
}
private fun createToolWindow(file: ScratchFile): ToolWindow {
val project = file.project
val toolWindowManager = ToolWindowManager.getInstance(project)
toolWindowManager.registerToolWindow(ScratchToolWindowFactory.ID, true, ToolWindowAnchor.BOTTOM)
val window = toolWindowManager.getToolWindow(ScratchToolWindowFactory.ID)
ScratchToolWindowFactory().createToolWindowContent(project, window)
Disposer.register(
parentDisposable,
Disposable {
toolWindowManager.unregisterToolWindow(ScratchToolWindowFactory.ID)
},
)
return window
}
}
private fun scratchIcon() = PlainTextFileType.INSTANCE.icon
private fun getLineInfo(psiFile: PsiFile, expression: ScratchExpression) =
"${psiFile.name}:${expression.lineStart + 1}"
private class ScratchToolWindowFactory : ToolWindowFactory {
companion object {
const val ID = "Scratch Output"
}
override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) {
val consoleView = ConsoleViewImpl(project, true)
toolWindow.isToHideOnEmptyContent = true
toolWindow.icon = scratchIcon()
toolWindow.hide(null)
val contentManager = toolWindow.contentManager
val content = contentManager.factory.createContent(consoleView.component, null, false)
contentManager.addContent(content)
val editor = consoleView.editor
if (editor is EditorEx) {
editor.isRendererMode = true
}
Disposer.register(project, consoleView)
}
}
private object TestOutputHandler : ScratchOutputHandlerAdapter() {
private val errors = arrayListOf<String>()
private val inlays = arrayListOf<Pair<ScratchExpression, String>>()
override fun handle(file: ScratchFile, expression: ScratchExpression, output: ScratchOutput) {
inlays.add(expression to output.text)
}
override fun error(file: ScratchFile, message: String) {
errors.add(message)
}
override fun onFinish(file: ScratchFile) {
TransactionGuard.submitTransaction(
file.project,
Runnable {
val psiFile = file.getPsiFile()
?: error(
"PsiFile cannot be found for scratch to render inlays in tests:\n" +
"project.isDisposed = ${file.project.isDisposed}\n" +
"inlays = ${inlays.joinToString { it.second }}\n" +
"errors = ${errors.joinToString()}",
)
if (inlays.isNotEmpty()) {
testPrint(
psiFile,
inlays.map { (expression, text) ->
"/** ${getLineInfo(psiFile, expression)} $text */"
},
)
inlays.clear()
}
if (errors.isNotEmpty()) {
testPrint(psiFile, listOf(errors.joinToString(prefix = "/** ", postfix = " */")))
errors.clear()
}
},
)
}
private fun testPrint(file: PsiFile, comments: List<String>) {
WriteCommandAction.runWriteCommandAction(file.project) {
for (comment in comments) {
file.addAfter(
KtPsiFactory(file.project).createComment(comment),
file.lastChild,
)
}
}
}
}

View File

@@ -22,7 +22,6 @@ import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.JBSplitter;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.idea.KotlinJvmBundle;
@@ -473,7 +472,6 @@ class SplitEditorToolbar extends JPanel implements Disposable {
}
@Deprecated
@ApiStatus.ScheduledForRemoval
public void addGutterToTrack(@NotNull EditorGutterComponentEx gutterComponentEx) {}
public void refresh() {
@@ -481,7 +479,6 @@ class SplitEditorToolbar extends JPanel implements Disposable {
}
@Deprecated
@ApiStatus.ScheduledForRemoval
@Override
public void dispose() {}
}

View File

@@ -0,0 +1,487 @@
/*
* 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.ui;
import com.intellij.codeHighlighting.BackgroundEditorHighlighter;
import com.intellij.icons.AllIcons;
import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.ex.EditorGutterComponentEx;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.ui.JBSplitter;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.idea.KotlinJvmBundle;
import javax.swing.*;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.HashMap;
import java.util.Map;
/**
* Two panel editor with three states: Editor, Preview and Editor with Preview.
* Based on SplitFileEditor by Valentin Fondaratov
* <p/>
* <b>NOTE:</b> This class is a copy of {@link com.intellij.openapi.fileEditor.TextEditorWithPreview} from the most recent intellij-community
* repository. We cannot use bundled version of this class because it doesn't yet have customization methods
* (namely {@link TextEditorWithPreview#createLeftToolbarActionGroup()}).
* <p/>
* {@link SplitEditorToolbar} is also copied from the platform.
* <p/>
* This class also may have some minimal customizations to allow tracking when its layout have been changed. In the future we hope to
* remove this copied class entirely and to use the bundled version.
*/
public class TextEditorWithPreview extends UserDataHolderBase implements FileEditor {
protected final TextEditor myEditor;
protected final FileEditor myPreview;
@NotNull
private final MyListenersMultimap myListenersGenerator = new MyListenersMultimap();
private Layout myLayout;
private JComponent myComponent;
private SplitEditorToolbar myToolbarWrapper;
private final String myName;
public TextEditorWithPreview(@NotNull TextEditor editor, @NotNull FileEditor preview, @NotNull String editorName) {
myEditor = editor;
myPreview = preview;
myName = editorName;
}
public TextEditorWithPreview(@NotNull TextEditor editor, @NotNull FileEditor preview) {
this(editor, preview, "TextEditorWithPreview");
}
@Nullable
@Override
public BackgroundEditorHighlighter getBackgroundHighlighter() {
return myEditor.getBackgroundHighlighter();
}
@Nullable
@Override
public FileEditorLocation getCurrentLocation() {
return myEditor.getCurrentLocation();
}
@Nullable
@Override
public StructureViewBuilder getStructureViewBuilder() {
return myEditor.getStructureViewBuilder();
}
@Override
public void dispose() {
Disposer.dispose(myEditor);
Disposer.dispose(myPreview);
}
@Override
public void selectNotify() {
myEditor.selectNotify();
myPreview.selectNotify();
}
@Override
public void deselectNotify() {
myEditor.deselectNotify();
myPreview.deselectNotify();
}
@NotNull
@Override
public JComponent getComponent() {
if (myComponent == null) {
final JBSplitter splitter = new JBSplitter(false, 0.5f, 0.15f, 0.85f);
splitter.setSplitterProportionKey(getSplitterProportionKey());
splitter.setFirstComponent(myEditor.getComponent());
splitter.setSecondComponent(myPreview.getComponent());
splitter.setDividerWidth(3);
myToolbarWrapper = createMarkdownToolbarWrapper(splitter);
Disposer.register(this, myToolbarWrapper);
if (myLayout == null) {
String lastUsed = PropertiesComponent.getInstance().getValue(getLayoutPropertyName());
setLayout(Layout.fromName(lastUsed, Layout.SHOW_EDITOR_AND_PREVIEW));
}
adjustEditorsVisibility();
myComponent = JBUI.Panels.simplePanel(splitter).addToTop(myToolbarWrapper);
}
return myComponent;
}
@NotNull
private SplitEditorToolbar createMarkdownToolbarWrapper (@NotNull JComponent targetComponentForActions) {
final ActionToolbar leftToolbar = createToolbar();
if (leftToolbar != null) {
leftToolbar.setTargetComponent(targetComponentForActions);
leftToolbar.setReservePlaceAutoPopupIcon(false);
}
final ActionToolbar rightToolbar = createRightToolbar();
rightToolbar.setTargetComponent(targetComponentForActions);
rightToolbar.setReservePlaceAutoPopupIcon(false);
return new SplitEditorToolbar(leftToolbar, rightToolbar);
}
@Override
public void setState(@NotNull FileEditorState state) {
if (state instanceof MyFileEditorState) {
final MyFileEditorState compositeState = (MyFileEditorState)state;
if (compositeState.getFirstState() != null) {
myEditor.setState(compositeState.getFirstState());
}
if (compositeState.getSecondState() != null) {
myPreview.setState(compositeState.getSecondState());
}
if (compositeState.getSplitLayout() != null) {
setLayout(compositeState.getSplitLayout());
invalidateLayout();
}
}
}
private void adjustEditorsVisibility() {
myEditor.getComponent().setVisible(myLayout == Layout.SHOW_EDITOR || myLayout == Layout.SHOW_EDITOR_AND_PREVIEW);
myPreview.getComponent().setVisible(myLayout == Layout.SHOW_PREVIEW || myLayout == Layout.SHOW_EDITOR_AND_PREVIEW);
}
private void invalidateLayout() {
adjustEditorsVisibility();
myToolbarWrapper.refresh();
myComponent.repaint();
final JComponent focusComponent = getPreferredFocusedComponent();
if (focusComponent != null) {
IdeFocusManager.findInstanceByComponent(focusComponent).requestFocus(focusComponent, true);
}
}
@NotNull
protected String getSplitterProportionKey() {
return "TextEditorWithPreview.SplitterProportionKey";
}
@Nullable
@Override
public JComponent getPreferredFocusedComponent() {
switch (myLayout) {
case SHOW_EDITOR_AND_PREVIEW:
case SHOW_EDITOR:
return myEditor.getPreferredFocusedComponent();
case SHOW_PREVIEW:
return myPreview.getPreferredFocusedComponent();
default:
throw new IllegalStateException(myLayout.myName);
}
}
@NotNull
@Override
public String getName() {
return myName;
}
@NotNull
@Override
public FileEditorState getState(@NotNull FileEditorStateLevel level) {
return new MyFileEditorState(myLayout, myEditor.getState(level), myPreview.getState(level));
}
@Override
public void addPropertyChangeListener(@NotNull PropertyChangeListener listener) {
myEditor.addPropertyChangeListener(listener);
myPreview.addPropertyChangeListener(listener);
final DoublingEventListenerDelegate delegate = myListenersGenerator.addListenerAndGetDelegate(listener);
myEditor.addPropertyChangeListener(delegate);
myPreview.addPropertyChangeListener(delegate);
}
@Override
public void removePropertyChangeListener(@NotNull PropertyChangeListener listener) {
myEditor.removePropertyChangeListener(listener);
myPreview.removePropertyChangeListener(listener);
final DoublingEventListenerDelegate delegate = myListenersGenerator.removeListenerAndGetDelegate(listener);
if (delegate != null) {
myEditor.removePropertyChangeListener(delegate);
myPreview.removePropertyChangeListener(delegate);
}
}
@NotNull
public TextEditor getTextEditor() {
return myEditor;
}
public Layout getLayout() {
return myLayout;
}
protected void setLayout(@NotNull Layout layout) {
myLayout = layout;
}
static class MyFileEditorState implements FileEditorState {
private final Layout mySplitLayout;
private final FileEditorState myFirstState;
private final FileEditorState mySecondState;
MyFileEditorState(Layout layout, FileEditorState firstState, FileEditorState secondState) {
mySplitLayout = layout;
myFirstState = firstState;
mySecondState = secondState;
}
@Nullable
public Layout getSplitLayout() {
return mySplitLayout;
}
@Nullable
public FileEditorState getFirstState() {
return myFirstState;
}
@Nullable
public FileEditorState getSecondState() {
return mySecondState;
}
@Override
public boolean canBeMergedWith(FileEditorState otherState, FileEditorStateLevel level) {
return otherState instanceof MyFileEditorState
&& (myFirstState == null || myFirstState.canBeMergedWith(((MyFileEditorState)otherState).myFirstState, level))
&& (mySecondState == null || mySecondState.canBeMergedWith(((MyFileEditorState)otherState).mySecondState, level));
}
}
@Override
public boolean isModified() {
return myEditor.isModified() || myPreview.isModified();
}
@Override
public boolean isValid() {
return myEditor.isValid() && myPreview.isValid();
}
private class DoublingEventListenerDelegate implements PropertyChangeListener {
@NotNull
private final PropertyChangeListener myDelegate;
private DoublingEventListenerDelegate(@NotNull PropertyChangeListener delegate) {
myDelegate = delegate;
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
myDelegate.propertyChange(
new PropertyChangeEvent(TextEditorWithPreview.this, evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()));
}
}
private class MyListenersMultimap {
private final Map<PropertyChangeListener, Pair<Integer, DoublingEventListenerDelegate>> myMap = new HashMap<>();
@NotNull
public DoublingEventListenerDelegate addListenerAndGetDelegate(@NotNull PropertyChangeListener listener) {
if (!myMap.containsKey(listener)) {
myMap.put(listener, Pair.create(1, new DoublingEventListenerDelegate(listener)));
}
else {
final Pair<Integer, DoublingEventListenerDelegate> oldPair = myMap.get(listener);
myMap.put(listener, Pair.create(oldPair.getFirst() + 1, oldPair.getSecond()));
}
return myMap.get(listener).getSecond();
}
@Nullable
public DoublingEventListenerDelegate removeListenerAndGetDelegate(@NotNull PropertyChangeListener listener) {
final Pair<Integer, DoublingEventListenerDelegate> oldPair = myMap.get(listener);
if (oldPair == null) {
return null;
}
if (oldPair.getFirst() == 1) {
myMap.remove(listener);
}
else {
myMap.put(listener, Pair.create(oldPair.getFirst() - 1, oldPair.getSecond()));
}
return oldPair.getSecond();
}
}
@Nullable
protected ActionToolbar createToolbar() {
ActionGroup actionGroup = createLeftToolbarActionGroup();
if (actionGroup != null) {
return ActionManager.getInstance().createActionToolbar("TextEditorWithPreview", actionGroup, true);
}
else {
return null;
}
}
@Nullable
protected ActionGroup createLeftToolbarActionGroup() {
return null;
}
@NotNull
private ActionToolbar createRightToolbar() {
final ActionGroup viewActions = createViewActionGroup();
final ActionGroup group = createRightToolbarActionGroup();
final ActionGroup rightToolbarActions = group == null
? viewActions
: new DefaultActionGroup(group, Separator.create(), viewActions);
return ActionManager.getInstance().createActionToolbar("TextEditorWithPreview", rightToolbarActions, true);
}
@NotNull
protected ActionGroup createViewActionGroup() {
return new DefaultActionGroup(
getShowEditorAction(),
getShowEditorAndPreviewAction(),
getShowPreviewAction()
);
}
@Nullable
protected ActionGroup createRightToolbarActionGroup() {
return null;
}
@NotNull
protected ToggleAction getShowEditorAction() {
return new ChangeViewModeAction(Layout.SHOW_EDITOR);
}
@NotNull
protected ToggleAction getShowPreviewAction() {
return new ChangeViewModeAction(Layout.SHOW_PREVIEW);
}
@NotNull
protected ToggleAction getShowEditorAndPreviewAction() {
return new ChangeViewModeAction(Layout.SHOW_EDITOR_AND_PREVIEW);
}
public enum Layout {
SHOW_EDITOR(KotlinJvmBundle.message("editor.editor.only"), AllIcons.General.LayoutEditorOnly),
SHOW_PREVIEW(KotlinJvmBundle.message("editor.preview.only"), AllIcons.General.LayoutPreviewOnly),
SHOW_EDITOR_AND_PREVIEW(KotlinJvmBundle.message("editor.editor.and.preview"), AllIcons.General.LayoutEditorPreview);
private final String myName;
private final Icon myIcon;
Layout(String name, Icon icon) {
myName = name;
myIcon = icon;
}
public static Layout fromName(String name, Layout defaultValue) {
for (Layout layout : Layout.values()) {
if (layout.myName.equals(name)) {
return layout;
}
}
return defaultValue;
}
public String getName() {
return myName;
}
public Icon getIcon() {
return myIcon;
}
}
private class ChangeViewModeAction extends ToggleAction implements DumbAware {
private final Layout myActionLayout;
ChangeViewModeAction(Layout layout) {
super(layout.getName(), layout.getName(), layout.getIcon());
myActionLayout = layout;
}
@Override
public boolean isSelected(@NotNull AnActionEvent e) {
return myLayout == myActionLayout;
}
@Override
public void setSelected(@NotNull AnActionEvent e, boolean state) {
if (state) {
setLayout(myActionLayout);
PropertiesComponent.getInstance().setValue(getLayoutPropertyName(), myLayout.myName, Layout.SHOW_EDITOR_AND_PREVIEW.myName);
adjustEditorsVisibility();
}
}
}
@NotNull
private String getLayoutPropertyName() {
return myName + "Layout";
}
}
class SplitEditorToolbar extends JPanel implements Disposable {
private final ActionToolbar myRightToolbar;
public SplitEditorToolbar(@Nullable ActionToolbar leftToolbar, @NotNull ActionToolbar rightToolbar) {
super(new GridBagLayout());
myRightToolbar = rightToolbar;
if (leftToolbar != null) {
add(leftToolbar.getComponent());
}
final JPanel centerPanel = new JPanel(new BorderLayout());
add(centerPanel, new GridBagConstraints(2, 0, 1, 1, 1.0, 1.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH, JBUI.emptyInsets(), 0, 0));
add(myRightToolbar.getComponent());
setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, UIUtil.CONTRAST_BORDER_COLOR));
if (leftToolbar != null) leftToolbar.updateActionsImmediately();
rightToolbar.updateActionsImmediately();
}
@Deprecated
@ApiStatus.ScheduledForRemoval
public void addGutterToTrack(@NotNull EditorGutterComponentEx gutterComponentEx) {}
public void refresh() {
myRightToolbar.updateActionsImmediately();
}
@Deprecated
@ApiStatus.ScheduledForRemoval
@Override
public void dispose() {}
}

View File

@@ -11,5 +11,5 @@ import com.intellij.openapi.project.Project
// FIX ME WHEN BUNCH 193 REMOVED
fun setTemplateTestingCompat(project: Project, disposable: Disposable) {
TemplateManagerImpl.setTemplateTesting(project, disposable)
TemplateManagerImpl.setTemplateTesting(disposable)
}

View File

@@ -0,0 +1,15 @@
/*
* 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.liveTemplates
import com.intellij.codeInsight.template.impl.TemplateManagerImpl
import com.intellij.openapi.Disposable
import com.intellij.openapi.project.Project
// FIX ME WHEN BUNCH 193 REMOVED
fun setTemplateTestingCompat(project: Project, disposable: Disposable) {
TemplateManagerImpl.setTemplateTesting(project, disposable)
}

View File

@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.isGradle
import org.jetbrains.plugins.gradle.service.project.open.linkAndRefreshGradleProject
import java.nio.file.Path
// FIX ME WHEN BUNCH 201 REMOVED
class IdeaGradleWizardService(private val project: Project) : ProjectImportingWizardService,
IdeaWizardService {
override fun isSuitableFor(buildSystemType: BuildSystemType): Boolean =

View File

@@ -0,0 +1,47 @@
/*
* 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.openapi.project.Project
import org.jetbrains.kotlin.tools.projectWizard.core.Reader
import org.jetbrains.kotlin.tools.projectWizard.core.TaskResult
import org.jetbrains.kotlin.tools.projectWizard.core.UNIT_SUCCESS
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.service.project.open.linkAndRefreshGradleProject
import java.nio.file.Path
class IdeaGradleWizardService(private val project: Project) : ProjectImportingWizardService,
IdeaWizardService {
override fun isSuitableFor(buildSystemType: BuildSystemType): Boolean =
buildSystemType.isGradle
override fun importProject(
reader: Reader,
path: Path,
modulesIrs: List<ModuleIR>,
buildSystem: BuildSystemType
): TaskResult<Unit> {
withGradleWrapperEnabled {
linkAndRefreshGradleProject(path.toString(), project)
}
return UNIT_SUCCESS
}
private fun withGradleWrapperEnabled(action: () -> Unit) {
val oldGradleDistributionType = System.getProperty("idea.gradle.distributionType")
System.setProperty("idea.gradle.distributionType", "WRAPPED")
try {
action()
} finally {
if (oldGradleDistributionType != null) {
System.setProperty("idea.gradle.distributionType", oldGradleDistributionType)
}
}
}
}

View File

@@ -41,12 +41,14 @@ class ConsoleCompilerHelper(
}
fun compileModule() {
if (ExecutionManager.getInstance(project).contentManager.removeRunContent(executor, contentDescriptor)) {
ProjectTaskManager.getInstance(project).build(module).onSuccess { executionResult ->
if (!module.isDisposed) {
KotlinConsoleKeeper.getInstance(project).run(module, previousCompilationFailed = executionResult.hasErrors())
if (ExecutionManager.getInstance(project).getContentManager().removeRunContent(executor, contentDescriptor)) {
ProjectTaskManager.getInstance(project).build(arrayOf(module), object : ProjectTaskNotification {
override fun finished(context: ProjectTaskContext, executionResult: ProjectTaskResult) {
if (!module.isDisposed) {
KotlinConsoleKeeper.getInstance(project).run(module, previousCompilationFailed = executionResult.errors > 0)
}
}
}
})
}
}
}

View File

@@ -0,0 +1,52 @@
/*
* 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.console
import com.intellij.execution.ExecutionManager
import com.intellij.execution.Executor
import com.intellij.execution.ui.RunContentDescriptor
import com.intellij.openapi.compiler.CompilerManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.task.ProjectTaskContext
import com.intellij.task.ProjectTaskManager
import com.intellij.task.ProjectTaskNotification
import com.intellij.task.ProjectTaskResult
class ConsoleCompilerHelper(
private val project: Project,
private val module: Module,
private val executor: Executor,
private val contentDescriptor: RunContentDescriptor
) {
fun moduleIsUpToDate(): Boolean {
val compilerManager = CompilerManager.getInstance(project)
val compilerScope = compilerManager.createModuleCompileScope(module, true)
return compilerManager.isUpToDate(compilerScope)
}
fun compileModule() {
if (ExecutionManager.getInstance(project).contentManager.removeRunContent(executor, contentDescriptor)) {
ProjectTaskManager.getInstance(project).build(module).onSuccess { executionResult ->
if (!module.isDisposed) {
KotlinConsoleKeeper.getInstance(project).run(module, previousCompilationFailed = executionResult.hasErrors())
}
}
}
}
}

View File

@@ -25,6 +25,7 @@ import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.testFramework.IdeaTestUtil;
import kotlin.jvm.functions.Function0;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.TestOnly;
@@ -49,7 +50,7 @@ public class PluginTestCaseBase {
@NotNull
@TestOnly
private static Sdk createMockJdk(@NotNull String name, String path) {
return ((JavaSdkImpl)JavaSdk.getInstance()).createMockJdk(name, path, false);
return IdeaTestUtil.createMockJdk(name, path, false);
}
@NotNull

View File

@@ -17,5 +17,4 @@ fun editorTrackerProjectOpened(project: Project) {
// FIX ME WHEN BUNCH 193 REMOVED
fun runPostStartupActivitiesOnce(project: Project) {
(StartupManager.getInstance(project) as StartupManagerImpl).runPostStartupActivities()
}
}

View File

@@ -0,0 +1,21 @@
/*
* 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.codeInsight.daemon.impl.EditorTracker
import com.intellij.ide.startup.impl.StartupManagerImpl
import com.intellij.openapi.project.Project
import com.intellij.openapi.startup.StartupManager
// FIX ME WHEN BUNCH 192 REMOVED
fun editorTrackerProjectOpened(project: Project) {
EditorTracker.getInstance(project)
}
// FIX ME WHEN BUNCH 193 REMOVED
fun runPostStartupActivitiesOnce(project: Project) {
(StartupManager.getInstance(project) as StartupManagerImpl).runPostStartupActivities()
}

View File

@@ -6,20 +6,22 @@
package org.jetbrains.kotlin.idea.debugger.coroutine.data
import com.intellij.debugger.engine.DebugProcessImpl
import com.intellij.debugger.engine.JVMStackFrameInfoProvider
import com.intellij.debugger.engine.JavaStackFrame
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
import com.intellij.debugger.jdi.StackFrameProxyImpl
import com.intellij.debugger.memory.utils.StackFrameItem
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener
import com.intellij.xdebugger.XSourcePosition
import com.intellij.xdebugger.frame.XCompositeNode
import com.intellij.xdebugger.frame.XNamedValue
import com.intellij.xdebugger.frame.XStackFrame
import com.intellij.xdebugger.frame.XValueChildrenList
import com.intellij.xdebugger.impl.frame.XDebuggerFramesList
import com.sun.jdi.Location
import org.jetbrains.kotlin.idea.debugger.*
import org.jetbrains.kotlin.idea.debugger.coroutine.KotlinDebuggerCoroutinesBundle
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.LocationStackFrameProxyImpl
import org.jetbrains.kotlin.idea.debugger.coroutine.util.findPosition
import org.jetbrains.kotlin.idea.debugger.coroutine.util.isFilteredInvokeSuspend
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
import org.jetbrains.kotlin.idea.debugger.stackFrame.KotlinStackFrame
@@ -32,12 +34,12 @@ class CreationCoroutineStackFrameItem(
val first: Boolean
) : CoroutineStackFrameItem(location, emptyList()) {
override fun createFrame(debugProcess: DebugProcessImpl): CoroutineGeneratedFrame? {
override fun createFrame(debugProcess: DebugProcessImpl): XStackFrame? {
return debugProcess.invokeInManagerThread {
val frame = debugProcess.findFirstFrame() ?: return@invokeInManagerThread null
val locationFrame = LocationStackFrameProxyImpl(location, frame)
val position = location.findPosition(debugProcess.project)
CreationCoroutineStackFrame(debugProcess, this, first)
CreationCoroutineStackFrame(locationFrame, position, first)
}
}
}
@@ -51,18 +53,19 @@ class SuspendCoroutineStackFrameItem(
spilledVariables: List<XNamedValue> = emptyList()
) : CoroutineStackFrameItem(location, spilledVariables)
/**
* Restored from memory dump
*/
class DefaultCoroutineStackFrameItem(location: Location, spilledVariables: List<XNamedValue>) :
CoroutineStackFrameItem(location, spilledVariables) {
override fun createFrame(debugProcess: DebugProcessImpl): CoroutineGeneratedFrame? {
override fun createFrame(debugProcess: DebugProcessImpl): XStackFrame? {
return debugProcess.invokeInManagerThread {
val frame = debugProcess.findFirstFrame() ?: return@invokeInManagerThread null
val locationStackFrameProxyImpl = LocationStackFrameProxyImpl(location, frame)
val position = location.findPosition(debugProcess.project) ?: return@invokeInManagerThread null
CoroutineStackFrame(debugProcess, this)
CoroutineStackFrame(locationStackFrameProxyImpl, position, spilledVariables, false)
}
}
}
@@ -82,24 +85,25 @@ class DefaultCoroutineStackFrameItem(location: Location, spilledVariables: List<
open class RunningCoroutineStackFrameItem(
val frame: StackFrameProxyImpl,
spilledVariables: List<XNamedValue> = emptyList()
) : CoroutineStackFrameItem(frame.location(), spilledVariables), FrameProvider {
override fun createFrame(debugProcess: DebugProcessImpl): CoroutineGeneratedFrame? {
) : CoroutineStackFrameItem(frame.location(), spilledVariables) {
override fun createFrame(debugProcess: DebugProcessImpl): XStackFrame? {
return debugProcess.invokeInManagerThread {
CoroutineStackFrame(debugProcess, this)
val position = frame.location().findPosition(debugProcess.project)
CoroutineStackFrame(frame, position)
}
}
override fun provideFrame(debugProcess: DebugProcessImpl): XStackFrame? =
debugProcess.invokeInManagerThread { KotlinStackFrame(frame) }
}
sealed class CoroutineStackFrameItem(val location: Location, val spilledVariables: List<XNamedValue>) :
StackFrameItem(location, spilledVariables) {
val log by logger
override fun createFrame(debugProcess: DebugProcessImpl): CoroutineGeneratedFrame? {
override fun createFrame(debugProcess: DebugProcessImpl): XStackFrame? {
return debugProcess.invokeInManagerThread {
CoroutineStackFrame(debugProcess, this)
val frame = debugProcess.findFirstFrame() ?: return@invokeInManagerThread null
val locationFrame = LocationStackFrameProxyImpl(location, frame)
val position = location.findPosition(debugProcess.project)
CoroutineStackFrame(locationFrame, position)
}
}
@@ -108,10 +112,6 @@ sealed class CoroutineStackFrameItem(val location: Location, val spilledVariable
location.safeLineNumber() + ":" + location.safeKotlinPreferredLineNumber()
}
interface FrameProvider {
fun provideFrame(debugProcess: DebugProcessImpl): XStackFrame?
}
fun DebugProcessImpl.findFirstFrame(): StackFrameProxyImpl? =
suspendManager.pausedContext.thread?.forceFrames()?.firstOrNull()
@@ -123,19 +123,71 @@ fun DebugProcessImpl.findFirstFrame(): StackFrameProxyImpl? =
*/
class CoroutinePreflightFrame(
val coroutineInfoData: CoroutineInfoData,
private val frame: StackFrameProxyImpl,
val frame: StackFrameProxyImpl,
val threadPreCoroutineFrames: List<StackFrameProxyImpl>,
val mode: SuspendExitMode
) : KotlinStackFrame(frame), JVMStackFrameInfoProvider {
val mode: SuspendExitMode,
private val firstFrameVariables: List<XNamedValue> = coroutineInfoData.topFrameVariables()
) : CoroutineStackFrame(frame, null, firstFrameVariables) {
override fun isInLibraryContent() = false
override fun isSynthetic() = false
}
class CreationCoroutineStackFrame(
frame: StackFrameProxyImpl,
sourcePosition: XSourcePosition?,
val first: Boolean
) : CoroutineStackFrame(frame, sourcePosition, emptyList(), false), XDebuggerFramesList.ItemWithSeparatorAbove {
override fun getCaptionAboveOf() =
KotlinDebuggerCoroutinesBundle.message("coroutine.dump.creation.trace")
override fun hasSeparatorAbove() =
first
}
open class CoroutineStackFrame(
frame: StackFrameProxyImpl,
val position: XSourcePosition?,
private val spilledVariables: List<XNamedValue>? = null,
private val includeFrameVariables: Boolean = true,
) : KotlinStackFrame(frame) {
init {
descriptor.updateRepresentation(null, DescriptorLabelListener.DUMMY_LISTENER)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
val frame = other as? JavaStackFrame ?: return false
return descriptor.frameProxy == frame.descriptor.frameProxy
}
override fun hashCode(): Int {
return descriptor.frameProxy.hashCode()
}
override fun computeChildren(node: XCompositeNode) {
if (includeFrameVariables || spilledVariables == null) {
super.computeChildren(node)
} else {
// ignore original frame variables
val list = XValueChildrenList()
spilledVariables.forEach { list.add(it) }
node.addChildren(list, true)
}
}
override fun superBuildVariables(evaluationContext: EvaluationContextImpl, children: XValueChildrenList) {
super.superBuildVariables(evaluationContext, children)
val topRestoredFrame = coroutineInfoData.stackTrace.firstOrNull()
if (topRestoredFrame != null && topRestoredFrame.location.isFilteredInvokeSuspend()) {
val firstFrameVariables: List<XNamedValue> = topRestoredFrame.spilledVariables
if (spilledVariables != null) {
children.let {
val varNames = (0 until children.size()).map { children.getName(it) }.toSet()
firstFrameVariables.forEach {
spilledVariables.forEach {
if (!varNames.contains(it.name))
children.add(it)
}
@@ -143,32 +195,6 @@ class CoroutinePreflightFrame(
}
}
override fun isInLibraryContent() = false
override fun isSynthetic() = false
}
class CreationCoroutineStackFrame(debugProcess: DebugProcessImpl, item: CoroutineStackFrameItem, val first: Boolean) : CoroutineStackFrame(debugProcess, item) {
override fun getCaptionAboveOf() = KotlinDebuggerCoroutinesBundle.message("coroutine.dump.creation.trace")
override fun hasSeparatorAbove(): Boolean =
first
}
open class CoroutineStackFrame(val debugProcess: DebugProcessImpl, val item: CoroutineStackFrameItem) :
StackFrameItem.CapturedStackFrame(debugProcess, item) {
override fun computeChildren(node: XCompositeNode) {
if (item is FrameProvider)
item.provideFrame(debugProcess)?.computeChildren(node)
else
super.computeChildren(node)
}
override fun getCaptionAboveOf() = "CoroutineExit"
override fun hasSeparatorAbove(): Boolean =
false
}
typealias CoroutineGeneratedFrame = StackFrameItem.CapturedStackFrame
override fun getSourcePosition() =
position ?: super.getSourcePosition()
}

View File

@@ -0,0 +1,174 @@
/*
* 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.data
import com.intellij.debugger.engine.DebugProcessImpl
import com.intellij.debugger.engine.JVMStackFrameInfoProvider
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl
import com.intellij.debugger.jdi.StackFrameProxyImpl
import com.intellij.debugger.memory.utils.StackFrameItem
import com.intellij.xdebugger.frame.XCompositeNode
import com.intellij.xdebugger.frame.XNamedValue
import com.intellij.xdebugger.frame.XStackFrame
import com.intellij.xdebugger.frame.XValueChildrenList
import com.sun.jdi.Location
import org.jetbrains.kotlin.idea.debugger.*
import org.jetbrains.kotlin.idea.debugger.coroutine.KotlinDebuggerCoroutinesBundle
import org.jetbrains.kotlin.idea.debugger.coroutine.proxy.LocationStackFrameProxyImpl
import org.jetbrains.kotlin.idea.debugger.coroutine.util.findPosition
import org.jetbrains.kotlin.idea.debugger.coroutine.util.isFilteredInvokeSuspend
import org.jetbrains.kotlin.idea.debugger.coroutine.util.logger
import org.jetbrains.kotlin.idea.debugger.stackFrame.KotlinStackFrame
/**
* Creation frame of coroutine either in RUNNING or SUSPENDED state.
*/
class CreationCoroutineStackFrameItem(
val stackTraceElement: StackTraceElement,
location: Location,
val first: Boolean
) : CoroutineStackFrameItem(location, emptyList()) {
override fun createFrame(debugProcess: DebugProcessImpl): CoroutineGeneratedFrame? {
return debugProcess.invokeInManagerThread {
val frame = debugProcess.findFirstFrame() ?: return@invokeInManagerThread null
val locationFrame = LocationStackFrameProxyImpl(location, frame)
val position = location.findPosition(debugProcess.project)
CreationCoroutineStackFrame(debugProcess, this, first)
}
}
}
/**
* Restored frame in SUSPENDED coroutine, not attached to any thread.
*/
class SuspendCoroutineStackFrameItem(
val stackTraceElement: StackTraceElement,
location: Location,
spilledVariables: List<XNamedValue> = emptyList()
) : CoroutineStackFrameItem(location, spilledVariables)
/**
* Restored from memory dump
*/
class DefaultCoroutineStackFrameItem(location: Location, spilledVariables: List<XNamedValue>) :
CoroutineStackFrameItem(location, spilledVariables) {
override fun createFrame(debugProcess: DebugProcessImpl): CoroutineGeneratedFrame? {
return debugProcess.invokeInManagerThread {
val frame = debugProcess.findFirstFrame() ?: return@invokeInManagerThread null
val locationStackFrameProxyImpl = LocationStackFrameProxyImpl(location, frame)
val position = location.findPosition(debugProcess.project) ?: return@invokeInManagerThread null
CoroutineStackFrame(debugProcess, this)
}
}
}
/**
* Original frame appeared before resumeWith call.
*
* Sequence is the following
*
* - KotlinStackFrame
* - invokeSuspend(KotlinStackFrame) -|
* | replaced with CoroutinePreflightStackFrame
* - resumeWith(KotlinStackFrame) ----|
* - Kotlin/JavaStackFrame -> PreCoroutineStackFrameItem : CoroutinePreflightStackFrame.threadPreCoroutineFrames
*
*/
open class RunningCoroutineStackFrameItem(
val frame: StackFrameProxyImpl,
spilledVariables: List<XNamedValue> = emptyList()
) : CoroutineStackFrameItem(frame.location(), spilledVariables), FrameProvider {
override fun createFrame(debugProcess: DebugProcessImpl): CoroutineGeneratedFrame? {
return debugProcess.invokeInManagerThread {
CoroutineStackFrame(debugProcess, this)
}
}
override fun provideFrame(debugProcess: DebugProcessImpl): XStackFrame? =
debugProcess.invokeInManagerThread { KotlinStackFrame(frame) }
}
sealed class CoroutineStackFrameItem(val location: Location, val spilledVariables: List<XNamedValue>) :
StackFrameItem(location, spilledVariables) {
val log by logger
override fun createFrame(debugProcess: DebugProcessImpl): CoroutineGeneratedFrame? {
return debugProcess.invokeInManagerThread {
CoroutineStackFrame(debugProcess, this)
}
}
fun uniqueId() =
location.safeSourceName() + ":" + location.safeMethod().toString() + ":" +
location.safeLineNumber() + ":" + location.safeKotlinPreferredLineNumber()
}
interface FrameProvider {
fun provideFrame(debugProcess: DebugProcessImpl): XStackFrame?
}
fun DebugProcessImpl.findFirstFrame(): StackFrameProxyImpl? =
suspendManager.pausedContext.thread?.forceFrames()?.firstOrNull()
/**
* Coroutine exit frame represented by a stack frames
* invokeSuspend():-1
* resumeWith()
*
*/
class CoroutinePreflightFrame(
val coroutineInfoData: CoroutineInfoData,
private val frame: StackFrameProxyImpl,
val threadPreCoroutineFrames: List<StackFrameProxyImpl>,
val mode: SuspendExitMode
) : KotlinStackFrame(frame), JVMStackFrameInfoProvider {
override fun superBuildVariables(evaluationContext: EvaluationContextImpl, children: XValueChildrenList) {
super.superBuildVariables(evaluationContext, children)
val topRestoredFrame = coroutineInfoData.stackTrace.firstOrNull()
if (topRestoredFrame != null && topRestoredFrame.location.isFilteredInvokeSuspend()) {
val firstFrameVariables: List<XNamedValue> = topRestoredFrame.spilledVariables
children.let {
val varNames = (0 until children.size()).map { children.getName(it) }.toSet()
firstFrameVariables.forEach {
if (!varNames.contains(it.name))
children.add(it)
}
}
}
}
override fun isInLibraryContent() = false
override fun isSynthetic() = false
}
class CreationCoroutineStackFrame(debugProcess: DebugProcessImpl, item: CoroutineStackFrameItem, val first: Boolean) : CoroutineStackFrame(debugProcess, item) {
override fun getCaptionAboveOf() = KotlinDebuggerCoroutinesBundle.message("coroutine.dump.creation.trace")
override fun hasSeparatorAbove(): Boolean =
first
}
open class CoroutineStackFrame(val debugProcess: DebugProcessImpl, val item: CoroutineStackFrameItem) :
StackFrameItem.CapturedStackFrame(debugProcess, item) {
override fun computeChildren(node: XCompositeNode) {
if (item is FrameProvider)
item.provideFrame(debugProcess)?.computeChildren(node)
else
super.computeChildren(node)
}
override fun getCaptionAboveOf() = "CoroutineExit"
override fun hasSeparatorAbove(): Boolean =
false
}
typealias CoroutineGeneratedFrame = StackFrameItem.CapturedStackFrame

View File

@@ -11,8 +11,8 @@ import com.intellij.openapi.project.ex.ProjectManagerEx
// FIX ME WHEN BUNCH 193 REMOVED
fun ProjectManagerEx.forceCloseProjectEx(project: Project, dispose: Boolean): Boolean {
if (!dispose) error("dispose should be true")
return this.forceCloseProject(project, true)
return this.forceCloseProject(project)
}
// FIX ME WHEN BUNCH 193 REMOVED
typealias TestApplicationManager = com.intellij.idea.IdeaTestApplication
typealias TestApplicationManager = com.intellij.testFramework.TestApplicationManager

View File

@@ -0,0 +1,18 @@
/*
* 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.testFramework
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ex.ProjectManagerEx
// FIX ME WHEN BUNCH 193 REMOVED
fun ProjectManagerEx.forceCloseProjectEx(project: Project, dispose: Boolean): Boolean {
if (!dispose) error("dispose should be true")
return this.forceCloseProject(project, true)
}
// FIX ME WHEN BUNCH 193 REMOVED
typealias TestApplicationManager = com.intellij.idea.IdeaTestApplication

View File

@@ -13,11 +13,13 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import org.gradle.util.GradleVersion
import org.jetbrains.plugins.gradle.service.project.open.setupGradleSettings
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
import org.jetbrains.plugins.gradle.settings.GradleSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import org.jetbrains.plugins.gradle.util.GradleLog
import org.jetbrains.plugins.gradle.util.suggestGradleVersion
import java.io.File
import kotlin.test.assertNotNull
@@ -34,14 +36,13 @@ const val GRADLE_JDK_NAME = "Gradle JDK"
*/
private fun _importProject(projectPath: String, project: Project) {
GradleLog.LOG.info("Import project at $projectPath")
val projectSdk = ProjectRootManager.getInstance(project).projectSdk
assertNotNull(projectSdk, "project SDK not found for ${project.name} at $projectPath")
val gradleProjectSettings = GradleProjectSettings()
val gradleVersion = suggestGradleVersion(project) ?: GradleVersion.current()
GradleSettings.getInstance(project).gradleVmOptions =
"-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${System.getProperty("user.dir")}"
setupGradleSettings(gradleProjectSettings, projectPath, project, projectSdk)
setupGradleSettings(project, gradleProjectSettings, projectPath, gradleVersion)
gradleProjectSettings.gradleJvm = GRADLE_JDK_NAME
GradleSettings.getInstance(project).getLinkedProjectSettings(projectPath)?.let { linkedProjectSettings ->
@@ -65,8 +66,6 @@ private fun _attachGradleProjectAndRefresh(
ExternalSystemUtil.ensureToolWindowInitialized(project, GradleConstants.SYSTEM_ID)
}
}
ExternalProjectsManagerImpl.disableProjectWatcherAutoUpdate(project)
val settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
if (settings.getLinkedProjectSettings(externalProjectPath) == null) {
settings.linkProject(gradleProjectSettings)

View File

@@ -0,0 +1,84 @@
/*
* 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.service.project.manage.ExternalProjectsManagerImpl
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import org.jetbrains.plugins.gradle.service.project.open.setupGradleSettings
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings
import org.jetbrains.plugins.gradle.settings.GradleSettings
import org.jetbrains.plugins.gradle.util.GradleConstants
import org.jetbrains.plugins.gradle.util.GradleLog
import java.io.File
import kotlin.test.assertNotNull
fun refreshGradleProject(projectPath: String, project: Project) {
_importProject(File(projectPath).absolutePath, project)
dispatchAllInvocationEvents()
}
const val GRADLE_JDK_NAME = "Gradle JDK"
/**
* inspired by org.jetbrains.plugins.gradle.service.project.open.importProject(projectDirectory, project)
*/
private fun _importProject(projectPath: String, project: Project) {
GradleLog.LOG.info("Import project at $projectPath")
val projectSdk = ProjectRootManager.getInstance(project).projectSdk
assertNotNull(projectSdk, "project SDK not found for ${project.name} at $projectPath")
val gradleProjectSettings = GradleProjectSettings()
GradleSettings.getInstance(project).gradleVmOptions =
"-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${System.getProperty("user.dir")}"
setupGradleSettings(gradleProjectSettings, projectPath, project, projectSdk)
gradleProjectSettings.gradleJvm = GRADLE_JDK_NAME
GradleSettings.getInstance(project).getLinkedProjectSettings(projectPath)?.let { linkedProjectSettings ->
linkedProjectSettings.gradleJvm = GRADLE_JDK_NAME
}
_attachGradleProjectAndRefresh(gradleProjectSettings, project)
}
/**
* inspired by org.jetbrains.plugins.gradle.service.project.open.attachGradleProjectAndRefresh(gradleProjectSettings, project)
* except everything is MODAL_SYNC
*/
private fun _attachGradleProjectAndRefresh(
gradleProjectSettings: GradleProjectSettings,
project: Project
) {
val externalProjectPath = gradleProjectSettings.externalProjectPath
ExternalProjectsManagerImpl.getInstance(project).runWhenInitialized {
DumbService.getInstance(project).runWhenSmart {
ExternalSystemUtil.ensureToolWindowInitialized(project, GradleConstants.SYSTEM_ID)
}
}
ExternalProjectsManagerImpl.disableProjectWatcherAutoUpdate(project)
val settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID)
if (settings.getLinkedProjectSettings(externalProjectPath) == null) {
settings.linkProject(gradleProjectSettings)
}
StatefulTestGradleProjectRefreshCallback(externalProjectPath, project).use { callback ->
ExternalSystemUtil.refreshProject(
externalProjectPath,
ImportSpecBuilder(project, GradleConstants.SYSTEM_ID)
.use(ProgressExecutionMode.MODAL_SYNC)
.callback(callback)
.build()
)
}
}

View File

@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.idea.testFramework
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl
import com.intellij.ide.impl.OpenProjectTask
import com.intellij.ide.startup.impl.StartupManagerImpl
import com.intellij.lang.LanguageAnnotators
import com.intellij.lang.LanguageExtensionPoint
@@ -19,6 +20,7 @@ import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.ex.ProjectManagerEx
import com.intellij.openapi.startup.StartupManager
import com.intellij.platform.PlatformProjectOpenProcessor
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.impl.PsiDocumentManagerBase
import com.intellij.testFramework.ExtensionTestUtil
@@ -70,7 +72,7 @@ fun dispatchAllInvocationEvents() {
}
fun loadProjectWithName(path: String, name: String): Project? =
ProjectManagerEx.getInstanceEx().loadProject(Paths.get(path), name)
PlatformProjectOpenProcessor.openExistingProject(Paths.get(path), Paths.get(path), OpenProjectTask(projectName = name))
fun TestApplicationManager.closeProject(project: Project) {
val name = project.name
@@ -92,11 +94,7 @@ fun TestApplicationManager.closeProject(project: Project) {
}
fun runStartupActivities(project: Project) {
with(StartupManager.getInstance(project) as StartupManagerImpl) {
//scheduleInitialVfsRefresh()
runStartupActivities()
}
runPostStartupActivitiesOnce(project)
// obsolete
}
fun waitForAllEditorsFinallyLoaded(project: Project) {

View File

@@ -1,63 +1,57 @@
<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.KotlinNonJvmGutterConfigurator"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelResolver" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.cocoapods.KotlinCocoaPodsModelResolver" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.commonizer.KotlinCommonizerModelResolver" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectResolverExtension" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleCoroutineDebugProjectResolver" order="last"/>
<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="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.scripting.gradle.importing.KotlinDslScriptModelResolver" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.commonizer.KotlinCommonizerModelResolver" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectResolverExtension" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleCoroutineDebugProjectResolver" order="last"/>
<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"/>
<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"/>
<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>
<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"/>
<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"/>
<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"/>
<scriptDefinitionContributor implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDefinitionsContributor" order="first"/>
<scriptAdditionalIdeaDependenciesProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptAdditionalIdeaDependenciesProvider"/>
</extensions>
</extensions>
</idea-plugin>

View File

@@ -0,0 +1,63 @@
<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.KotlinNonJvmGutterConfigurator"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelResolver" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.cocoapods.KotlinCocoaPodsModelResolver" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.commonizer.KotlinCommonizerModelResolver" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectResolverExtension" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleCoroutineDebugProjectResolver" order="last"/>
<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>

View File

@@ -24,6 +24,8 @@
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinGradleOrderEnumerationHandler$Factory" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver"/>
<testTasksProvider implementation="org.jetbrains.kotlin.idea.run.KotlinMPPGradleTestTasksProvider"/>
<projectModelContributor implementation="org.jetbrains.kotlin.idea.scripting.gradle.importing.KotlinDslScriptModelContributor"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
@@ -42,5 +44,9 @@
<action id="Kotlin.Gradle.ShowDslLogs" class="org.jetbrains.kotlin.idea.actions.ShowKotlinGradleDslLogs"
text="Show Kotlin Gradle DSL Logs" description="Show Kotlin Gradle DSL logs">
</action>
<action id="LoadConfigurationAction" class="org.jetbrains.kotlin.idea.scripting.gradle.LoadConfigurationAction">
<add-to-group group-id="ExternalSystem.ProjectRefreshActionGroup" anchor="first"/>
</action>
</actions>
</idea-plugin>

View File

@@ -0,0 +1,46 @@
<idea-plugin>
<extensionPoints>
<extensionPoint qualifiedName="org.jetbrains.kotlin.gradleProjectImportHandler" area="IDEA_PROJECT"
interface="org.jetbrains.kotlin.idea.configuration.GradleProjectImportHandler"/>
<extensionPoint qualifiedName="org.jetbrains.kotlin.gradleModelFacade"
interface="org.jetbrains.kotlin.idea.inspections.gradle.KotlinGradleModelFacade"/>
</extensionPoints>
<extensions defaultExtensionNs="org.jetbrains.kotlin">
<buildSystemTypeDetector implementation="org.jetbrains.kotlin.idea.configuration.GradleDetector"/>
<scriptDiagnosticFixProvider implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptDiagnosticFixProvider"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.kotlin.scripting.idea">
<listener order="first" implementation="org.jetbrains.kotlin.idea.scripting.gradle.GradleScriptListener"/>
<loader order="first" implementation="org.jetbrains.kotlin.idea.scripting.gradle.legacy.GradleLegacyScriptConfigurationLoader"/>
<scriptingSupport implementation="org.jetbrains.kotlin.idea.scripting.gradle.roots.GradleBuildRootsManager"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinGradleOrderEnumerationHandler$Factory" order="first"/>
<projectResolve implementation="org.jetbrains.kotlin.idea.configuration.KotlinMPPGradleProjectResolver"/>
<testTasksProvider implementation="org.jetbrains.kotlin.idea.run.KotlinMPPGradleTestTasksProvider"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<projectTaskRunner implementation="org.jetbrains.kotlin.idea.gradle.execution.KotlinMPPGradleProjectTaskRunner" order="first, before gradle"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService"/>
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectSettingsDataService"/>
<registryKey key="kotlin.mpp.tests.force.gradle"
description="Run multi-platform tests with Gradle runner even if the platform runner is used by default.
This setting currently affects only HMPP projects. You may need to delete existing test configurations for the change to take place."
defaultValue="true"
restartRequired="false"/>
</extensions>
<actions>
<action id="Kotlin.Gradle.ShowDslLogs" class="org.jetbrains.kotlin.idea.actions.ShowKotlinGradleDslLogs"
text="Show Kotlin Gradle DSL Logs" description="Show Kotlin Gradle DSL logs">
</action>
</actions>
</idea-plugin>

View File

@@ -1,5 +1,9 @@
<idea-plugin>
<extensions defaultExtensionNs="org.jetbrains.uast">
<generate.uastCodeGenerationPlugin implementation="org.jetbrains.uast.kotlin.generate.KotlinUastCodeGenerationPlugin"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<postStartupActivity implementation="org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerStartupActivity"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.JvmPluginStartupActivity"/>

View File

@@ -0,0 +1,12 @@
<idea-plugin>
<extensions defaultExtensionNs="com.intellij">
<postStartupActivity implementation="org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerStartupActivity"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.JvmPluginStartupActivity"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.compiler.KotlinCompilerStartupActivity"/>
<postStartupActivity implementation="org.jetbrains.kotlin.idea.scratch.ScratchFileModuleInfoProvider"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerService"/>
</extensions>
</idea-plugin>

View File

@@ -13,7 +13,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<version>@snapshot@</version>
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
<idea-version since-build="193.4099.13" until-build="193.*"/>
<idea-version since-build="202.1" until-build="203.*"/>
<depends>com.intellij.modules.platform</depends>
@@ -35,7 +35,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
<depends>com.intellij.modules.idea</depends>
<incompatible-with>com.intellij.modules.androidstudio</incompatible-with>
<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>
@@ -60,12 +60,6 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<xi:include href="scripting-support.xml" xpointer="xpointer(/idea-plugin/*)"/>
<project-components>
<component>
<implementation-class>org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener</implementation-class>
</component>
</project-components>
<extensionPoints>
<xi:include href="extensions/compiler.xml" xpointer="xpointer(/idea-plugin/extensionPoints/*)"/>
@@ -97,6 +91,8 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.parameterInfo.custom.KotlinCodeHintsPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener"/>
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="2"/>
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
@@ -118,8 +114,12 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<completion.ml.model implementation="org.jetbrains.kotlin.idea.completion.ml.KotlinMLRankingProvider"/>
<completion.ml.contextFeatures language="kotlin" implementationClass="org.jetbrains.kotlin.idea.completion.ml.KotlinContextFeatureProvider"/>
<suggestedRefactoringSupport language="kotlin" implementationClass="org.jetbrains.kotlin.idea.refactoring.suggested.KotlinSuggestedRefactoringSupport"/>
<defaultLiveTemplatesProvider implementation="org.jetbrains.kotlin.idea.liveTemplates.KotlinLiveTemplatesProvider"/>
<refactoring.moveInnerHandler language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveKotlinInnerHandler"/>
<defaultLiveTemplates file="liveTemplates/Kotlin.xml"/>
<fileType name="Kotlin"
implementationClass="org.jetbrains.kotlin.idea.KotlinFileType"

View File

@@ -13,7 +13,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<version>@snapshot@</version>
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
<idea-version since-build="202.1" until-build="203.*"/>
<idea-version since-build="193.4099.13" until-build="193.*"/>
<depends>com.intellij.modules.platform</depends>
@@ -35,7 +35,7 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
<incompatible-with>com.intellij.modules.androidstudio</incompatible-with>
<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>
@@ -60,6 +60,12 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<xi:include href="scripting-support.xml" xpointer="xpointer(/idea-plugin/*)"/>
<project-components>
<component>
<implementation-class>org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener</implementation-class>
</component>
</project-components>
<extensionPoints>
<xi:include href="extensions/compiler.xml" xpointer="xpointer(/idea-plugin/extensionPoints/*)"/>
@@ -91,8 +97,6 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.parameterInfo.custom.KotlinCodeHintsPass$Registrar"/>
<highlightingPassFactory implementation="org.jetbrains.kotlin.idea.refactoring.cutPaste.MoveDeclarationsPassFactory$Registrar"/>
<projectService serviceImplementation="org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListener"/>
<statistics.counterUsagesCollector groupId="kotlin.gradle.target" version="2"/>
<statistics.counterUsagesCollector groupId="kotlin.maven.target" version="3"/>
<statistics.counterUsagesCollector groupId="kotlin.jps.target" version="3"/>
@@ -114,12 +118,8 @@ The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
<completion.ml.model implementation="org.jetbrains.kotlin.idea.completion.ml.KotlinMLRankingProvider"/>
<completion.ml.contextFeatures language="kotlin" implementationClass="org.jetbrains.kotlin.idea.completion.ml.KotlinContextFeatureProvider"/>
<suggestedRefactoringSupport language="kotlin" implementationClass="org.jetbrains.kotlin.idea.refactoring.suggested.KotlinSuggestedRefactoringSupport"/>
<refactoring.moveInnerHandler language="kotlin"
implementationClass="org.jetbrains.kotlin.idea.refactoring.move.MoveKotlinInnerHandler"/>
<defaultLiveTemplates file="liveTemplates/Kotlin.xml"/>
<defaultLiveTemplatesProvider implementation="org.jetbrains.kotlin.idea.liveTemplates.KotlinLiveTemplatesProvider"/>
<fileType name="Kotlin"
implementationClass="org.jetbrains.kotlin.idea.KotlinFileType"

View File

@@ -46,7 +46,7 @@ abstract class AbstractScratchLineMarkersTest : FileEditorManagerTestCase() {
val project = myFixture.project
val document = myFixture.editor.document
val data = ExpectedHighlightingData(document, false, false, false, myFixture.file)
val data = ExpectedHighlightingData(document, false, false, false)
data.init()
PsiDocumentManager.getInstance(project).commitAllDocuments()
@@ -69,7 +69,7 @@ abstract class AbstractScratchLineMarkersTest : FileEditorManagerTestCase() {
): List<LineMarkerInfo<*>> {
myFixture.doHighlighting()
return AbstractLineMarkersTest.checkHighlighting(myFixture.project, documentToAnalyze, expectedHighlighting, expectedFile)
return AbstractLineMarkersTest.checkHighlighting(myFixture.file, documentToAnalyze, expectedHighlighting, expectedFile)
}
}

View File

@@ -5,5 +5,35 @@
package org.jetbrains.kotlin.idea
import com.intellij.codeInsight.javadoc.JavaDocExternalFilter
import com.intellij.psi.PsiDocCommentBase
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import java.util.function.Consumer
// FIX ME WHEN BUNCH 201 REMOVED
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase()
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase() {
override fun collectDocComments(file: PsiFile, sink: Consumer<PsiDocCommentBase>) {
if (file !is KtFile) return
PsiTreeUtil.processElements(file) {
val comment = (it as? KtDeclaration)?.docComment
if (comment != null) sink.accept(comment)
true
}
}
override fun generateRenderedDoc(element: PsiElement): String? {
val docComment = (element as? KtDeclaration)?.docComment ?: return null
val result = StringBuilder().also {
it.renderKDoc(docComment.getDefaultSection(), docComment.getAllSections())
}
return JavaDocExternalFilter.filterInternalDocInfo(result.toString())
}
}

View File

@@ -0,0 +1,9 @@
/*
* 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
// FIX ME WHEN BUNCH 201 REMOVED
class KotlinDocumentationProvider : KotlinDocumentationProviderCompatBase()

View File

@@ -5,7 +5,11 @@
package org.jetbrains.kotlin.idea.codeInsight
import com.intellij.xml.breadcrumbs.BreadcrumbsInfoProvider
import com.intellij.ide.ui.UISettings
import com.intellij.ui.breadcrumbs.BreadcrumbsProvider
// FIX ME WHEN BUNCH 201 REMOVED
typealias BreadcrumbsProviderCompatBase = BreadcrumbsInfoProvider
abstract class BreadcrumbsProviderCompatBase : BreadcrumbsProvider {
override fun isShownByDefault(): Boolean =
!UISettings.instance.showMembersInNavigationBar
}

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