mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-22 15:51:33 +00:00
Compare commits
149 Commits
rr/faster_
...
master_171
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5035c9fa54 | ||
|
|
f56867fc3b | ||
|
|
8bcfcc4d78 | ||
|
|
cf6641693e | ||
|
|
39dbd25ea7 | ||
|
|
26bedccc28 | ||
|
|
0836fe199b | ||
|
|
5c236caef5 | ||
|
|
2c24e81aef | ||
|
|
46592f860f | ||
|
|
df7f9007c2 | ||
|
|
1916415ae1 | ||
|
|
53886f8eb8 | ||
|
|
f0c5a8aacf | ||
|
|
0047a8d0b8 | ||
|
|
2c72862eb5 | ||
|
|
97cb8d126c | ||
|
|
97d2430260 | ||
|
|
c89eeb579d | ||
|
|
e55bd30b75 | ||
|
|
3fae3132ef | ||
|
|
7ee8d49d6a | ||
|
|
69a623d596 | ||
|
|
5463e3531d | ||
|
|
c413c9bafb | ||
|
|
235963ea3f | ||
|
|
f57e70a3d2 | ||
|
|
ff9564685a | ||
|
|
52a738ac0f | ||
|
|
add5f0fdd3 | ||
|
|
68c6681cb8 | ||
|
|
b6544fbd53 | ||
|
|
b1c39f33aa | ||
|
|
a9a1696e35 | ||
|
|
2f35ad5f10 | ||
|
|
ad73d21c8b | ||
|
|
37acd0f9f4 | ||
|
|
f3ae8cdc2d | ||
|
|
599011cea6 | ||
|
|
4d917db729 | ||
|
|
5ef8849607 | ||
|
|
79ce15d9aa | ||
|
|
e74a7d93d9 | ||
|
|
58b18c5617 | ||
|
|
6189b60c9a | ||
|
|
1cf039e8bc | ||
|
|
968c857933 | ||
|
|
b8d1805b24 | ||
|
|
c10c23567a | ||
|
|
b3ad8dd9d9 | ||
|
|
5c27501c0c | ||
|
|
66a2538082 | ||
|
|
f157c2527f | ||
|
|
266fe49e18 | ||
|
|
4870d1d2de | ||
|
|
29fdbe53fe | ||
|
|
e5ef0ed62c | ||
|
|
06bf92e78c | ||
|
|
d529c253ed | ||
|
|
718e68ac77 | ||
|
|
889e27801f | ||
|
|
0a907f5ba4 | ||
|
|
3068461f90 | ||
|
|
1f7758cd74 | ||
|
|
3f1cbf8391 | ||
|
|
d52b4c9d17 | ||
|
|
9130222b5e | ||
|
|
ff6354fb2c | ||
|
|
5f76dcc45f | ||
|
|
e4a322a29b | ||
|
|
12592bb76d | ||
|
|
ba655ad59d | ||
|
|
a919601f9a | ||
|
|
1c3672cb88 | ||
|
|
0dd5df8163 | ||
|
|
40cfa186e0 | ||
|
|
2002449917 | ||
|
|
8ab85f3138 | ||
|
|
69250f4ef6 | ||
|
|
dfe77c0723 | ||
|
|
6c578275a9 | ||
|
|
c78da40bec | ||
|
|
df3977bf83 | ||
|
|
14c80a5e01 | ||
|
|
b54a476dc2 | ||
|
|
a715d666b7 | ||
|
|
fe33d8c1a7 | ||
|
|
45596b8260 | ||
|
|
e2010af17d | ||
|
|
e1893cc49b | ||
|
|
180822cb22 | ||
|
|
f1f5d64324 | ||
|
|
183277c585 | ||
|
|
7ee877f5b9 | ||
|
|
443a77db67 | ||
|
|
a1c84c0aae | ||
|
|
5bf610b933 | ||
|
|
544720953b | ||
|
|
7295035179 | ||
|
|
737a59749e | ||
|
|
fbf5b9518e | ||
|
|
41756d8887 | ||
|
|
2a5e50c137 | ||
|
|
8010b37be6 | ||
|
|
6e8960c1f1 | ||
|
|
60e703b44d | ||
|
|
2d463d3de6 | ||
|
|
2b8de185de | ||
|
|
3553ab13ac | ||
|
|
d0e40712f6 | ||
|
|
a4867f3c2b | ||
|
|
bfd9e9f51f | ||
|
|
2c998fb6a8 | ||
|
|
e13ccd4a23 | ||
|
|
d57c1ccc4b | ||
|
|
642bee1d37 | ||
|
|
5967d53b97 | ||
|
|
e3119a3eac | ||
|
|
dce6f728ab | ||
|
|
3d1b7080c8 | ||
|
|
50d9dd23cf | ||
|
|
c21ef998a8 | ||
|
|
cd07fce0e0 | ||
|
|
4b244f8b37 | ||
|
|
6afe378542 | ||
|
|
0a8bd2025a | ||
|
|
8cfa2c101e | ||
|
|
e4add32f5a | ||
|
|
1aa096bcea | ||
|
|
810c0fecdf | ||
|
|
c03f990b9c | ||
|
|
16778b2710 | ||
|
|
4341913fd8 | ||
|
|
3ea1541f8e | ||
|
|
7211a9277d | ||
|
|
176828d621 | ||
|
|
e7ee045ba2 | ||
|
|
8afd1ba794 | ||
|
|
333288c475 | ||
|
|
6504b7ee20 | ||
|
|
0f4ea105ab | ||
|
|
5ad86b7bfc | ||
|
|
8d7a07271f | ||
|
|
0a4efa54da | ||
|
|
d077d5add7 | ||
|
|
8a6db402d6 | ||
|
|
628ef645b4 | ||
|
|
5cac1e218f | ||
|
|
14fbe38a3e |
@@ -22,6 +22,7 @@ buildscript {
|
||||
"https://jcenter.bintray.com/",
|
||||
"https://plugins.gradle.org/m2",
|
||||
"http://dl.bintray.com/kotlin/kotlinx",
|
||||
"http://dl.bintray.com/kotlin/uast",
|
||||
"https://repo.gradle.org/gradle/libs-releases-local", // for native-platform
|
||||
"https://jetbrains.bintray.com/intellij-third-party-dependencies", // for jflex
|
||||
"https://dl.bintray.com/jetbrains/markdown" // for org.jetbrains:markdown
|
||||
@@ -142,6 +143,7 @@ extra["versions.robolectric"] = "3.1"
|
||||
extra["versions.org.springframework"] = "4.2.0.RELEASE"
|
||||
extra["versions.jflex"] = "1.7.0"
|
||||
extra["versions.markdown"] = "0.1.25"
|
||||
extra["versions.org.jetbrains.uast"] = "1.0.12"
|
||||
|
||||
val isTeamcityBuild = project.hasProperty("teamcity") || System.getenv("TEAMCITY_VERSION") != null
|
||||
val intellijUltimateEnabled = project.getBooleanProperty("intellijUltimateEnabled") ?: isTeamcityBuild
|
||||
@@ -156,7 +158,7 @@ extra["intellijSeparateSdks"] = intellijSeparateSdks
|
||||
extra["IntellijCoreDependencies"] =
|
||||
listOf("annotations",
|
||||
"asm-all",
|
||||
"guava-21.0",
|
||||
"guava-19.0",
|
||||
"jdom",
|
||||
"jna",
|
||||
"log4j",
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.ide.plugins.PluginManagerCore
|
||||
import com.intellij.lang.MetaLanguage
|
||||
import com.intellij.lang.java.JavaParserDefinition
|
||||
import com.intellij.lang.jvm.facade.JvmElementProvider
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.TransactionGuard
|
||||
import com.intellij.openapi.application.TransactionGuardImpl
|
||||
@@ -44,7 +43,6 @@ import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.openapi.vfs.*
|
||||
import com.intellij.openapi.vfs.impl.ZipHandler
|
||||
import com.intellij.psi.FileContextProvider
|
||||
import com.intellij.psi.JavaModuleSystem
|
||||
import com.intellij.psi.PsiElementFinder
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.augment.PsiAugmentProvider
|
||||
@@ -386,7 +384,7 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val ideaCompatibleBuildNumber = "173.1"
|
||||
private val ideaCompatibleBuildNumber = "172.9999"
|
||||
|
||||
init {
|
||||
setCompatibleBuild()
|
||||
@@ -509,8 +507,6 @@ class KotlinCoreEnvironment private constructor(
|
||||
//
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), TypeAnnotationModifier.EP_NAME, TypeAnnotationModifier::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), MetaLanguage.EP_NAME, MetaLanguage::class.java)
|
||||
//
|
||||
CoreApplicationEnvironment.registerExtensionPoint(Extensions.getRootArea(), JavaModuleSystem.EP_NAME, JavaModuleSystem::class.java)
|
||||
}
|
||||
|
||||
private fun registerApplicationExtensionPointsAndExtensionsFrom(configuration: CompilerConfiguration, configFilePath: String) {
|
||||
@@ -561,7 +557,6 @@ class KotlinCoreEnvironment private constructor(
|
||||
private fun registerProjectExtensionPoints(area: ExtensionsArea) {
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiTreeChangePreprocessor.EP_NAME, PsiTreeChangePreprocessor::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP_NAME, PsiElementFinder::class.java)
|
||||
CoreApplicationEnvironment.registerExtensionPoint(area, JvmElementProvider.EP_NAME, JvmElementProvider::class.java)
|
||||
}
|
||||
|
||||
// made public for Upsource
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
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() {
|
||||
@@ -41,8 +40,4 @@ class MockExternalAnnotationsManager : ExternalAnnotationsManager() {
|
||||
override fun editExternalAnnotation(listOwner: PsiModifierListOwner, annotationFQN: String, value: Array<out PsiNameValuePair>?): Boolean {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
|
||||
override fun hasAnnotationRootsForFile(file: VirtualFile): Boolean {
|
||||
throw UnsupportedOperationException("not implemented")
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,6 @@ messages/**)
|
||||
-dontwarn net.jpountz.lz4.LZ4Factory
|
||||
-dontwarn org.jetbrains.annotations.ReadOnly
|
||||
-dontwarn org.jetbrains.annotations.Mutable
|
||||
-dontwarn com.intellij.util.io.TarUtil
|
||||
|
||||
#-libraryjars '<rtjar>'
|
||||
#-libraryjars '<jssejar>'
|
||||
|
||||
@@ -28,8 +28,8 @@ enum class JvmTarget(override val description: String) : TargetPlatformVersion {
|
||||
JVM_1_6 -> Opcodes.V1_6
|
||||
JVM_1_8 ->
|
||||
when {
|
||||
java.lang.Boolean.valueOf(System.getProperty("kotlin.test.substitute.bytecode.1.8.to.10")) -> Opcodes.V9 + 1
|
||||
java.lang.Boolean.valueOf(System.getProperty("kotlin.test.substitute.bytecode.1.8.to.1.9")) -> Opcodes.V9
|
||||
java.lang.Boolean.valueOf(System.getProperty("kotlin.test.substitute.bytecode.1.8.to.10")) -> Opcodes.V1_9 + 1
|
||||
java.lang.Boolean.valueOf(System.getProperty("kotlin.test.substitute.bytecode.1.8.to.1.9")) -> Opcodes.V1_9
|
||||
else -> Opcodes.V1_8
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||
import org.jetbrains.kotlin.resolve.constants.ErrorValue
|
||||
|
||||
val JVM_STATIC_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmStatic")
|
||||
private val JVM_STATIC_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmStatic")
|
||||
|
||||
val JVM_FIELD_ANNOTATION_FQ_NAME = FqName("kotlin.jvm.JvmField")
|
||||
|
||||
|
||||
@@ -55,12 +55,6 @@ abstract class KtLightAbstractAnnotation(parent: PsiElement, computeDelegate: ()
|
||||
|
||||
override fun getParameterList() = clsDelegate.parameterList
|
||||
|
||||
override fun canNavigate(): Boolean = super<KtLightElementBase>.canNavigate()
|
||||
|
||||
override fun canNavigateToSource(): Boolean = super<KtLightElementBase>.canNavigateToSource()
|
||||
|
||||
override fun navigate(requestFocus: Boolean) = super<KtLightElementBase>.navigate(requestFocus)
|
||||
|
||||
open fun fqNameMatches(fqName: String): Boolean = qualifiedName == fqName
|
||||
}
|
||||
|
||||
@@ -273,7 +267,7 @@ class KtLightAnnotationForSourceEntry(
|
||||
PsiNameValuePair {
|
||||
override fun setValue(newValue: PsiAnnotationMemberValue): PsiAnnotationMemberValue = psiNameValuePair.setValue(newValue)
|
||||
override fun getNameIdentifier(): PsiIdentifier? = psiNameValuePair.nameIdentifier
|
||||
override fun getLiteralValue(): String? = (value as? PsiLiteralValue)?.value?.toString()
|
||||
override fun getLiteralValue(): String? = (value as? PsiLiteral)?.value?.toString()
|
||||
override val kotlinOrigin: KtElement? = null
|
||||
|
||||
override fun getValue(): PsiAnnotationMemberValue? = psiNameValuePair.value?.let { wrapAnnotationValue(it) }
|
||||
@@ -319,12 +313,6 @@ class KtLightNonExistentAnnotation(parent: KtLightElement<*, *>) : KtLightElemen
|
||||
override fun findDeclaredAttributeValue(attributeName: String?) = null
|
||||
override fun getMetaData() = null
|
||||
override fun getParameterList() = KtLightEmptyAnnotationParameterList(this)
|
||||
|
||||
override fun canNavigate(): Boolean = super<KtLightElementBase>.canNavigate()
|
||||
|
||||
override fun canNavigateToSource(): Boolean = super<KtLightElementBase>.canNavigateToSource()
|
||||
|
||||
override fun navigate(requestFocus: Boolean) = super<KtLightElementBase>.navigate(requestFocus)
|
||||
}
|
||||
|
||||
class KtLightEmptyAnnotationParameterList(parent: PsiElement) : KtLightElementBase(parent), PsiAnnotationParameterList {
|
||||
|
||||
@@ -325,8 +325,6 @@ class KtPsiFactory @JvmOverloads constructor(private val project: Project, val m
|
||||
return createProperty(text + " val x").modifierList!!
|
||||
}
|
||||
|
||||
fun createEmptyModifierList() = createModifierList(KtTokens.PRIVATE_KEYWORD).apply { firstChild.delete() }
|
||||
|
||||
fun createModifier(modifier: KtModifierKeywordToken): PsiElement {
|
||||
return createModifierList(modifier.value).getModifier(modifier)!!
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// FILE: a/a.java
|
||||
package a;
|
||||
|
||||
public class a {}
|
||||
|
||||
// FILE: a/b.java
|
||||
package a;
|
||||
|
||||
public class b {
|
||||
public void a_b() {}
|
||||
}
|
||||
|
||||
// FILE: test/a.java
|
||||
package test;
|
||||
|
||||
public class a {}
|
||||
|
||||
// FILE: test/d.java
|
||||
package test;
|
||||
|
||||
public class d {
|
||||
public a.b getB() { return null; }
|
||||
}
|
||||
|
||||
// FILE: b.kt
|
||||
package test
|
||||
|
||||
val x = d().getB()
|
||||
|
||||
// FILE: test/c.java
|
||||
package test;
|
||||
|
||||
import a.a;
|
||||
|
||||
public class c {
|
||||
public static a getA() { return null; }
|
||||
}
|
||||
|
||||
// FILE: c.kt
|
||||
package test
|
||||
|
||||
fun foo() {
|
||||
val a = c.getA()
|
||||
a.<!UNRESOLVED_REFERENCE!>a<!>
|
||||
a.<!UNRESOLVED_REFERENCE!>a<!>()
|
||||
}
|
||||
@@ -139,8 +139,18 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
||||
}
|
||||
|
||||
var exceptionFromDescriptorValidation: Throwable? = null
|
||||
val originalTestFile = testDataFile.readText()
|
||||
try {
|
||||
val expectedFile = getExpectedDescriptorFile(testDataFile, files)
|
||||
val postfix = when {
|
||||
InTextDirectivesUtils.isDirectiveDefined(originalTestFile, "// JAVAC_EXPECTED_FILE") &&
|
||||
environment.configuration.getBoolean(JVMConfigurationKeys.USE_JAVAC) -> ".javac.txt"
|
||||
|
||||
InTextDirectivesUtils.isDirectiveDefined(originalTestFile, "// NI_EXPECTED_FILE") &&
|
||||
files.any { it.newInferenceEnabled } && !USE_OLD_INFERENCE_DIAGNOSTICS_FOR_NI -> ".ni.txt"
|
||||
|
||||
else -> ".txt"
|
||||
}
|
||||
val expectedFile = File(FileUtil.getNameWithoutExtension(testDataFile.absolutePath) + postfix)
|
||||
validateAndCompareDescriptorWithFile(expectedFile, files, modules)
|
||||
} catch (e: Throwable) {
|
||||
exceptionFromDescriptorValidation = e
|
||||
@@ -175,7 +185,7 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
||||
exceptionFromDynamicCallDescriptorsValidation = e
|
||||
}
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(getExpectedDiagnosticsFile(testDataFile), actualText.toString())
|
||||
KotlinTestUtils.assertEqualsToFile(testDataFile, actualText.toString())
|
||||
|
||||
assertTrue("Diagnostics mismatch. See the output above", ok)
|
||||
|
||||
@@ -187,26 +197,6 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
||||
performAdditionalChecksAfterDiagnostics(testDataFile, files, groupedByModule, modules, moduleBindings)
|
||||
}
|
||||
|
||||
protected open fun getExpectedDiagnosticsFile(testDataFile: File): File {
|
||||
return testDataFile
|
||||
}
|
||||
|
||||
protected open fun getExpectedDescriptorFile(testDataFile: File, files: List<TestFile>): File {
|
||||
val originalTestFileText = testDataFile.readText()
|
||||
|
||||
val postfix = when {
|
||||
InTextDirectivesUtils.isDirectiveDefined(originalTestFileText, "// JAVAC_EXPECTED_FILE") &&
|
||||
environment.configuration.getBoolean(JVMConfigurationKeys.USE_JAVAC) -> ".javac.txt"
|
||||
|
||||
InTextDirectivesUtils.isDirectiveDefined(originalTestFileText, "// NI_EXPECTED_FILE") &&
|
||||
files.any { it.newInferenceEnabled } && !USE_OLD_INFERENCE_DIAGNOSTICS_FOR_NI -> ".ni.txt"
|
||||
|
||||
else -> ".txt"
|
||||
}
|
||||
|
||||
return File(FileUtil.getNameWithoutExtension(testDataFile.absolutePath) + postfix)
|
||||
}
|
||||
|
||||
protected open fun performAdditionalChecksAfterDiagnostics(
|
||||
testDataFile: File,
|
||||
testFiles: List<TestFile>,
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.checkers.javac
|
||||
|
||||
import org.jetbrains.kotlin.checkers.AbstractDiagnosticsTest
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractJavacDiagnosticsTest : AbstractDiagnosticsTest() {
|
||||
@@ -40,19 +39,5 @@ abstract class AbstractJavacDiagnosticsTest : AbstractDiagnosticsTest() {
|
||||
super.doTest(path)
|
||||
}
|
||||
|
||||
override fun getExpectedDiagnosticsFile(testDataFile: File): File {
|
||||
val suffix = if (useJavac) ".WithJavac.txt" else ".WithoutJavac.txt"
|
||||
val specialFile = File(testDataFile.parent, testDataFile.name + suffix)
|
||||
return specialFile.takeIf { it.exists() } ?: super.getExpectedDiagnosticsFile(testDataFile)
|
||||
}
|
||||
|
||||
override fun createTestFiles(file: File, expectedText: String, modules: MutableMap<String, ModuleAndDependencies>?): List<TestFile> {
|
||||
val specialFile = getExpectedDiagnosticsFile(file)
|
||||
if (file.path == specialFile.path) {
|
||||
return super.createTestFiles(file, expectedText, modules)
|
||||
}
|
||||
|
||||
return super.createTestFiles(specialFile, KotlinTestUtils.doLoadFile(specialFile), modules)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.jetbrains.kotlin.test.testFramework
|
||||
|
||||
import com.intellij.mock.MockApplication
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import javax.swing.SwingUtilities
|
||||
@@ -41,12 +39,7 @@ fun runInEdtAndWait(runnable: () -> Unit) {
|
||||
}
|
||||
else {
|
||||
try {
|
||||
val application = ApplicationManager.getApplication()
|
||||
.takeIf { it !is MockApplication } // because MockApplication do nothing instead of `invokeAndWait`
|
||||
if (application != null)
|
||||
application.invokeAndWait(runnable)
|
||||
else
|
||||
SwingUtilities.invokeAndWait(runnable)
|
||||
SwingUtilities.invokeAndWait(runnable)
|
||||
}
|
||||
catch (e: InvocationTargetException) {
|
||||
throw e.cause ?: e
|
||||
|
||||
@@ -52,7 +52,6 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@SuppressWarnings("UseOfSystemOutOrSystemErr")
|
||||
public abstract class KtUsefulTestCase extends TestCase {
|
||||
@@ -218,11 +217,9 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
protected void runTest() throws Throwable {
|
||||
Throwable[] throwables = new Throwable[1];
|
||||
|
||||
AtomicBoolean completed = new AtomicBoolean(false);
|
||||
Runnable runnable = () -> {
|
||||
try {
|
||||
super.runTest();
|
||||
completed.set(true);
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
e.fillInStackTrace();
|
||||
@@ -242,9 +239,6 @@ public abstract class KtUsefulTestCase extends TestCase {
|
||||
if (throwables[0] != null) {
|
||||
throw throwables[0];
|
||||
}
|
||||
if (!completed.get()) {
|
||||
throw new IllegalStateException("test didn't start");
|
||||
}
|
||||
}
|
||||
|
||||
private static void invokeTestRunnable(@NotNull Runnable runnable) throws Exception {
|
||||
|
||||
@@ -19,7 +19,6 @@ import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.EditorKind;
|
||||
import com.intellij.openapi.editor.event.EditorEventMulticaster;
|
||||
import com.intellij.openapi.editor.event.EditorFactoryListener;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
@@ -28,7 +27,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.text.CharArrayCharSequence;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class MockEditorFactory extends EditorFactory {
|
||||
@Override
|
||||
@@ -61,27 +59,6 @@ public class MockEditorFactory extends EditorFactory {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor createEditor(
|
||||
@NotNull Document document, @Nullable Project project, @NotNull EditorKind kind
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor createEditor(
|
||||
@NotNull Document document, Project project, @NotNull VirtualFile file, boolean isViewer, @NotNull EditorKind kind
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor createViewer(
|
||||
@NotNull Document document, @Nullable Project project, @NotNull EditorKind kind
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseEditor(@NotNull Editor editor) {
|
||||
}
|
||||
|
||||
@@ -30,15 +30,14 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
public class MockFileManager implements FileManager {
|
||||
private final PsiManagerEx myManager;
|
||||
// in mock tests it's LightVirtualFile, they're only alive when they're referenced,
|
||||
// and there can not be several instances representing the same file
|
||||
private final ConcurrentMap<VirtualFile, FileViewProvider> myViewProviders = new ConcurrentWeakFactoryMap<VirtualFile, FileViewProvider>() {
|
||||
private final FactoryMap<VirtualFile, FileViewProvider> myViewProviders = new ConcurrentWeakFactoryMap<VirtualFile, FileViewProvider>() {
|
||||
@Override
|
||||
protected ConcurrentMap<VirtualFile, FileViewProvider> createMap() {
|
||||
protected Map<VirtualFile, FileViewProvider> createMap() {
|
||||
return ContainerUtil.createConcurrentWeakKeyWeakValueMap();
|
||||
}
|
||||
|
||||
|
||||
@@ -190,8 +190,4 @@ public class MockPsiManager extends PsiManagerEx {
|
||||
@Override
|
||||
public void beforeChildAddition(@NotNull PsiTreeChangeEventImpl event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropPsiCaches() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,9 +133,7 @@ import org.jetbrains.kotlin.idea.scratch.AbstractScratchRunActionTest
|
||||
import org.jetbrains.kotlin.idea.script.AbstractScriptConfigurationCompletionTest
|
||||
import org.jetbrains.kotlin.idea.script.AbstractScriptConfigurationHighlightingTest
|
||||
import org.jetbrains.kotlin.idea.script.AbstractScriptConfigurationNavigationTest
|
||||
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest
|
||||
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest
|
||||
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTreeTest
|
||||
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTest
|
||||
import org.jetbrains.kotlin.idea.structureView.AbstractKotlinFileStructureTest
|
||||
import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest
|
||||
import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest
|
||||
@@ -727,18 +725,10 @@ fun main(args: Array<String>) {
|
||||
model("refactoring/nameSuggestionProvider")
|
||||
}
|
||||
|
||||
testClass<AbstractSlicerTreeTest> {
|
||||
testClass<AbstractSlicerTest> {
|
||||
model("slicer", singleClass = true)
|
||||
}
|
||||
|
||||
testClass<AbstractSlicerLeafGroupingTest> {
|
||||
model("slicer/inflow", singleClass = true)
|
||||
}
|
||||
|
||||
testClass<AbstractSlicerNullnessGroupingTest> {
|
||||
model("slicer/inflow", singleClass = true)
|
||||
}
|
||||
|
||||
testClass<AbstractScratchRunActionTest> {
|
||||
model("scratch", extension = "kts", testMethod = "doCompilingTest", testClassName = "Compiling", recursive = false)
|
||||
model("scratch", extension = "kts", testMethod = "doReplTest", testClassName = "Repl", recursive = false)
|
||||
|
||||
@@ -85,13 +85,12 @@ public class KotlinCommonCodeStyleSettings extends CommonCodeStyleSettings {
|
||||
private void writeExternalBase(Element element, CommonCodeStyleSettings defaultSettings) throws WriteExternalException {
|
||||
Set<String> supportedFields = getSupportedFields();
|
||||
if (supportedFields != null) {
|
||||
supportedFields.add("PARENT_SETTINGS_INSTALLED");
|
||||
supportedFields.add("FORCE_REARRANGE_MODE");
|
||||
supportedFields.add("CODE_STYLE_DEFAULTS");
|
||||
}
|
||||
//noinspection deprecation
|
||||
DefaultJDOMExternalizer.writeExternal(this, element, new SupportedFieldsDiffFilter(this, supportedFields, defaultSettings));
|
||||
List<Integer> softMargins = getSoftMargins();
|
||||
serializeInto(softMargins, element);
|
||||
|
||||
IndentOptions myIndentOptions = getIndentOptions();
|
||||
if (myIndentOptions != null) {
|
||||
@@ -140,21 +139,6 @@ public class KotlinCommonCodeStyleSettings extends CommonCodeStyleSettings {
|
||||
commonSettings.setArrangementSettings(arrangementSettings.clone());
|
||||
}
|
||||
|
||||
try {
|
||||
Method setRootSettingsMethod = ArraysKt.singleOrNull(
|
||||
CommonCodeStyleSettings.class.getDeclaredMethods(),
|
||||
method -> "setSoftMargins".equals(method.getName()));
|
||||
|
||||
if (setRootSettingsMethod != null) {
|
||||
// Method was introduced in 173
|
||||
setRootSettingsMethod.setAccessible(true);
|
||||
setRootSettingsMethod.invoke(commonSettings, getSoftMargins());
|
||||
}
|
||||
}
|
||||
catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
return commonSettings;
|
||||
}
|
||||
|
||||
@@ -169,9 +153,6 @@ public class KotlinCommonCodeStyleSettings extends CommonCodeStyleSettings {
|
||||
}
|
||||
|
||||
CommonCodeStyleSettings other = (CommonCodeStyleSettings) obj;
|
||||
if (!getSoftMargins().equals(other.getSoftMargins())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IndentOptions options = getIndentOptions();
|
||||
if ((options == null && other.getIndentOptions() != null) ||
|
||||
@@ -179,14 +160,7 @@ public class KotlinCommonCodeStyleSettings extends CommonCodeStyleSettings {
|
||||
return false;
|
||||
}
|
||||
|
||||
return arrangementSettingsEqual(other);
|
||||
}
|
||||
|
||||
// SoftMargins.serializeInfo
|
||||
private void serializeInto(@NotNull List<Integer> softMargins, @NotNull Element element) {
|
||||
if (softMargins.size() > 0) {
|
||||
XmlSerializer.serializeInto(this, element);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="backend" />
|
||||
<orderEntry type="module" module-name="frontend" />
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
<orderEntry type="module" module-name="light-classes" />
|
||||
<orderEntry type="module" module-name="eval4j" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/../../ideaSDK/core/annotations.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="library" name="guava" level="project" />
|
||||
<orderEntry type="module" module-name="js.frontend" />
|
||||
<orderEntry type="module" module-name="js.serializer" />
|
||||
<orderEntry type="library" name="trove4j" level="project" />
|
||||
<orderEntry type="module" module-name="ide-common" exported="" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="module" module-name="idea-core" />
|
||||
<orderEntry type="module" module-name="idea-jps-common" />
|
||||
<orderEntry type="module" module-name="cli-common" />
|
||||
<orderEntry type="module" module-name="descriptors" />
|
||||
<orderEntry type="library" exported="" name="idea-full" level="project" />
|
||||
<orderEntry type="library" name="uast-java" level="project" />
|
||||
<orderEntry type="module" module-name="frontend.script" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -11,7 +11,6 @@ import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.fileTypes.FileTypeRegistry
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.rootManager
|
||||
import com.intellij.openapi.roots.ModuleRootEvent
|
||||
import com.intellij.openapi.roots.ModuleRootListener
|
||||
import com.intellij.openapi.util.Disposer
|
||||
@@ -33,6 +32,7 @@ import org.jetbrains.kotlin.idea.caches.project.getNullableModuleInfo
|
||||
import org.jetbrains.kotlin.idea.stubindex.PackageIndexUtil
|
||||
import org.jetbrains.kotlin.idea.util.getSourceRoot
|
||||
import org.jetbrains.kotlin.idea.util.sourceRoot
|
||||
import org.jetbrains.kotlin.idea.util.rootManager
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPackageDirective
|
||||
@@ -60,7 +60,7 @@ class KotlinPackageContentModificationListener(private val project: Project) {
|
||||
events
|
||||
.asSequence()
|
||||
.filter { it.file != null }
|
||||
.filter(::isRelevant)
|
||||
.filter(this::isRelevant)
|
||||
.filter {
|
||||
val vFile = it.file!!
|
||||
vFile.isDirectory || FileTypeRegistry.getInstance().getFileTypeByFileName(vFile.name) == KotlinFileType.INSTANCE
|
||||
|
||||
@@ -33,7 +33,7 @@ class KtLightClassForDecompiledDeclaration(
|
||||
override val kotlinOrigin: KtClassOrObject?,
|
||||
private val file: KtClsFile
|
||||
) : KtLightClassBase(clsDelegate.manager) {
|
||||
val fqName = kotlinOrigin?.fqName ?: FqName(clsDelegate.qualifiedName.orEmpty())
|
||||
val fqName = kotlinOrigin?.fqName ?: FqName(clsDelegate.qualifiedName)
|
||||
|
||||
override fun copy() = this
|
||||
|
||||
|
||||
@@ -19,13 +19,14 @@ dependencies {
|
||||
compile(project(":idea:idea-core"))
|
||||
compile(project(":idea:ide-common"))
|
||||
compile(project(":idea:idea-gradle"))
|
||||
compile(project(":plugins:uast-kotlin"))
|
||||
|
||||
compile(androidDxJar())
|
||||
|
||||
compileOnly(project(":kotlin-android-extensions-runtime"))
|
||||
compileOnly(intellijDep()) { includeJars("openapi", "idea", "extensions", "util", "guava", "android-base-common", rootProject = rootProject) }
|
||||
compileOnly(intellijPluginDep("android")) {
|
||||
includeJars("android", "android-common", "sdk-common", "sdklib", "sdk-tools", "layoutlib-api")
|
||||
includeJars("android", "android-common", "common", "sdk-common", "sdklib", "sdk-tools", "layoutlib-api")
|
||||
}
|
||||
|
||||
testCompile(projectDist(":kotlin-test:kotlin-test-jvm"))
|
||||
@@ -40,7 +41,7 @@ dependencies {
|
||||
testCompile(intellijDep()) { includeJars("gson", rootProject = rootProject) }
|
||||
testCompile(intellijPluginDep("properties"))
|
||||
testCompileOnly(intellijPluginDep("android")) {
|
||||
includeJars("android", "android-common", "sdk-common", "sdklib", "sdk-tools", "layoutlib-api")
|
||||
includeJars("android", "android-common", "common", "sdk-common", "sdklib", "sdk-tools", "layoutlib-api")
|
||||
}
|
||||
|
||||
testRuntime(projectDist(":kotlin-reflect"))
|
||||
|
||||
@@ -10,7 +10,7 @@ dependencies {
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeJars("guava", "android-base-common", rootProject = rootProject) }
|
||||
compileOnly(intellijPluginDep("gradle")) { includeJars("gradle-tooling-api", rootProject = rootProject) }
|
||||
compileOnly(intellijPluginDep("android")) { includeJars("android", "android-common", "sdk-common") }
|
||||
compileOnly(intellijPluginDep("android")) { includeJars("android", "android-common", "common", "sdk-common") }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
@@ -68,7 +68,7 @@ class AndroidResourceReferenceAnnotator : Annotator {
|
||||
val iconFile = AndroidColorAnnotator.pickBestBitmap(file)
|
||||
if (iconFile != null) {
|
||||
val annotation = holder.createInfoAnnotation(element, null)
|
||||
annotation.gutterIconRenderer = GutterIconRenderer(resourceResolver, element, iconFile)
|
||||
annotation.gutterIconRenderer = GutterIconRenderer(element, iconFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ internal fun getReferredResourceOrManifestField(facet: AndroidFacet, expression:
|
||||
val qName = rClassDescriptor.fqNameSafe.asString()
|
||||
|
||||
if (SdkConstants.CLASS_R == qName || AndroidPsiElementFinder.INTERNAL_R_CLASS_QNAME == qName) {
|
||||
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, facet.module, true, false)
|
||||
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, true, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ internal fun getReferredResourceOrManifestField(facet: AndroidFacet, expression:
|
||||
return null
|
||||
}
|
||||
|
||||
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, facet.module, false, false)
|
||||
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, false, false)
|
||||
}
|
||||
|
||||
private fun KtExpression.getPreviousInQualifiedChain(): KtExpression? {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.android.configure
|
||||
|
||||
import com.android.tools.idea.gradle.project.sync.idea.data.service.AndroidProjectKeys
|
||||
import com.android.tools.idea.gradle.AndroidProjectKeys
|
||||
import com.intellij.openapi.externalSystem.model.DataNode
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData
|
||||
@@ -46,7 +46,7 @@ import com.android.builder.model.Library
|
||||
class AndroidGradleModelFacade : KotlinGradleModelFacade {
|
||||
override fun getResolvedKotlinStdlibVersionByModuleData(moduleData: DataNode<*>, libraryIds: List<String>): String? {
|
||||
ExternalSystemApiUtil
|
||||
.findAllRecursively(moduleData, AndroidProjectKeys.JAVA_MODULE_MODEL).asSequence()
|
||||
.findAllRecursively(moduleData, AndroidProjectKeys.JAVA_PROJECT).asSequence()
|
||||
.flatMap { it.data.jarLibraryDependencies.asSequence() }
|
||||
.forEach {
|
||||
val libraryName = it.name
|
||||
@@ -60,7 +60,7 @@ class AndroidGradleModelFacade : KotlinGradleModelFacade {
|
||||
|
||||
override fun getDependencyModules(ideModule: DataNode<ModuleData>, gradleIdeaProject: IdeaProject): Collection<DataNode<ModuleData>> {
|
||||
val ideProject = ideModule.parent as DataNode<ProjectData>
|
||||
ExternalSystemApiUtil.find(ideModule, AndroidProjectKeys.JAVA_MODULE_MODEL)?.let { javaModuleModel ->
|
||||
ExternalSystemApiUtil.find(ideModule, AndroidProjectKeys.JAVA_PROJECT)?.let { javaModuleModel ->
|
||||
val moduleNames = javaModuleModel.data.javaModuleDependencies.map { it.moduleName }.toHashSet()
|
||||
return findModulesByNames(moduleNames, gradleIdeaProject, ideProject)
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package org.jetbrains.kotlin.android.configure
|
||||
|
||||
import com.android.tools.idea.gradle.project.model.JavaModuleModel
|
||||
import com.android.tools.idea.gradle.project.sync.idea.data.service.AndroidProjectKeys
|
||||
import com.android.tools.idea.gradle.AndroidProjectKeys
|
||||
import com.android.tools.idea.gradle.JavaProject
|
||||
import com.android.tools.idea.gradle.util.FilePaths
|
||||
import com.intellij.openapi.externalSystem.model.DataNode
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData
|
||||
@@ -33,11 +33,11 @@ import org.jetbrains.kotlin.idea.framework.detectLibraryKind
|
||||
import org.jetbrains.kotlin.idea.framework.libraryKind
|
||||
import java.io.File
|
||||
|
||||
class KotlinAndroidGradleLibraryDataService : AbstractProjectDataService<JavaModuleModel, Void>() {
|
||||
override fun getTargetDataKey() = AndroidProjectKeys.JAVA_MODULE_MODEL
|
||||
class KotlinAndroidGradleLibraryDataService : AbstractProjectDataService<JavaProject, Void>() {
|
||||
override fun getTargetDataKey() = AndroidProjectKeys.JAVA_PROJECT
|
||||
|
||||
override fun postProcess(
|
||||
toImport: MutableCollection<DataNode<JavaModuleModel>>,
|
||||
toImport: MutableCollection<DataNode<JavaProject>>,
|
||||
projectData: ProjectData?,
|
||||
project: Project,
|
||||
modelsProvider: IdeModifiableModelsProvider
|
||||
|
||||
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.android.inspection
|
||||
|
||||
import com.android.builder.model.AndroidProject.ARTIFACT_UNIT_TEST
|
||||
import com.android.tools.idea.AndroidPsiUtils
|
||||
import com.android.tools.idea.gradle.project.model.AndroidModuleModel
|
||||
import com.android.tools.idea.gradle.AndroidGradleModel
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
@@ -112,7 +112,7 @@ class IllegalIdentifierInspection : AbstractKotlinInspection() {
|
||||
|
||||
private fun getJunitTestPaths(module: Module): List<File> {
|
||||
val androidFacet = AndroidFacet.getInstance(module) ?: return emptyList()
|
||||
val androidModuleModel = AndroidModuleModel.get(androidFacet) ?: return emptyList()
|
||||
val androidModuleModel = AndroidGradleModel.get(androidFacet) ?: return emptyList()
|
||||
|
||||
return androidModuleModel.getTestSourceProviders(ARTIFACT_UNIT_TEST).flatMap { it.javaDirectories }
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.intellij.psi.util.PsiTreeUtil
|
||||
import com.intellij.psi.PsiClass
|
||||
import org.jetbrains.android.util.AndroidUtils
|
||||
import com.android.SdkConstants
|
||||
import com.intellij.openapi.module.ModuleUtil
|
||||
import org.jetbrains.android.augment.AndroidPsiElementFinder
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
@@ -68,7 +67,6 @@ private fun getReferredInfo(
|
||||
val firstPart = getReceiverAsSimpleNameExpression(middlePart) ?: return null
|
||||
|
||||
val resolvedClass = firstPart.mainReference.resolve() as? PsiClass ?: return null
|
||||
val resolvedModule = ModuleUtil.findModuleForPsiElement(resolvedClass)
|
||||
|
||||
//the following code is copied from
|
||||
// org.jetbrains.android.util.AndroidResourceUtil.getReferredResourceOrManifestField
|
||||
@@ -83,7 +81,7 @@ private fun getReferredInfo(
|
||||
val qName = resolvedClass.qualifiedName
|
||||
|
||||
if (SdkConstants.CLASS_R == qName || AndroidPsiElementFinder.INTERNAL_R_CLASS_QNAME == qName) {
|
||||
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, resolvedModule, true, false)
|
||||
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, true, false)
|
||||
}
|
||||
val containingFile = resolvedClass.containingFile ?: return null
|
||||
|
||||
@@ -95,7 +93,7 @@ private fun getReferredInfo(
|
||||
return null
|
||||
}
|
||||
|
||||
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, resolvedModule, false, fromManifest)
|
||||
return AndroidResourceUtil.MyReferredResourceFieldInfo(resClassName, resFieldName, false, fromManifest)
|
||||
}
|
||||
|
||||
private fun getReceiverAsSimpleNameExpression(exp: KtSimpleNameExpression): KtSimpleNameExpression? {
|
||||
|
||||
@@ -121,7 +121,7 @@ public abstract class AndroidTestCase extends AndroidTestBase {
|
||||
Module additionalModule = data.myModuleFixtureBuilder.getFixture().getModule();
|
||||
myAdditionalModules.add(additionalModule);
|
||||
AndroidFacet facet = addAndroidFacet(additionalModule);
|
||||
facet.setProjectType(data.myProjectType);
|
||||
facet.setLibraryProject(data.myProjectType == 1);
|
||||
String rootPath = getAdditionalModulePath(data.myDirName);
|
||||
myFixture.copyDirectoryToProject(getResDir(), rootPath + "/res");
|
||||
myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, rootPath + '/' + SdkConstants.FN_ANDROID_MANIFEST_XML);
|
||||
|
||||
@@ -70,6 +70,7 @@ import org.jetbrains.kotlin.util.kind
|
||||
import org.jetbrains.kotlin.util.supertypesWithAny
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import java.util.*
|
||||
|
||||
class BasicCompletionSession(
|
||||
configuration: CompletionSessionConfiguration,
|
||||
@@ -223,13 +224,6 @@ class BasicCompletionSession(
|
||||
}
|
||||
}
|
||||
|
||||
withCollectRequiredContextVariableTypes { lookupFactory ->
|
||||
DslMembersCompletion(
|
||||
prefixMatcher, lookupFactory, receiverTypes,
|
||||
collector, indicesHelper(true), callTypeAndReceiver
|
||||
).completeDslFunctions()
|
||||
}
|
||||
|
||||
val contextVariableTypesForSmartCompletion = withCollectRequiredContextVariableTypes(::completeWithSmartCompletion)
|
||||
|
||||
val contextVariableTypesForReferenceVariants = withCollectRequiredContextVariableTypes { lookupElementFactory ->
|
||||
@@ -464,14 +458,8 @@ class BasicCompletionSession(
|
||||
.filterNot { it.original in foundDescriptors }
|
||||
.onEach { foundDescriptors += it.original }
|
||||
|
||||
collector.addDescriptorElements(
|
||||
unique.toList(), factory,
|
||||
prohibitDuplicates = true
|
||||
)
|
||||
collector.addDescriptorElements(
|
||||
uniqueNotImportedExtensions.toList(), factory,
|
||||
notImported = true, prohibitDuplicates = true
|
||||
)
|
||||
collector.addDescriptorElements(unique.toList(), factory)
|
||||
collector.addDescriptorElements(uniqueNotImportedExtensions.toList(), factory, notImported = true)
|
||||
|
||||
flushToResultSet()
|
||||
}
|
||||
@@ -792,14 +780,8 @@ class BasicCompletionSession(
|
||||
|
||||
private fun addReferenceVariantElements(lookupElementFactory: LookupElementFactory, descriptorKindFilter: DescriptorKindFilter) {
|
||||
fun addReferenceVariants(referenceVariants: ReferenceVariants) {
|
||||
collector.addDescriptorElements(
|
||||
referenceVariantsHelper.excludeNonInitializedVariable(referenceVariants.imported, position),
|
||||
lookupElementFactory, prohibitDuplicates = true
|
||||
)
|
||||
collector.addDescriptorElements(
|
||||
referenceVariants.notImportedExtensions, lookupElementFactory,
|
||||
notImported = true, prohibitDuplicates = true
|
||||
)
|
||||
collector.addDescriptorElements(referenceVariantsHelper.excludeNonInitializedVariable(referenceVariants.imported, position), lookupElementFactory)
|
||||
collector.addDescriptorElements(referenceVariants.notImportedExtensions, lookupElementFactory, notImported = true)
|
||||
}
|
||||
|
||||
val referenceVariantsCollector = referenceVariantsCollector!!
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.idea.completion
|
||||
|
||||
import com.intellij.codeInsight.lookup.*
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
@@ -30,7 +29,6 @@ import org.jetbrains.kotlin.idea.completion.handlers.KotlinClassifierInsertHandl
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.KotlinFunctionInsertHandler
|
||||
import org.jetbrains.kotlin.idea.core.completion.DeclarationLookupObject
|
||||
import org.jetbrains.kotlin.idea.core.completion.PackageLookupObject
|
||||
import org.jetbrains.kotlin.idea.highlighter.dsl.DslHighlighterExtension
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -39,10 +37,11 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.synthetic.SamAdapterExtensionFunctionDescriptor
|
||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
import java.awt.Font
|
||||
import javax.swing.Icon
|
||||
|
||||
class BasicLookupElementFactory(
|
||||
private val project: Project,
|
||||
@@ -234,14 +233,6 @@ class BasicLookupElementFactory(
|
||||
|
||||
if (descriptor is CallableDescriptor) {
|
||||
appendContainerAndReceiverInformation(descriptor) { element = element.appendTailText(it, true) }
|
||||
|
||||
val dslTextAttributes = DslHighlighterExtension.dslCustomTextStyle(descriptor)?.let {
|
||||
EditorColorsManager.getInstance().globalScheme.getAttributes(it)
|
||||
}
|
||||
if (dslTextAttributes != null) {
|
||||
element = element.withBoldness(dslTextAttributes.fontType == Font.BOLD)
|
||||
dslTextAttributes.foregroundColor?.let { element = element.withItemTextForeground(it) }
|
||||
}
|
||||
}
|
||||
|
||||
if (descriptor is PropertyDescriptor) {
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
@@ -49,9 +50,9 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import java.util.*
|
||||
import kotlin.collections.LinkedHashMap
|
||||
|
||||
class CompletionSessionConfiguration(
|
||||
val useBetterPrefixMatcherForNonImportedClasses: Boolean,
|
||||
@@ -271,12 +272,6 @@ abstract class CompletionSession(
|
||||
|
||||
sorter = sorter.weighAfter("kotlin.proximity", ByNameAlphabeticalWeigher, PreferLessParametersWeigher)
|
||||
|
||||
if (expectedInfos.all { it.fuzzyType?.type?.isUnit() == true }) {
|
||||
sorter = sorter.weighBefore("prefix", PreferDslMembers)
|
||||
} else {
|
||||
sorter = sorter.weighAfter("kotlin.preferContextElements", PreferDslMembers)
|
||||
}
|
||||
|
||||
return sorter
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,6 @@ enum class ItemPriority {
|
||||
}
|
||||
|
||||
val ITEM_PRIORITY_KEY = Key<ItemPriority>("ITEM_PRIORITY_KEY")
|
||||
var LookupElement.isDslMember: Boolean? by UserDataProperty(Key.create("DSL_LOOKUP_ITEM"))
|
||||
|
||||
fun LookupElement.assignPriority(priority: ItemPriority): LookupElement {
|
||||
putUserData(ITEM_PRIORITY_KEY, priority)
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.completion
|
||||
|
||||
import com.intellij.codeInsight.completion.PrefixMatcher
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.core.KotlinIndicesHelper
|
||||
import org.jetbrains.kotlin.idea.util.CallTypeAndReceiver
|
||||
import org.jetbrains.kotlin.idea.util.ReceiverType
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.psi.psiUtil.collectAnnotationEntriesFromStubOrPsi
|
||||
import org.jetbrains.kotlin.resolve.calls.DslMarkerUtils
|
||||
|
||||
class DslMembersCompletion(
|
||||
private val prefixMatcher: PrefixMatcher,
|
||||
private val elementFactory: LookupElementFactory,
|
||||
receiverTypes: Collection<ReceiverType>?,
|
||||
private val collector: LookupElementsCollector,
|
||||
private val indicesHelper: KotlinIndicesHelper,
|
||||
private val callTypeAndReceiver: CallTypeAndReceiver<*, *>
|
||||
) {
|
||||
private val nearestReceiver = receiverTypes?.firstOrNull()
|
||||
private val nearestReceiverMarkers = nearestReceiver?.takeIf { it.implicit }
|
||||
?.let { DslMarkerUtils.extractDslMarkerFqNames(it.type) }.orEmpty()
|
||||
|
||||
private val factory = object : AbstractLookupElementFactory {
|
||||
override fun createLookupElement(
|
||||
descriptor: DeclarationDescriptor,
|
||||
useReceiverTypes: Boolean,
|
||||
qualifyNestedClasses: Boolean,
|
||||
includeClassTypeArguments: Boolean,
|
||||
parametersAndTypeGrayed: Boolean
|
||||
): LookupElement? {
|
||||
error("Should not be called")
|
||||
}
|
||||
|
||||
override fun createStandardLookupElementsForDescriptor(
|
||||
descriptor: DeclarationDescriptor,
|
||||
useReceiverTypes: Boolean
|
||||
): Collection<LookupElement> {
|
||||
return elementFactory.createStandardLookupElementsForDescriptor(descriptor, useReceiverTypes).also {
|
||||
it.forEach { element ->
|
||||
element.isDslMember = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun completeDslFunctions() {
|
||||
if (nearestReceiver == null || nearestReceiverMarkers.isEmpty()) return
|
||||
|
||||
val receiverMarkersShortNames = nearestReceiverMarkers.map { it.shortName() }.distinct()
|
||||
val extensionDescriptors = indicesHelper.getCallableTopLevelExtensions(
|
||||
nameFilter = { prefixMatcher.prefixMatches(it) },
|
||||
declarationFilter = {
|
||||
(it as KtModifierListOwner).modifierList?.collectAnnotationEntriesFromStubOrPsi()?.any { it.shortName in receiverMarkersShortNames }
|
||||
?: false
|
||||
},
|
||||
callTypeAndReceiver = callTypeAndReceiver,
|
||||
receiverTypes = listOf(nearestReceiver.type)
|
||||
)
|
||||
extensionDescriptors.forEach {
|
||||
collector.addDescriptorElements(it, factory, notImported = true, withReceiverCast = false, prohibitDuplicates = true)
|
||||
}
|
||||
|
||||
collector.flushToResultSet()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,7 +22,6 @@ import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementDecorator
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.patterns.ElementPattern
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.WithExpressionPrefixInsertHandler
|
||||
import org.jetbrains.kotlin.idea.completion.handlers.WithTailInsertHandler
|
||||
@@ -48,7 +47,6 @@ class LookupElementsCollector(
|
||||
.withRelevanceSorter(sorter)
|
||||
|
||||
private val postProcessors = ArrayList<(LookupElement) -> LookupElement>()
|
||||
private val processedCallables = mutableSetOf<CallableDescriptor>()
|
||||
|
||||
var isResultEmpty: Boolean = true
|
||||
private set
|
||||
@@ -68,27 +66,22 @@ class LookupElementsCollector(
|
||||
postProcessors.add(processor)
|
||||
}
|
||||
|
||||
fun addDescriptorElements(
|
||||
descriptors: Iterable<DeclarationDescriptor>,
|
||||
lookupElementFactory: AbstractLookupElementFactory,
|
||||
notImported: Boolean = false,
|
||||
withReceiverCast: Boolean = false,
|
||||
prohibitDuplicates: Boolean = false
|
||||
fun addDescriptorElements(descriptors: Iterable<DeclarationDescriptor>,
|
||||
lookupElementFactory: LookupElementFactory,
|
||||
notImported: Boolean = false,
|
||||
withReceiverCast: Boolean = false
|
||||
) {
|
||||
for (descriptor in descriptors) {
|
||||
addDescriptorElements(descriptor, lookupElementFactory, notImported, withReceiverCast, prohibitDuplicates)
|
||||
addDescriptorElements(descriptor, lookupElementFactory, notImported, withReceiverCast)
|
||||
}
|
||||
}
|
||||
|
||||
fun addDescriptorElements(
|
||||
descriptor: DeclarationDescriptor,
|
||||
lookupElementFactory: AbstractLookupElementFactory,
|
||||
notImported: Boolean = false,
|
||||
withReceiverCast: Boolean = false,
|
||||
prohibitDuplicates: Boolean = false
|
||||
descriptor: DeclarationDescriptor,
|
||||
lookupElementFactory: LookupElementFactory,
|
||||
notImported: Boolean = false,
|
||||
withReceiverCast: Boolean = false
|
||||
) {
|
||||
if (prohibitDuplicates && descriptor is CallableDescriptor && descriptor in processedCallables) return
|
||||
|
||||
var lookupElements = lookupElementFactory.createStandardLookupElementsForDescriptor(descriptor, useReceiverTypes = true)
|
||||
|
||||
if (withReceiverCast) {
|
||||
@@ -96,8 +89,6 @@ class LookupElementsCollector(
|
||||
}
|
||||
|
||||
addElements(lookupElements, notImported)
|
||||
|
||||
if (prohibitDuplicates && descriptor is CallableDescriptor) processedCallables.add(descriptor)
|
||||
}
|
||||
|
||||
fun addElement(element: LookupElement, notImported: Boolean = false) {
|
||||
|
||||
@@ -43,13 +43,6 @@ object PriorityWeigher : LookupElementWeigher("kotlin.priority") {
|
||||
= element.getUserData(ITEM_PRIORITY_KEY) ?: ItemPriority.DEFAULT
|
||||
}
|
||||
|
||||
object PreferDslMembers : LookupElementWeigher("kotlin.preferDsl") {
|
||||
override fun weigh(element: LookupElement, context: WeighingContext): Boolean {
|
||||
if (element.isDslMember == true) return false // high priority
|
||||
return true // lower priority
|
||||
}
|
||||
}
|
||||
|
||||
class NotImportedWeigher(private val classifier: ImportableFqNameClassifier) : LookupElementWeigher("kotlin.notImported") {
|
||||
private enum class Weight {
|
||||
default,
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
// RUNTIME
|
||||
package test
|
||||
|
||||
import bar.r
|
||||
import bar.foo3
|
||||
|
||||
fun main() {
|
||||
val foo5 = 3
|
||||
r {
|
||||
val j: String = foo<caret>
|
||||
}
|
||||
}
|
||||
|
||||
@DslMarker
|
||||
annotation class Dsl
|
||||
|
||||
|
||||
@Dsl
|
||||
class R
|
||||
|
||||
fun r(body: R.() -> Unit) {
|
||||
|
||||
}
|
||||
|
||||
fun foo1(i: Int): String ""
|
||||
|
||||
fun foo3() {
|
||||
|
||||
}
|
||||
|
||||
@Dsl
|
||||
fun R.foobar2(): String = ""
|
||||
|
||||
@Dsl
|
||||
fun R.foobar4() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ORDER: foobar2
|
||||
// ORDER: foo1
|
||||
// ORDER: foo5
|
||||
// ORDER: foobar4
|
||||
// ORDER: foo3
|
||||
@@ -1,42 +0,0 @@
|
||||
package bar
|
||||
|
||||
@DslMarker
|
||||
annotation class Dsl
|
||||
|
||||
|
||||
@Dsl
|
||||
class R
|
||||
|
||||
fun r(body: R.() -> Unit) {
|
||||
|
||||
}
|
||||
|
||||
fun foo1(i: Int) {
|
||||
|
||||
}
|
||||
|
||||
fun foo3() {
|
||||
|
||||
}
|
||||
|
||||
@Dsl
|
||||
fun R.foo2() {}
|
||||
|
||||
@Dsl
|
||||
fun R.foo4() {
|
||||
|
||||
}
|
||||
|
||||
@Dsl
|
||||
fun R.fooloooooong() {
|
||||
|
||||
}
|
||||
|
||||
val R.fooval
|
||||
get() = Unit
|
||||
|
||||
@Dsl
|
||||
fun R.SomethingSomethingFooSomething() {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
// RUNTIME
|
||||
package test
|
||||
|
||||
import bar.r
|
||||
import bar.foo3
|
||||
|
||||
fun main() {
|
||||
val foo5 = 3
|
||||
r {
|
||||
foo<caret>
|
||||
}
|
||||
}
|
||||
|
||||
// ORDER: foo2
|
||||
// ORDER: foo4
|
||||
// ORDER: fooloooooong
|
||||
// ORDER: foo3
|
||||
// ORDER: foo5
|
||||
// ORDER: fooval
|
||||
// ORDER: foo1
|
||||
@@ -1,8 +0,0 @@
|
||||
package dsl
|
||||
|
||||
import test.Dsl
|
||||
import test.R
|
||||
|
||||
@Dsl
|
||||
fun R.foo2() {}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
// RUNTIME
|
||||
package test
|
||||
|
||||
class HasFoo {
|
||||
fun foo10() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val foo5 = 3
|
||||
with(0) {
|
||||
with("") {
|
||||
with(HasFoo()) {
|
||||
r {
|
||||
foo<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DslMarker
|
||||
annotation class Dsl
|
||||
|
||||
|
||||
@Dsl
|
||||
class R
|
||||
|
||||
fun r(body: R.() -> Unit) {
|
||||
|
||||
}
|
||||
|
||||
fun foo1(i: Int) {
|
||||
|
||||
}
|
||||
|
||||
// ORDER: foo2
|
||||
// ORDER: foo10
|
||||
// ORDER: foo1
|
||||
// ORDER: foo5
|
||||
@@ -41,7 +41,7 @@ abstract class AbstractCompletionHandlerTest(private val defaultCompletionType:
|
||||
|
||||
val settingManager = CodeStyleSettingsManager.getInstance()
|
||||
val tempSettings = settingManager.currentSettings.clone()
|
||||
settingManager.setTemporarySettings(tempSettings)
|
||||
settingManager.temporarySettings = tempSettings
|
||||
try {
|
||||
val fileText = FileUtil.loadFile(File(testPath))
|
||||
assertTrue("\"<caret>\" is missing in file \"$testPath\"", fileText.contains("<caret>"));
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.CompletionType
|
||||
import org.jetbrains.kotlin.idea.completion.test.RELATIVE_COMPLETION_TEST_DATA_BASE_PATH
|
||||
import org.jetbrains.kotlin.idea.completion.test.configureWithExtraFile
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.junit.Assert
|
||||
@@ -43,6 +44,7 @@ abstract class AbstractCompletionWeigherTest(val completionType: CompletionType,
|
||||
}
|
||||
|
||||
abstract class AbstractBasicCompletionWeigherTest() : AbstractCompletionWeigherTest(CompletionType.BASIC, "weighers/basic") {
|
||||
override fun getProjectDescriptor() = KotlinLightProjectDescriptor.INSTANCE
|
||||
}
|
||||
|
||||
abstract class AbstractSmartCompletionWeigherTest() : AbstractCompletionWeigherTest(CompletionType.SMART, "weighers/smart") {
|
||||
|
||||
@@ -61,24 +61,6 @@ public class BasicCompletionWeigherTestGenerated extends AbstractBasicCompletion
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("DslCallWithExpectedType.kt")
|
||||
public void testDslCallWithExpectedType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/DslCallWithExpectedType.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("DslCalls.kt")
|
||||
public void testDslCalls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/DslCalls.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("DslCallsWithMultipleReceivers.kt")
|
||||
public void testDslCallsWithMultipleReceivers() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/DslCallsWithMultipleReceivers.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ExactMatchForKeyword.kt")
|
||||
public void testExactMatchForKeyword() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/weighers/basic/ExactMatchForKeyword.kt");
|
||||
|
||||
@@ -20,6 +20,8 @@ dependencies {
|
||||
compile(project(":plugins:android-extensions-compiler"))
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-core")) { isTransitive = false }
|
||||
compile(commonDep("org.jetbrains.kotlinx", "kotlinx-coroutines-jdk8")) { isTransitive = false }
|
||||
compile(commonDep("org.jetbrains.uast", "uast-common")) { isTransitive = false }
|
||||
compile(commonDep("org.jetbrains.uast", "uast-java")) { isTransitive = false }
|
||||
compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||
compileOnly(intellijDep()) { includeJars("util", "openapi", "idea", "asm-all", "jdom", "annotations", "trove4j", "guava", rootProject = rootProject) }
|
||||
compileOnly(intellijPluginDep("gradle")) { includeJars("gradle-tooling-api", "gradle", rootProject = rootProject) }
|
||||
|
||||
@@ -145,8 +145,7 @@ class KotlinIndicesHelper(
|
||||
fun getCallableTopLevelExtensions(
|
||||
callTypeAndReceiver: CallTypeAndReceiver<*, *>,
|
||||
receiverTypes: Collection<KotlinType>,
|
||||
nameFilter: (String) -> Boolean,
|
||||
declarationFilter: (KtDeclaration) -> Boolean = { true }
|
||||
nameFilter: (String) -> Boolean
|
||||
): Collection<CallableDescriptor> {
|
||||
if (receiverTypes.isEmpty()) return emptyList()
|
||||
|
||||
@@ -162,7 +161,7 @@ class KotlinIndicesHelper(
|
||||
KotlinTopLevelExtensionsByReceiverTypeIndex.receiverTypeNameFromKey(it) in receiverTypeNames
|
||||
&& nameFilter(KotlinTopLevelExtensionsByReceiverTypeIndex.callableNameFromKey(it))
|
||||
}
|
||||
.flatMap { index.get(it, project, scope).asSequence() }.filter(declarationFilter)
|
||||
.flatMap { index.get(it, project, scope).asSequence() }
|
||||
|
||||
val suitableExtensions = findSuitableExtensions(declarations, receiverTypes, callTypeAndReceiver.callType)
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.addRemoveModifier.MODIFIERS_ORDER
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.psi.typeRefHelpers.setReceiverTypeReference
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -44,7 +43,6 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.isError
|
||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
inline fun <reified T : PsiElement> PsiElement.replaced(newElement: T): T {
|
||||
@@ -449,30 +447,6 @@ fun KtParameter.setDefaultValue(newDefaultValue: KtExpression): PsiElement? {
|
||||
return addAfter(newDefaultValue, eq) as KtExpression
|
||||
}
|
||||
|
||||
fun KtModifierList.appendModifier(modifier: KtModifierKeywordToken) {
|
||||
add(KtPsiFactory(this).createModifier(modifier))
|
||||
}
|
||||
|
||||
fun KtModifierList.normalize(): KtModifierList {
|
||||
val psiFactory = KtPsiFactory(this)
|
||||
return psiFactory.createEmptyModifierList().also { newList ->
|
||||
val modifiers = SmartList<PsiElement>()
|
||||
allChildren.forEach {
|
||||
val elementType = it.node.elementType
|
||||
when {
|
||||
it is KtAnnotation || it is KtAnnotationEntry -> newList.add(it)
|
||||
elementType is KtModifierKeywordToken -> {
|
||||
if (elementType == KtTokens.DEFAULT_VISIBILITY_KEYWORD) return@forEach
|
||||
if (elementType == KtTokens.FINALLY_KEYWORD && !hasModifier(KtTokens.OVERRIDE_KEYWORD)) return@forEach
|
||||
modifiers.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
modifiers.sortBy { MODIFIERS_ORDER.indexOf(it.node.elementType) }
|
||||
modifiers.forEach { newList.add(it) }
|
||||
}
|
||||
}
|
||||
|
||||
fun KtBlockStringTemplateEntry.canDropBraces() =
|
||||
expression is KtNameReferenceExpression && canPlaceAfterSimpleNameEntry(nextSibling)
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.progress.Task
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.isProjectOrWorkspaceFile
|
||||
import com.intellij.openapi.project.ProjectUtil
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.roots.ex.ProjectRootManagerEx
|
||||
import com.intellij.openapi.util.EmptyRunnable
|
||||
@@ -267,7 +267,7 @@ class ScriptDependenciesUpdater(
|
||||
// the isUnitTestMode check fixes ScriptConfigurationHighlighting & Navigation tests, since they are not trigger proper update mechanims
|
||||
// TODO: find out the reason, then consider to fix tests and remove this check
|
||||
(application.isUnitTestMode ||
|
||||
scriptDefinitionProvider.isScript(it.name) && projectFileIndex.isInContent(it)) && !isProjectOrWorkspaceFile(it)
|
||||
scriptDefinitionProvider.isScript(it.name) && projectFileIndex.isInContent(it)) && !ProjectUtil.isProjectOrWorkspaceFile(it)
|
||||
}
|
||||
}
|
||||
requestUpdate(modifiedScripts)
|
||||
|
||||
@@ -14,12 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
@file:JvmName("GradleKotlinDSLConstants")
|
||||
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
package org.jetbrains.kotlin.gradle.kdsl
|
||||
|
||||
fun ModuleChunk.isDummy(context: CompileContext): Boolean {
|
||||
val targetIndex = context.projectDescriptor.buildTargetIndex
|
||||
return targets.all { targetIndex.isDummy(it) }
|
||||
}
|
||||
const val DEFAULT_SCRIPT_NAME = "build.gradle.kts"
|
||||
@@ -0,0 +1,55 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.kotlin.gradle.kdsl.GradleFrameworksWizardStep">
|
||||
<grid id="27dc6" binding="myPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="22e59" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="ad16" binding="myOptionsPanel" layout-manager="CardLayout" hgap="0" vgap="0">
|
||||
<constraints border-constraint="Center"/>
|
||||
<properties/>
|
||||
<clientProperties>
|
||||
<BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
|
||||
</clientProperties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="27a92" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<card name="templates card"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
<grid id="b50ee" binding="myFrameworksPanelPlaceholder" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<card name="frameworks card"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="916d9" class="com.intellij.ui.components.JBLabel" binding="myFrameworksLabel">
|
||||
<constraints border-constraint="North"/>
|
||||
<properties>
|
||||
<text value="Additional Libraries and &Frameworks:"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.gradle.kdsl;
|
||||
|
||||
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
|
||||
import com.intellij.ide.util.newProjectWizard.AddSupportForFrameworksPanel;
|
||||
import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
|
||||
import com.intellij.ide.util.projectWizard.ModuleBuilder;
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
|
||||
import com.intellij.ide.util.projectWizard.WizardContext;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
|
||||
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleFrameworkSupportProvider;
|
||||
import org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleJavaFrameworkSupportProvider;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class GradleFrameworksWizardStep extends ModuleWizardStep implements Disposable {
|
||||
|
||||
private JPanel myPanel;
|
||||
private final AddSupportForFrameworksPanel myFrameworksPanel;
|
||||
private JPanel myFrameworksPanelPlaceholder;
|
||||
private JPanel myOptionsPanel;
|
||||
@SuppressWarnings("unused") private JBLabel myFrameworksLabel;
|
||||
|
||||
public GradleFrameworksWizardStep(WizardContext context, final ModuleBuilder builder) {
|
||||
|
||||
Project project = context.getProject();
|
||||
final LibrariesContainer container = LibrariesContainerFactory.createContainer(context.getProject());
|
||||
FrameworkSupportModelBase model = new FrameworkSupportModelBase(project, null, container) {
|
||||
@NotNull
|
||||
@Override
|
||||
public String getBaseDirectoryForLibrariesPath() {
|
||||
return StringUtil.notNullize(builder.getContentEntryPath());
|
||||
}
|
||||
};
|
||||
|
||||
myFrameworksPanel =
|
||||
new AddSupportForFrameworksPanel(Collections.emptyList(), model, true, null);
|
||||
|
||||
List<FrameworkSupportInModuleProvider> providers = ContainerUtil.newArrayList();
|
||||
Collections.addAll(providers, GradleFrameworkSupportProvider.EP_NAME.getExtensions());
|
||||
|
||||
myFrameworksPanel.setProviders(providers, Collections.emptySet(), Collections.singleton(GradleJavaFrameworkSupportProvider.ID));
|
||||
Disposer.register(this, myFrameworksPanel);
|
||||
myFrameworksPanelPlaceholder.add(myFrameworksPanel.getMainPanel());
|
||||
|
||||
ModuleBuilder.ModuleConfigurationUpdater configurationUpdater = new ModuleBuilder.ModuleConfigurationUpdater() {
|
||||
@Override
|
||||
public void update(@NotNull Module module, @NotNull ModifiableRootModel rootModel) {
|
||||
myFrameworksPanel.addSupport(module, rootModel);
|
||||
}
|
||||
};
|
||||
builder.addModuleConfigurationUpdater(configurationUpdater);
|
||||
|
||||
((CardLayout)myOptionsPanel.getLayout()).show(myOptionsPanel, "frameworks card");
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getComponent() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDataModel() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
Disposer.dispose(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,474 @@
|
||||
/*
|
||||
* 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.gradle.kdsl;
|
||||
|
||||
import com.intellij.ide.fileTemplates.FileTemplate;
|
||||
import com.intellij.ide.fileTemplates.FileTemplateManager;
|
||||
import com.intellij.ide.highlighter.ModuleFileType;
|
||||
import com.intellij.ide.projectWizard.ProjectSettingsStep;
|
||||
import com.intellij.ide.util.EditorHelper;
|
||||
import com.intellij.ide.util.projectWizard.JavaModuleBuilder;
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
|
||||
import com.intellij.ide.util.projectWizard.SettingsStep;
|
||||
import com.intellij.ide.util.projectWizard.WizardContext;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.components.StorageScheme;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.externalSystem.model.ExternalSystemDataKeys;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectId;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
|
||||
import com.intellij.openapi.externalSystem.service.project.wizard.AbstractExternalModuleBuilder;
|
||||
import com.intellij.openapi.externalSystem.service.project.wizard.ExternalModuleSettingsStep;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
|
||||
import com.intellij.openapi.module.*;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkType;
|
||||
import com.intellij.openapi.projectRoots.SdkTypeId;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.io.FileUtilRt;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.gradle.util.GradleVersion;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.BuildScriptDataBuilder;
|
||||
import org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.KotlinBuildScriptDataBuilder;
|
||||
import org.jetbrains.plugins.gradle.service.settings.GradleProjectSettingsControl;
|
||||
import org.jetbrains.plugins.gradle.settings.DistributionType;
|
||||
import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.kotlin.gradle.kdsl.GradleKotlinDSLConstants.DEFAULT_SCRIPT_NAME;
|
||||
|
||||
public class GradleModuleBuilder extends AbstractExternalModuleBuilder<GradleProjectSettings> {
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(GradleModuleBuilder.class);
|
||||
|
||||
private static final String TEMPLATE_GRADLE_SETTINGS = "Gradle Kotlin DSL Settings.gradle";
|
||||
private static final String TEMPLATE_GRADLE_SETTINGS_MERGE = "Gradle Settings merge.gradle";
|
||||
private static final String TEMPLATE_GRADLE_BUILD_WITH_WRAPPER = "Gradle Build Script with wrapper.gradle";
|
||||
private static final String DEFAULT_TEMPLATE_GRADLE_BUILD = "Gradle Kotlin DSL Build Script.gradle";
|
||||
|
||||
private static final String TEMPLATE_ATTRIBUTE_PROJECT_NAME = "PROJECT_NAME";
|
||||
private static final String TEMPLATE_ATTRIBUTE_MODULE_PATH = "MODULE_PATH";
|
||||
private static final String TEMPLATE_ATTRIBUTE_MODULE_FLAT_DIR = "MODULE_FLAT_DIR";
|
||||
private static final String TEMPLATE_ATTRIBUTE_MODULE_NAME = "MODULE_NAME";
|
||||
private static final String TEMPLATE_ATTRIBUTE_MODULE_GROUP = "MODULE_GROUP";
|
||||
private static final String TEMPLATE_ATTRIBUTE_MODULE_VERSION = "MODULE_VERSION";
|
||||
private static final String TEMPLATE_ATTRIBUTE_GRADLE_VERSION = "GRADLE_VERSION";
|
||||
private static final String TEMPLATE_ATTRIBUTE_BUILD_FILE_NAME = "BUILD_FILE_NAME";
|
||||
private static final Key<KotlinBuildScriptDataBuilder> BUILD_SCRIPT_DATA =
|
||||
Key.create("gradle.module.kotlinBuildScriptData");
|
||||
|
||||
private WizardContext myWizardContext;
|
||||
|
||||
@Nullable
|
||||
private ProjectData myParentProject;
|
||||
private boolean myInheritGroupId;
|
||||
private boolean myInheritVersion;
|
||||
private ProjectId myProjectId;
|
||||
private String rootProjectPath;
|
||||
|
||||
public GradleModuleBuilder() {
|
||||
super(GradleConstants.SYSTEM_ID, new GradleProjectSettings());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "Gradle (Kotlin DSL)";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Module createModule(@NotNull ModifiableModuleModel moduleModel)
|
||||
throws InvalidDataException, IOException, ModuleWithNameAlreadyExists, JDOMException, ConfigurationException {
|
||||
LOG.assertTrue(getName() != null);
|
||||
final String originModuleFilePath = getModuleFilePath();
|
||||
LOG.assertTrue(originModuleFilePath != null);
|
||||
|
||||
String moduleName;
|
||||
if (myProjectId == null) {
|
||||
moduleName = getName();
|
||||
}
|
||||
else {
|
||||
moduleName = ModuleGrouperKt.isQualifiedModuleNamesEnabled() && StringUtil.isNotEmpty(myProjectId.getGroupId())
|
||||
? (myProjectId.getGroupId() + '.' + myProjectId.getArtifactId())
|
||||
: myProjectId.getArtifactId();
|
||||
}
|
||||
Project contextProject = myWizardContext.getProject();
|
||||
String projectFileDirectory = null;
|
||||
if (myWizardContext.isCreatingNewProject() || contextProject == null || contextProject.getBasePath() == null) {
|
||||
projectFileDirectory = myWizardContext.getProjectFileDirectory();
|
||||
}
|
||||
else if (myWizardContext.getProjectStorageFormat() == StorageScheme.DEFAULT) {
|
||||
String moduleFileDirectory = getModuleFileDirectory();
|
||||
if (moduleFileDirectory != null) {
|
||||
projectFileDirectory = moduleFileDirectory;
|
||||
}
|
||||
}
|
||||
if (projectFileDirectory == null) {
|
||||
projectFileDirectory = contextProject.getBasePath();
|
||||
}
|
||||
if (myWizardContext.getProjectStorageFormat() == StorageScheme.DIRECTORY_BASED) {
|
||||
projectFileDirectory += "/.idea/modules";
|
||||
}
|
||||
String moduleFilePath = projectFileDirectory + "/" + moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION;
|
||||
deleteModuleFile(moduleFilePath);
|
||||
final ModuleType moduleType = getModuleType();
|
||||
final Module module = moduleModel.newModule(moduleFilePath, moduleType.getId());
|
||||
setupModule(module);
|
||||
return module;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupRootModel(final ModifiableRootModel modifiableRootModel) throws ConfigurationException {
|
||||
String contentEntryPath = getContentEntryPath();
|
||||
if (StringUtil.isEmpty(contentEntryPath)) {
|
||||
return;
|
||||
}
|
||||
File contentRootDir = new File(contentEntryPath);
|
||||
FileUtilRt.createDirectory(contentRootDir);
|
||||
LocalFileSystem fileSystem = LocalFileSystem.getInstance();
|
||||
VirtualFile modelContentRootDir = fileSystem.refreshAndFindFileByIoFile(contentRootDir);
|
||||
if (modelContentRootDir == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
modifiableRootModel.addContentEntry(modelContentRootDir);
|
||||
// todo this should be moved to generic ModuleBuilder
|
||||
if (myJdk != null) {
|
||||
modifiableRootModel.setSdk(myJdk);
|
||||
}
|
||||
else {
|
||||
modifiableRootModel.inheritSdk();
|
||||
}
|
||||
|
||||
final Project project = modifiableRootModel.getProject();
|
||||
if (myParentProject != null) {
|
||||
rootProjectPath = myParentProject.getLinkedExternalProjectPath();
|
||||
}
|
||||
else {
|
||||
rootProjectPath =
|
||||
FileUtil.toCanonicalPath(myWizardContext.isCreatingNewProject() ? project.getBasePath() : modelContentRootDir.getPath());
|
||||
}
|
||||
assert rootProjectPath != null;
|
||||
|
||||
final VirtualFile gradleBuildFile = setupGradleBuildFile(modelContentRootDir);
|
||||
setupGradleSettingsFile(
|
||||
rootProjectPath, modelContentRootDir, modifiableRootModel.getProject().getName(),
|
||||
myProjectId == null ? modifiableRootModel.getModule().getName() : myProjectId.getArtifactId(),
|
||||
myWizardContext.isCreatingNewProject() || myParentProject == null
|
||||
);
|
||||
|
||||
if (gradleBuildFile != null) {
|
||||
modifiableRootModel.getModule().putUserData(
|
||||
BUILD_SCRIPT_DATA, new KotlinBuildScriptDataBuilder(gradleBuildFile));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupModule(Module module) throws ConfigurationException {
|
||||
super.setupModule(module);
|
||||
assert rootProjectPath != null;
|
||||
|
||||
VirtualFile buildScriptFile = null;
|
||||
final BuildScriptDataBuilder buildScriptDataBuilder = getBuildScriptData(module);
|
||||
try {
|
||||
if (buildScriptDataBuilder != null) {
|
||||
buildScriptFile = buildScriptDataBuilder.getBuildScriptFile();
|
||||
String lineSeparator = lineSeparator(buildScriptFile);
|
||||
String configurationPart = StringUtil.convertLineSeparators(buildScriptDataBuilder.buildConfigurationPart(), lineSeparator);
|
||||
String existingText = StringUtil.trimTrailing(VfsUtilCore.loadText(buildScriptFile));
|
||||
String content = (!configurationPart.isEmpty() ? configurationPart + lineSeparator : "") +
|
||||
(!existingText.isEmpty() ? existingText + lineSeparator : "") +
|
||||
lineSeparator +
|
||||
StringUtil.convertLineSeparators(buildScriptDataBuilder.buildMainPart(), lineSeparator);
|
||||
VfsUtil.saveText(buildScriptFile, content);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn("Unexpected exception on applying frameworks templates", e);
|
||||
}
|
||||
|
||||
final Project project = module.getProject();
|
||||
if (myWizardContext.isCreatingNewProject()) {
|
||||
getExternalProjectSettings().setExternalProjectPath(rootProjectPath);
|
||||
AbstractExternalSystemSettings settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID);
|
||||
project.putUserData(ExternalSystemDataKeys.NEWLY_CREATED_PROJECT, Boolean.TRUE);
|
||||
//noinspection unchecked
|
||||
settings.linkProject(getExternalProjectSettings());
|
||||
}
|
||||
else {
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
final GradleProjectSettings gradleProjectSettings = getExternalProjectSettings();
|
||||
final VirtualFile finalBuildScriptFile = buildScriptFile;
|
||||
Runnable runnable = () -> {
|
||||
if (myParentProject == null) {
|
||||
gradleProjectSettings.setExternalProjectPath(rootProjectPath);
|
||||
AbstractExternalSystemSettings settings = ExternalSystemApiUtil.getSettings(project, GradleConstants.SYSTEM_ID);
|
||||
//noinspection unchecked
|
||||
settings.linkProject(gradleProjectSettings);
|
||||
}
|
||||
|
||||
ExternalSystemUtil.refreshProject(
|
||||
project, GradleConstants.SYSTEM_ID, rootProjectPath, false,
|
||||
ProgressExecutionMode.IN_BACKGROUND_ASYNC);
|
||||
|
||||
final PsiFile psiFile;
|
||||
if (finalBuildScriptFile != null) {
|
||||
psiFile = PsiManager.getInstance(project).findFile(finalBuildScriptFile);
|
||||
if (psiFile != null) {
|
||||
EditorHelper.openInEditor(psiFile);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// execute when current dialog is closed
|
||||
ExternalSystemUtil.invokeLater(project, ModalityState.NON_MODAL, runnable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
|
||||
myWizardContext = wizardContext;
|
||||
return new ModuleWizardStep[]{
|
||||
new GradleModuleWizardStep(this, wizardContext),
|
||||
new ExternalModuleSettingsStep<>(
|
||||
wizardContext, this, new GradleProjectSettingsControl(getExternalProjectSettings()))
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) {
|
||||
final GradleFrameworksWizardStep step = new GradleFrameworksWizardStep(context, this);
|
||||
Disposer.register(parentDisposable, step);
|
||||
return step;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuitableSdkType(SdkTypeId sdk) {
|
||||
return sdk instanceof JavaSdkType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentGroup() {
|
||||
return JavaModuleType.BUILD_TOOLS_GROUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getWeight() {
|
||||
return JavaModuleBuilder.BUILD_SYSTEM_WEIGHT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModuleType getModuleType() {
|
||||
return StdModuleTypes.JAVA;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private VirtualFile setupGradleBuildFile(@NotNull VirtualFile modelContentRootDir)
|
||||
throws ConfigurationException {
|
||||
final VirtualFile file = getOrCreateExternalProjectConfigFile(modelContentRootDir.getPath(), GradleKotlinDSLConstants.DEFAULT_SCRIPT_NAME);
|
||||
|
||||
if (file != null) {
|
||||
final String templateName = getExternalProjectSettings().getDistributionType() == DistributionType.WRAPPED
|
||||
? TEMPLATE_GRADLE_BUILD_WITH_WRAPPER
|
||||
: DEFAULT_TEMPLATE_GRADLE_BUILD;
|
||||
Map<String, String> attributes = ContainerUtil.newHashMap();
|
||||
if (myProjectId != null) {
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_MODULE_VERSION, myProjectId.getVersion());
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_MODULE_GROUP, myProjectId.getGroupId());
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_GRADLE_VERSION, GradleVersion.current().getVersion());
|
||||
}
|
||||
saveFile(file, templateName, attributes);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static VirtualFile setupGradleSettingsFile(@NotNull String rootProjectPath,
|
||||
@NotNull VirtualFile modelContentRootDir,
|
||||
String projectName,
|
||||
String moduleName,
|
||||
boolean renderNewFile)
|
||||
throws ConfigurationException {
|
||||
final VirtualFile file = getOrCreateExternalProjectConfigFile(rootProjectPath, GradleConstants.SETTINGS_FILE_NAME);
|
||||
if (file == null) return null;
|
||||
|
||||
if (renderNewFile) {
|
||||
final String moduleDirName = VfsUtilCore.getRelativePath(modelContentRootDir, file.getParent(), '/');
|
||||
|
||||
Map<String, String> attributes = ContainerUtil.newHashMap();
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_PROJECT_NAME, projectName);
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_MODULE_PATH, moduleDirName);
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_MODULE_NAME, moduleName);
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_BUILD_FILE_NAME, DEFAULT_SCRIPT_NAME); // TODO: gradle > 4.0 doesn't need this
|
||||
saveFile(file, TEMPLATE_GRADLE_SETTINGS, attributes);
|
||||
}
|
||||
else {
|
||||
char separatorChar = file.getParent() == null || !VfsUtilCore.isAncestor(file.getParent(), modelContentRootDir, true) ? '/' : ':';
|
||||
String modulePath = VfsUtil.getPath(file, modelContentRootDir, separatorChar);
|
||||
|
||||
Map<String, String> attributes = ContainerUtil.newHashMap();
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_MODULE_NAME, moduleName);
|
||||
// check for flat structure
|
||||
final String flatStructureModulePath =
|
||||
modulePath != null && StringUtil.startsWith(modulePath, "../") ? StringUtil.trimStart(modulePath, "../") : null;
|
||||
if (StringUtil.equals(flatStructureModulePath, modelContentRootDir.getName())) {
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_MODULE_FLAT_DIR, "true");
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_MODULE_PATH, flatStructureModulePath);
|
||||
}
|
||||
else {
|
||||
attributes.put(TEMPLATE_ATTRIBUTE_MODULE_PATH, modulePath);
|
||||
}
|
||||
|
||||
appendToFile(file, TEMPLATE_GRADLE_SETTINGS_MERGE, attributes);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
private static void saveFile(@NotNull VirtualFile file, @NotNull String templateName, @Nullable Map templateAttributes)
|
||||
throws ConfigurationException {
|
||||
FileTemplateManager manager = FileTemplateManager.getDefaultInstance();
|
||||
FileTemplate template = manager.getInternalTemplate(templateName);
|
||||
try {
|
||||
appendToFile(file, templateAttributes != null ? template.getText(templateAttributes) : template.getText());
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn(String.format("Unexpected exception on applying template %s config", GradleConstants.SYSTEM_ID.getReadableName()), e);
|
||||
throw new ConfigurationException(
|
||||
e.getMessage(), String.format("Can't apply %s template config text", GradleConstants.SYSTEM_ID.getReadableName())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendToFile(@NotNull VirtualFile file, @NotNull String templateName, @Nullable Map templateAttributes)
|
||||
throws ConfigurationException {
|
||||
FileTemplateManager manager = FileTemplateManager.getDefaultInstance();
|
||||
FileTemplate template = manager.getInternalTemplate(templateName);
|
||||
try {
|
||||
appendToFile(file, templateAttributes != null ? template.getText(templateAttributes) : template.getText());
|
||||
}
|
||||
catch (IOException e) {
|
||||
LOG.warn(String.format("Unexpected exception on appending template %s config", GradleConstants.SYSTEM_ID.getReadableName()), e);
|
||||
throw new ConfigurationException(
|
||||
e.getMessage(), String.format("Can't append %s template config text", GradleConstants.SYSTEM_ID.getReadableName())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private static VirtualFile getOrCreateExternalProjectConfigFile(@NotNull String parent, @NotNull String fileName) {
|
||||
File file = new File(parent, fileName);
|
||||
FileUtilRt.createIfNotExists(file);
|
||||
return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
|
||||
}
|
||||
|
||||
public void setParentProject(@Nullable ProjectData parentProject) {
|
||||
myParentProject = parentProject;
|
||||
}
|
||||
|
||||
public boolean isInheritGroupId() {
|
||||
return myInheritGroupId;
|
||||
}
|
||||
|
||||
public void setInheritGroupId(boolean inheritGroupId) {
|
||||
myInheritGroupId = inheritGroupId;
|
||||
}
|
||||
|
||||
public boolean isInheritVersion() {
|
||||
return myInheritVersion;
|
||||
}
|
||||
|
||||
public void setInheritVersion(boolean inheritVersion) {
|
||||
myInheritVersion = inheritVersion;
|
||||
}
|
||||
|
||||
public ProjectId getProjectId() {
|
||||
return myProjectId;
|
||||
}
|
||||
|
||||
public void setProjectId(@NotNull ProjectId projectId) {
|
||||
myProjectId = projectId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep) {
|
||||
if (settingsStep instanceof ProjectSettingsStep) {
|
||||
final ProjectSettingsStep projectSettingsStep = (ProjectSettingsStep)settingsStep;
|
||||
if (myProjectId != null) {
|
||||
final JTextField moduleNameField = settingsStep.getModuleNameField();
|
||||
if (moduleNameField != null) {
|
||||
moduleNameField.setText(myProjectId.getArtifactId());
|
||||
}
|
||||
projectSettingsStep.setModuleName(myProjectId.getArtifactId());
|
||||
}
|
||||
projectSettingsStep.bindModuleSettings();
|
||||
}
|
||||
return super.modifySettingsStep(settingsStep);
|
||||
}
|
||||
|
||||
public static void appendToFile(@NotNull VirtualFile file, @NotNull String text) throws IOException {
|
||||
String lineSeparator = lineSeparator(file);
|
||||
final String existingText = StringUtil.trimTrailing(VfsUtilCore.loadText(file));
|
||||
String content = (StringUtil.isNotEmpty(existingText) ? existingText + lineSeparator : "") +
|
||||
StringUtil.convertLineSeparators(text, lineSeparator);
|
||||
VfsUtil.saveText(file, content);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String lineSeparator(@NotNull VirtualFile file) {
|
||||
String lineSeparator = LoadTextUtil.detectLineSeparator(file, true);
|
||||
if (lineSeparator == null) {
|
||||
lineSeparator = CodeStyleSettingsManager.getSettings(ProjectManagerEx.getInstanceEx().getDefaultProject()).getLineSeparator();
|
||||
}
|
||||
return lineSeparator;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BuildScriptDataBuilder getBuildScriptData(@Nullable Module module) {
|
||||
return module == null ? null : module.getUserData(BUILD_SCRIPT_DATA);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.kotlin.gradle.kdsl.GradleModuleWizardStep">
|
||||
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="5" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="529" height="386"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="ddae6" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="d7d25"/>
|
||||
<text value="GroupId"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="bbb74" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="efb5e"/>
|
||||
<text value="ArtifactId"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="4eb56" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="b1344"/>
|
||||
<text value="Version"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="d7d25" class="javax.swing.JTextField" binding="myGroupIdField">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="efb5e" class="javax.swing.JTextField" binding="myArtifactIdField">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="b1344" class="javax.swing.JTextField" binding="myVersionField">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="d0095" class="javax.swing.JCheckBox" binding="myInheritGroupIdCheckBox">
|
||||
<constraints>
|
||||
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Inherit"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="897ff" class="javax.swing.JCheckBox" binding="myInheritVersionCheckBox">
|
||||
<constraints>
|
||||
<grid row="3" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Inherit"/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="102d8" binding="myAddToPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
<grid id="90185" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<enabled value="true"/>
|
||||
</properties>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<vspacer id="f04b8">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* 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.gradle.kdsl;
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
|
||||
import com.intellij.ide.util.projectWizard.WizardContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectId;
|
||||
import com.intellij.openapi.externalSystem.service.project.wizard.ExternalModuleSettingsStep;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.gradle.service.project.wizard.GradleParentProjectForm;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public class GradleModuleWizardStep extends ModuleWizardStep {
|
||||
private static final Icon WIZARD_ICON = null;
|
||||
|
||||
private static final String INHERIT_GROUP_ID_KEY = "GradleModuleWizard.inheritGroupId";
|
||||
private static final String INHERIT_VERSION_KEY = "GradleModuleWizard.inheritVersion";
|
||||
private static final String DEFAULT_VERSION = "1.0-SNAPSHOT";
|
||||
|
||||
@Nullable
|
||||
private final Project myProjectOrNull;
|
||||
@NotNull
|
||||
private final GradleModuleBuilder myBuilder;
|
||||
@NotNull
|
||||
private final WizardContext myContext;
|
||||
@NotNull
|
||||
private final GradleParentProjectForm myParentProjectForm;
|
||||
|
||||
private String myInheritedGroupId;
|
||||
private String myInheritedVersion;
|
||||
|
||||
private JPanel myMainPanel;
|
||||
|
||||
private JTextField myGroupIdField;
|
||||
private JCheckBox myInheritGroupIdCheckBox;
|
||||
private JTextField myArtifactIdField;
|
||||
private JTextField myVersionField;
|
||||
private JCheckBox myInheritVersionCheckBox;
|
||||
private JPanel myAddToPanel;
|
||||
|
||||
public GradleModuleWizardStep(@NotNull GradleModuleBuilder builder, @NotNull WizardContext context) {
|
||||
myProjectOrNull = context.getProject();
|
||||
myBuilder = builder;
|
||||
myContext = context;
|
||||
myParentProjectForm = new GradleParentProjectForm(context, parentProject -> updateComponents());
|
||||
initComponents();
|
||||
loadSettings();
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
myAddToPanel.add(myParentProjectForm.getComponent());
|
||||
ActionListener updatingListener = new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
updateComponents();
|
||||
}
|
||||
};
|
||||
myInheritGroupIdCheckBox.addActionListener(updatingListener);
|
||||
myInheritVersionCheckBox.addActionListener(updatingListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myGroupIdField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStepLeaving() {
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
private void loadSettings() {
|
||||
myBuilder.setInheritGroupId(getSavedValue(INHERIT_GROUP_ID_KEY, true));
|
||||
myBuilder.setInheritVersion(getSavedValue(INHERIT_VERSION_KEY, true));
|
||||
}
|
||||
|
||||
private void saveSettings() {
|
||||
saveValue(INHERIT_GROUP_ID_KEY, myInheritGroupIdCheckBox.isSelected());
|
||||
saveValue(INHERIT_VERSION_KEY, myInheritVersionCheckBox.isSelected());
|
||||
}
|
||||
|
||||
private static boolean getSavedValue(String key, boolean defaultValue) {
|
||||
return getSavedValue(key, String.valueOf(defaultValue)).equals(String.valueOf(true));
|
||||
}
|
||||
|
||||
private static String getSavedValue(String key, String defaultValue) {
|
||||
String value = PropertiesComponent.getInstance().getValue(key);
|
||||
return value == null ? defaultValue : value;
|
||||
}
|
||||
|
||||
private static void saveValue(String key, boolean value) {
|
||||
saveValue(key, String.valueOf(value));
|
||||
}
|
||||
|
||||
private static void saveValue(String key, String value) {
|
||||
PropertiesComponent.getInstance().setValue(key, value);
|
||||
}
|
||||
|
||||
public JComponent getComponent() {
|
||||
return myMainPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validate() throws ConfigurationException {
|
||||
if (StringUtil.isEmptyOrSpaces(myArtifactIdField.getText())) {
|
||||
ApplicationManager.getApplication().invokeLater(
|
||||
() -> IdeFocusManager.getInstance(myProjectOrNull).requestFocus(myArtifactIdField, true));
|
||||
throw new ConfigurationException("Please, specify artifactId");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateStep() {
|
||||
ProjectData parentProject = myParentProjectForm.getParentProject();
|
||||
ProjectId projectId = myBuilder.getProjectId();
|
||||
|
||||
if (projectId == null) {
|
||||
setTestIfEmpty(myArtifactIdField, myBuilder.getName());
|
||||
setTestIfEmpty(myGroupIdField, parentProject == null ? myBuilder.getName() : parentProject.getGroup());
|
||||
setTestIfEmpty(myVersionField, parentProject == null ? DEFAULT_VERSION : parentProject.getVersion());
|
||||
}
|
||||
else {
|
||||
setTestIfEmpty(myArtifactIdField, projectId.getArtifactId());
|
||||
setTestIfEmpty(myGroupIdField, projectId.getGroupId());
|
||||
setTestIfEmpty(myVersionField, projectId.getVersion());
|
||||
}
|
||||
|
||||
myInheritGroupIdCheckBox.setSelected(myBuilder.isInheritGroupId());
|
||||
myInheritVersionCheckBox.setSelected(myBuilder.isInheritVersion());
|
||||
|
||||
updateComponents();
|
||||
}
|
||||
|
||||
|
||||
private void updateComponents() {
|
||||
final boolean isAddToVisible = myParentProjectForm.isVisible();
|
||||
|
||||
myInheritGroupIdCheckBox.setVisible(isAddToVisible);
|
||||
myInheritVersionCheckBox.setVisible(isAddToVisible);
|
||||
|
||||
myParentProjectForm.updateComponents();
|
||||
ProjectData parentProject = myParentProjectForm.getParentProject();
|
||||
if (parentProject == null) {
|
||||
myContext.putUserData(ExternalModuleSettingsStep.SKIP_STEP_KEY, Boolean.FALSE);
|
||||
myGroupIdField.setEnabled(true);
|
||||
myVersionField.setEnabled(true);
|
||||
myInheritGroupIdCheckBox.setEnabled(false);
|
||||
myInheritVersionCheckBox.setEnabled(false);
|
||||
|
||||
setTestIfEmpty(myArtifactIdField, myBuilder.getName());
|
||||
setTestIfEmpty(myGroupIdField, "");
|
||||
setTestIfEmpty(myVersionField, DEFAULT_VERSION);
|
||||
}
|
||||
else {
|
||||
myContext.putUserData(ExternalModuleSettingsStep.SKIP_STEP_KEY, Boolean.TRUE);
|
||||
myGroupIdField.setEnabled(!myInheritGroupIdCheckBox.isSelected());
|
||||
myVersionField.setEnabled(!myInheritVersionCheckBox.isSelected());
|
||||
|
||||
if (myInheritGroupIdCheckBox.isSelected()
|
||||
|| myGroupIdField.getText().equals(myInheritedGroupId)) {
|
||||
myGroupIdField.setText(parentProject.getGroup());
|
||||
}
|
||||
if (myInheritVersionCheckBox.isSelected()
|
||||
|| myVersionField.getText().equals(myInheritedVersion)) {
|
||||
myVersionField.setText(parentProject.getVersion());
|
||||
}
|
||||
myInheritedGroupId = myGroupIdField.getText();
|
||||
myInheritedVersion = myVersionField.getText();
|
||||
|
||||
myInheritGroupIdCheckBox.setEnabled(true);
|
||||
myInheritVersionCheckBox.setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isGradleModuleExist(WizardContext myContext) {
|
||||
for (Module module : myContext.getModulesProvider().getModules()) {
|
||||
if (ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDataModel() {
|
||||
myContext.setProjectBuilder(myBuilder);
|
||||
ProjectData parentProject = myParentProjectForm.getParentProject();
|
||||
myBuilder.setParentProject(parentProject);
|
||||
|
||||
myBuilder.setProjectId(new ProjectId(myGroupIdField.getText(),
|
||||
myArtifactIdField.getText(),
|
||||
myVersionField.getText()));
|
||||
myBuilder.setInheritGroupId(myInheritGroupIdCheckBox.isSelected());
|
||||
myBuilder.setInheritVersion(myInheritVersionCheckBox.isSelected());
|
||||
|
||||
if (StringUtil.isNotEmpty(myBuilder.getProjectId().getArtifactId())) {
|
||||
myContext.setProjectName(myBuilder.getProjectId().getArtifactId());
|
||||
}
|
||||
if (parentProject != null) {
|
||||
myContext.setProjectFileDirectory(parentProject.getLinkedExternalProjectPath() + '/' + myContext.getProjectName());
|
||||
}
|
||||
else {
|
||||
if (myProjectOrNull != null) {
|
||||
myContext.setProjectFileDirectory(myProjectOrNull.getBaseDir().getPath() + '/' + myContext.getProjectName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return WIZARD_ICON;
|
||||
}
|
||||
|
||||
private static void setTestIfEmpty(@NotNull JTextField field, @Nullable String text) {
|
||||
if (StringUtil.isEmpty(field.getText())) {
|
||||
field.setText(StringUtil.notNullize(text));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpId() {
|
||||
return "Gradle_Archetype_Dialog";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disposeUIResources() {
|
||||
Disposer.dispose(myParentProjectForm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2000-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.gradle.kdsl.frameworkSupport;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class BuildScriptDataBuilder {
|
||||
@NotNull private final VirtualFile myBuildScriptFile;
|
||||
private final Set<String> plugins = ContainerUtil.newTreeSet();
|
||||
private final Set<String> pluginsInGroup = ContainerUtil.newTreeSet();
|
||||
private final Set<String> repositories = ContainerUtil.newTreeSet();
|
||||
private final Set<String> dependencies = ContainerUtil.newTreeSet();
|
||||
private final Set<String> properties = ContainerUtil.newTreeSet();
|
||||
private final Set<String> buildScriptProperties = ContainerUtil.newTreeSet();
|
||||
private final Set<String> buildScriptRepositories = ContainerUtil.newTreeSet();
|
||||
private final Set<String> buildScriptDependencies = ContainerUtil.newTreeSet();
|
||||
private final Set<String> other = ContainerUtil.newTreeSet();
|
||||
|
||||
public BuildScriptDataBuilder(@NotNull VirtualFile buildScriptFile) {
|
||||
myBuildScriptFile = buildScriptFile;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public VirtualFile getBuildScriptFile() {
|
||||
return myBuildScriptFile;
|
||||
}
|
||||
|
||||
public String buildConfigurationPart() {
|
||||
List<String> lines = ContainerUtil.newArrayList();
|
||||
addBuildscriptLines(lines, BuildScriptDataBuilder::padding);
|
||||
if (!pluginsInGroup.isEmpty()) {
|
||||
lines.add("plugins {");
|
||||
lines.addAll(ContainerUtil.map(pluginsInGroup, BuildScriptDataBuilder::padding));
|
||||
lines.add("}");
|
||||
lines.add("");
|
||||
}
|
||||
return StringUtil.join(lines, "\n");
|
||||
}
|
||||
|
||||
public String buildMainPart() {
|
||||
List<String> lines = ContainerUtil.newArrayList();
|
||||
if (!plugins.isEmpty()) {
|
||||
lines.addAll(plugins);
|
||||
lines.add("");
|
||||
}
|
||||
if (!properties.isEmpty()) {
|
||||
lines.addAll(properties);
|
||||
lines.add("");
|
||||
}
|
||||
if (!repositories.isEmpty()) {
|
||||
lines.add("repositories {");
|
||||
lines.addAll(ContainerUtil.map(repositories, BuildScriptDataBuilder::padding));
|
||||
lines.add("}");
|
||||
lines.add("");
|
||||
}
|
||||
if (!dependencies.isEmpty()) {
|
||||
lines.add("dependencies {");
|
||||
lines.addAll(ContainerUtil.map(dependencies, BuildScriptDataBuilder::padding));
|
||||
lines.add("}");
|
||||
lines.add("");
|
||||
}
|
||||
if (!other.isEmpty()) {
|
||||
lines.addAll(other);
|
||||
}
|
||||
return StringUtil.join(lines, "\n");
|
||||
}
|
||||
|
||||
private void addBuildscriptLines(@NotNull List<String> lines, @NotNull Function<String, String> padding) {
|
||||
if (!buildScriptRepositories.isEmpty() || !buildScriptDependencies.isEmpty() || !buildScriptProperties.isEmpty()) {
|
||||
lines.add("buildscript {");
|
||||
final List<String> buildScriptLines = ContainerUtil.newSmartList();
|
||||
if (!buildScriptProperties.isEmpty()) {
|
||||
buildScriptLines.addAll(buildScriptProperties);
|
||||
buildScriptLines.add("");
|
||||
}
|
||||
if (!buildScriptRepositories.isEmpty()) {
|
||||
buildScriptLines.add("repositories {");
|
||||
buildScriptLines.addAll(ContainerUtil.map(buildScriptRepositories, padding));
|
||||
buildScriptLines.add("}");
|
||||
}
|
||||
if (!buildScriptDependencies.isEmpty()) {
|
||||
buildScriptLines.add("dependencies {");
|
||||
buildScriptLines.addAll(ContainerUtil.map(buildScriptDependencies, padding));
|
||||
buildScriptLines.add("}");
|
||||
}
|
||||
lines.addAll(ContainerUtil.map(buildScriptLines, padding));
|
||||
lines.add("}");
|
||||
lines.add("");
|
||||
}
|
||||
}
|
||||
|
||||
public BuildScriptDataBuilder addBuildscriptPropertyDefinition(@NotNull String definition) {
|
||||
buildScriptProperties.add(definition.trim());
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuildScriptDataBuilder addBuildscriptRepositoriesDefinition(@NotNull String definition) {
|
||||
buildScriptRepositories.add(definition.trim());
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuildScriptDataBuilder addBuildscriptDependencyNotation(@NotNull String notation) {
|
||||
buildScriptDependencies.add(notation.trim());
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuildScriptDataBuilder addPluginDefinitionInPluginsGroup(@NotNull String definition) {
|
||||
pluginsInGroup.add(definition.trim());
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuildScriptDataBuilder addPluginDefinition(@NotNull String definition) {
|
||||
plugins.add(definition.trim());
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuildScriptDataBuilder addRepositoriesDefinition(@NotNull String definition) {
|
||||
repositories.add(definition.trim());
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuildScriptDataBuilder addDependencyNotation(@NotNull String notation) {
|
||||
dependencies.add(notation.trim());
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuildScriptDataBuilder addPropertyDefinition(@NotNull String definition) {
|
||||
properties.add(definition.trim());
|
||||
return this;
|
||||
}
|
||||
|
||||
public BuildScriptDataBuilder addOther(@NotNull String definition) {
|
||||
other.add(definition.trim());
|
||||
return this;
|
||||
}
|
||||
|
||||
private static String padding(String s) {return StringUtil.isNotEmpty(s) ? " " + s : "";}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.gradle.kdsl.frameworkSupport;
|
||||
|
||||
import com.intellij.framework.addSupport.FrameworkSupportInModuleConfigurable;
|
||||
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
|
||||
import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleType;
|
||||
import com.intellij.openapi.roots.ModifiableModelsProvider;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import static org.jetbrains.kotlin.gradle.kdsl.GradleModuleBuilder.getBuildScriptData;
|
||||
|
||||
public abstract class GradleFrameworkSupportProvider extends FrameworkSupportInModuleProvider {
|
||||
|
||||
public static final ExtensionPointName<GradleFrameworkSupportProvider> EP_NAME =
|
||||
ExtensionPointName.create("org.jetbrains.kotlin.gradleFrameworkSupport");
|
||||
|
||||
public abstract void addSupport(@NotNull Module module, @NotNull ModifiableRootModel rootModel,
|
||||
@NotNull ModifiableModelsProvider modifiableModelsProvider,
|
||||
@NotNull BuildScriptDataBuilder buildScriptData);
|
||||
|
||||
public JComponent createComponent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FrameworkSupportInModuleConfigurable createConfigurable(@NotNull FrameworkSupportModel model) {
|
||||
return new FrameworkSupportInModuleConfigurable() {
|
||||
@Nullable
|
||||
@Override
|
||||
public JComponent createComponent() {
|
||||
return GradleFrameworkSupportProvider.this.createComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSupport(@NotNull Module module,
|
||||
@NotNull ModifiableRootModel rootModel,
|
||||
@NotNull ModifiableModelsProvider modifiableModelsProvider) {
|
||||
final BuildScriptDataBuilder buildScriptData = getBuildScriptData(module);
|
||||
if (buildScriptData != null) {
|
||||
GradleFrameworkSupportProvider.this.addSupport(module, rootModel, modifiableModelsProvider, buildScriptData);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledForModuleType(@NotNull ModuleType moduleType) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.gradle.kdsl.frameworkSupport;
|
||||
|
||||
import com.intellij.framework.FrameworkTypeEx;
|
||||
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.ModifiableModelsProvider;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import icons.JetgroovyIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class GradleGroovyFrameworkSupportProvider extends GradleFrameworkSupportProvider {
|
||||
|
||||
public static final String ID = "groovy";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FrameworkTypeEx getFrameworkType() {
|
||||
return new FrameworkTypeEx(ID) {
|
||||
@NotNull
|
||||
@Override
|
||||
public FrameworkSupportInModuleProvider createProvider() {
|
||||
return GradleGroovyFrameworkSupportProvider.this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "Groovy";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return JetgroovyIcons.Groovy.Groovy_16x16;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSupport(@NotNull Module module,
|
||||
@NotNull ModifiableRootModel rootModel,
|
||||
@NotNull ModifiableModelsProvider modifiableModelsProvider,
|
||||
@NotNull BuildScriptDataBuilder buildScriptData) {
|
||||
buildScriptData
|
||||
.addPluginDefinition("plugin(\"groovy\")")
|
||||
.addRepositoriesDefinition("mavenCentral()")
|
||||
.addDependencyNotation("compile(\"org.codehaus.groovy:groovy-all:2.3.11\")")
|
||||
.addDependencyNotation("testCompile(\"junit\", \"junit\", \"4.12\")");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2000-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.gradle.kdsl.frameworkSupport;
|
||||
|
||||
import com.intellij.framework.FrameworkTypeEx;
|
||||
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.roots.ModifiableModelsProvider;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class GradleJavaFrameworkSupportProvider extends GradleFrameworkSupportProvider {
|
||||
|
||||
public static final String ID = "java";
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FrameworkTypeEx getFrameworkType() {
|
||||
return new FrameworkTypeEx(ID) {
|
||||
@NotNull
|
||||
@Override
|
||||
public FrameworkSupportInModuleProvider createProvider() {
|
||||
return GradleJavaFrameworkSupportProvider.this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getPresentableName() {
|
||||
return "Java";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Icon getIcon() {
|
||||
return AllIcons.Nodes.Module;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addSupport(@NotNull Module module,
|
||||
@NotNull ModifiableRootModel rootModel,
|
||||
@NotNull ModifiableModelsProvider modifiableModelsProvider,
|
||||
@NotNull BuildScriptDataBuilder buildScriptData) {
|
||||
buildScriptData
|
||||
.addPluginDefinition("plugin(\"java\")")
|
||||
// TODO: in gradle > 4.0 it is just 'java { ... }'
|
||||
.addOther("configure<JavaPluginConvention> {\n sourceCompatibility = JavaVersion.VERSION_1_8\n}")
|
||||
.addRepositoriesDefinition("mavenCentral()")
|
||||
.addDependencyNotation("testCompile(\"junit\", \"junit\", \"4.12\")");
|
||||
}
|
||||
}
|
||||
@@ -14,36 +14,34 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.configuration
|
||||
package org.jetbrains.kotlin.gradle.kdsl.frameworkSupport
|
||||
|
||||
import com.intellij.framework.FrameworkTypeEx
|
||||
import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectId
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ModifiableModelsProvider
|
||||
import com.intellij.openapi.roots.ModifiableRootModel
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.idea.configuration.*
|
||||
import org.jetbrains.kotlin.idea.configuration.KotlinBuildScriptManipulator.Companion.GSK_KOTLIN_VERSION_PROPERTY_NAME
|
||||
import org.jetbrains.kotlin.idea.configuration.KotlinBuildScriptManipulator.Companion.getCompileDependencySnippet
|
||||
import org.jetbrains.kotlin.idea.configuration.KotlinBuildScriptManipulator.Companion.getKotlinGradlePluginClassPathSnippet
|
||||
import org.jetbrains.kotlin.idea.versions.*
|
||||
import org.jetbrains.plugins.gradle.frameworkSupport.BuildScriptDataBuilder
|
||||
import org.jetbrains.plugins.gradle.frameworkSupport.KotlinDslGradleFrameworkSupportProvider
|
||||
import javax.swing.Icon
|
||||
|
||||
abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
|
||||
abstract class GradleKotlinDSLKotlinFrameworkSupportProvider(
|
||||
val frameworkTypeId: String,
|
||||
val displayName: String,
|
||||
val frameworkIcon: Icon
|
||||
) : KotlinDslGradleFrameworkSupportProvider() {
|
||||
) : GradleFrameworkSupportProvider() {
|
||||
override fun getFrameworkType(): FrameworkTypeEx = object : FrameworkTypeEx(frameworkTypeId) {
|
||||
override fun getIcon(): Icon = frameworkIcon
|
||||
override fun getPresentableName(): String = displayName
|
||||
override fun createProvider(): FrameworkSupportInModuleProvider = this@KotlinDslGradleKotlinFrameworkSupportProvider
|
||||
override fun createProvider(): FrameworkSupportInModuleProvider = this@GradleKotlinDSLKotlinFrameworkSupportProvider
|
||||
}
|
||||
|
||||
override fun addSupport(
|
||||
projectId: ProjectId,
|
||||
module: Module,
|
||||
rootModel: ModifiableRootModel,
|
||||
modifiableModelsProvider: ModifiableModelsProvider,
|
||||
@@ -68,20 +66,18 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
|
||||
.addBuildscriptRepositoriesDefinition("mavenCentral()")
|
||||
.addRepositoriesDefinition("mavenCentral()")
|
||||
// TODO: in gradle > 4.1 this could be single declaration e.g. 'val kotlin_version: String by extra { "1.1.11" }'
|
||||
.addBuildscriptPropertyDefinition("var $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra\n $GSK_KOTLIN_VERSION_PROPERTY_NAME = \"$kotlinVersion\"")
|
||||
.addBuildscriptPropertyDefinition("var $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra\n$GSK_KOTLIN_VERSION_PROPERTY_NAME = \"$kotlinVersion\"")
|
||||
.addDependencyNotation(getRuntimeLibrary(rootModel))
|
||||
.addBuildscriptDependencyNotation(getKotlinGradlePluginClassPathSnippet())
|
||||
}
|
||||
|
||||
private fun RepositoryDescription.toKotlinRepositorySnippet() = "maven { setUrl(\"$url\") }"
|
||||
|
||||
protected abstract fun getRuntimeLibrary(rootModel: ModifiableRootModel): String
|
||||
|
||||
protected abstract fun getPluginDefinition(): String
|
||||
}
|
||||
|
||||
class KotlinDslGradleKotlinJavaFrameworkSupportProvider :
|
||||
KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN", "Kotlin (Java)", KotlinIcons.SMALL_LOGO) {
|
||||
class GradleKotlinDSLKotlinJavaFrameworkSupportProvider :
|
||||
GradleKotlinDSLKotlinFrameworkSupportProvider("KOTLIN", "Kotlin (Java)", KotlinIcons.SMALL_LOGO) {
|
||||
|
||||
override fun getPluginDefinition() = "plugin(\"${KotlinGradleModuleConfigurator.KOTLIN}\")"
|
||||
|
||||
@@ -89,24 +85,28 @@ class KotlinDslGradleKotlinJavaFrameworkSupportProvider :
|
||||
getCompileDependencySnippet(KOTLIN_GROUP_ID, getStdlibArtifactId(rootModel.sdk, bundledRuntimeVersion()))
|
||||
|
||||
override fun addSupport(
|
||||
projectId: ProjectId,
|
||||
module: Module,
|
||||
rootModel: ModifiableRootModel,
|
||||
modifiableModelsProvider: ModifiableModelsProvider,
|
||||
buildScriptData: BuildScriptDataBuilder
|
||||
) {
|
||||
super.addSupport(projectId, module, rootModel, modifiableModelsProvider, buildScriptData)
|
||||
super.addSupport(module, rootModel, modifiableModelsProvider, buildScriptData)
|
||||
val jvmTarget = getDefaultJvmTarget(rootModel.sdk, bundledRuntimeVersion())
|
||||
if (jvmTarget != null) {
|
||||
buildScriptData
|
||||
.addImport("import org.jetbrains.kotlin.gradle.tasks.KotlinCompile")
|
||||
.addImports("import org.jetbrains.kotlin.gradle.tasks.KotlinCompile")
|
||||
.addOther("tasks.withType<KotlinCompile> {\n kotlinOptions.jvmTarget = \"1.8\"\n}\n")
|
||||
}
|
||||
}
|
||||
|
||||
private fun BuildScriptDataBuilder.addImports(vararg import: String): BuildScriptDataBuilder = apply {
|
||||
val text = VfsUtil.loadText(buildScriptFile)
|
||||
VfsUtil.saveText(buildScriptFile, import.joinToString(separator = "\n") + "\n\n" + text)
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinDslGradleKotlinJSFrameworkSupportProvider :
|
||||
KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN_JS", "Kotlin (JavaScript)", KotlinIcons.JS) {
|
||||
class GradleKotlinDSLKotlinJSFrameworkSupportProvider :
|
||||
GradleKotlinDSLKotlinFrameworkSupportProvider("KOTLIN_JS", "Kotlin (JavaScript)", KotlinIcons.JS) {
|
||||
|
||||
override fun getPluginDefinition(): String = "plugin(\"${KotlinJsGradleModuleConfigurator.KOTLIN_JS}\")"
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* 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.gradle.kdsl.frameworkSupport
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
|
||||
class KotlinBuildScriptDataBuilder(buildScriptFile: VirtualFile) : BuildScriptDataBuilder(buildScriptFile) {
|
||||
private val plugins: MutableSet<String> = ContainerUtil.newTreeSet<String>()
|
||||
private val properties: MutableSet<String> = ContainerUtil.newTreeSet<String>()
|
||||
private val repositories: MutableSet<String> = ContainerUtil.newTreeSet<String>()
|
||||
private val dependencies: MutableSet<String> = ContainerUtil.newTreeSet<String>()
|
||||
|
||||
private val buildScriptProperties: MutableSet<String> = ContainerUtil.newTreeSet<String>()
|
||||
private val buildScriptRepositories: MutableSet<String> = ContainerUtil.newTreeSet<String>()
|
||||
private val buildScriptDependencies: MutableSet<String> = ContainerUtil.newTreeSet<String>()
|
||||
private val other: MutableSet<String> = ContainerUtil.newTreeSet<String>()
|
||||
|
||||
override fun addPluginDefinition(definition: String): BuildScriptDataBuilder = apply { plugins.add(definition) }
|
||||
|
||||
override fun addRepositoriesDefinition(definition: String): BuildScriptDataBuilder = apply { repositories.add(definition) }
|
||||
|
||||
override fun addPropertyDefinition(definition: String): BuildScriptDataBuilder = apply { properties.add(definition) }
|
||||
|
||||
override fun addDependencyNotation(notation: String): BuildScriptDataBuilder = apply { dependencies.add(notation) }
|
||||
|
||||
override fun addBuildscriptPropertyDefinition(definition: String): BuildScriptDataBuilder = apply { buildScriptProperties.add(definition) }
|
||||
|
||||
override fun addBuildscriptRepositoriesDefinition(definition: String): BuildScriptDataBuilder = apply { buildScriptRepositories.add(definition) }
|
||||
|
||||
override fun addBuildscriptDependencyNotation(notation: String): BuildScriptDataBuilder = apply { buildScriptDependencies.add(notation) }
|
||||
|
||||
override fun addOther(definition: String): BuildScriptDataBuilder = apply { other.add(definition) }
|
||||
|
||||
override fun buildMainPart(): String = buildString {
|
||||
|
||||
appendlnIfNotNull(buildBuildScriptBlock())
|
||||
|
||||
appendlnIfNotNull(buildBlock("apply", plugins))
|
||||
|
||||
if (properties.isNotEmpty()) {
|
||||
properties.forEach { appendln(it) }
|
||||
appendln()
|
||||
}
|
||||
|
||||
appendlnIfNotNull(buildBlock("repositories", repositories))
|
||||
|
||||
appendlnIfNotNull(buildBlock("dependencies", dependencies))
|
||||
|
||||
other.forEach { appendln(it) }
|
||||
}
|
||||
|
||||
private fun buildBuildScriptBlock(): String? = buildString {
|
||||
if (buildScriptProperties.isEmpty() || buildScriptRepositories.isEmpty() || buildScriptDependencies.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
appendln("buildscript {")
|
||||
buildScriptProperties.forEach { appendln(it.withMargin) }
|
||||
appendln()
|
||||
appendlnIfNotNull(buildBlock("repositories", buildScriptRepositories)?.withMargin)
|
||||
appendlnIfNotNull(buildBlock("dependencies", buildScriptDependencies)?.withMargin)
|
||||
appendln("}")
|
||||
}
|
||||
|
||||
private fun buildBlock(name: String, lines: Set<String>): String? = buildString {
|
||||
if (lines.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
|
||||
appendln("$name {")
|
||||
lines.forEach { appendln(it.withMargin) }
|
||||
appendln("}")
|
||||
}
|
||||
|
||||
private val String.withMargin: String
|
||||
get() = lines().joinToString(separator = "\n") { " " + it }
|
||||
|
||||
private fun StringBuilder.appendlnIfNotNull(text: String?) = text?.let { appendln(it) }
|
||||
}
|
||||
@@ -103,7 +103,7 @@ class KotlinGradleMultiplatformModuleBuilder : GradleModuleBuilder() {
|
||||
val buildGradle = moduleDir.createChildData(null, "build.gradle")
|
||||
val buildScriptData = BuildScriptDataBuilder(buildGradle)
|
||||
extendScript(buildScriptData, sdk ?: rootModule.rootManager.sdk)
|
||||
VfsUtil.saveText(buildGradle, buildScriptData.buildConfigurationPart() + buildScriptData.buildMainPart())
|
||||
VfsUtil.saveText(buildGradle, buildScriptData.build())
|
||||
}
|
||||
|
||||
private fun setupCommonModule(
|
||||
|
||||
@@ -233,10 +233,10 @@ class GradleScriptDefinitionsContributor(private val project: Project) : ScriptD
|
||||
override val dependencyResolver: DependenciesResolver = ErrorScriptDependenciesResolver(message)
|
||||
|
||||
override fun getScriptName(script: KtScript) =
|
||||
Name.identifier(script.containingKtFile.name.removeSuffix(GradleConstants.KOTLIN_DSL_SCRIPT_EXTENSION))
|
||||
Name.identifier(script.containingKtFile.name.removeSuffix(".gradle.kts"))
|
||||
|
||||
override fun isScript(fileName: String): Boolean =
|
||||
fileName.endsWith(GradleConstants.KOTLIN_DSL_SCRIPT_EXTENSION)
|
||||
fileName.endsWith(".gradle.kts")
|
||||
}
|
||||
|
||||
private class ErrorScriptDependenciesResolver(private val message: String? = null) : DependenciesResolver {
|
||||
@@ -267,7 +267,7 @@ class ReloadGradleTemplatesOnSync : ExternalSystemTaskNotificationListenerAdapte
|
||||
internal val gradleState = GradleSyncState()
|
||||
}
|
||||
|
||||
override fun onStart(id: ExternalSystemTaskId, workingDir: String?) {
|
||||
override fun onStart(id: ExternalSystemTaskId) {
|
||||
if (id.type == ExternalSystemTaskType.RESOLVE_PROJECT && id.projectSystemId == GRADLE_SYSTEM_ID) {
|
||||
gradleState.isSyncInProgress = true
|
||||
}
|
||||
|
||||
@@ -54,7 +54,8 @@ class ScriptModificationListener(private val project: Project) {
|
||||
}) {
|
||||
return
|
||||
}
|
||||
ExternalProjectsManager.getInstance(project).externalProjectsWatcher.markDirty(project.basePath)
|
||||
// externalProjectsWatcher is not avaliable in 171
|
||||
//ExternalProjectsManager.getInstance(project).externalProjectsWatcher.markDirty(project.basePath)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -67,6 +68,8 @@ class ScriptModificationListener(private val project: Project) {
|
||||
changedDocumentsQueue.activate()
|
||||
|
||||
EditorFactory.getInstance().eventMulticaster.addDocumentListener(object : DocumentListener {
|
||||
override fun beforeDocumentChange(event: DocumentEvent?) {}
|
||||
|
||||
override fun documentChanged(event: DocumentEvent) {
|
||||
if (project.isDisposed) return
|
||||
|
||||
|
||||
@@ -18,9 +18,10 @@ package org.jetbrains.kotlin.idea.run
|
||||
|
||||
import com.intellij.execution.configurations.JavaRunConfigurationModule
|
||||
import com.intellij.execution.configurations.ModuleBasedConfiguration
|
||||
import com.intellij.openapi.externalSystem.ExternalSystemModulePropertyManager
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.externalSystem.model.project.ExternalSystemSourceType
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemConstants
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ModuleOrderEntry
|
||||
@@ -120,8 +121,7 @@ class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradle
|
||||
if (!ExternalSystemApiUtil.isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, rootModel.module)) return false
|
||||
|
||||
if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake) {
|
||||
val gradleProjectPath =
|
||||
ExternalSystemModulePropertyManager.getInstance(rootModel.module).getRootProjectPath() ?: return false
|
||||
val gradleProjectPath = rootModel.module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
|
||||
val externalProjectDataCache = ExternalProjectDataCache.getInstance(rootModel.module.project)!!
|
||||
val externalRootProject = externalProjectDataCache.getRootExternalProject(
|
||||
GradleConstants.SYSTEM_ID,
|
||||
@@ -156,7 +156,11 @@ class MultiplatformGradleOrderEnumeratorHandler(val factory: MultiplatformGradle
|
||||
}
|
||||
|
||||
private fun addOutputModuleRoots(directorySet: ExternalSourceDirectorySet?, result: MutableCollection<String>) {
|
||||
directorySet?.gradleOutputDirs?.mapTo(result) { VfsUtilCore.pathToUrl(it.absolutePath) }
|
||||
if (directorySet == null) return;
|
||||
|
||||
if (directorySet.isCompilerOutputPathInherited) return
|
||||
val path = directorySet.outputDir.absolutePath
|
||||
result.add(VfsUtilCore.pathToUrl(path))
|
||||
}
|
||||
|
||||
class FactoryImpl : Factory() {
|
||||
|
||||
@@ -24,7 +24,7 @@ import com.intellij.openapi.externalSystem.model.ProjectSystemId;
|
||||
import com.intellij.openapi.externalSystem.model.project.ProjectData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
|
||||
import com.intellij.openapi.externalSystem.service.project.ExternalProjectRefreshCallback;
|
||||
import com.intellij.openapi.externalSystem.service.project.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataManager;
|
||||
import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemSettings;
|
||||
import com.intellij.openapi.externalSystem.settings.ExternalProjectSettings;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
|
||||
|
||||
@@ -120,7 +120,7 @@ public abstract class GradleImportingTestCase extends ExternalSystemImportingTes
|
||||
}
|
||||
}.execute();
|
||||
Messages.setTestDialog(TestDialog.DEFAULT);
|
||||
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory().toFile());
|
||||
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory());
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
|
||||
@@ -350,6 +350,7 @@ class GradleInspectionTest : GradleImportingTestCase() {
|
||||
|
||||
val foundProblems = presentation.problemElements
|
||||
.values
|
||||
.flatMap { it.toList() }
|
||||
.mapNotNull { it as? ProblemDescriptorBase }
|
||||
.map { it.descriptionTemplate }
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskType
|
||||
import org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerComponent
|
||||
|
||||
class KotlinExternalSystemSyncListener : ExternalSystemTaskNotificationListenerAdapter() {
|
||||
override fun onStart(id: ExternalSystemTaskId, workingDir: String) {
|
||||
override fun onStart(id: ExternalSystemTaskId) {
|
||||
if (id.type == ExternalSystemTaskType.RESOLVE_PROJECT) {
|
||||
id.findProject()?.let { project ->
|
||||
KotlinConfigurationCheckerComponent.getInstance(project).syncStarted()
|
||||
|
||||
@@ -54,7 +54,6 @@ import org.jetbrains.kotlin.utils.getOrPutNullable
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import java.util.concurrent.ConcurrentMap
|
||||
|
||||
fun isInlineFunctionLineNumber(file: VirtualFile, lineNumber: Int, project: Project): Boolean {
|
||||
if (ProjectRootsUtil.isProjectSourceFile(project, file)) {
|
||||
@@ -119,7 +118,7 @@ class WeakBytecodeDebugInfoStorage : ConcurrentWeakFactoryMap<BinaryCacheKey, By
|
||||
|
||||
return BytecodeDebugInfo(smapData, lineNumberMapping)
|
||||
}
|
||||
override fun createMap(): ConcurrentMap<BinaryCacheKey, BytecodeDebugInfo?> {
|
||||
override fun createMap(): Map<BinaryCacheKey, BytecodeDebugInfo?> {
|
||||
return ContainerUtil.createConcurrentWeakKeyWeakValueMap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class KotlinRuntimeTypeCastSurrounder: KotlinExpressionSurrounder() {
|
||||
val debuggerContext = DebuggerManagerEx.getInstanceEx(project).context
|
||||
val debuggerSession = debuggerContext.debuggerSession
|
||||
if (debuggerSession != null) {
|
||||
val progressWindow = ProgressWindow(true, expression.project)
|
||||
val progressWindow = ProgressWindowWithNotification(true, expression.project)
|
||||
val worker = SurroundWithCastWorker(editor, expression, debuggerContext, progressWindow)
|
||||
progressWindow.title = DebuggerBundle.message("title.evaluating")
|
||||
debuggerContext.debugProcess?.managerThread?.startProgress(worker, progressWindow)
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.ide.util.projectWizard.SettingsStep
|
||||
import com.intellij.ide.util.projectWizard.WizardContext
|
||||
import com.intellij.openapi.projectRoots.SdkTypeId
|
||||
import com.intellij.openapi.roots.ui.configuration.ModulesProvider
|
||||
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import javax.swing.Icon
|
||||
@@ -33,6 +34,7 @@ class KotlinModuleBuilder(
|
||||
override fun getName() = builderName
|
||||
override fun getPresentableName() = builderName
|
||||
override fun getDescription() = builderDescription
|
||||
override fun getBigIcon() = KotlinIcons.KOTLIN_LOGO_24
|
||||
override fun getNodeIcon() = icon
|
||||
override fun getGroupName() = KotlinTemplatesFactory.KOTLIN_GROUP_NAME
|
||||
override fun createWizardSteps(wizardContext: WizardContext, modulesProvider: ModulesProvider) = ModuleWizardStep.EMPTY_ARRAY
|
||||
|
||||
@@ -23,30 +23,20 @@ import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.progress.ProgressManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
import com.intellij.openapi.util.text.StringUtilRt
|
||||
import com.intellij.patterns.PatternCondition
|
||||
import com.intellij.patterns.PatternConditionPlus
|
||||
import com.intellij.patterns.PsiClassNamePatternCondition
|
||||
import com.intellij.patterns.ValuePatternCondition
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.intellij.plugins.intelliLang.Configuration
|
||||
import org.intellij.plugins.intelliLang.inject.InjectorUtils
|
||||
import org.intellij.plugins.intelliLang.inject.LanguageInjectionSupport
|
||||
import org.intellij.plugins.intelliLang.inject.TemporaryPlacesRegistry
|
||||
import org.intellij.plugins.intelliLang.inject.config.BaseInjection
|
||||
import org.intellij.plugins.intelliLang.inject.config.InjectionPlace
|
||||
import org.intellij.plugins.intelliLang.inject.java.JavaLanguageInjectionSupport
|
||||
import org.intellij.plugins.intelliLang.util.AnnotationUtilEx
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.patterns.KotlinFunctionPattern
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.runInReadActionWithWriteActionPriority
|
||||
@@ -56,31 +46,30 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import org.jetbrains.kotlin.util.aliasImportMap
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class KotlinLanguageInjector(
|
||||
private val configuration: Configuration,
|
||||
private val project: Project,
|
||||
private val temporaryPlacesRegistry: TemporaryPlacesRegistry
|
||||
val configuration: Configuration,
|
||||
val project: Project,
|
||||
val temporaryPlacesRegistry: TemporaryPlacesRegistry
|
||||
) : MultiHostInjector {
|
||||
companion object {
|
||||
private val STRING_LITERALS_REGEXP = "\"([^\"]*)\"".toRegex()
|
||||
private val ABSENT_KOTLIN_INJECTION = BaseInjection("ABSENT_KOTLIN_BASE_INJECTION")
|
||||
}
|
||||
|
||||
var annotationInjectionsEnabled = Registry.`is`("kotlin.annotation.injection.enabled", false)
|
||||
|
||||
private val kotlinSupport: KotlinLanguageInjectionSupport? by lazy {
|
||||
val kotlinSupport: KotlinLanguageInjectionSupport? by lazy {
|
||||
ArrayList(InjectorUtils.getActiveInjectionSupports()).filterIsInstance(KotlinLanguageInjectionSupport::class.java).firstOrNull()
|
||||
}
|
||||
|
||||
private data class KotlinCachedInjection(val modificationCount: Long, val baseInjection: BaseInjection)
|
||||
|
||||
private var KtStringTemplateExpression.cachedInjectionWithModification: KotlinCachedInjection? by UserDataProperty(
|
||||
Key.create<KotlinCachedInjection>("CACHED_INJECTION_WITH_MODIFICATION"))
|
||||
Key.create<KotlinCachedInjection>("CACHED_INJECTION_WITH_MODIFICATION"))
|
||||
|
||||
override fun getLanguagesToInject(registrar: MultiHostRegistrar, context: PsiElement) {
|
||||
val ktHost: KtStringTemplateExpression = context as? KtStringTemplateExpression ?: return
|
||||
@@ -88,7 +77,7 @@ class KotlinLanguageInjector(
|
||||
|
||||
val support = kotlinSupport ?: return
|
||||
|
||||
if (!ProjectRootsUtil.isInProjectOrLibSource(ktHost.containingFile.originalFile)) return
|
||||
if (!ProjectRootsUtil.isInProjectOrLibSource(ktHost)) return
|
||||
|
||||
val needImmediateAnswer = with(ApplicationManager.getApplication()) { isDispatchThread && !isUnitTestMode }
|
||||
val kotlinCachedInjection = ktHost.cachedInjectionWithModification
|
||||
@@ -144,9 +133,9 @@ class KotlinLanguageInjector(
|
||||
|
||||
@Suppress("FoldInitializerAndIfToElvis")
|
||||
private fun computeBaseInjection(
|
||||
ktHost: KtStringTemplateExpression,
|
||||
support: KotlinLanguageInjectionSupport,
|
||||
registrar: MultiHostRegistrar): BaseInjection? {
|
||||
ktHost: KtStringTemplateExpression,
|
||||
support: KotlinLanguageInjectionSupport,
|
||||
registrar: MultiHostRegistrar): BaseInjection? {
|
||||
val containingFile = ktHost.containingFile
|
||||
|
||||
val tempInjectedLanguage = temporaryPlacesRegistry.getLanguageFor(ktHost, containingFile)
|
||||
@@ -168,10 +157,10 @@ class KotlinLanguageInjector(
|
||||
|
||||
private fun findInjectionInfo(place: KtElement, originalHost: Boolean = true): InjectionInfo? {
|
||||
return injectWithExplicitCodeInstruction(place)
|
||||
?: injectWithCall(place)
|
||||
?: injectInAnnotationCall(place)
|
||||
?: injectWithReceiver(place)
|
||||
?: injectWithVariableUsage(place, originalHost)
|
||||
?: injectWithCall(place)
|
||||
?: injectWithReceiver(place)
|
||||
?: injectWithVariableUsage(place, originalHost)
|
||||
?: injectWithAnnotationEntry(place)
|
||||
}
|
||||
|
||||
private fun injectWithExplicitCodeInstruction(host: KtElement): InjectionInfo? {
|
||||
@@ -186,9 +175,9 @@ class KotlinLanguageInjector(
|
||||
val callExpression = qualifiedExpression.selectorExpression as? KtCallExpression ?: return null
|
||||
val callee = callExpression.calleeExpression ?: return null
|
||||
|
||||
if (isAnalyzeOff()) return null
|
||||
if (isAnalyzeOff(qualifiedExpression.project)) return null
|
||||
|
||||
val kotlinInjections = configuration.getInjections(KOTLIN_SUPPORT_ID)
|
||||
val kotlinInjections = Configuration.getInstance().getInjections(KOTLIN_SUPPORT_ID)
|
||||
|
||||
val calleeName = callee.text
|
||||
val possibleNames = collectPossibleNames(kotlinInjections)
|
||||
@@ -231,10 +220,11 @@ class KotlinLanguageInjector(
|
||||
// Given place is not original host of the injection so we stop to prevent stepping through indirect references
|
||||
if (!originalHost) return null
|
||||
|
||||
val ktHost: KtElement = host
|
||||
val ktProperty = host.parent as? KtProperty ?: return null
|
||||
if (ktProperty.initializer != host) return null
|
||||
|
||||
if (isAnalyzeOff()) return null
|
||||
if (isAnalyzeOff(ktHost.project)) return null
|
||||
|
||||
val searchScope = LocalSearchScope(arrayOf(ktProperty.containingFile), "", true)
|
||||
return ReferencesSearch.search(ktProperty, searchScope).asSequence().mapNotNull { psiReference ->
|
||||
@@ -247,10 +237,10 @@ class KotlinLanguageInjector(
|
||||
val ktHost: KtElement = host
|
||||
val argument = ktHost.parent as? KtValueArgument ?: return null
|
||||
|
||||
val callExpression = PsiTreeUtil.getParentOfType(ktHost, KtCallElement::class.java) ?: return null
|
||||
val callee = getNameReference(callExpression.calleeExpression) ?: return null
|
||||
val callExpression = PsiTreeUtil.getParentOfType(ktHost, KtCallExpression::class.java) ?: return null
|
||||
val callee = callExpression.calleeExpression ?: return null
|
||||
|
||||
if (isAnalyzeOff()) return null
|
||||
if (isAnalyzeOff(ktHost.project)) return null
|
||||
|
||||
for (reference in callee.references) {
|
||||
ProgressManager.checkCanceled()
|
||||
@@ -273,44 +263,19 @@ class KotlinLanguageInjector(
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getNameReference(callee: KtExpression?): KtNameReferenceExpression? {
|
||||
if (callee is KtConstructorCalleeExpression)
|
||||
return callee.constructorReferenceExpression as? KtNameReferenceExpression
|
||||
return callee as? KtNameReferenceExpression
|
||||
}
|
||||
|
||||
private fun injectInAnnotationCall(host: KtElement): InjectionInfo? {
|
||||
if (!annotationInjectionsEnabled) return null
|
||||
val argument = host.parent as? KtValueArgument ?: return null
|
||||
val annotationEntry = argument.parent.parent as? KtCallElement ?: return null
|
||||
if (!fastCheckInjectionsExists(annotationEntry)) return null
|
||||
val calleeExpression = annotationEntry.calleeExpression ?: return null
|
||||
val callee = getNameReference(calleeExpression)?.mainReference?.resolve()
|
||||
when (callee) {
|
||||
is PsiClass -> {
|
||||
val psiClass = callee as? PsiClass ?: return null
|
||||
val argumentName = argument.getArgumentName()?.asName?.identifier ?: "value"
|
||||
val method = psiClass.findMethodsByName(argumentName, false).singleOrNull() ?: return null
|
||||
return findInjection(method, configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID))
|
||||
}
|
||||
else -> return null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun injectionForJavaMethod(argument: KtValueArgument, javaMethod: PsiMethod): InjectionInfo? {
|
||||
val argumentIndex = (argument.parent as KtValueArgumentList).arguments.indexOf(argument)
|
||||
val psiParameter = javaMethod.parameterList.parameters.getOrNull(argumentIndex) ?: return null
|
||||
|
||||
val injectionInfo = findInjection(psiParameter, configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID))
|
||||
val injectionInfo = findInjection(psiParameter, Configuration.getInstance().getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID))
|
||||
if (injectionInfo != null) {
|
||||
return injectionInfo
|
||||
}
|
||||
|
||||
val annotations = AnnotationUtilEx.getAnnotationFrom(
|
||||
psiParameter,
|
||||
configuration.advancedConfiguration.languageAnnotationPair,
|
||||
true)
|
||||
psiParameter,
|
||||
Configuration.getProjectInstance(psiParameter.project).advancedConfiguration.languageAnnotationPair,
|
||||
true)
|
||||
|
||||
if (annotations.isNotEmpty()) {
|
||||
return processAnnotationInjectionInner(annotations)
|
||||
@@ -323,7 +288,7 @@ class KotlinLanguageInjector(
|
||||
val argumentIndex = (argument.parent as KtValueArgumentList).arguments.indexOf(argument)
|
||||
val ktParameter = ktFunction.valueParameters.getOrNull(argumentIndex) ?: return null
|
||||
|
||||
val patternInjection = findInjection(ktParameter, configuration.getInjections(KOTLIN_SUPPORT_ID))
|
||||
val patternInjection = findInjection(ktParameter, Configuration.getInstance().getInjections(KOTLIN_SUPPORT_ID))
|
||||
if (patternInjection != null) {
|
||||
return patternInjection
|
||||
}
|
||||
@@ -341,6 +306,29 @@ class KotlinLanguageInjector(
|
||||
return InjectionInfo(languageId, null, null)
|
||||
}
|
||||
|
||||
private fun injectWithAnnotationEntry(host: KtElement): InjectionInfo? {
|
||||
val argument = host.parent as? KtValueArgument ?: return null
|
||||
val annotationEntry = PsiTreeUtil.getParentOfType(host, KtAnnotationEntry::class.java) ?: return null
|
||||
if (isAnalyzeOff(host.project)) return null
|
||||
|
||||
val calleeReference = annotationEntry.calleeExpression?.constructorReferenceExpression?.mainReference
|
||||
val callee = calleeReference?.resolve()
|
||||
return when (callee) {
|
||||
is KtFunction -> injectionForKotlinCall(argument, callee, calleeReference)
|
||||
is PsiClass -> {
|
||||
// Look for java injections for the PsiAnnotationMethod.
|
||||
(argument.reference ?: argument.getArgumentName()?.referenceExpression?.mainReference)
|
||||
?.let { it.resolve() as? PsiMethod }
|
||||
?.let { findInjection(it, Configuration.getInstance().getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)) }
|
||||
?.takeIf { injectionInfo ->
|
||||
// Temporary forbid injection for SpEL because of inspections that gives warnings when host language is not Java.
|
||||
injectionInfo.languageId != "SpEL"
|
||||
}
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun findInjection(element: PsiElement?, injections: List<BaseInjection>): InjectionInfo? {
|
||||
for (injection in injections) {
|
||||
if (injection.acceptsPsiElement(element)) {
|
||||
@@ -351,8 +339,8 @@ class KotlinLanguageInjector(
|
||||
return null
|
||||
}
|
||||
|
||||
private fun isAnalyzeOff(): Boolean {
|
||||
return configuration.advancedConfiguration.dfaOption == Configuration.DfaOption.OFF
|
||||
private fun isAnalyzeOff(project: Project): Boolean {
|
||||
return Configuration.getProjectInstance(project).advancedConfiguration.dfaOption == Configuration.DfaOption.OFF
|
||||
}
|
||||
|
||||
private fun processAnnotationInjectionInner(annotations: Array<PsiAnnotation>): InjectionInfo? {
|
||||
@@ -362,52 +350,4 @@ class KotlinLanguageInjector(
|
||||
|
||||
return InjectionInfo(id, prefix, suffix)
|
||||
}
|
||||
|
||||
private val injectableTargetClassShortNames = CachedValuesManager.getManager(project)
|
||||
.createCachedValue({
|
||||
CachedValueProvider.Result.create(HashSet<String>().apply {
|
||||
for (injection in configuration.getInjections(JavaLanguageInjectionSupport.JAVA_SUPPORT_ID)) {
|
||||
for (injectionPlace in injection.injectionPlaces) {
|
||||
for (targetClassFQN in retrieveJavaPlaceTargetClassesFQNs(injectionPlace)) {
|
||||
add(StringUtilRt.getShortName(targetClassFQN))
|
||||
}
|
||||
}
|
||||
}
|
||||
for (injection in configuration.getInjections(org.jetbrains.kotlin.idea.injection.KOTLIN_SUPPORT_ID)) {
|
||||
for (injectionPlace in injection.injectionPlaces) {
|
||||
for (targetClassFQN in retrieveKotlinPlaceTargetClassesFQNs(injectionPlace)) {
|
||||
add(StringUtilRt.getShortName(targetClassFQN))
|
||||
}
|
||||
}
|
||||
}
|
||||
}, configuration)
|
||||
}, false)
|
||||
|
||||
private fun fastCheckInjectionsExists(annotationEntry: KtCallElement): Boolean {
|
||||
val referencedName = getNameReference(annotationEntry.calleeExpression)?.getReferencedName() ?: return false
|
||||
val annotationShortName = annotationEntry.containingKtFile.aliasImportMap()[referencedName].singleOrNull() ?: referencedName
|
||||
return annotationShortName in injectableTargetClassShortNames.value
|
||||
}
|
||||
|
||||
private fun retrieveJavaPlaceTargetClassesFQNs(place: InjectionPlace): Collection<String> {
|
||||
val classCondition = place.elementPattern.condition.conditions.firstOrNull { it.debugMethodName == "definedInClass" }
|
||||
as? PatternConditionPlus<*, *> ?: return emptyList()
|
||||
val psiClassNamePatternCondition = classCondition.valuePattern.condition.conditions.
|
||||
firstIsInstanceOrNull<PsiClassNamePatternCondition>() ?: return emptyList()
|
||||
val valuePatternCondition = psiClassNamePatternCondition.namePattern.condition.conditions.firstIsInstanceOrNull<ValuePatternCondition<String>>() ?: return emptyList()
|
||||
return valuePatternCondition.values
|
||||
}
|
||||
|
||||
private fun retrieveKotlinPlaceTargetClassesFQNs(place: InjectionPlace): Collection<String> {
|
||||
val classNames = SmartList<String>()
|
||||
fun collect(condition: PatternCondition<*>) {
|
||||
when (condition) {
|
||||
is PatternConditionPlus<*, *> -> condition.valuePattern.condition.conditions.forEach { collect(it) }
|
||||
is KotlinFunctionPattern.DefinedInClassCondition -> classNames.add(condition.fqName)
|
||||
}
|
||||
}
|
||||
place.elementPattern.condition.conditions.forEach { collect(it) }
|
||||
return classNames
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.run
|
||||
|
||||
import com.intellij.compiler.options.CompileStepBeforeRun
|
||||
import com.intellij.execution.configurations.RunConfiguration
|
||||
|
||||
fun RunConfiguration.addBuildTask() {
|
||||
beforeRunTasks = beforeRunTasks + CompileStepBeforeRun.MakeBeforeRunTask()
|
||||
}
|
||||
@@ -123,7 +123,7 @@ object InlayScratchOutputHandler : ScratchOutputHandler {
|
||||
return fontInfo.fontMetrics().stringWidth(text)
|
||||
}
|
||||
|
||||
override fun paint(editor: Editor, g: Graphics, r: Rectangle, textAttributes: TextAttributes) {
|
||||
override fun paint(editor: Editor, g: Graphics, r: Rectangle) {
|
||||
val attributes = getAttributes()
|
||||
val fgColor = attributes.foregroundColor ?: return
|
||||
g.color = fgColor
|
||||
|
||||
@@ -71,11 +71,10 @@ abstract class AbstractKotlinMavenInspectionTest : MavenImportingTestCase() {
|
||||
|
||||
val problemElements = runInspection(inspectionClass, myProject).problemElements
|
||||
val actualProblems = problemElements
|
||||
.keys()
|
||||
.filter { it.name == "pom.xml" }
|
||||
.map { problemElements.get(it) }
|
||||
.flatMap { it.toList() }
|
||||
.mapNotNull { it as? ProblemDescriptorBase }
|
||||
.filter { it.key.name == "pom.xml" }
|
||||
.values
|
||||
.flatMap { it.toList() }
|
||||
.mapNotNull { it as? ProblemDescriptorBase }
|
||||
|
||||
val actual = actualProblems
|
||||
.map { SimplifiedProblemDescription(it.descriptionTemplate, it.psiElement.text.replace("\\s+".toRegex(), "")) to it }
|
||||
|
||||
@@ -89,7 +89,7 @@ public abstract class MavenImportingTestCase extends MavenTestCase {
|
||||
VfsRootAccess.disallowRootAccess(PathManager.getConfigPath());
|
||||
Messages.setTestDialog(TestDialog.DEFAULT);
|
||||
removeFromLocalRepository("test");
|
||||
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory().toFile());
|
||||
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory());
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.intellij.execution.process.ProcessOutputTypes
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.annotations.NotNull
|
||||
import org.jetbrains.kotlin.console.actions.logError
|
||||
import org.jetbrains.kotlin.diagnostics.Severity
|
||||
import org.jetbrains.kotlin.utils.repl.ReplEscapeType
|
||||
@@ -50,7 +49,7 @@ class ReplOutputHandler(
|
||||
|
||||
override fun isSilentlyDestroyOnClose() = true
|
||||
|
||||
override fun notifyTextAvailable(text: String, key: Key<*>) {
|
||||
override fun notifyTextAvailable(text: String, key: Key<*>?) {
|
||||
// hide warning about adding test folder to classpath
|
||||
if (text.startsWith("warning: classpath entry points to a non-existent location")) return
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ public class PluginTestCaseBase {
|
||||
@NotNull
|
||||
public static Sdk addJdk(@NotNull Disposable disposable, @NotNull Function0<Sdk> getJdk) {
|
||||
Sdk jdk = getJdk.invoke();
|
||||
ApplicationManager.getApplication().runWriteAction(() -> ProjectJdkTable.getInstance().addJdk(jdk, disposable));
|
||||
ApplicationManager.getApplication().runWriteAction(() -> ProjectJdkTable.getInstance().addJdk(jdk));
|
||||
return jdk;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<externalAnnotator language="kotlin" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintExternalAnnotator"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.uast.UastContext"
|
||||
serviceImplementation="org.jetbrains.uast.UastContext"/>
|
||||
|
||||
<globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintAddJavascriptInterface" displayName="addJavascriptInterface Called" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintAddJavascriptInterfaceInspection"/>
|
||||
<globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintAllowAllHostnameVerifier" displayName="Insecure HostnameVerifier" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintAllowAllHostnameVerifierInspection"/>
|
||||
<globalInspection language="kotlin" hasStaticDescription="true" shortName="AndroidKLintAlwaysShowAction" displayName="Usage of showAsAction=always" groupKey="android.klint.inspections.group.name" bundle="org.jetbrains.kotlin.idea.KotlinBundle" enabledByDefault="true" level="WARNING" implementationClass="org.jetbrains.android.inspections.klint.AndroidLintInspectionToolProvider$AndroidKLintAlwaysShowActionInspection"/>
|
||||
@@ -115,4 +118,14 @@
|
||||
|
||||
<codeInspection.InspectionExtension implementation="org.jetbrains.android.inspections.klint.AndroidInspectionExtensionsFactory"/>
|
||||
</extensions>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="org.jetbrains.uast.uastLanguagePlugin"
|
||||
interface="org.jetbrains.uast.UastLanguagePlugin"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.uast">
|
||||
<uastLanguagePlugin implementation="org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin"/>
|
||||
<uastLanguagePlugin implementation="org.jetbrains.uast.java.JavaUastLanguagePlugin"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -1,6 +1,5 @@
|
||||
<idea-plugin>
|
||||
<id>org.jetbrains.kotlin</id>
|
||||
<version>1.2</version>
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.diagnosticSuppressor"
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPCommonFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPJavaFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPJSFrameworkSupportProvider"/>
|
||||
@@ -61,6 +59,8 @@
|
||||
|
||||
<projectTaskRunner implementation="org.jetbrains.kotlin.idea.run.MultiplatformGradleProjectTaskRunner" order="first,before gradle"/>
|
||||
<orderEnumerationHandlerFactory implementation="org.jetbrains.kotlin.idea.run.MultiplatformGradleOrderEnumeratorHandler$FactoryImpl" order="first"/>
|
||||
|
||||
<moduleBuilder builderClass="org.jetbrains.kotlin.gradle.kdsl.GradleModuleBuilder" />
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
@@ -77,6 +77,10 @@
|
||||
|
||||
<moduleBuilder implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleMultiplatformModuleBuilder"/>
|
||||
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleJavaFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJavaFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJSFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleGroovyFrameworkSupportProvider" />
|
||||
<buildSystemTypeDetector implementation="org.jetbrains.kotlin.idea.configuration.GradleDetector"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<version>@snapshot@</version>
|
||||
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
|
||||
|
||||
<idea-version since-build="173.1" until-build="173.*"/>
|
||||
<idea-version since-build="171.1" until-build="171.*"/>
|
||||
|
||||
<depends>com.intellij.modules.platform</depends>
|
||||
<depends>com.intellij.modules.remoteServers</depends>
|
||||
@@ -630,7 +630,6 @@
|
||||
<elementDescriptionProvider
|
||||
implementation="org.jetbrains.kotlin.idea.findUsages.KotlinNonCodeSearchElementDescriptionProvider"/>
|
||||
<highlightUsagesHandlerFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightExitPointsHandlerFactory"/>
|
||||
<highlightUsagesHandlerFactory implementation="org.jetbrains.kotlin.idea.highlighter.KotlinHighlightImplicitItHandlerFactory"/>
|
||||
<findUsagesHandlerFactory implementation="org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory"/>
|
||||
<usageTypeProvider implementation="org.jetbrains.kotlin.idea.findUsages.KotlinUsageTypeProvider"/>
|
||||
|
||||
@@ -794,8 +793,6 @@
|
||||
<usageContextPanelProvider implementation="org.jetbrains.kotlin.idea.slicer.KotlinUsageContextDataInflowPanel$Provider"/>
|
||||
<usageContextPanelProvider implementation="org.jetbrains.kotlin.idea.slicer.KotlinUsageContextDataOutflowPanel$Provider"/>
|
||||
|
||||
<gotoRelatedProvider implementation="org.jetbrains.kotlin.idea.goto.KotlinExpectOrActualGotoRelatedProvider"/>
|
||||
|
||||
<declarationRangeHandler key="org.jetbrains.kotlin.psi.KtClassOrObject"
|
||||
implementationClass="org.jetbrains.kotlin.idea.codeInsight.KotlinClassDeclarationRangeHandler"/>
|
||||
|
||||
@@ -2673,7 +2670,7 @@
|
||||
level="WARNING"
|
||||
language="kotlin"
|
||||
/>
|
||||
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SortModifiersInspection"
|
||||
displayName="Non-canonical modifier order"
|
||||
groupPath="Kotlin"
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.formatter
|
||||
|
||||
import com.intellij.internal.statistic.AbstractProjectsUsagesCollector
|
||||
import com.intellij.internal.statistic.beans.GroupDescriptor
|
||||
import com.intellij.internal.statistic.beans.UsageDescriptor
|
||||
import com.intellij.internal.statistic.utils.getEnumUsage
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||
import org.jetbrains.kotlin.idea.core.formatter.KotlinCodeStyleSettings
|
||||
import org.jetbrains.kotlin.idea.util.compat.statistic.AbstractProjectsUsagesCollector
|
||||
import org.jetbrains.kotlin.idea.util.compat.statistic.getEnumUsage
|
||||
|
||||
class KotlinFormatterUsageCollector : AbstractProjectsUsagesCollector() {
|
||||
override fun getGroupId(): GroupDescriptor = GroupDescriptor.create(GROUP_ID)
|
||||
|
||||
@@ -53,7 +53,7 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
|
||||
val lineNumber = element.getLineNumber()
|
||||
if (lineNumber !in markedLineNumbers && isRecursiveCall(element)) {
|
||||
markedLineNumbers.add(lineNumber)
|
||||
result.add(RecursiveMethodCallMarkerInfo(getElementForLineMark(element)))
|
||||
result.add(RecursiveMethodCallMarkerInfo(element))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,8 +113,8 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
|
||||
return true
|
||||
}
|
||||
|
||||
private class RecursiveMethodCallMarkerInfo(callElement: PsiElement)
|
||||
: LineMarkerInfo<PsiElement>(
|
||||
private class RecursiveMethodCallMarkerInfo(callElement: KtElement)
|
||||
: LineMarkerInfo<KtElement>(
|
||||
callElement,
|
||||
callElement.textRange,
|
||||
AllIcons.Gutter.RecursiveMethod,
|
||||
@@ -125,7 +125,7 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
|
||||
) {
|
||||
|
||||
override fun createGutterRenderer(): GutterIconRenderer? {
|
||||
return object : LineMarkerInfo.LineMarkerGutterIconRenderer<PsiElement>(this) {
|
||||
return object : LineMarkerInfo.LineMarkerGutterIconRenderer<KtElement>(this) {
|
||||
override fun getClickAction() = null // to place breakpoint on mouse click
|
||||
}
|
||||
}
|
||||
@@ -133,15 +133,6 @@ class KotlinRecursiveCallLineMarkerProvider : LineMarkerProvider {
|
||||
|
||||
}
|
||||
|
||||
internal fun getElementForLineMark(callElement: PsiElement): PsiElement =
|
||||
when (callElement) {
|
||||
is KtSimpleNameExpression -> callElement.getReferencedNameElement()
|
||||
else ->
|
||||
// a fallback,
|
||||
//but who knows what to reference in KtArrayAccessExpression ?
|
||||
generateSequence(callElement, { it.firstChild }).last()
|
||||
}
|
||||
|
||||
private fun PsiElement.getLineNumber(): Int {
|
||||
return PsiDocumentManager.getInstance(project).getDocument(containingFile)!!.getLineNumber(textOffset)
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.checkers.isBuiltInCoroutineContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider {
|
||||
private class SuspendCallMarkerInfo(callElement: PsiElement, message: String) : LineMarkerInfo<PsiElement>(
|
||||
private class SuspendCallMarkerInfo(callElement: KtElement, message: String) : LineMarkerInfo<KtElement>(
|
||||
callElement,
|
||||
callElement.textRange,
|
||||
KotlinIcons.SUSPEND_CALL,
|
||||
@@ -37,7 +37,7 @@ class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider {
|
||||
GutterIconRenderer.Alignment.RIGHT
|
||||
) {
|
||||
override fun createGutterRenderer(): GutterIconRenderer? {
|
||||
return object : LineMarkerInfo.LineMarkerGutterIconRenderer<PsiElement>(this) {
|
||||
return object : LineMarkerInfo.LineMarkerGutterIconRenderer<KtElement>(this) {
|
||||
override fun getClickAction(): AnAction? = null
|
||||
}
|
||||
}
|
||||
@@ -61,9 +61,9 @@ class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider {
|
||||
|
||||
markedLineNumbers += lineNumber
|
||||
result += if (element is KtForExpression) {
|
||||
SuspendCallMarkerInfo(getElementForLineMark(element.loopRange!!), "Suspending iteration")
|
||||
SuspendCallMarkerInfo(element.loopRange!!, "Suspending iteration")
|
||||
} else {
|
||||
SuspendCallMarkerInfo(getElementForLineMark(element), "Suspend function call")
|
||||
SuspendCallMarkerInfo(element, "Suspend function call")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.execution.lineMarker.RunLineMarkerContributor
|
||||
import com.intellij.execution.testframework.TestIconMapper
|
||||
import com.intellij.execution.testframework.sm.runner.states.TestStateInfo
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.openapi.module.ModuleUtilCore
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.psi.PsiElement
|
||||
@@ -33,10 +34,8 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptorWithResolutionScopes
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.js.jsOrJsImpl
|
||||
import org.jetbrains.kotlin.idea.js.jsTestOutputFilePath
|
||||
import org.jetbrains.kotlin.idea.js.getJsOutputFilePath
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.util.module
|
||||
import org.jetbrains.kotlin.idea.util.string.joinWithEscape
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -46,7 +45,6 @@ import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform.Common
|
||||
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import javax.swing.Icon
|
||||
|
||||
@@ -110,8 +108,8 @@ class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
|
||||
private fun getJavaScriptTestIcon(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor): Icon? {
|
||||
if (!descriptor.isTest()) return null
|
||||
|
||||
val module = declaration.module?.jsOrJsImpl() ?: return null
|
||||
val testFilePath = module.jsTestOutputFilePath ?: return null
|
||||
val module = ModuleUtilCore.findModuleForPsiElement(declaration) ?: return null
|
||||
val testFilePath = getJsOutputFilePath(module, true, false) ?: return null
|
||||
|
||||
val locations = ArrayList<String>()
|
||||
|
||||
@@ -150,7 +148,7 @@ class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
|
||||
val platform = TargetPlatformDetector.getPlatform(declaration.containingKtFile)
|
||||
val icon = when (platform) {
|
||||
is JvmPlatform -> getJavaTestIcon(declaration)
|
||||
is JsPlatform, is Common -> getJavaScriptTestIcon(declaration, descriptor)
|
||||
is JsPlatform -> getJavaScriptTestIcon(declaration, descriptor)
|
||||
else -> return null
|
||||
} ?: return null
|
||||
return RunLineMarkerContributor.Info(icon, { "Run Test" }, ExecutorAction.getActions())
|
||||
|
||||
@@ -8,10 +8,10 @@ package org.jetbrains.kotlin.idea.highlighter.dsl
|
||||
import com.intellij.ide.highlighter.custom.CustomHighlighterColors.*
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.highlighter.HighlighterExtension
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.calls.DslMarkerUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
|
||||
@@ -24,7 +24,16 @@ class DslHighlighterExtension : HighlighterExtension() {
|
||||
}
|
||||
|
||||
override fun highlightCall(elementToHighlight: PsiElement, resolvedCall: ResolvedCall<*>): TextAttributesKey? {
|
||||
return dslCustomTextStyle(resolvedCall.resultingDescriptor)
|
||||
val markerAnnotationFqName = markerAnnotationFqName(resolvedCall) ?: return null
|
||||
return styleForDsl(markerAnnotationFqName)
|
||||
}
|
||||
|
||||
private fun markerAnnotationFqName(resolvedCall: ResolvedCall<*>): FqName? {
|
||||
val markerAnnotation = resolvedCall.resultingDescriptor.annotations.find { annotation ->
|
||||
annotation.annotationClass?.isDslHighlightingMarker() ?: false
|
||||
}
|
||||
|
||||
return markerAnnotation?.fqName
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -44,24 +53,11 @@ class DslHighlighterExtension : HighlighterExtension() {
|
||||
fun externalKeyName(index: Int) = "KOTLIN_DSL_STYLE$index"
|
||||
|
||||
val descriptionsToStyles = (1..numStyles).associate { index ->
|
||||
"Dsl//${styleOptionDisplayName(index)}" to styles[index - 1]
|
||||
"Dsl//Style$index" to styles[index - 1]
|
||||
}
|
||||
|
||||
fun styleOptionDisplayName(index: Int) = "Style$index"
|
||||
|
||||
fun styleIdByMarkerAnnotation(markerAnnotation: ClassDescriptor): Int? {
|
||||
val markerAnnotationFqName = markerAnnotation.fqNameSafe
|
||||
return (markerAnnotationFqName.asString().hashCode() % numStyles).absoluteValue + 1
|
||||
}
|
||||
|
||||
fun dslCustomTextStyle(callableDescriptor: CallableDescriptor): TextAttributesKey? {
|
||||
val markerAnnotation = callableDescriptor.annotations.find { annotation ->
|
||||
annotation.annotationClass?.isDslHighlightingMarker() ?: false
|
||||
}?.annotationClass ?: return null
|
||||
|
||||
val styleId = styleIdByMarkerAnnotation(markerAnnotation) ?: return null
|
||||
return styles[styleId - 1]
|
||||
}
|
||||
private fun styleForDsl(markerAnnotationFqName: FqName) =
|
||||
styles[(markerAnnotationFqName.asString().hashCode() % numStyles).absoluteValue]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter.markers
|
||||
|
||||
import com.intellij.application.options.colors.ColorAndFontOptions
|
||||
import com.intellij.codeHighlighting.Pass
|
||||
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler
|
||||
import com.intellij.codeInsight.daemon.LineMarkerInfo
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.ide.DataManager
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.Function
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||
import org.jetbrains.kotlin.idea.highlighter.dsl.DslHighlighterExtension
|
||||
import org.jetbrains.kotlin.idea.highlighter.dsl.isDslHighlightingMarker
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import javax.swing.JComponent
|
||||
|
||||
private val navHandler = GutterIconNavigationHandler<PsiElement> { event, element ->
|
||||
val dataContext = (event.component as? JComponent)?.let { DataManager.getInstance().getDataContext(it) }
|
||||
?: return@GutterIconNavigationHandler
|
||||
val ktClass = element?.parent as? KtClass ?: return@GutterIconNavigationHandler
|
||||
val styleId = ktClass.styleIdForMarkerAnnotation() ?: return@GutterIconNavigationHandler
|
||||
ColorAndFontOptions.selectOrEditColor(dataContext, DslHighlighterExtension.styleOptionDisplayName(styleId), KotlinLanguage.NAME)
|
||||
}
|
||||
|
||||
private val toolTipHandler = Function<PsiElement, String> {
|
||||
"Marker annotation for DSL"
|
||||
}
|
||||
|
||||
fun collectHighlightingColorsMarkers(
|
||||
ktClass: KtClass,
|
||||
result: MutableCollection<LineMarkerInfo<*>>
|
||||
) {
|
||||
if (ktClass.styleIdForMarkerAnnotation() == null) return
|
||||
|
||||
val anchor = ktClass.nameIdentifier ?: return
|
||||
|
||||
result.add(
|
||||
LineMarkerInfo<PsiElement>(
|
||||
anchor,
|
||||
anchor.textRange,
|
||||
AllIcons.Gutter.Colors,
|
||||
Pass.LINE_MARKERS,
|
||||
toolTipHandler, navHandler,
|
||||
GutterIconRenderer.Alignment.RIGHT
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun KtClass.styleIdForMarkerAnnotation(): Int? {
|
||||
val classDescriptor = toDescriptor() as? ClassDescriptor ?: return null
|
||||
if (classDescriptor.kind != ClassKind.ANNOTATION_CLASS) return null
|
||||
if (!classDescriptor.isDslHighlightingMarker()) return null
|
||||
return DslHighlighterExtension.styleIdByMarkerAnnotation(classDescriptor)
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.intellij.codeInsight.daemon.impl.MarkerType
|
||||
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
|
||||
import com.intellij.codeInsight.navigation.ListBackgroundUpdaterTask
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.ide.util.PsiClassOrFunctionalExpressionListCellRenderer
|
||||
import com.intellij.openapi.actionSystem.IdeActions
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||
@@ -43,7 +42,6 @@ import org.jetbrains.kotlin.idea.facet.implementedDescriptors
|
||||
import org.jetbrains.kotlin.idea.facet.implementingDescriptors
|
||||
import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMethods
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.idea.util.module
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
|
||||
@@ -96,7 +94,6 @@ class KotlinLineMarkerProvider : LineMarkerProvider {
|
||||
when (element) {
|
||||
is KtClass -> {
|
||||
collectInheritedClassMarker(element, result)
|
||||
collectHighlightingColorsMarkers(element, result)
|
||||
}
|
||||
is KtNamedFunction -> {
|
||||
functions.add(element)
|
||||
@@ -158,20 +155,12 @@ interface TestableLineMarkerNavigator {
|
||||
fun getTargetsPopupDescriptor(element: PsiElement?): NavigationPopupDescriptor?
|
||||
}
|
||||
|
||||
private class SubclassRenderer: PsiClassOrFunctionalExpressionListCellRenderer() {
|
||||
override fun getComparingObject(element: NavigatablePsiElement?): Comparable<Nothing> {
|
||||
val baseText = super.getComparingObject(element)
|
||||
val moduleName = element?.module?.name ?: return baseText
|
||||
return "$baseText [$moduleName]"
|
||||
}
|
||||
}
|
||||
|
||||
private val SUBCLASSED_CLASS = MarkerType(
|
||||
"SUBCLASSED_CLASS",
|
||||
{ getPsiClass(it)?.let { MarkerType.getSubclassedClassTooltip(it) } },
|
||||
object : LineMarkerNavigator() {
|
||||
override fun browse(e: MouseEvent?, element: PsiElement?) {
|
||||
getPsiClass(element)?.let { MarkerType.navigateToSubclassedClass(e, it, SubclassRenderer()) }
|
||||
getPsiClass(element)?.let { MarkerType.navigateToSubclassedClass(e, it) }
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ import com.intellij.codeInspection.IntentionWrapper
|
||||
import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter
|
||||
import com.intellij.openapi.editor.event.DocumentEvent
|
||||
import com.intellij.openapi.editor.event.DocumentListener
|
||||
import com.intellij.openapi.ui.LabeledComponent
|
||||
import com.intellij.ui.EditorTextField
|
||||
import org.intellij.lang.regexp.RegExpFileType
|
||||
@@ -81,7 +81,7 @@ class PlatformExtensionReceiverOfInlineInspection : AbstractKotlinInspection() {
|
||||
val regexField = EditorTextField(owner.namePattern, null, RegExpFileType.INSTANCE).apply {
|
||||
setOneLineMode(true)
|
||||
}
|
||||
regexField.document.addDocumentListener(object : DocumentListener {
|
||||
regexField.document.addDocumentListener(object : DocumentAdapter() {
|
||||
override fun documentChanged(e: DocumentEvent?) {
|
||||
owner.namePattern = regexField.text
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.js.resolve.JsPlatform
|
||||
import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings
|
||||
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
|
||||
|
||||
val Module.jsTestOutputFilePath: String?
|
||||
get() {
|
||||
@@ -38,16 +39,6 @@ val Module.jsTestOutputFilePath: String?
|
||||
return JpsPathUtil.urlToPath("$outputDir/${name}_test.js")
|
||||
}
|
||||
|
||||
val Module.jsProductionOutputFilePath: String?
|
||||
get() {
|
||||
if (!shouldUseJpsOutput) {
|
||||
(KotlinFacet.get(this)?.configuration?.settings?.productionOutputPath)?.let { return it }
|
||||
}
|
||||
|
||||
val compilerExtension = CompilerModuleExtension.getInstance(this)
|
||||
val outputDir = compilerExtension?.compilerOutputUrl ?: return null
|
||||
return JpsPathUtil.urlToPath("$outputDir/$name.js")
|
||||
}
|
||||
|
||||
fun Module.jsOrJsImpl() = when (TargetPlatformDetector.getPlatform(this)) {
|
||||
is TargetPlatform.Common -> implementingModules.firstOrNull { TargetPlatformDetector.getPlatform(it) is JsPlatform }
|
||||
@@ -56,4 +47,14 @@ fun Module.jsOrJsImpl() = when (TargetPlatformDetector.getPlatform(this)) {
|
||||
}
|
||||
|
||||
val Module.shouldUseJpsOutput: Boolean
|
||||
get() = !(isGradleModule() && GradleSystemRunningSettings.getInstance().isUseGradleAwareMake)
|
||||
get() = !(isGradleModule() && GradleSystemRunningSettings.getInstance().isUseGradleAwareMake)
|
||||
|
||||
fun getJsOutputFilePath(module: Module, isTests: Boolean, isMeta: Boolean): String? {
|
||||
val compilerExtension = CompilerModuleExtension.getInstance(module)
|
||||
val outputDir = (if (isTests) compilerExtension?.compilerOutputUrlForTests else compilerExtension?.compilerOutputUrl)
|
||||
?: return null
|
||||
val extension = if (isMeta) KotlinJavascriptMetadataUtils.META_JS_SUFFIX else KotlinJavascriptMetadataUtils.JS_EXT
|
||||
return JpsPathUtil.urlToPath("$outputDir/${module.name}${suffix(isTests)}$extension")
|
||||
}
|
||||
|
||||
private fun suffix(isTests: Boolean) = if (isTests) "_test" else ""
|
||||
@@ -9,8 +9,8 @@ import com.intellij.codeInsight.hints.InlayParameterHintsExtension
|
||||
import com.intellij.internal.statistic.UsagesCollector
|
||||
import com.intellij.internal.statistic.beans.GroupDescriptor
|
||||
import com.intellij.internal.statistic.beans.UsageDescriptor
|
||||
import com.intellij.internal.statistic.utils.getBooleanUsage
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.util.compat.statistic.getBooleanUsage
|
||||
|
||||
class KotlinInlayParameterHintsUsageCollector : UsagesCollector() {
|
||||
override fun getGroupId(): GroupDescriptor = GroupDescriptor.create(GROUP_ID)
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
|
||||
abstract class KotlinCrossLanguageQuickFixAction<out T : PsiElement>(element: T) : QuickFixActionBase<T>(element) {
|
||||
override val isCrossLanguageFix: Boolean
|
||||
get() = true
|
||||
|
||||
override final fun invoke(project: Project, editor: Editor?, file: PsiFile) {
|
||||
val element = element
|
||||
if (element != null && FileModificationService.getInstance().prepareFileForWrite(element.containingFile)) {
|
||||
invokeImpl(project, editor, file)
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun invokeImpl(project: Project, editor: Editor?, file: PsiFile)
|
||||
}
|
||||
@@ -17,18 +17,42 @@
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.psi.CREATEBYPATTERN_MAY_NOT_REFORMAT
|
||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
|
||||
abstract class KotlinQuickFixAction<out T : PsiElement>(element: T) : QuickFixActionBase<T>(element) {
|
||||
protected open fun isAvailable(project: Project, editor: Editor?, file: KtFile) = true
|
||||
abstract class KotlinQuickFixAction<out T : PsiElement>(element: T) : IntentionAction {
|
||||
private val elementPointer = element.createSmartPointer()
|
||||
|
||||
override fun isAvailableImpl(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
val ktFile = file as? KtFile ?: return false
|
||||
return isAvailable(project, editor, ktFile)
|
||||
protected val element: T?
|
||||
get() = elementPointer.element
|
||||
|
||||
final override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
CREATEBYPATTERN_MAY_NOT_REFORMAT = true
|
||||
}
|
||||
try {
|
||||
val element = element ?: return false
|
||||
return element.isValid &&
|
||||
!element.project.isDisposed &&
|
||||
(file.manager.isInProject(file) || file is KtCodeFragment) &&
|
||||
(file is KtFile) &&
|
||||
isAvailable(project, editor, file)
|
||||
}
|
||||
finally {
|
||||
CREATEBYPATTERN_MAY_NOT_REFORMAT = false
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun isAvailable(project: Project, editor: Editor?, file: KtFile): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
final override fun invoke(project: Project, editor: Editor?, file: PsiFile) {
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import org.jetbrains.kotlin.psi.CREATEBYPATTERN_MAY_NOT_REFORMAT
|
||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
|
||||
abstract class QuickFixActionBase<out T : PsiElement>(element: T) : IntentionAction {
|
||||
private val elementPointer = element.createSmartPointer()
|
||||
|
||||
protected val element: T?
|
||||
get() = elementPointer.element
|
||||
|
||||
open val isCrossLanguageFix: Boolean = false
|
||||
|
||||
protected open fun isAvailableImpl(project: Project, editor: Editor?, file: PsiFile) = true
|
||||
|
||||
final override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||
CREATEBYPATTERN_MAY_NOT_REFORMAT = true
|
||||
}
|
||||
try {
|
||||
val element = element ?: return false
|
||||
return element.isValid &&
|
||||
!element.project.isDisposed &&
|
||||
(file.manager.isInProject(file) || file is KtCodeFragment) &&
|
||||
(file is KtFile || isCrossLanguageFix) &&
|
||||
isAvailableImpl(project, editor, file)
|
||||
}
|
||||
finally {
|
||||
CREATEBYPATTERN_MAY_NOT_REFORMAT = false
|
||||
}
|
||||
}
|
||||
|
||||
override fun startInWriteAction() = true
|
||||
}
|
||||
@@ -464,34 +464,16 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
|
||||
val psiFactory = KtPsiFactory(currentFile)
|
||||
|
||||
val modifiers = buildString {
|
||||
val modifierList = callableInfo.modifierList?.copied() ?: psiFactory.createEmptyModifierList()
|
||||
val visibilityKeyword = modifierList.visibilityModifierType()
|
||||
if (visibilityKeyword == null) {
|
||||
val defaultVisibility =
|
||||
if (callableInfo.isAbstract) ""
|
||||
else if (containingElement is KtClassOrObject
|
||||
&& !(containingElement is KtClass && containingElement.isInterface())
|
||||
&& containingElement.isAncestor(config.originalElement)
|
||||
&& callableInfo.kind != CallableKind.CONSTRUCTOR) "private "
|
||||
else if (isExtension) "private "
|
||||
else ""
|
||||
append(defaultVisibility)
|
||||
}
|
||||
|
||||
// TODO: Get rid of isAbstract
|
||||
if (callableInfo.isAbstract
|
||||
&& containingElement is KtClass
|
||||
&& !containingElement.isInterface()
|
||||
&& !modifierList.hasModifier(KtTokens.ABSTRACT_KEYWORD)) {
|
||||
modifierList.appendModifier(KtTokens.ABSTRACT_KEYWORD)
|
||||
}
|
||||
|
||||
val text = modifierList.normalize().text
|
||||
if (text.isNotEmpty()) {
|
||||
append("$text ")
|
||||
}
|
||||
}
|
||||
val modifiers =
|
||||
if (callableInfo.isAbstract) {
|
||||
if (containingElement is KtClass && containingElement.isInterface()) "" else "abstract "
|
||||
}
|
||||
else if (containingElement is KtClassOrObject
|
||||
&& !(containingElement is KtClass && containingElement.isInterface())
|
||||
&& containingElement.isAncestor(config.originalElement)
|
||||
&& callableInfo.kind != CallableKind.CONSTRUCTOR) "private "
|
||||
else if (isExtension) "private "
|
||||
else ""
|
||||
|
||||
val isExpectClassMember by lazy {
|
||||
containingElement is KtClassOrObject && containingElement.resolveToDescriptorIfAny()?.isExpect ?: false
|
||||
@@ -500,7 +482,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
val declaration: KtNamedDeclaration = when (callableInfo.kind) {
|
||||
CallableKind.FUNCTION, CallableKind.CONSTRUCTOR -> {
|
||||
val body = when {
|
||||
callableInfo is ConstructorInfo -> if (callableInfo.withBody) "{\n\n}" else ""
|
||||
callableInfo.kind == CallableKind.CONSTRUCTOR -> ""
|
||||
callableInfo.isAbstract -> ""
|
||||
containingElement is KtClass && containingElement.hasModifier(KtTokens.EXTERNAL_KEYWORD) -> ""
|
||||
containingElement is KtObjectDeclaration && containingElement.hasModifier(KtTokens.EXTERNAL_KEYWORD) -> ""
|
||||
@@ -508,12 +490,14 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
&& containingElement.parent.parent is KtClass
|
||||
&& (containingElement.parent.parent as KtClass).hasModifier(KtTokens.EXTERNAL_KEYWORD) -> ""
|
||||
isExpectClassMember -> ""
|
||||
else -> "{\n\n}"
|
||||
else -> "{}"
|
||||
|
||||
}
|
||||
@Suppress("USELESS_CAST") // KT-10755
|
||||
if (callableInfo is FunctionInfo) {
|
||||
psiFactory.createFunction("${modifiers}fun<> $header $body") as KtNamedDeclaration
|
||||
val operatorModifier = if (callableInfo.isOperator) "operator " else ""
|
||||
val infixModifier = if (callableInfo.isInfix) "infix " else ""
|
||||
psiFactory.createFunction("$modifiers$infixModifier${operatorModifier}fun<> $header $body") as KtNamedDeclaration
|
||||
}
|
||||
else if ((callableInfo as ConstructorInfo).isPrimary) {
|
||||
val constructorText = if (modifiers.isNotEmpty()) "${modifiers}constructor$paramList" else paramList
|
||||
@@ -572,11 +556,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
return assignmentToReplace.replace(declaration) as KtCallableDeclaration
|
||||
}
|
||||
|
||||
val container = if (containingElement is KtClass && callableInfo.isForCompanion) {
|
||||
containingElement.getOrCreateCompanionObject()
|
||||
}
|
||||
else containingElement
|
||||
val declarationInPlace = placeDeclarationInContainer(declaration, container, config.originalElement, jetFileToEdit)
|
||||
val declarationInPlace = placeDeclarationInContainer(declaration, containingElement, config.originalElement, jetFileToEdit)
|
||||
|
||||
if (declarationInPlace is KtSecondaryConstructor) {
|
||||
val containingClass = declarationInPlace.containingClassOrObject!!
|
||||
@@ -613,11 +593,14 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
}
|
||||
|
||||
private fun setupTypeReferencesForShortening(declaration: KtNamedDeclaration,
|
||||
parameterTypeExpressions: List<TypeExpression>) {
|
||||
parameterTypeExpressions: List<TypeExpression>): List<KtElement> {
|
||||
val typeRefsToShorten = ArrayList<KtElement>()
|
||||
|
||||
if (config.isExtension) {
|
||||
val receiverTypeText = receiverTypeCandidate!!.theType.renderLong(typeParameterNameMap).first()
|
||||
val replacingTypeRef = KtPsiFactory(declaration).createType(receiverTypeText)
|
||||
(declaration as KtCallableDeclaration).setReceiverTypeReference(replacingTypeRef)!!
|
||||
val newTypeRef = (declaration as KtCallableDeclaration).setReceiverTypeReference(replacingTypeRef)!!
|
||||
typeRefsToShorten.add(newTypeRef)
|
||||
}
|
||||
|
||||
val returnTypeRefs = declaration.getReturnTypeReferences()
|
||||
@@ -628,6 +611,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
if (returnType != null) {
|
||||
// user selected a given type
|
||||
replaceWithLongerName(returnTypeRefs, returnType)
|
||||
typeRefsToShorten.addAll(declaration.getReturnTypeReferences())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -646,6 +630,11 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val expandedValueParameters = declaration.getValueParameters()
|
||||
parameterIndicesToShorten.mapNotNullTo(typeRefsToShorten) { expandedValueParameters[it].typeReference }
|
||||
|
||||
return typeRefsToShorten
|
||||
}
|
||||
|
||||
private fun postprocessDeclaration(declaration: KtNamedDeclaration) {
|
||||
@@ -656,22 +645,18 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
if (TypeUtils.isNullableType(returnType) || KotlinBuiltIns.isPrimitiveType(returnType)) return
|
||||
declaration.addModifier(KtTokens.LATEINIT_KEYWORD)
|
||||
}
|
||||
|
||||
if (callableInfo.isAbstract) {
|
||||
val containingClass = declaration.containingClassOrObject
|
||||
if (containingClass is KtClass && containingClass.isInterface()) {
|
||||
declaration.removeModifier(KtTokens.ABSTRACT_KEYWORD)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupDeclarationBody(func: KtDeclarationWithBody) {
|
||||
if (func !is KtNamedFunction && func !is KtPropertyAccessor) return
|
||||
if (skipReturnType && callableInfo is FunctionInfo && callableInfo.preferEmptyBody) return
|
||||
val oldBody = func.bodyExpression ?: return
|
||||
val templateKind = when (func) {
|
||||
is KtSecondaryConstructor -> TemplateKind.SECONDARY_CONSTRUCTOR
|
||||
is KtNamedFunction, is KtPropertyAccessor -> TemplateKind.FUNCTION
|
||||
else -> throw AssertionError("Unexpected declaration: " + func.getElementTextWithContext())
|
||||
}
|
||||
val bodyText = getFunctionBodyTextFromTemplate(
|
||||
func.project,
|
||||
TemplateKind.FUNCTION,
|
||||
templateKind,
|
||||
if (callableInfo.name.isNotEmpty()) callableInfo.name else null,
|
||||
if (skipReturnType) "Unit" else (func as? KtFunction)?.typeReference?.text ?: "",
|
||||
receiverClassDescriptor?.importableFqName ?: receiverClassDescriptor?.name?.let { FqName.topLevel(it) }
|
||||
@@ -778,7 +763,13 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
|
||||
// add parameter name to the template
|
||||
val possibleNamesFromExpression = parameter.typeInfo.getPossibleNamesFromExpression(currentFileContext)
|
||||
val possibleNames = arrayOf(*parameter.nameSuggestions.toTypedArray(), *possibleNamesFromExpression)
|
||||
val preferredName = parameter.preferredName
|
||||
val possibleNames = if (preferredName != null) {
|
||||
arrayOf(preferredName, *possibleNamesFromExpression)
|
||||
}
|
||||
else {
|
||||
possibleNamesFromExpression
|
||||
}
|
||||
|
||||
// figure out suggested names for each type option
|
||||
val parameterTypeToNamesMap = HashMap<String, Array<String>>()
|
||||
@@ -972,14 +963,6 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
|
||||
if (newDeclaration is KtProperty) {
|
||||
newDeclaration.getter?.let { setupDeclarationBody(it) }
|
||||
|
||||
if (newDeclaration.getter == null
|
||||
&& newDeclaration.initializer == null
|
||||
&& callableInfo is PropertyInfo
|
||||
&& callableInfo.withInitializer
|
||||
&& !callableInfo.isLateinitPreferred) {
|
||||
newDeclaration.initializer = KtPsiFactory(newDeclaration).createExpression("TODO(\"initialize me\")")
|
||||
}
|
||||
}
|
||||
|
||||
val callElement = config.originalElement as? KtCallElement
|
||||
@@ -990,9 +973,9 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||
CodeStyleManager.getInstance(project).reformat(newDeclaration)
|
||||
|
||||
// change short type names to fully qualified ones (to be shortened below)
|
||||
setupTypeReferencesForShortening(newDeclaration, parameterTypeExpressions)
|
||||
val typeRefsToShorten = setupTypeReferencesForShortening(newDeclaration, parameterTypeExpressions)
|
||||
if (!transformToJavaMemberIfApplicable(newDeclaration)) {
|
||||
elementsToShorten.add(newDeclaration)
|
||||
elementsToShorten.addAll(typeRefsToShorten)
|
||||
setupEditor(newDeclaration)
|
||||
}
|
||||
}
|
||||
@@ -1119,24 +1102,17 @@ internal fun <D : KtNamedDeclaration> placeDeclarationInContainer(
|
||||
}
|
||||
|
||||
container is KtClassOrObject -> {
|
||||
var sibling: PsiElement? = container.declarations.lastOrNull { it::class == declaration::class }
|
||||
if (sibling == null && declaration is KtProperty) {
|
||||
sibling = container.getBody()?.lBrace
|
||||
}
|
||||
|
||||
insertMember(null, container, declaration, sibling)
|
||||
insertMember(null, container, declaration, container.declarations.lastOrNull())
|
||||
}
|
||||
else -> throw AssertionError("Invalid containing element: ${container.text}")
|
||||
}
|
||||
|
||||
if (declaration !is KtPrimaryConstructor) {
|
||||
val parent = declarationInPlace.parent
|
||||
calcNecessaryEmptyLines(declarationInPlace, false).let {
|
||||
if (it > 0) parent.addBefore(psiFactory.createNewLine(it), declarationInPlace)
|
||||
}
|
||||
calcNecessaryEmptyLines(declarationInPlace, true).let {
|
||||
if (it > 0) parent.addAfter(psiFactory.createNewLine(it), declarationInPlace)
|
||||
}
|
||||
val parent = declarationInPlace.parent
|
||||
calcNecessaryEmptyLines(declarationInPlace, false).let {
|
||||
if (it > 0) parent.addBefore(psiFactory.createNewLine(it), declarationInPlace)
|
||||
}
|
||||
calcNecessaryEmptyLines(declarationInPlace, true).let {
|
||||
if (it > 0) parent.addAfter(psiFactory.createNewLine(it), declarationInPlace)
|
||||
}
|
||||
return declarationInPlace
|
||||
}
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassInfo
|
||||
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||
import org.jetbrains.kotlin.idea.util.getResolvableApproximations
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
@@ -71,10 +70,6 @@ abstract class TypeInfo(val variance: Variance) {
|
||||
(builder.placement as CallablePlacement.WithReceiver).receiverTypeCandidate.theType.getPossibleSupertypes(variance, builder)
|
||||
}
|
||||
|
||||
class ByExplicitCandidateTypes(val types: List<KotlinType>) : TypeInfo(Variance.INVARIANT) {
|
||||
override fun getPossibleTypes(builder: CallableBuilder) = types
|
||||
}
|
||||
|
||||
abstract class DelegatingTypeInfo(val delegate: TypeInfo): TypeInfo(delegate.variance) {
|
||||
override val substitutionsAllowed: Boolean = delegate.substitutionsAllowed
|
||||
override fun getPossibleNamesFromExpression(bindingContext: BindingContext) = delegate.getPossibleNamesFromExpression(bindingContext)
|
||||
@@ -160,10 +155,8 @@ fun TypeInfo.ofThis() = TypeInfo.OfThis(this)
|
||||
*/
|
||||
class ParameterInfo(
|
||||
val typeInfo: TypeInfo,
|
||||
val nameSuggestions: List<String>
|
||||
) {
|
||||
constructor(typeInfo: TypeInfo, preferredName: String? = null): this(typeInfo, listOfNotNull(preferredName))
|
||||
}
|
||||
val preferredName: String? = null
|
||||
)
|
||||
|
||||
enum class CallableKind {
|
||||
FUNCTION,
|
||||
@@ -178,17 +171,14 @@ abstract class CallableInfo (
|
||||
val returnTypeInfo: TypeInfo,
|
||||
val possibleContainers: List<KtElement>,
|
||||
val typeParameterInfos: List<TypeInfo>,
|
||||
val isForCompanion: Boolean = false,
|
||||
val modifierList: KtModifierList? = null
|
||||
val isAbstract: Boolean = false
|
||||
) {
|
||||
abstract val kind: CallableKind
|
||||
abstract val parameterInfos: List<ParameterInfo>
|
||||
|
||||
val isAbstract get() = modifierList?.hasModifier(KtTokens.ABSTRACT_KEYWORD) == true
|
||||
|
||||
abstract fun copy(receiverTypeInfo: TypeInfo = this.receiverTypeInfo,
|
||||
possibleContainers: List<KtElement> = this.possibleContainers,
|
||||
modifierList: KtModifierList? = this.modifierList): CallableInfo
|
||||
isAbstract: Boolean = this.isAbstract): CallableInfo
|
||||
}
|
||||
|
||||
class FunctionInfo(name: String,
|
||||
@@ -197,59 +187,42 @@ class FunctionInfo(name: String,
|
||||
possibleContainers: List<KtElement> = Collections.emptyList(),
|
||||
override val parameterInfos: List<ParameterInfo> = Collections.emptyList(),
|
||||
typeParameterInfos: List<TypeInfo> = Collections.emptyList(),
|
||||
isForCompanion: Boolean = false,
|
||||
modifierList: KtModifierList? = null,
|
||||
val preferEmptyBody: Boolean = false
|
||||
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers, typeParameterInfos, isForCompanion, modifierList) {
|
||||
val isOperator: Boolean = false,
|
||||
val isInfix: Boolean = false,
|
||||
isAbstract: Boolean = false
|
||||
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers, typeParameterInfos, isAbstract) {
|
||||
override val kind: CallableKind get() = CallableKind.FUNCTION
|
||||
|
||||
override fun copy(
|
||||
receiverTypeInfo: TypeInfo,
|
||||
possibleContainers: List<KtElement>,
|
||||
modifierList: KtModifierList?
|
||||
) = FunctionInfo(
|
||||
override fun copy(receiverTypeInfo: TypeInfo, possibleContainers: List<KtElement>, isAbstract: Boolean) = FunctionInfo(
|
||||
name,
|
||||
receiverTypeInfo,
|
||||
returnTypeInfo,
|
||||
possibleContainers,
|
||||
parameterInfos,
|
||||
typeParameterInfos,
|
||||
isForCompanion,
|
||||
modifierList
|
||||
isOperator,
|
||||
isInfix,
|
||||
isAbstract
|
||||
)
|
||||
}
|
||||
|
||||
class ClassWithPrimaryConstructorInfo(
|
||||
val classInfo: ClassInfo,
|
||||
expectedTypeInfo: TypeInfo,
|
||||
modifierList: KtModifierList? = null
|
||||
): CallableInfo(
|
||||
classInfo.name, TypeInfo.Empty, expectedTypeInfo.forceNotNull(), Collections.emptyList(), classInfo.typeArguments, false, modifierList = modifierList
|
||||
class ClassWithPrimaryConstructorInfo(val classInfo: ClassInfo, expectedTypeInfo: TypeInfo): CallableInfo(
|
||||
classInfo.name, TypeInfo.Empty, expectedTypeInfo.forceNotNull(), Collections.emptyList(), classInfo.typeArguments, false
|
||||
) {
|
||||
override val kind: CallableKind get() = CallableKind.CLASS_WITH_PRIMARY_CONSTRUCTOR
|
||||
override val parameterInfos: List<ParameterInfo> get() = classInfo.parameterInfos
|
||||
|
||||
override fun copy(
|
||||
receiverTypeInfo: TypeInfo,
|
||||
possibleContainers: List<KtElement>,
|
||||
modifierList: KtModifierList?
|
||||
) = throw UnsupportedOperationException()
|
||||
override fun copy(receiverTypeInfo: TypeInfo, possibleContainers: List<KtElement>, isAbstract: Boolean) = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
class ConstructorInfo(
|
||||
override val parameterInfos: List<ParameterInfo>,
|
||||
val targetClass: PsiElement,
|
||||
val isPrimary: Boolean = false,
|
||||
modifierList: KtModifierList? = null,
|
||||
val withBody: Boolean = false
|
||||
): CallableInfo("", TypeInfo.Empty, TypeInfo.Empty, Collections.emptyList(), Collections.emptyList(), false, modifierList = modifierList) {
|
||||
val isPrimary: Boolean = false
|
||||
): CallableInfo("", TypeInfo.Empty, TypeInfo.Empty, Collections.emptyList(), Collections.emptyList(), false) {
|
||||
override val kind: CallableKind get() = CallableKind.CONSTRUCTOR
|
||||
|
||||
override fun copy(
|
||||
receiverTypeInfo: TypeInfo,
|
||||
possibleContainers: List<KtElement>,
|
||||
modifierList: KtModifierList?
|
||||
) = throw UnsupportedOperationException()
|
||||
override fun copy(receiverTypeInfo: TypeInfo, possibleContainers: List<KtElement>, isAbstract: Boolean) = throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
class PropertyInfo(name: String,
|
||||
@@ -258,35 +231,20 @@ class PropertyInfo(name: String,
|
||||
val writable: Boolean,
|
||||
possibleContainers: List<KtElement> = Collections.emptyList(),
|
||||
typeParameterInfos: List<TypeInfo> = Collections.emptyList(),
|
||||
val isLateinitPreferred: Boolean = false,
|
||||
isForCompanion: Boolean = false,
|
||||
modifierList: KtModifierList? = null,
|
||||
val withInitializer: Boolean = false
|
||||
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers, typeParameterInfos, isForCompanion, modifierList) {
|
||||
isAbstract: Boolean = false,
|
||||
val isLateinitPreferred: Boolean = false
|
||||
) : CallableInfo(name, receiverTypeInfo, returnTypeInfo, possibleContainers, typeParameterInfos, isAbstract) {
|
||||
override val kind: CallableKind get() = CallableKind.PROPERTY
|
||||
override val parameterInfos: List<ParameterInfo> get() = Collections.emptyList()
|
||||
|
||||
override fun copy(
|
||||
receiverTypeInfo: TypeInfo,
|
||||
possibleContainers: List<KtElement>,
|
||||
modifierList: KtModifierList?
|
||||
) = copyProperty(receiverTypeInfo, possibleContainers, modifierList)
|
||||
|
||||
fun copyProperty(
|
||||
receiverTypeInfo: TypeInfo = this.receiverTypeInfo,
|
||||
possibleContainers: List<KtElement> = this.possibleContainers,
|
||||
modifierList: KtModifierList? = this.modifierList,
|
||||
isLateinitPreferred: Boolean = this.isLateinitPreferred
|
||||
) = PropertyInfo(
|
||||
override fun copy(receiverTypeInfo: TypeInfo, possibleContainers: List<KtElement>, isAbstract: Boolean) = PropertyInfo(
|
||||
name,
|
||||
receiverTypeInfo,
|
||||
returnTypeInfo,
|
||||
writable,
|
||||
possibleContainers,
|
||||
typeParameterInfos,
|
||||
isLateinitPreferred,
|
||||
isForCompanion,
|
||||
modifierList,
|
||||
withInitializer
|
||||
isAbstract,
|
||||
isLateinitPreferred
|
||||
)
|
||||
}
|
||||
|
||||
@@ -29,13 +29,11 @@ fun setupEditorSelection(editor: Editor, declaration: KtNamedDeclaration) {
|
||||
val caretModel = editor.caretModel
|
||||
val selectionModel = editor.selectionModel
|
||||
|
||||
val offset = when (declaration) {
|
||||
is KtPrimaryConstructor -> declaration.getConstructorKeyword()?.endOffset ?: declaration.valueParameterList?.startOffset
|
||||
is KtSecondaryConstructor -> declaration.getConstructorKeyword().endOffset
|
||||
else -> declaration.nameIdentifier?.endOffset
|
||||
if (declaration is KtSecondaryConstructor) {
|
||||
caretModel.moveToOffset(declaration.getConstructorKeyword().endOffset)
|
||||
}
|
||||
if (offset != null) {
|
||||
caretModel.moveToOffset(offset)
|
||||
else {
|
||||
caretModel.moveToOffset(declaration.nameIdentifier!!.endOffset)
|
||||
}
|
||||
|
||||
fun positionBetween(left: PsiElement, right: PsiElement) {
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
|
||||
import org.jetbrains.kotlin.lexer.KtToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import java.util.*
|
||||
@@ -56,12 +55,8 @@ object CreateBinaryOperationActionFactory : CreateCallableMemberFromUsageFactory
|
||||
}
|
||||
val parameters = Collections.singletonList(ParameterInfo(TypeInfo(argumentExpr, Variance.IN_VARIANCE)))
|
||||
val isOperator = token != KtTokens.IDENTIFIER
|
||||
return FunctionInfo(
|
||||
operationName,
|
||||
receiverType,
|
||||
returnType,
|
||||
parameterInfos = parameters,
|
||||
modifierList = KtPsiFactory(element).createModifierList(if (isOperator) KtTokens.OPERATOR_KEYWORD else KtTokens.INFIX_KEYWORD)
|
||||
)
|
||||
return FunctionInfo(operationName, receiverType, returnType, parameterInfos = parameters,
|
||||
isOperator = isOperator,
|
||||
isInfix = !isOperator)
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user