Remove 182 support
#KT-33536 Fixed
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
|
||||
fun visitAnnotableParameterCount(mv: MethodVisitor, paramCount: Int) {}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||
|
||||
import com.intellij.codeInsight.InferredAnnotationsManager
|
||||
import com.intellij.psi.PsiAnnotation
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
|
||||
class MockInferredAnnotationsManager : InferredAnnotationsManager() {
|
||||
override fun findInferredAnnotation(listOwner: PsiModifierListOwner, annotationFQN: String): PsiAnnotation? = null
|
||||
override fun ignoreInference(owner: PsiModifierListOwner, annotationFQN: String?): Boolean = true
|
||||
override fun findInferredAnnotations(listOwner: PsiModifierListOwner): Array<out PsiAnnotation> = EMPTY_PSI_ANNOTATION_ARRAY
|
||||
override fun isInferredAnnotation(annotation: PsiAnnotation): Boolean = false
|
||||
|
||||
companion object {
|
||||
val EMPTY_PSI_ANNOTATION_ARRAY = arrayOf<PsiAnnotation>()
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.util
|
||||
|
||||
import com.intellij.openapi.util.ThrowableComputable
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.util.AstLoadingFilter
|
||||
|
||||
/**
|
||||
* Absent in 181. Methods were renamed in 183.
|
||||
*
|
||||
* BUNCH: 182
|
||||
*/
|
||||
@Suppress("IncompatibleAPI", "MissingRecentApi")
|
||||
object AstLoadingFilter {
|
||||
@JvmStatic
|
||||
fun <T, E : Throwable> forceAllowTreeLoading(psiFile: PsiFile, computable: ThrowableComputable<out T, E>): T {
|
||||
return AstLoadingFilter.forceEnableTreeLoading(psiFile, computable)
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
public final class AnnotatedParameterInInnerClassConstructor {
|
||||
public AnnotatedParameterInInnerClassConstructor() { /* compiled code */ }
|
||||
|
||||
public final class Inner {
|
||||
public Inner(@test.Anno(x = "a") @org.jetbrains.annotations.NotNull java.lang.String $outer, @test.Anno(x = "b") @org.jetbrains.annotations.NotNull java.lang.String a) { /* compiled code */ }
|
||||
}
|
||||
|
||||
public final class InnerGeneric <T> {
|
||||
public InnerGeneric(@test.Anno(x = "a") T $outer, @test.Anno(x = "b") @org.jetbrains.annotations.NotNull java.lang.String a) { /* compiled code */ }
|
||||
}
|
||||
}
|
||||
Vendored
-69
@@ -1,69 +0,0 @@
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class Ann
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Sealed$Derived {
|
||||
inner class Sealed$Derived
|
||||
private method <init>(p0: int): void
|
||||
public synthetic @Ann method <init>(p0: int, p1: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Sealed$Inner {
|
||||
synthetic final field this$0: Sealed
|
||||
private final field z2: int
|
||||
inner class Sealed$Inner
|
||||
public synthetic @Ann method <init>(@java.lang.Synthetic p0: Sealed, p1: int, @Ann p2: int, @Ann p3: java.lang.String, p4: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
private method <init>(p0: Sealed, p1: int, p2: int, p3: java.lang.String): void
|
||||
public final method getZ2(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public abstract class Sealed {
|
||||
private final field z: int
|
||||
inner class Sealed$Derived
|
||||
inner class Sealed$Inner
|
||||
private @Ann method <init>(@Ann p0: int): void
|
||||
public synthetic method <init>(p0: int, p1: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public final method getZ(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Test$Inner {
|
||||
synthetic final field this$0: Test
|
||||
private final field z2: int
|
||||
inner class Test$Inner
|
||||
public synthetic @Ann method <init>(@java.lang.Synthetic p0: Test, p1: int, @Ann p2: int, @Ann p3: java.lang.String, p4: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
private method <init>(p0: Test, p1: int, p2: int, p3: java.lang.String): void
|
||||
public final method getZ2(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Test {
|
||||
private final field z: int
|
||||
inner class Test$Inner
|
||||
public synthetic @Ann method <init>(@Ann p0: int, p1: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
private method <init>(p0: int): void
|
||||
public synthetic @Ann method <init>(p0: int, @Ann p1: int, p2: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
private @Ann method <init>(p0: int, @Ann p1: java.lang.String): void
|
||||
private method <init>(p0: int, p1: int): void
|
||||
public final method getZ(): int
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class Z {
|
||||
private final field x: int
|
||||
private synthetic method <init>(p0: int): void
|
||||
public synthetic final static @org.jetbrains.annotations.NotNull method box-impl(p0: int): Z
|
||||
public static method constructor-impl(p0: int): int
|
||||
public method equals(p0: java.lang.Object): boolean
|
||||
public static method equals-impl(p0: int, @org.jetbrains.annotations.Nullable p1: java.lang.Object): boolean
|
||||
public final static method equals-impl0(p0: int, p1: int): boolean
|
||||
public final method getX(): int
|
||||
public method hashCode(): int
|
||||
public static method hashCode-impl(p0: int): int
|
||||
public method toString(): java.lang.String
|
||||
public static @org.jetbrains.annotations.NotNull method toString-impl(p0: int): java.lang.String
|
||||
public synthetic final method unbox-impl(): int
|
||||
}
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
@kotlin.Metadata
|
||||
public final class ASimpleClass {
|
||||
public method <init>(): void
|
||||
public synthetic static @kotlin.jvm.JvmOverloads method showSnackbar$default(p0: ASimpleClass, p1: java.lang.String, p2: int, p3: int, p4: int, p5: java.lang.Object): void
|
||||
public final @kotlin.jvm.JvmOverloads method showSnackbar(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int): void
|
||||
public final @kotlin.jvm.JvmOverloads method showSnackbar(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, p2: int): void
|
||||
public synthetic static @kotlin.jvm.JvmOverloads method showSnackbarLong$default(p0: ASimpleClass, p1: java.lang.String, p2: int, p3: int, p4: long, p5: java.lang.String, p6: int, p7: java.lang.Object): void
|
||||
public final @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long): void
|
||||
public final @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long, @org.jetbrains.annotations.NotNull p4: java.lang.String): void
|
||||
public final @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @LongRes p2: long): void
|
||||
public synthetic static @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension$default(p0: ASimpleClass, p1: int, p2: int, p3: long, p4: java.lang.String, p5: int, p6: java.lang.Object): void
|
||||
public final @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long): void
|
||||
public final @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long, @org.jetbrains.annotations.NotNull p3: java.lang.String): void
|
||||
public final @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @LongRes p1: long): void
|
||||
public synthetic static @kotlin.jvm.JvmOverloads method showSnackbarNoExtension$default(p0: ASimpleClass, p1: int, p2: int, p3: int, p4: java.lang.Object): void
|
||||
public final @kotlin.jvm.JvmOverloads method showSnackbarNoExtension(@StringRes p0: int): void
|
||||
public final @kotlin.jvm.JvmOverloads method showSnackbarNoExtension(@StringRes p0: int, p1: int): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class BSimpleObject {
|
||||
public final static field INSTANCE: BSimpleObject
|
||||
static method <clinit>(): void
|
||||
private method <init>(): void
|
||||
public synthetic static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbar$default(p0: java.lang.String, p1: int, p2: int, p3: int, p4: java.lang.Object): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbar(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbar(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, p2: int): void
|
||||
public synthetic static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong$default(p0: java.lang.String, p1: int, p2: int, p3: long, p4: java.lang.String, p5: int, p6: java.lang.Object): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long, @org.jetbrains.annotations.NotNull p4: java.lang.String): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @LongRes p2: long): void
|
||||
public synthetic static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension$default(p0: int, p1: int, p2: long, p3: java.lang.String, p4: int, p5: java.lang.Object): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long, @org.jetbrains.annotations.NotNull p3: java.lang.String): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @LongRes p1: long): void
|
||||
public synthetic static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarNoExtension$default(p0: int, p1: int, p2: int, p3: java.lang.Object): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarNoExtension(@StringRes p0: int): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarNoExtension(@StringRes p0: int, p1: int): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class CClassWithCompanion$Companion {
|
||||
inner class CClassWithCompanion$Companion
|
||||
private method <init>(): void
|
||||
public synthetic method <init>(p0: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public synthetic static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbar$default(p0: CClassWithCompanion$Companion, p1: java.lang.String, p2: int, p3: int, p4: int, p5: java.lang.Object): void
|
||||
public final @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbar(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int): void
|
||||
public final @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbar(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, p2: int): void
|
||||
public synthetic static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong$default(p0: CClassWithCompanion$Companion, p1: java.lang.String, p2: int, p3: int, p4: long, p5: java.lang.String, p6: int, p7: java.lang.Object): void
|
||||
public final @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long): void
|
||||
public final @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long, @org.jetbrains.annotations.NotNull p4: java.lang.String): void
|
||||
public final @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @LongRes p2: long): void
|
||||
public synthetic static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension$default(p0: CClassWithCompanion$Companion, p1: int, p2: int, p3: long, p4: java.lang.String, p5: int, p6: java.lang.Object): void
|
||||
public final @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long): void
|
||||
public final @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long, @org.jetbrains.annotations.NotNull p3: java.lang.String): void
|
||||
public final @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @LongRes p1: long): void
|
||||
public synthetic static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarNoExtension$default(p0: CClassWithCompanion$Companion, p1: int, p2: int, p3: int, p4: java.lang.Object): void
|
||||
public final @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarNoExtension(@StringRes p0: int): void
|
||||
public final @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarNoExtension(@StringRes p0: int, p1: int): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class CClassWithCompanion {
|
||||
public final static field Companion: CClassWithCompanion$Companion
|
||||
inner class CClassWithCompanion$Companion
|
||||
static method <clinit>(): void
|
||||
public method <init>(): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbar(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbar(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, p2: int): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long, @org.jetbrains.annotations.NotNull p4: java.lang.String): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @LongRes p2: long): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long, @org.jetbrains.annotations.NotNull p3: java.lang.String): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @LongRes p1: long): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarNoExtension(@StringRes p0: int): void
|
||||
public final static @kotlin.jvm.JvmStatic @kotlin.jvm.JvmOverloads method showSnackbarNoExtension(@StringRes p0: int, p1: int): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class DClassConstuctors$InnerClass {
|
||||
synthetic final field this$0: DClassConstuctors
|
||||
inner class DClassConstuctors$InnerClass
|
||||
public @kotlin.jvm.JvmOverloads method <init>(@java.lang.Synthetic @java.lang.Synthetic p0: DClassConstuctors, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long, @org.jetbrains.annotations.NotNull p4: java.lang.String): void
|
||||
public @kotlin.jvm.JvmOverloads method <init>(@java.lang.Synthetic p0: DClassConstuctors, @StringRes p1: int): void
|
||||
public @kotlin.jvm.JvmOverloads method <init>(@java.lang.Synthetic p0: DClassConstuctors, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long): void
|
||||
public @kotlin.jvm.JvmOverloads method <init>(@java.lang.Synthetic p0: DClassConstuctors, @StringRes p1: int, @LongRes p2: long): void
|
||||
public @kotlin.jvm.JvmOverloads method <init>(@java.lang.Synthetic p0: DClassConstuctors, @StringRes p1: int, p2: int): void
|
||||
public synthetic @kotlin.jvm.JvmOverloads method <init>(p0: DClassConstuctors, p1: int, p2: int, p3: int, p4: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public synthetic @kotlin.jvm.JvmOverloads method <init>(p0: DClassConstuctors, p1: int, p2: int, p3: long, p4: java.lang.String, p5: int, p6: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class DClassConstuctors {
|
||||
inner class DClassConstuctors$InnerClass
|
||||
public @kotlin.jvm.JvmOverloads method <init>(@StringRes p0: int): void
|
||||
public @kotlin.jvm.JvmOverloads method <init>(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long): void
|
||||
public @kotlin.jvm.JvmOverloads method <init>(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long, @org.jetbrains.annotations.NotNull p3: java.lang.String): void
|
||||
public @kotlin.jvm.JvmOverloads method <init>(@StringRes p0: int, @LongRes p1: long): void
|
||||
public @kotlin.jvm.JvmOverloads method <init>(@StringRes p0: int, p1: int): void
|
||||
public synthetic @kotlin.jvm.JvmOverloads method <init>(p0: int, p1: int, p2: int, p3: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
public synthetic @kotlin.jvm.JvmOverloads method <init>(p0: int, p1: int, p2: long, p3: java.lang.String, p4: int, p5: kotlin.jvm.internal.DefaultConstructorMarker): void
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class DefRes
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class JvmOverloadsAndParametersAnnotationsKt {
|
||||
public synthetic static @kotlin.jvm.JvmOverloads method showSnackbar$default(p0: java.lang.String, p1: int, p2: int, p3: int, p4: java.lang.Object): void
|
||||
public final static @kotlin.jvm.JvmOverloads method showSnackbar(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int): void
|
||||
public final static @kotlin.jvm.JvmOverloads method showSnackbar(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, p2: int): void
|
||||
public synthetic static @kotlin.jvm.JvmOverloads method showSnackbarLong$default(p0: java.lang.String, p1: int, p2: int, p3: long, p4: java.lang.String, p5: int, p6: java.lang.Object): void
|
||||
public final static @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long): void
|
||||
public final static @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @DefRes p2: int, @LongRes p3: long, @org.jetbrains.annotations.NotNull p4: java.lang.String): void
|
||||
public final static @kotlin.jvm.JvmOverloads method showSnackbarLong(@org.jetbrains.annotations.NotNull p0: java.lang.String, @StringRes p1: int, @LongRes p2: long): void
|
||||
public synthetic static @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension$default(p0: int, p1: int, p2: long, p3: java.lang.String, p4: int, p5: java.lang.Object): void
|
||||
public final static @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long): void
|
||||
public final static @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @DefRes p1: int, @LongRes p2: long, @org.jetbrains.annotations.NotNull p3: java.lang.String): void
|
||||
public final static @kotlin.jvm.JvmOverloads method showSnackbarLongNoExtension(@StringRes p0: int, @LongRes p1: long): void
|
||||
public synthetic static @kotlin.jvm.JvmOverloads method showSnackbarNoExtension$default(p0: int, p1: int, p2: int, p3: java.lang.Object): void
|
||||
public final static @kotlin.jvm.JvmOverloads method showSnackbarNoExtension(@StringRes p0: int): void
|
||||
public final static @kotlin.jvm.JvmOverloads method showSnackbarNoExtension(@StringRes p0: int, p1: int): void
|
||||
}
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class LongRes
|
||||
|
||||
@java.lang.annotation.Retention
|
||||
@kotlin.Metadata
|
||||
public annotation class StringRes
|
||||
@@ -1,14 +0,0 @@
|
||||
versions.intellijSdk=182.5107.16
|
||||
versions.androidBuildTools=r23.0.1
|
||||
versions.idea.NodeJS=181.3494.12
|
||||
versions.jar.guava=23.6-jre
|
||||
versions.jar.groovy-all=2.4.15
|
||||
versions.jar.lombok-ast=0.2.3
|
||||
versions.jar.swingx-core=1.6.2-2
|
||||
versions.jar.kxml2=2.3.0
|
||||
versions.jar.streamex=0.6.5
|
||||
versions.jar.gson=2.8.4
|
||||
versions.jar.oro=2.0.8
|
||||
versions.jar.picocontainer=1.2
|
||||
ignore.jar.snappy-in-java=true
|
||||
versions.gradle-api=4.5.1
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea;
|
||||
|
||||
// BUNCH: 182
|
||||
|
||||
public interface IconExtensionChooser {
|
||||
static String iconExtension() {
|
||||
return "png";
|
||||
}
|
||||
}
|
||||
-166
@@ -1,166 +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.highlighter
|
||||
|
||||
import com.intellij.codeHighlighting.Pass
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPass
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory
|
||||
import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil
|
||||
import com.intellij.lang.annotation.Annotation
|
||||
import com.intellij.lang.annotation.HighlightSeverity
|
||||
import com.intellij.lang.annotation.HighlightSeverity.*
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.ProjectComponent
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.progress.ProgressIndicator
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.ui.MessageType
|
||||
import com.intellij.openapi.wm.WindowManager
|
||||
import com.intellij.openapi.wm.ex.StatusBarEx
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import org.jetbrains.kotlin.idea.core.script.IdeScriptReportSink
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptDefinitionsManager
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptsCompilationConfigurationUpdater
|
||||
import org.jetbrains.kotlin.idea.script.ScriptDiagnosticFixProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import kotlin.script.experimental.api.ScriptDiagnostic
|
||||
import kotlin.script.experimental.api.SourceCode
|
||||
|
||||
class ScriptExternalHighlightingPass(
|
||||
private val file: KtFile,
|
||||
document: Document
|
||||
) : TextEditorHighlightingPass(file.project, document), DumbAware {
|
||||
override fun doCollectInformation(progress: ProgressIndicator) = Unit
|
||||
|
||||
override fun doApplyInformationToEditor() {
|
||||
val document = document ?: return
|
||||
|
||||
if (!file.isScript()) return
|
||||
|
||||
if (!ScriptDefinitionsManager.getInstance(file.project).isReady()) {
|
||||
showNotification(
|
||||
file,
|
||||
"Highlighting in scripts is not available until all Script Definitions are loaded"
|
||||
)
|
||||
}
|
||||
|
||||
if (!ScriptsCompilationConfigurationUpdater.areDependenciesCached(file)) {
|
||||
// initiate configuration refinement, if needed
|
||||
ScriptDependenciesManager.getInstance(file.project).getRefinedCompilationConfiguration(file.virtualFile)
|
||||
if (!ScriptsCompilationConfigurationUpdater.areDependenciesCached(file)) {
|
||||
showNotification(
|
||||
file,
|
||||
"Highlighting in scripts is not available until all Script Dependencies are loaded"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val reports = IdeScriptReportSink.getReports(file.virtualFile)
|
||||
|
||||
val annotations = reports.mapNotNull { scriptDiagnostic ->
|
||||
val (startOffset, endOffset) = scriptDiagnostic.location?.let { computeOffsets(document, it) } ?: 0 to 0
|
||||
val annotation = Annotation(
|
||||
startOffset,
|
||||
endOffset,
|
||||
scriptDiagnostic.severity.convertSeverity() ?: return@mapNotNull null,
|
||||
scriptDiagnostic.message,
|
||||
scriptDiagnostic.message
|
||||
)
|
||||
|
||||
// if range is empty, show notification panel in editor
|
||||
annotation.isFileLevelAnnotation = startOffset == endOffset
|
||||
|
||||
for (provider in ScriptDiagnosticFixProvider.EP_NAME.extensions) {
|
||||
provider.provideFixes(scriptDiagnostic).forEach {
|
||||
annotation.registerFix(it)
|
||||
}
|
||||
}
|
||||
|
||||
annotation
|
||||
}
|
||||
|
||||
val infos = annotations.map { HighlightInfo.fromAnnotation(it) }
|
||||
UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument!!, 0, file.textLength, infos, colorsScheme, id)
|
||||
}
|
||||
|
||||
private fun computeOffsets(document: Document, position: SourceCode.Location): Pair<Int, Int> {
|
||||
val startLine = position.start.line.coerceLineIn(document)
|
||||
val startOffset = document.offsetBy(startLine, position.start.col)
|
||||
|
||||
val endLine = position.end?.line?.coerceAtLeast(startLine)?.coerceLineIn(document) ?: startLine
|
||||
val endOffset = document.offsetBy(
|
||||
endLine,
|
||||
position.end?.col ?: document.getLineEndOffset(endLine)
|
||||
).coerceAtLeast(startOffset)
|
||||
|
||||
return startOffset to endOffset
|
||||
}
|
||||
|
||||
private fun Int.coerceLineIn(document: Document) = coerceIn(0, document.lineCount - 1)
|
||||
|
||||
private fun Document.offsetBy(line: Int, col: Int): Int {
|
||||
return (getLineStartOffset(line) + col).coerceIn(getLineStartOffset(line), getLineEndOffset(line))
|
||||
}
|
||||
|
||||
private fun ScriptDiagnostic.Severity.convertSeverity(): HighlightSeverity? {
|
||||
return when (this) {
|
||||
ScriptDiagnostic.Severity.FATAL -> ERROR
|
||||
ScriptDiagnostic.Severity.ERROR -> ERROR
|
||||
ScriptDiagnostic.Severity.WARNING -> WARNING
|
||||
ScriptDiagnostic.Severity.INFO -> INFORMATION
|
||||
ScriptDiagnostic.Severity.DEBUG -> if (ApplicationManager.getApplication().isInternal) INFORMATION else null
|
||||
}
|
||||
}
|
||||
|
||||
private fun showNotification(file: KtFile, message: String) {
|
||||
UIUtil.invokeLaterIfNeeded {
|
||||
val ideFrame = WindowManager.getInstance().getIdeFrame(file.project)
|
||||
if (ideFrame != null) {
|
||||
val statusBar = ideFrame.statusBar as StatusBarEx
|
||||
statusBar.notifyProgressByBalloon(
|
||||
MessageType.WARNING,
|
||||
message,
|
||||
null,
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Factory(registrar: TextEditorHighlightingPassRegistrar) : ProjectComponent,
|
||||
TextEditorHighlightingPassFactory {
|
||||
init {
|
||||
registrar.registerTextEditorHighlightingPass(
|
||||
this,
|
||||
TextEditorHighlightingPassRegistrar.Anchor.BEFORE,
|
||||
Pass.UPDATE_FOLDING,
|
||||
false,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? {
|
||||
if (file !is KtFile) return null
|
||||
return ScriptExternalHighlightingPass(file, editor.document)
|
||||
}
|
||||
}
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.search
|
||||
|
||||
import com.intellij.psi.impl.search.IndexPatternBuilder
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
|
||||
abstract class IndexPatternBuilderAdapter : IndexPatternBuilder {
|
||||
}
|
||||
@@ -1,388 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.android;
|
||||
|
||||
import com.android.SdkConstants;
|
||||
import com.android.tools.idea.rendering.RenderSecurityManager;
|
||||
import com.android.tools.idea.startup.AndroidCodeStyleSettingsModifier;
|
||||
import com.intellij.analysis.AnalysisScope;
|
||||
import com.intellij.codeInspection.GlobalInspectionTool;
|
||||
import com.intellij.codeInspection.InspectionManager;
|
||||
import com.intellij.codeInspection.ex.GlobalInspectionToolWrapper;
|
||||
import com.intellij.codeInspection.ex.InspectionManagerEx;
|
||||
import com.intellij.facet.FacetManager;
|
||||
import com.intellij.facet.ModifiableFacetModel;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
|
||||
import com.intellij.openapi.roots.ModuleRootModificationUtil;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSchemes;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.testFramework.InspectionTestUtil;
|
||||
import com.intellij.testFramework.ThreadTracker;
|
||||
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
|
||||
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
|
||||
import com.intellij.testFramework.fixtures.JavaTestFixtureFactory;
|
||||
import com.intellij.testFramework.fixtures.TestFixtureBuilder;
|
||||
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
|
||||
import com.intellij.testFramework.fixtures.impl.GlobalInspectionContextForTests;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.android.facet.AndroidFacet;
|
||||
import org.jetbrains.android.facet.AndroidRootUtil;
|
||||
import org.jetbrains.android.formatter.AndroidXmlCodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.picocontainer.MutablePicoContainer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Copied from AS 2.3 sources
|
||||
*/
|
||||
@SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"})
|
||||
public abstract class AndroidTestCase extends AndroidTestBase {
|
||||
protected Module myModule;
|
||||
protected List<Module> myAdditionalModules;
|
||||
|
||||
protected AndroidFacet myFacet;
|
||||
protected CodeStyleSettings mySettings;
|
||||
|
||||
private List<String> myAllowedRoots = new ArrayList<>();
|
||||
private boolean myUseCustomSettings;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
VfsRootAccess.allowRootAccess(KotlinTestUtils.getHomeDirectory());
|
||||
|
||||
TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName());
|
||||
myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture());
|
||||
JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
|
||||
File moduleRoot = new File(myFixture.getTempDirPath());
|
||||
|
||||
if (!moduleRoot.exists()) {
|
||||
assertTrue(moduleRoot.mkdirs());
|
||||
}
|
||||
initializeModuleFixtureBuilderWithSrcAndGen(moduleFixtureBuilder, moduleRoot.toString());
|
||||
|
||||
ArrayList<MyAdditionalModuleData> modules = new ArrayList<>();
|
||||
configureAdditionalModules(projectBuilder, modules);
|
||||
|
||||
myFixture.setUp();
|
||||
myFixture.setTestDataPath(getTestDataPath());
|
||||
myModule = moduleFixtureBuilder.getFixture().getModule();
|
||||
|
||||
// Must be done before addAndroidFacet, and must always be done, even if a test provides
|
||||
// its own custom manifest file. However, in that case, we will delete it shortly below.
|
||||
createManifest();
|
||||
|
||||
myFacet = addAndroidFacet(myModule);
|
||||
|
||||
LanguageLevel languageLevel = getLanguageLevel();
|
||||
if (languageLevel != null) {
|
||||
LanguageLevelProjectExtension extension = LanguageLevelProjectExtension.getInstance(myModule.getProject());
|
||||
if (extension != null) {
|
||||
extension.setLanguageLevel(languageLevel);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: myFixture.copyDirectoryToProject(getResDir(), "res");
|
||||
|
||||
myAdditionalModules = new ArrayList<>();
|
||||
for (MyAdditionalModuleData data : modules) {
|
||||
Module additionalModule = data.myModuleFixtureBuilder.getFixture().getModule();
|
||||
myAdditionalModules.add(additionalModule);
|
||||
AndroidFacet facet = addAndroidFacet(additionalModule);
|
||||
facet.getProperties().PROJECT_TYPE = data.myProjectType;
|
||||
String rootPath = getAdditionalModulePath(data.myDirName);
|
||||
myFixture.copyDirectoryToProject(getResDir(), rootPath + "/res");
|
||||
myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, rootPath + '/' + SdkConstants.FN_ANDROID_MANIFEST_XML);
|
||||
if (data.myIsMainModuleDependency) {
|
||||
ModuleRootModificationUtil.addDependency(myModule, additionalModule);
|
||||
}
|
||||
}
|
||||
|
||||
if (providesCustomManifest()) {
|
||||
deleteManifest();
|
||||
}
|
||||
|
||||
if (RenderSecurityManager.RESTRICT_READS) {
|
||||
// Unit test class loader includes disk directories which security manager does not allow access to
|
||||
RenderSecurityManager.sEnabled = false;
|
||||
}
|
||||
|
||||
ArrayList<String> allowedRoots = new ArrayList<>();
|
||||
collectAllowedRoots(allowedRoots);
|
||||
// TODO: registerAllowedRoots(allowedRoots, myTestRootDisposable);
|
||||
mySettings = CodeStyleSettingsManager.getSettings(getProject()).clone();
|
||||
AndroidCodeStyleSettingsModifier.modify(mySettings);
|
||||
CodeStyleSettingsManager.getInstance(getProject()).setTemporarySettings(mySettings);
|
||||
myUseCustomSettings = getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS;
|
||||
getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS = true;
|
||||
|
||||
// Layoutlib rendering thread will be shutdown when the app is closed so do not report it as a leak
|
||||
ThreadTracker.longRunningThreadCreated(ApplicationManager.getApplication(), "Layoutlib");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
try {
|
||||
Sdk androidSdk = ProjectJdkTable.getInstance().findJdk(ANDROID_SDK_NAME);
|
||||
if (androidSdk != null) {
|
||||
ApplicationManager.getApplication().runWriteAction(() -> ProjectJdkTable.getInstance().removeJdk(androidSdk));
|
||||
}
|
||||
|
||||
CodeStyleSettingsManager.getInstance(getProject()).dropTemporarySettings();
|
||||
myModule = null;
|
||||
myAdditionalModules = null;
|
||||
myFixture.tearDown();
|
||||
myFixture = null;
|
||||
myFacet = null;
|
||||
getAndroidCodeStyleSettings().USE_CUSTOM_SETTINGS = myUseCustomSettings;
|
||||
if (RenderSecurityManager.RESTRICT_READS) {
|
||||
RenderSecurityManager.sEnabled = true;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
VfsRootAccess.disallowRootAccess(KotlinTestUtils.getHomeDirectory());
|
||||
}
|
||||
}
|
||||
|
||||
private static void initializeModuleFixtureBuilderWithSrcAndGen(JavaModuleFixtureBuilder moduleFixtureBuilder, String moduleRoot) {
|
||||
moduleFixtureBuilder.addContentRoot(moduleRoot);
|
||||
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
new File(moduleRoot + "/src/").mkdir();
|
||||
moduleFixtureBuilder.addSourceRoot("src");
|
||||
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
new File(moduleRoot + "/gen/").mkdir();
|
||||
moduleFixtureBuilder.addSourceRoot("gen");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path that any additional modules registered by
|
||||
* {@link #configureAdditionalModules(TestFixtureBuilder, List)} or
|
||||
* {@link #addModuleWithAndroidFacet(TestFixtureBuilder, List, String, int, boolean)} are
|
||||
* installed into.
|
||||
*/
|
||||
protected static String getAdditionalModulePath(@NotNull String moduleName) {
|
||||
return "/additionalModules/" + moduleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this class provides its own {@code AndroidManifest.xml} for its tests. If
|
||||
* {@code true}, then {@link #setUp()} calls {@link #deleteManifest()} before finishing.
|
||||
*/
|
||||
protected boolean providesCustomManifest() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "res" directory for this SDK. Children classes can override this if they need to
|
||||
* provide a custom "res" location for tests.
|
||||
*/
|
||||
protected String getResDir() {
|
||||
return "res";
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the project level to set for the test project, or null to get the default language
|
||||
* level associated with the test project.
|
||||
*/
|
||||
@Nullable
|
||||
protected LanguageLevel getLanguageLevel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static AndroidXmlCodeStyleSettings getAndroidCodeStyleSettings() {
|
||||
return AndroidXmlCodeStyleSettings.getInstance(CodeStyleSchemes.getInstance().getDefaultScheme().getCodeStyleSettings());
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook point for child test classes to register directories that can be safely accessed by all
|
||||
* of its tests.
|
||||
*
|
||||
* @see {@link VfsRootAccess}
|
||||
*/
|
||||
protected void collectAllowedRoots(List<String> roots) throws IOException {
|
||||
}
|
||||
|
||||
private void registerAllowedRoots(List<String> roots, @NotNull Disposable disposable) {
|
||||
List<String> newRoots = new ArrayList<>(roots);
|
||||
newRoots.removeAll(myAllowedRoots);
|
||||
|
||||
String[] newRootsArray = ArrayUtil.toStringArray(newRoots);
|
||||
VfsRootAccess.allowRootAccess(newRootsArray);
|
||||
myAllowedRoots.addAll(newRoots);
|
||||
|
||||
Disposer.register(disposable, () -> {
|
||||
VfsRootAccess.disallowRootAccess(newRootsArray);
|
||||
myAllowedRoots.removeAll(newRoots);
|
||||
});
|
||||
}
|
||||
|
||||
public static AndroidFacet addAndroidFacet(Module module) {
|
||||
return addAndroidFacet(module, true);
|
||||
}
|
||||
|
||||
private static AndroidFacet addAndroidFacet(Module module, boolean attachSdk) {
|
||||
FacetManager facetManager = FacetManager.getInstance(module);
|
||||
AndroidFacet facet = facetManager.createFacet(AndroidFacet.getFacetType(), "Android", null);
|
||||
|
||||
if (attachSdk) {
|
||||
addLatestAndroidSdk(module);
|
||||
}
|
||||
ModifiableFacetModel facetModel = facetManager.createModifiableModel();
|
||||
facetModel.addFacet(facet);
|
||||
ApplicationManager.getApplication().runWriteAction(facetModel::commit);
|
||||
return facet;
|
||||
}
|
||||
|
||||
protected void configureAdditionalModules(
|
||||
@NotNull TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder, @NotNull List<MyAdditionalModuleData> modules) {
|
||||
}
|
||||
|
||||
protected final void addModuleWithAndroidFacet(
|
||||
@NotNull TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder,
|
||||
@NotNull List<MyAdditionalModuleData> modules,
|
||||
@NotNull String dirName,
|
||||
int projectType) {
|
||||
// By default, created module is declared as a main module's dependency
|
||||
addModuleWithAndroidFacet(projectBuilder, modules, dirName, projectType, true);
|
||||
}
|
||||
|
||||
protected final void addModuleWithAndroidFacet(
|
||||
@NotNull TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder,
|
||||
@NotNull List<MyAdditionalModuleData> modules,
|
||||
@NotNull String dirName,
|
||||
int projectType,
|
||||
boolean isMainModuleDependency) {
|
||||
JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
|
||||
String moduleDirPath = myFixture.getTempDirPath() + getAdditionalModulePath(dirName);
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
new File(moduleDirPath).mkdirs();
|
||||
initializeModuleFixtureBuilderWithSrcAndGen(moduleFixtureBuilder, moduleDirPath);
|
||||
modules.add(new MyAdditionalModuleData(moduleFixtureBuilder, dirName, projectType, isMainModuleDependency));
|
||||
}
|
||||
|
||||
protected void createManifest() throws IOException {
|
||||
myFixture.copyFileToProject(SdkConstants.FN_ANDROID_MANIFEST_XML, SdkConstants.FN_ANDROID_MANIFEST_XML);
|
||||
}
|
||||
|
||||
protected final void createProjectProperties() throws IOException {
|
||||
myFixture.copyFileToProject(SdkConstants.FN_PROJECT_PROPERTIES, SdkConstants.FN_PROJECT_PROPERTIES);
|
||||
}
|
||||
|
||||
protected final void deleteManifest() throws IOException {
|
||||
deleteManifest(myModule);
|
||||
}
|
||||
|
||||
protected final void deleteManifest(final Module module) throws IOException {
|
||||
AndroidFacet facet = AndroidFacet.getInstance(module);
|
||||
assertNotNull(facet);
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
String manifestRelativePath = facet.getProperties().MANIFEST_FILE_RELATIVE_PATH;
|
||||
VirtualFile manifest = AndroidRootUtil.getFileByRelativeModulePath(module, manifestRelativePath, true);
|
||||
if (manifest != null) {
|
||||
try {
|
||||
manifest.delete(this);
|
||||
}
|
||||
catch (IOException e) {
|
||||
fail("Could not delete default manifest");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected final void doGlobalInspectionTest(
|
||||
@NotNull GlobalInspectionTool inspection, @NotNull String globalTestDir, @NotNull AnalysisScope scope) {
|
||||
doGlobalInspectionTest(new GlobalInspectionToolWrapper(inspection), globalTestDir, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given an inspection and a path to a directory that contains an "expected.xml" file, run the
|
||||
* inspection on the current test project and verify that its output matches that of the
|
||||
* expected file.
|
||||
*/
|
||||
protected final void doGlobalInspectionTest(
|
||||
@NotNull GlobalInspectionToolWrapper wrapper, @NotNull String globalTestDir, @NotNull AnalysisScope scope) {
|
||||
myFixture.enableInspections(wrapper.getTool());
|
||||
|
||||
scope.invalidate();
|
||||
|
||||
InspectionManagerEx inspectionManager = (InspectionManagerEx)InspectionManager.getInstance(getProject());
|
||||
GlobalInspectionContextForTests globalContext =
|
||||
CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, getProject(), inspectionManager, wrapper);
|
||||
|
||||
InspectionTestUtil.runTool(wrapper, scope, globalContext);
|
||||
InspectionTestUtil.compareToolResults(globalContext, wrapper, false, getTestDataPath() + globalTestDir);
|
||||
}
|
||||
|
||||
protected static class MyAdditionalModuleData {
|
||||
final JavaModuleFixtureBuilder myModuleFixtureBuilder;
|
||||
final String myDirName;
|
||||
final int myProjectType;
|
||||
final boolean myIsMainModuleDependency;
|
||||
|
||||
private MyAdditionalModuleData(
|
||||
@NotNull JavaModuleFixtureBuilder moduleFixtureBuilder, @NotNull String dirName, int projectType, boolean isMainModuleDependency) {
|
||||
myModuleFixtureBuilder = moduleFixtureBuilder;
|
||||
myDirName = dirName;
|
||||
myProjectType = projectType;
|
||||
myIsMainModuleDependency = isMainModuleDependency;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected <T> T registerApplicationComponent(@NotNull Class<T> key, @NotNull T instance) throws Exception {
|
||||
MutablePicoContainer picoContainer = (MutablePicoContainer)ApplicationManager.getApplication().getPicoContainer();
|
||||
@SuppressWarnings("unchecked")
|
||||
T old = (T)picoContainer.getComponentInstance(key.getName());
|
||||
picoContainer.unregisterComponent(key.getName());
|
||||
picoContainer.registerComponentInstance(key.getName(), instance);
|
||||
return old;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected <T> T registerProjectComponent(@NotNull Class<T> key, @NotNull T instance) {
|
||||
MutablePicoContainer picoContainer = (MutablePicoContainer)getProject().getPicoContainer();
|
||||
@SuppressWarnings("unchecked")
|
||||
T old = (T)picoContainer.getComponentInstance(key.getName());
|
||||
picoContainer.unregisterComponent(key.getName());
|
||||
picoContainer.registerComponentInstance(key.getName(), instance);
|
||||
return old;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.git
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vcs.FilePath
|
||||
import git4idea.checkin.GitCheckinExplicitMovementProvider
|
||||
import org.jetbrains.kotlin.idea.actions.pathBeforeJ2K
|
||||
import java.util.*
|
||||
|
||||
class KotlinExplicitMovementProvider : GitCheckinExplicitMovementProvider() {
|
||||
override fun isEnabled(project: Project): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getDescription(): String {
|
||||
return "Extra commit for .java > .kt renames"
|
||||
}
|
||||
|
||||
override fun getCommitMessage(oldCommitMessage: String): String {
|
||||
return "Rename .java to .kt"
|
||||
}
|
||||
|
||||
override fun collectExplicitMovements(
|
||||
project: Project,
|
||||
beforePaths: List<FilePath>,
|
||||
afterPaths: List<FilePath>
|
||||
): Collection<GitCheckinExplicitMovementProvider.Movement> {
|
||||
val movedChanges = ArrayList<GitCheckinExplicitMovementProvider.Movement>()
|
||||
for (after in afterPaths) {
|
||||
val pathBeforeJ2K = after.virtualFile?.pathBeforeJ2K
|
||||
if (pathBeforeJ2K != null) {
|
||||
val before = beforePaths.firstOrNull { it.path == pathBeforeJ2K }
|
||||
if (before != null) {
|
||||
movedChanges.add(GitCheckinExplicitMovementProvider.Movement(before, after))
|
||||
after.virtualFile?.pathBeforeJ2K = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return movedChanges
|
||||
}
|
||||
}
|
||||
-121
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.core.script
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.application.Result
|
||||
import com.intellij.openapi.application.WriteAction
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.EditorFactory
|
||||
import com.intellij.openapi.editor.event.DocumentEvent
|
||||
import com.intellij.openapi.editor.event.DocumentListener
|
||||
import com.intellij.openapi.externalSystem.service.project.manage.ExternalProjectsManager
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectRootManager
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.newvfs.BulkFileListener
|
||||
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.util.ui.update.MergingUpdateQueue
|
||||
import com.intellij.util.ui.update.MergingUpdateQueue.ANY_COMPONENT
|
||||
import com.intellij.util.ui.update.Update
|
||||
import org.jetbrains.plugins.gradle.service.project.GradleAutoImportAware
|
||||
import java.io.File
|
||||
|
||||
fun initializeScriptModificationListener(project: Project) {
|
||||
ServiceManager.getService(project, ScriptModificationListener::class.java)
|
||||
}
|
||||
|
||||
class ScriptModificationListener(private val project: Project) {
|
||||
private val changedDocuments = HashSet<Document>()
|
||||
private val changedDocumentsQueue = MergingUpdateQueue("ScriptModificationListener: Scripts queue", 1000, false, ANY_COMPONENT, project)
|
||||
|
||||
init {
|
||||
showNotificationIfScriptChangedListener()
|
||||
|
||||
saveScriptAfterModificationListener()
|
||||
}
|
||||
|
||||
private fun showNotificationIfScriptChangedListener() {
|
||||
project.messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, object : BulkFileListener.Adapter() {
|
||||
override fun after(events: List<VFileEvent>) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode) return
|
||||
|
||||
val modifiedScripts = events.mapNotNull {
|
||||
it.file?.takeIf { isGradleScript(it) }
|
||||
}
|
||||
|
||||
// Workaround for IDEA-182367 (fixed in IDEA 181.3666)
|
||||
if (modifiedScripts.isNotEmpty()) {
|
||||
if (modifiedScripts.any {
|
||||
GradleAutoImportAware().getAffectedExternalProjectPath(it.path, project) != null
|
||||
}) {
|
||||
return
|
||||
}
|
||||
ExternalProjectsManager.getInstance(project).externalProjectsWatcher.markDirty(project.basePath)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun saveScriptAfterModificationListener() {
|
||||
// partially copied from ExternalSystemProjectsWatcherImpl before fix will be implemented in IDEA:
|
||||
// "Gradle projects need to be imported" notification should be shown when kotlin script is modified
|
||||
val busConnection = project.messageBus.connect(changedDocumentsQueue)
|
||||
changedDocumentsQueue.activate()
|
||||
|
||||
EditorFactory.getInstance().eventMulticaster.addDocumentListener(object : DocumentListener {
|
||||
override fun documentChanged(event: DocumentEvent) {
|
||||
if (project.isDisposed) return
|
||||
|
||||
val doc = event.document
|
||||
val file = FileDocumentManager.getInstance().getFile(doc) ?: return
|
||||
|
||||
if (isGradleScript(file) && event.newFragment.isNotBlank()) {
|
||||
synchronized(changedDocuments) {
|
||||
changedDocuments.add(doc)
|
||||
}
|
||||
|
||||
changedDocumentsQueue.queue(object : Update(this) {
|
||||
override fun run() {
|
||||
var copy: Array<Document> = emptyArray()
|
||||
|
||||
synchronized(changedDocuments) {
|
||||
copy = changedDocuments.toTypedArray()
|
||||
changedDocuments.clear()
|
||||
}
|
||||
|
||||
ExternalSystemUtil.invokeLater(project) {
|
||||
object : WriteAction<Any>() {
|
||||
override fun run(result: Result<Any>) {
|
||||
for (each in copy) {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(each)
|
||||
(FileDocumentManager.getInstance() as? FileDocumentManagerImpl)?.saveDocument(each, false)
|
||||
}
|
||||
}
|
||||
}.execute()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}, busConnection)
|
||||
}
|
||||
|
||||
private fun isGradleScript(file: VirtualFile): Boolean {
|
||||
if (!ProjectRootManager.getInstance(project).fileIndex.isInContent(file)) return false
|
||||
|
||||
val contributor = ScriptDefinitionContributor.find<GradleScriptDefinitionsContributor>(project) ?: return false
|
||||
return ScriptDefinitionsManager.getInstance(project).getDefinitionsBy(contributor).any {
|
||||
it.isScript(File(file.path))
|
||||
}
|
||||
}
|
||||
}
|
||||
-367
@@ -1,367 +0,0 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.gradle.execution;
|
||||
|
||||
import com.intellij.build.BuildViewManager;
|
||||
import com.intellij.compiler.impl.CompilerUtil;
|
||||
import com.intellij.execution.executors.DefaultRunExecutor;
|
||||
import com.intellij.openapi.compiler.ex.CompilerPathsEx;
|
||||
import com.intellij.openapi.externalSystem.model.DataNode;
|
||||
import com.intellij.openapi.externalSystem.model.ProjectKeys;
|
||||
import com.intellij.openapi.externalSystem.model.execution.ExternalSystemTaskExecutionSettings;
|
||||
import com.intellij.openapi.externalSystem.model.project.ModuleData;
|
||||
import com.intellij.openapi.externalSystem.service.execution.ProgressExecutionMode;
|
||||
import com.intellij.openapi.externalSystem.task.TaskCallback;
|
||||
import com.intellij.openapi.externalSystem.util.ExternalSystemUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootModificationTracker;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.task.*;
|
||||
import com.intellij.task.impl.JpsProjectTaskRunner;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.FactoryMap;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.intellij.lang.annotations.Language;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.config.KotlinFacetSettings;
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet;
|
||||
import org.jetbrains.kotlin.konan.target.KonanTargetKt;
|
||||
import org.jetbrains.kotlin.platform.IdePlatformKindUtil;
|
||||
import org.jetbrains.kotlin.platform.TargetPlatformKt;
|
||||
import org.jetbrains.kotlin.platform.impl.CommonIdePlatformUtil;
|
||||
import org.jetbrains.kotlin.platform.impl.NativeIdePlatformUtil;
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform;
|
||||
import org.jetbrains.kotlin.platform.PlatformUtilKt;
|
||||
import org.jetbrains.kotlin.platform.konan.KonanPlatformKt;
|
||||
import org.jetbrains.plugins.gradle.execution.build.CachedModuleDataFinder;
|
||||
import org.jetbrains.plugins.gradle.execution.build.GradleProjectTaskRunner;
|
||||
import org.jetbrains.plugins.gradle.service.project.GradleBuildSrcProjectsResolver;
|
||||
import org.jetbrains.plugins.gradle.service.project.GradleProjectResolverUtil;
|
||||
import org.jetbrains.plugins.gradle.service.task.GradleTaskManager;
|
||||
import org.jetbrains.plugins.gradle.settings.GradleSettings;
|
||||
import org.jetbrains.plugins.gradle.settings.GradleSystemRunningSettings;
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.intellij.openapi.externalSystem.service.execution.ExternalSystemRunConfiguration.PROGRESS_LISTENER_KEY;
|
||||
import static com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil.*;
|
||||
import static com.intellij.openapi.util.text.StringUtil.*;
|
||||
import static org.jetbrains.plugins.gradle.execution.GradleRunnerUtil.resolveProjectPath;
|
||||
|
||||
/**
|
||||
* This is a modified copy of {@link GradleProjectTaskRunner} that allows building Kotlin Common and Kotlin Native modules
|
||||
* in IDEA by delegating to Gradle builder ("Delegate IDE build/run actions to gradle"). See #KT-27295, #KT-27296.
|
||||
*
|
||||
* TODO: Refactor this class to remove duplicated logic when {@link GradleProjectTaskRunner} will allow extending it to
|
||||
* collect custom Gradle tasks. See #IDEA-204372, #KT-28880.
|
||||
*/
|
||||
class KotlinMPPGradleProjectTaskRunner extends ProjectTaskRunner
|
||||
{
|
||||
|
||||
@Language("Groovy")
|
||||
private static final String FORCE_COMPILE_TASKS_INIT_SCRIPT_TEMPLATE = "projectsEvaluated { \n" +
|
||||
" rootProject.findProject('%s')?.tasks?.withType(AbstractCompile) { \n" +
|
||||
" outputs.upToDateWhen { false } \n" +
|
||||
" } \n" +
|
||||
"}\n";
|
||||
|
||||
@Override
|
||||
public void run(@NotNull Project project,
|
||||
@NotNull ProjectTaskContext context,
|
||||
@Nullable ProjectTaskNotification callback,
|
||||
@NotNull Collection<? extends ProjectTask> tasks) {
|
||||
MultiMap<String, String> buildTasksMap = MultiMap.createLinkedSet();
|
||||
MultiMap<String, String> cleanTasksMap = MultiMap.createLinkedSet();
|
||||
MultiMap<String, String> initScripts = MultiMap.createLinkedSet();
|
||||
|
||||
Map<Class<? extends ProjectTask>, List<ProjectTask>> taskMap = JpsProjectTaskRunner.groupBy(tasks);
|
||||
|
||||
List<Module> modules = addModulesBuildTasks(taskMap.get(ModuleBuildTask.class), buildTasksMap, initScripts);
|
||||
// TODO there should be 'gradle' way to build files instead of related modules entirely
|
||||
List<Module> modulesOfFiles = addModulesBuildTasks(taskMap.get(ModuleFilesBuildTask.class), buildTasksMap, initScripts);
|
||||
|
||||
// TODO send a message if nothing to build
|
||||
Set<String> rootPaths = buildTasksMap.keySet();
|
||||
AtomicInteger successCounter = new AtomicInteger();
|
||||
AtomicInteger errorCounter = new AtomicInteger();
|
||||
|
||||
TaskCallback taskCallback = callback == null ? null : new TaskCallback() {
|
||||
@Override
|
||||
public void onSuccess() {
|
||||
handle(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure() {
|
||||
handle(false);
|
||||
}
|
||||
|
||||
private void handle(boolean success) {
|
||||
int successes = success ? successCounter.incrementAndGet() : successCounter.get();
|
||||
int errors = success ? errorCounter.get() : errorCounter.incrementAndGet();
|
||||
if (successes + errors == rootPaths.size()) {
|
||||
if (!project.isDisposed()) {
|
||||
// refresh on output roots is required in order for the order enumerator to see all roots via VFS
|
||||
final List<Module> affectedModules = ContainerUtil.concat(modules, modulesOfFiles);
|
||||
// have to refresh in case of errors too, because run configuration may be set to ignore errors
|
||||
Collection<String> affectedRoots = ContainerUtil.newHashSet(
|
||||
CompilerPathsEx.getOutputPaths(affectedModules.toArray(Module.EMPTY_ARRAY)));
|
||||
if (!affectedRoots.isEmpty()) {
|
||||
CompilerUtil.refreshOutputRoots(affectedRoots);
|
||||
}
|
||||
}
|
||||
callback.finished(new ProjectTaskResult(false, errors, 0));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// TODO compiler options should be configurable
|
||||
@Language("Groovy")
|
||||
String compilerOptionsInitScript = "allprojects {\n" +
|
||||
" tasks.withType(JavaCompile) {\n" +
|
||||
" options.compilerArgs += [\"-Xlint:deprecation\"]\n" +
|
||||
" }" +
|
||||
"}\n";
|
||||
|
||||
String gradleVmOptions = GradleSettings.getInstance(project).getGradleVmOptions();
|
||||
for (String rootProjectPath : rootPaths) {
|
||||
Collection<String> buildTasks = buildTasksMap.get(rootProjectPath);
|
||||
if (buildTasks.isEmpty()) continue;
|
||||
Collection<String> cleanTasks = cleanTasksMap.get(rootProjectPath);
|
||||
|
||||
ExternalSystemTaskExecutionSettings settings = new ExternalSystemTaskExecutionSettings();
|
||||
|
||||
File projectFile = new File(rootProjectPath);
|
||||
final String projectName;
|
||||
if (projectFile.isFile()) {
|
||||
projectName = projectFile.getParentFile().getName();
|
||||
}
|
||||
else {
|
||||
projectName = projectFile.getName();
|
||||
}
|
||||
String executionName = "Build " + projectName;
|
||||
settings.setExecutionName(executionName);
|
||||
settings.setExternalProjectPath(rootProjectPath);
|
||||
settings.setTaskNames(ContainerUtil.collect(ContainerUtil.concat(cleanTasks, buildTasks).iterator()));
|
||||
//settings.setScriptParameters(scriptParameters);
|
||||
settings.setVmOptions(gradleVmOptions);
|
||||
settings.setExternalSystemIdString(GradleConstants.SYSTEM_ID.getId());
|
||||
|
||||
UserDataHolderBase userData = new UserDataHolderBase();
|
||||
userData.putUserData(PROGRESS_LISTENER_KEY, BuildViewManager.class);
|
||||
|
||||
Collection<String> scripts = initScripts.getModifiable(rootProjectPath);
|
||||
scripts.add(compilerOptionsInitScript);
|
||||
userData.putUserData(GradleTaskManager.INIT_SCRIPT_KEY, join(scripts, SystemProperties.getLineSeparator()));
|
||||
|
||||
ExternalSystemUtil.runTask(settings, DefaultRunExecutor.EXECUTOR_ID, project, GradleConstants.SYSTEM_ID,
|
||||
taskCallback, ProgressExecutionMode.IN_BACKGROUND_ASYNC, false, userData);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRun(@NotNull ProjectTask projectTask) {
|
||||
if (!GradleSystemRunningSettings.getInstance().isUseGradleAwareMake()) return false;
|
||||
if (projectTask instanceof ModuleBuildTask) {
|
||||
final ModuleBuildTask moduleBuildTask = (ModuleBuildTask) projectTask;
|
||||
final Module module = moduleBuildTask.getModule();
|
||||
|
||||
if (!isExternalSystemAwareModule(GradleConstants.SYSTEM_ID, module)) return false;
|
||||
|
||||
// ---------------------------------------- //
|
||||
// TODO BEGIN: Extract custom Kotlin logic. //
|
||||
// ---------------------------------------- //
|
||||
if (isProjectWithNativeSourceOrCommonProductionSourceModules(module.getProject())) return true;
|
||||
// ---------------------------------------- //
|
||||
// TODO END: Extract custom Kotlin logic. //
|
||||
// ---------------------------------------- //
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<Module> addModulesBuildTasks(@Nullable Collection<? extends ProjectTask> projectTasks,
|
||||
@NotNull MultiMap<String, String> buildTasksMap,
|
||||
@NotNull MultiMap<String, String> initScripts) {
|
||||
if (ContainerUtil.isEmpty(projectTasks)) return Collections.emptyList();
|
||||
|
||||
List<Module> affectedModules = new SmartList<>();
|
||||
Map<Module, String> rootPathsMap = FactoryMap.create(module -> notNullize(resolveProjectPath(module)));
|
||||
final CachedModuleDataFinder moduleDataFinder = new CachedModuleDataFinder();
|
||||
for (ProjectTask projectTask : projectTasks) {
|
||||
if (!(projectTask instanceof ModuleBuildTask)) continue;
|
||||
|
||||
ModuleBuildTask moduleBuildTask = (ModuleBuildTask)projectTask;
|
||||
Module module = moduleBuildTask.getModule();
|
||||
affectedModules.add(module);
|
||||
|
||||
final String rootProjectPath = rootPathsMap.get(module);
|
||||
if (isEmpty(rootProjectPath)) continue;
|
||||
|
||||
final String projectId = getExternalProjectId(module);
|
||||
if (projectId == null) continue;
|
||||
final String externalProjectPath = getExternalProjectPath(module);
|
||||
if (externalProjectPath == null || endsWith(externalProjectPath, "buildSrc")) continue;
|
||||
|
||||
final DataNode<? extends ModuleData> moduleDataNode = moduleDataFinder.findMainModuleData(module);
|
||||
if (moduleDataNode == null) continue;
|
||||
|
||||
// all buildSrc runtime projects will be built by gradle implicitly
|
||||
if (Boolean.parseBoolean(moduleDataNode.getData().getProperty(GradleBuildSrcProjectsResolver.BUILD_SRC_MODULE_PROPERTY))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String gradlePath = GradleProjectResolverUtil.getGradlePath(module);
|
||||
if (gradlePath == null) continue;
|
||||
String taskPrefix = endsWithChar(gradlePath, ':') ? gradlePath : (gradlePath + ':');
|
||||
|
||||
List<String> gradleTasks = ContainerUtil.mapNotNull(
|
||||
findAll(moduleDataNode, ProjectKeys.TASK), node ->
|
||||
node.getData().isInherited() ? null : trimStart(node.getData().getName(), taskPrefix));
|
||||
|
||||
Collection<String> projectInitScripts = initScripts.getModifiable(rootProjectPath);
|
||||
Collection<String> buildRootTasks = buildTasksMap.getModifiable(rootProjectPath);
|
||||
final String moduleType = getExternalModuleType(module);
|
||||
|
||||
if (!moduleBuildTask.isIncrementalBuild()) {
|
||||
projectInitScripts.add(String.format(FORCE_COMPILE_TASKS_INIT_SCRIPT_TEMPLATE, gradlePath));
|
||||
}
|
||||
String assembleTask = "assemble";
|
||||
if (GradleConstants.GRADLE_SOURCE_SET_MODULE_TYPE_KEY.equals(moduleType)) {
|
||||
String sourceSetName = GradleProjectResolverUtil.getSourceSetName(module);
|
||||
String gradleTask = isEmpty(sourceSetName) || "main".equals(sourceSetName) ? "classes" : sourceSetName + "Classes";
|
||||
if (gradleTasks.contains(gradleTask)) {
|
||||
buildRootTasks.add(taskPrefix + gradleTask);
|
||||
}
|
||||
else if ("main".equals(sourceSetName) || "test".equals(sourceSetName)) {
|
||||
buildRootTasks.add(taskPrefix + assembleTask);
|
||||
}
|
||||
// ---------------------------------------- //
|
||||
// TODO BEGIN: Extract custom Kotlin logic. //
|
||||
// ---------------------------------------- //
|
||||
else if (isNativeSourceModule(module)) {
|
||||
// Add tasks for Kotlin/Native.
|
||||
buildRootTasks.addAll(addPrefix(findNativeGradleBuildTasks(gradleTasks, sourceSetName), taskPrefix));
|
||||
}
|
||||
else if (isCommonProductionSourceModule(module)) {
|
||||
// Add tasks for compiling metadata.
|
||||
buildRootTasks.addAll(addPrefix(findMetadataBuildTasks(gradleTasks, sourceSetName), taskPrefix));
|
||||
}
|
||||
// ---------------------------------------- //
|
||||
// TODO END: Extract custom Kotlin logic. //
|
||||
// ---------------------------------------- //
|
||||
}
|
||||
else {
|
||||
if (gradleTasks.contains("classes")) {
|
||||
buildRootTasks.add(taskPrefix + "classes");
|
||||
buildRootTasks.add(taskPrefix + "testClasses");
|
||||
}
|
||||
else if (gradleTasks.contains(assembleTask)) {
|
||||
buildRootTasks.add(taskPrefix + assembleTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
return affectedModules;
|
||||
}
|
||||
|
||||
// ---------------------------------------- //
|
||||
// TODO BEGIN: Extract custom Kotlin logic. //
|
||||
// ---------------------------------------- //
|
||||
private static boolean isProjectWithNativeSourceOrCommonProductionSourceModules(Project project) {
|
||||
return CachedValuesManager.getManager(project).getCachedValue(
|
||||
project,
|
||||
() -> new CachedValueProvider.Result<>(
|
||||
Arrays.stream(ModuleManager.getInstance(project).getModules()).anyMatch(
|
||||
module -> isNativeSourceModule(module) || isCommonProductionSourceModule(module)
|
||||
),
|
||||
ProjectRootModificationTracker.getInstance(project)
|
||||
));
|
||||
}
|
||||
|
||||
private static boolean isNativeSourceModule(Module module) {
|
||||
final KotlinFacet kotlinFacet = KotlinFacet.Companion.get(module);
|
||||
if (kotlinFacet == null) return false;
|
||||
|
||||
final TargetPlatform platform = kotlinFacet.getConfiguration().getSettings().getTargetPlatform();
|
||||
if (platform == null) return false;
|
||||
|
||||
return KonanPlatformKt.isNative(platform);
|
||||
}
|
||||
|
||||
private static boolean isCommonProductionSourceModule(Module module) {
|
||||
final KotlinFacet kotlinFacet = KotlinFacet.Companion.get(module);
|
||||
if (kotlinFacet == null) return false;
|
||||
|
||||
final KotlinFacetSettings facetSettings = kotlinFacet.getConfiguration().getSettings();
|
||||
if (facetSettings.isTestModule()) return false;
|
||||
|
||||
final TargetPlatform platform = facetSettings.getTargetPlatform();
|
||||
if (platform == null) return false;
|
||||
|
||||
return TargetPlatformKt.isCommon(platform);
|
||||
}
|
||||
|
||||
private static Collection<String> findNativeGradleBuildTasks(Collection<String> gradleTasks, String sourceSetName) {
|
||||
// First, attempt to find Kotlin/Native convention Gradle task that unites all outputType-specific build tasks.
|
||||
final String conventionGradleTask = sourceSetName + "Binaries";
|
||||
if (gradleTasks.contains(conventionGradleTask)) {
|
||||
return Collections.singletonList(conventionGradleTask);
|
||||
}
|
||||
|
||||
// If convention task not found, then attempt to find all appropriate build tasks for the given source set.
|
||||
final Collection<String> linkPrefixes;
|
||||
final String targetName;
|
||||
if (sourceSetName.endsWith("Main")) {
|
||||
targetName = StringUtil.substringBeforeLast(sourceSetName,"Main");
|
||||
linkPrefixes = ContainerUtil.newArrayList("link", "linkMain");
|
||||
}
|
||||
else if (sourceSetName.endsWith("Test")) {
|
||||
targetName = StringUtil.substringBeforeLast(sourceSetName,"Test");
|
||||
linkPrefixes = Collections.singletonList("linkTest");
|
||||
}
|
||||
else {
|
||||
targetName = sourceSetName;
|
||||
linkPrefixes = Collections.singletonList("link");
|
||||
}
|
||||
|
||||
return linkPrefixes.stream()
|
||||
// get base task name (without disambiguation classifier)
|
||||
.map(linkPrefix -> linkPrefix + capitalize(targetName))
|
||||
// find all Gradle tasks that start with base task name
|
||||
.flatMap(nativeTaskName -> gradleTasks.stream().filter(taskName -> taskName.startsWith(nativeTaskName)))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private static Collection<String> findMetadataBuildTasks(Collection<String> gradleTasks, String sourceSetName) {
|
||||
if ("commonMain".equals(sourceSetName)) {
|
||||
final String metadataTaskName = "metadataMainClasses";
|
||||
if (gradleTasks.contains(metadataTaskName)) {
|
||||
return Collections.singletonList(metadataTaskName);
|
||||
}
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
private static Collection<String> addPrefix(Collection<String> tasks, String taskPrefix) {
|
||||
return tasks.stream().map(task -> taskPrefix + task).collect(Collectors.toList());
|
||||
}
|
||||
// ---------------------------------------- //
|
||||
// TODO END: Extract custom Kotlin logic. //
|
||||
// ---------------------------------------- //
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import java.lang.reflect.Modifier
|
||||
|
||||
// BUNCH: 182
|
||||
internal fun getLoggerFactory(): Class<out Logger.Factory> {
|
||||
val factoryField = Logger::class.java.declaredFields.single { Modifier.isStatic(it.modifiers) && !Modifier.isFinal(it.modifiers) }
|
||||
val oldIsAccessible = factoryField.isAccessible
|
||||
try {
|
||||
factoryField.isAccessible = true
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return factoryField.get(null).javaClass as Class<out Logger.Factory>
|
||||
} finally {
|
||||
factoryField.isAccessible = oldIsAccessible
|
||||
}
|
||||
}
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeInsight.gradle
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.testFramework.TestLoggerFactory
|
||||
|
||||
class GradleImportingTestLogSaver() {
|
||||
init {
|
||||
Logger.setFactory(TestLoggerFactory::class.java)
|
||||
}
|
||||
|
||||
fun restore() {
|
||||
}
|
||||
}
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.codeInsight.gradle
|
||||
|
||||
import com.intellij.testFramework.TestLoggerFactory
|
||||
import org.junit.rules.TestWatcher
|
||||
import org.junit.runner.Description
|
||||
|
||||
class ImportingTestWatcher : TestWatcher() {
|
||||
|
||||
override fun succeeded(description: Description) {
|
||||
TestLoggerFactory.onTestFinished(true)
|
||||
}
|
||||
|
||||
override fun failed(e: Throwable, description: Description) {
|
||||
TestLoggerFactory.onTestFinished(false)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.config
|
||||
|
||||
import org.jetbrains.jps.model.ex.JpsElementTypeBase
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootProperties
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootType
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||
|
||||
sealed class KotlinResourceRootType(val isTest: Boolean) : JpsElementTypeBase<JavaResourceRootProperties>(),
|
||||
JpsModuleSourceRootType<JavaResourceRootProperties>, KotlinRootType {
|
||||
|
||||
override fun createDefaultProperties() =
|
||||
JpsJavaExtensionService.getInstance().createResourceRootProperties("", false)
|
||||
|
||||
override fun isTestRoot() = isTest
|
||||
|
||||
override fun equals(other: Any?) = if (super.equals(other)) true else isSameRootType(this, other)
|
||||
}
|
||||
|
||||
object ResourceKotlinRootType : KotlinResourceRootType(false)
|
||||
object TestResourceKotlinRootType : KotlinResourceRootType(true)
|
||||
|
||||
val ALL_KOTLIN_RESOURCE_ROOT_TYPES = setOf(ResourceKotlinRootType, TestResourceKotlinRootType)
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.config
|
||||
|
||||
import org.jetbrains.jps.model.ex.JpsElementTypeBase
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootProperties
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||
|
||||
sealed class KotlinSourceRootType(val isTest: Boolean) : JpsElementTypeBase<JavaSourceRootProperties>(), JpsModuleSourceRootType<JavaSourceRootProperties>, KotlinRootType {
|
||||
|
||||
|
||||
override fun createDefaultProperties() = JpsJavaExtensionService.getInstance().createSourceRootProperties("")
|
||||
|
||||
|
||||
override fun isTestRoot() = isTest
|
||||
|
||||
override fun equals(other: Any?) = if (super.equals(other)) true else isSameRootType(this, other)
|
||||
}
|
||||
|
||||
object SourceKotlinRootType : KotlinSourceRootType(false)
|
||||
|
||||
object TestSourceKotlinRootType : KotlinSourceRootType(true)
|
||||
|
||||
val ALL_KOTLIN_SOURCE_ROOT_TYPES = setOf(SourceKotlinRootType, TestSourceKotlinRootType)
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("IncompatibleAPI")
|
||||
|
||||
package org.jetbrains.kotlin.idea.run
|
||||
|
||||
import com.intellij.execution.configurations.LocatableConfigurationBase
|
||||
import com.intellij.execution.configurations.ModuleBasedConfiguration
|
||||
import com.intellij.execution.configurations.RunConfigurationBase
|
||||
import org.jdom.Element
|
||||
|
||||
// Generalized in 183
|
||||
// BUNCH: 182
|
||||
typealias RunConfigurationBaseAny = RunConfigurationBase
|
||||
|
||||
// Generalized in 183
|
||||
// BUNCH: 182
|
||||
typealias ModuleBasedConfigurationAny = ModuleBasedConfiguration<*>
|
||||
|
||||
// Generalized in 183
|
||||
// BUNCH: 182
|
||||
typealias LocatableConfigurationBaseAny = LocatableConfigurationBase
|
||||
|
||||
// Generalized in 183
|
||||
// BUNCH: 182
|
||||
typealias ModuleBasedConfigurationElement<T> = ModuleBasedConfiguration<T>
|
||||
@@ -1,596 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.maven;
|
||||
|
||||
import com.intellij.compiler.server.BuildManager;
|
||||
import com.intellij.openapi.application.AccessToken;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
import com.intellij.openapi.progress.EmptyProgressIndicator;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
|
||||
import com.intellij.openapi.roots.*;
|
||||
import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
|
||||
import com.intellij.openapi.roots.libraries.Library;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.TestDialog;
|
||||
import com.intellij.openapi.util.AsyncResult;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.maven.execution.*;
|
||||
import org.jetbrains.idea.maven.model.MavenArtifact;
|
||||
import org.jetbrains.idea.maven.model.MavenExplicitProfiles;
|
||||
import org.jetbrains.idea.maven.project.*;
|
||||
import org.jetbrains.idea.maven.server.MavenServerManager;
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootType;
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootProperties;
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType;
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType;
|
||||
import org.jetbrains.kotlin.idea.test.KotlinSdkCreationChecker;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public abstract class MavenImportingTestCase extends MavenTestCase {
|
||||
protected MavenProjectsTree myProjectsTree;
|
||||
protected MavenProjectsManager myProjectsManager;
|
||||
private File myGlobalSettingsFile;
|
||||
protected KotlinSdkCreationChecker sdkCreationChecker;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
VfsRootAccess.allowRootAccess(PathManager.getConfigPath());
|
||||
super.setUp();
|
||||
myGlobalSettingsFile =
|
||||
MavenWorkspaceSettingsComponent.getInstance(myProject).getSettings().generalSettings.getEffectiveGlobalSettingsIoFile();
|
||||
if (myGlobalSettingsFile != null) {
|
||||
VfsRootAccess.allowRootAccess(myGlobalSettingsFile.getAbsolutePath());
|
||||
}
|
||||
sdkCreationChecker = new KotlinSdkCreationChecker();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUpInWriteAction() throws Exception {
|
||||
super.setUpInWriteAction();
|
||||
myProjectsManager = MavenProjectsManager.getInstance(myProject);
|
||||
removeFromLocalRepository("test");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
try {
|
||||
JavaAwareProjectJdkTableImpl.removeInternalJdkInTests();
|
||||
if (myGlobalSettingsFile != null) {
|
||||
VfsRootAccess.disallowRootAccess(myGlobalSettingsFile.getAbsolutePath());
|
||||
}
|
||||
VfsRootAccess.disallowRootAccess(PathManager.getConfigPath());
|
||||
Messages.setTestDialog(TestDialog.DEFAULT);
|
||||
removeFromLocalRepository("test");
|
||||
FileUtil.delete(BuildManager.getInstance().getBuildSystemDirectory().toFile());
|
||||
sdkCreationChecker.removeNewKotlinSdk();
|
||||
}
|
||||
finally {
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
|
||||
protected void assertModules(String... expectedNames) {
|
||||
Module[] actual = ModuleManager.getInstance(myProject).getModules();
|
||||
List<String> actualNames = new ArrayList<String>();
|
||||
|
||||
for (Module m : actual) {
|
||||
actualNames.add(m.getName());
|
||||
}
|
||||
|
||||
assertUnorderedElementsAreEqual(actualNames, expectedNames);
|
||||
}
|
||||
|
||||
protected void assertContentRoots(String moduleName, String... expectedRoots) {
|
||||
List<String> actual = new ArrayList<String>();
|
||||
for (ContentEntry e : getContentRoots(moduleName)) {
|
||||
actual.add(e.getUrl());
|
||||
}
|
||||
|
||||
for (int i = 0; i < expectedRoots.length; i++) {
|
||||
expectedRoots[i] = VfsUtil.pathToUrl(expectedRoots[i]);
|
||||
}
|
||||
|
||||
assertUnorderedPathsAreEqual(actual, Arrays.asList(expectedRoots));
|
||||
}
|
||||
|
||||
protected void assertSources(String moduleName, String... expectedSources) {
|
||||
assertContentFolders(moduleName, JavaSourceRootType.SOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertGeneratedSources(String moduleName, String... expectedSources) {
|
||||
ContentEntry contentRoot = getContentRoot(moduleName);
|
||||
List<ContentFolder> folders = new ArrayList<ContentFolder>();
|
||||
for (SourceFolder folder : contentRoot.getSourceFolders(JavaSourceRootType.SOURCE)) {
|
||||
JavaSourceRootProperties properties = folder.getJpsElement().getProperties(JavaSourceRootType.SOURCE);
|
||||
assertNotNull(properties);
|
||||
if (properties.isForGeneratedSources()) {
|
||||
folders.add(folder);
|
||||
}
|
||||
}
|
||||
doAssertContentFolders(contentRoot, folders, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertResources(String moduleName, String... expectedSources) {
|
||||
assertContentFolders(moduleName, JavaResourceRootType.RESOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertTestSources(String moduleName, String... expectedSources) {
|
||||
assertContentFolders(moduleName, JavaSourceRootType.TEST_SOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertTestResources(String moduleName, String... expectedSources) {
|
||||
assertContentFolders(moduleName, JavaResourceRootType.TEST_RESOURCE, expectedSources);
|
||||
}
|
||||
|
||||
protected void assertExcludes(String moduleName, String... expectedExcludes) {
|
||||
ContentEntry contentRoot = getContentRoot(moduleName);
|
||||
doAssertContentFolders(contentRoot, Arrays.asList(contentRoot.getExcludeFolders()), expectedExcludes);
|
||||
}
|
||||
|
||||
protected void assertContentRootExcludes(String moduleName, String contentRoot, String... expectedExcudes) {
|
||||
ContentEntry root = getContentRoot(moduleName, contentRoot);
|
||||
doAssertContentFolders(root, Arrays.asList(root.getExcludeFolders()), expectedExcudes);
|
||||
}
|
||||
|
||||
protected void assertContentFolders(String moduleName, @NotNull JpsModuleSourceRootType<?> rootType, String... expected) {
|
||||
ContentEntry contentRoot = getContentRoot(moduleName);
|
||||
doAssertContentFolders(contentRoot, contentRoot.getSourceFolders(rootType), expected);
|
||||
}
|
||||
|
||||
private static void doAssertContentFolders(ContentEntry e, final List<? extends ContentFolder> folders, String... expected) {
|
||||
List<String> actual = new ArrayList<String>();
|
||||
for (ContentFolder f : folders) {
|
||||
String rootUrl = e.getUrl();
|
||||
String folderUrl = f.getUrl();
|
||||
|
||||
if (folderUrl.startsWith(rootUrl)) {
|
||||
int length = rootUrl.length() + 1;
|
||||
folderUrl = folderUrl.substring(Math.min(length, folderUrl.length()));
|
||||
}
|
||||
|
||||
actual.add(folderUrl);
|
||||
}
|
||||
|
||||
assertOrderedElementsAreEqual(actual, Arrays.asList(expected));
|
||||
}
|
||||
|
||||
protected void assertModuleOutput(String moduleName, String output, String testOutput) {
|
||||
CompilerModuleExtension e = getCompilerExtension(moduleName);
|
||||
|
||||
assertFalse(e.isCompilerOutputPathInherited());
|
||||
assertEquals(output, getAbsolutePath(e.getCompilerOutputUrl()));
|
||||
assertEquals(testOutput, getAbsolutePath(e.getCompilerOutputUrlForTests()));
|
||||
}
|
||||
|
||||
private static String getAbsolutePath(String path) {
|
||||
path = VfsUtil.urlToPath(path);
|
||||
path = PathUtil.getCanonicalPath(path);
|
||||
return FileUtil.toSystemIndependentName(path);
|
||||
}
|
||||
|
||||
protected void assertProjectOutput(String module) {
|
||||
assertTrue(getCompilerExtension(module).isCompilerOutputPathInherited());
|
||||
}
|
||||
|
||||
protected CompilerModuleExtension getCompilerExtension(String module) {
|
||||
ModuleRootManager m = getRootManager(module);
|
||||
return CompilerModuleExtension.getInstance(m.getModule());
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(String moduleName, String depName) {
|
||||
assertModuleLibDep(moduleName, depName, null);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(String moduleName, String depName, String classesPath) {
|
||||
assertModuleLibDep(moduleName, depName, classesPath, null, null);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(String moduleName, String depName, String classesPath, String sourcePath, String javadocPath) {
|
||||
LibraryOrderEntry lib = getModuleLibDep(moduleName, depName);
|
||||
|
||||
assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPath == null ? null : Collections.singletonList(classesPath));
|
||||
assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePath == null ? null : Collections.singletonList(sourcePath));
|
||||
assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(),
|
||||
javadocPath == null ? null : Collections.singletonList(javadocPath));
|
||||
}
|
||||
|
||||
protected void assertModuleLibDep(
|
||||
String moduleName,
|
||||
String depName,
|
||||
List<String> classesPaths,
|
||||
List<String> sourcePaths,
|
||||
List<String> javadocPaths
|
||||
) {
|
||||
LibraryOrderEntry lib = getModuleLibDep(moduleName, depName);
|
||||
|
||||
assertModuleLibDepPath(lib, OrderRootType.CLASSES, classesPaths);
|
||||
assertModuleLibDepPath(lib, OrderRootType.SOURCES, sourcePaths);
|
||||
assertModuleLibDepPath(lib, JavadocOrderRootType.getInstance(), javadocPaths);
|
||||
}
|
||||
|
||||
private static void assertModuleLibDepPath(LibraryOrderEntry lib, OrderRootType type, List<String> paths) {
|
||||
if (paths == null) return;
|
||||
assertUnorderedPathsAreEqual(Arrays.asList(lib.getRootUrls(type)), paths);
|
||||
// also check the library because it may contain slight different set of urls (e.g. with duplicates)
|
||||
assertUnorderedPathsAreEqual(Arrays.asList(lib.getLibrary().getUrls(type)), paths);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDepScope(String moduleName, String depName, DependencyScope scope) {
|
||||
LibraryOrderEntry dep = getModuleLibDep(moduleName, depName);
|
||||
assertEquals(scope, dep.getScope());
|
||||
}
|
||||
|
||||
private LibraryOrderEntry getModuleLibDep(String moduleName, String depName) {
|
||||
return getModuleDep(moduleName, depName, LibraryOrderEntry.class);
|
||||
}
|
||||
|
||||
protected void assertModuleLibDeps(String moduleName, String... expectedDeps) {
|
||||
assertModuleDeps(moduleName, LibraryOrderEntry.class, expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertExportedDeps(String moduleName, String... expectedDeps) {
|
||||
final List<String> actual = new ArrayList<String>();
|
||||
|
||||
getRootManager(moduleName).orderEntries().withoutSdk().withoutModuleSourceEntries().exportedOnly()
|
||||
.process(new RootPolicy<Object>() {
|
||||
@Override
|
||||
public Object visitModuleOrderEntry(ModuleOrderEntry e, Object value) {
|
||||
actual.add(e.getModuleName());
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visitLibraryOrderEntry(LibraryOrderEntry e, Object value) {
|
||||
actual.add(e.getLibraryName());
|
||||
return null;
|
||||
}
|
||||
}, null);
|
||||
|
||||
assertOrderedElementsAreEqual(actual, expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertModuleModuleDeps(String moduleName, String... expectedDeps) {
|
||||
assertModuleDeps(moduleName, ModuleOrderEntry.class, expectedDeps);
|
||||
}
|
||||
|
||||
private void assertModuleDeps(String moduleName, Class clazz, String... expectedDeps) {
|
||||
assertOrderedElementsAreEqual(collectModuleDepsNames(moduleName, clazz), expectedDeps);
|
||||
}
|
||||
|
||||
protected void assertModuleModuleDepScope(String moduleName, String depName, DependencyScope scope) {
|
||||
ModuleOrderEntry dep = getModuleModuleDep(moduleName, depName);
|
||||
assertEquals(scope, dep.getScope());
|
||||
}
|
||||
|
||||
private ModuleOrderEntry getModuleModuleDep(String moduleName, String depName) {
|
||||
return getModuleDep(moduleName, depName, ModuleOrderEntry.class);
|
||||
}
|
||||
|
||||
private List<String> collectModuleDepsNames(String moduleName, Class clazz) {
|
||||
List<String> actual = new ArrayList<String>();
|
||||
|
||||
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
|
||||
if (clazz.isInstance(e)) {
|
||||
actual.add(e.getPresentableName());
|
||||
}
|
||||
}
|
||||
return actual;
|
||||
}
|
||||
|
||||
private <T> T getModuleDep(String moduleName, String depName, Class<T> clazz) {
|
||||
T dep = null;
|
||||
|
||||
for (OrderEntry e : getRootManager(moduleName).getOrderEntries()) {
|
||||
if (clazz.isInstance(e) && e.getPresentableName().equals(depName)) {
|
||||
dep = (T) e;
|
||||
}
|
||||
}
|
||||
assertNotNull("Dependency not found: " + depName
|
||||
+ "\namong: " + collectModuleDepsNames(moduleName, clazz),
|
||||
dep);
|
||||
return dep;
|
||||
}
|
||||
|
||||
public void assertProjectLibraries(String... expectedNames) {
|
||||
List<String> actualNames = new ArrayList<String>();
|
||||
for (Library each : ProjectLibraryTable.getInstance(myProject).getLibraries()) {
|
||||
String name = each.getName();
|
||||
actualNames.add(name == null ? "<unnamed>" : name);
|
||||
}
|
||||
assertUnorderedElementsAreEqual(actualNames, expectedNames);
|
||||
}
|
||||
|
||||
protected void assertModuleGroupPath(String moduleName, String... expected) {
|
||||
String[] path = ModuleManager.getInstance(myProject).getModuleGroupPath(getModule(moduleName));
|
||||
|
||||
if (expected.length == 0) {
|
||||
assertNull(path);
|
||||
}
|
||||
else {
|
||||
assertNotNull(path);
|
||||
assertOrderedElementsAreEqual(Arrays.asList(path), expected);
|
||||
}
|
||||
}
|
||||
|
||||
protected Module getModule(final String name) {
|
||||
AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
|
||||
try {
|
||||
Module m = ModuleManager.getInstance(myProject).findModuleByName(name);
|
||||
assertNotNull("Module " + name + " not found", m);
|
||||
return m;
|
||||
}
|
||||
finally {
|
||||
accessToken.finish();
|
||||
}
|
||||
}
|
||||
|
||||
private ContentEntry getContentRoot(String moduleName) {
|
||||
ContentEntry[] ee = getContentRoots(moduleName);
|
||||
List<String> roots = new ArrayList<String>();
|
||||
for (ContentEntry e : ee) {
|
||||
roots.add(e.getUrl());
|
||||
}
|
||||
|
||||
String message = "Several content roots found: [" + StringUtil.join(roots, ", ") + "]";
|
||||
assertEquals(message, 1, ee.length);
|
||||
|
||||
return ee[0];
|
||||
}
|
||||
|
||||
private ContentEntry getContentRoot(String moduleName, String path) {
|
||||
for (ContentEntry e : getContentRoots(moduleName)) {
|
||||
if (e.getUrl().equals(VfsUtil.pathToUrl(path))) return e;
|
||||
}
|
||||
throw new AssertionError("content root not found");
|
||||
}
|
||||
|
||||
public ContentEntry[] getContentRoots(String moduleName) {
|
||||
return getRootManager(moduleName).getContentEntries();
|
||||
}
|
||||
|
||||
private ModuleRootManager getRootManager(String module) {
|
||||
return ModuleRootManager.getInstance(getModule(module));
|
||||
}
|
||||
|
||||
protected void importProject(@NonNls String xml) throws IOException {
|
||||
createProjectPom(xml);
|
||||
importProject();
|
||||
}
|
||||
|
||||
protected void importProject() {
|
||||
importProjectWithProfiles();
|
||||
}
|
||||
|
||||
protected void importProjectWithProfiles(String... profiles) {
|
||||
doImportProjects(true, Collections.singletonList(myProjectPom), profiles);
|
||||
}
|
||||
|
||||
protected void importProject(VirtualFile file) {
|
||||
importProjects(file);
|
||||
}
|
||||
|
||||
protected void importProjects(VirtualFile... files) {
|
||||
doImportProjects(true, Arrays.asList(files));
|
||||
}
|
||||
|
||||
protected void importProjectWithMaven3(@NonNls String xml) throws IOException {
|
||||
createProjectPom(xml);
|
||||
importProjectWithMaven3();
|
||||
}
|
||||
|
||||
protected void importProjectWithMaven3() {
|
||||
importProjectWithMaven3WithProfiles();
|
||||
}
|
||||
|
||||
protected void importProjectWithMaven3WithProfiles(String... profiles) {
|
||||
doImportProjects(false, Collections.singletonList(myProjectPom), profiles);
|
||||
}
|
||||
|
||||
private void doImportProjects(boolean useMaven2, final List<VirtualFile> files, String... profiles) {
|
||||
MavenServerManager.getInstance().setUseMaven2(useMaven2);
|
||||
initProjectsManager(false);
|
||||
|
||||
readProjects(files, profiles);
|
||||
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myProjectsManager.waitForResolvingCompletion();
|
||||
myProjectsManager.scheduleImportInTests(files);
|
||||
myProjectsManager.importProjects();
|
||||
}
|
||||
});
|
||||
|
||||
for (MavenProject each : myProjectsTree.getProjects()) {
|
||||
if (each.hasReadingProblems()) {
|
||||
System.out.println(each + " has problems: " + each.getProblems());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void readProjects(List<VirtualFile> files, String... profiles) {
|
||||
myProjectsManager.resetManagedFilesAndProfilesInTests(files, new MavenExplicitProfiles(Arrays.asList(profiles)));
|
||||
waitForReadingCompletion();
|
||||
}
|
||||
|
||||
protected void updateProjectsAndImport(VirtualFile... files) {
|
||||
readProjects(files);
|
||||
myProjectsManager.performScheduledImportInTests();
|
||||
}
|
||||
|
||||
protected void initProjectsManager(boolean enableEventHandling) {
|
||||
myProjectsManager.initForTests();
|
||||
myProjectsTree = myProjectsManager.getProjectsTreeForTests();
|
||||
if (enableEventHandling) myProjectsManager.listenForExternalChanges();
|
||||
}
|
||||
|
||||
protected void scheduleResolveAll() {
|
||||
myProjectsManager.scheduleResolveAllInTests();
|
||||
}
|
||||
|
||||
protected void waitForReadingCompletion() {
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myProjectsManager.waitForReadingCompletion();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void readProjects() {
|
||||
readProjects(myProjectsManager.getProjectsFiles());
|
||||
}
|
||||
|
||||
protected void readProjects(VirtualFile... files) {
|
||||
List<MavenProject> projects = new ArrayList<MavenProject>();
|
||||
for (VirtualFile each : files) {
|
||||
projects.add(myProjectsManager.findProject(each));
|
||||
}
|
||||
myProjectsManager.forceUpdateProjects(projects);
|
||||
waitForReadingCompletion();
|
||||
}
|
||||
|
||||
protected void resolveDependenciesAndImport() {
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myProjectsManager.waitForResolvingCompletion();
|
||||
myProjectsManager.performScheduledImportInTests();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void resolveFoldersAndImport() {
|
||||
myProjectsManager.scheduleFoldersResolveForAllProjects();
|
||||
myProjectsManager.waitForFoldersResolvingCompletion();
|
||||
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myProjectsManager.performScheduledImportInTests();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void resolvePlugins() {
|
||||
myProjectsManager.waitForPluginsResolvingCompletion();
|
||||
}
|
||||
|
||||
protected void downloadArtifacts() {
|
||||
downloadArtifacts(myProjectsManager.getProjects(), null);
|
||||
}
|
||||
|
||||
protected MavenArtifactDownloader.DownloadResult downloadArtifacts(
|
||||
Collection<MavenProject> projects,
|
||||
List<MavenArtifact> artifacts
|
||||
) {
|
||||
final MavenArtifactDownloader.DownloadResult[] unresolved = new MavenArtifactDownloader.DownloadResult[1];
|
||||
|
||||
AsyncResult<MavenArtifactDownloader.DownloadResult> result = new AsyncResult<MavenArtifactDownloader.DownloadResult>();
|
||||
result.doWhenDone(new Consumer<MavenArtifactDownloader.DownloadResult>() {
|
||||
@Override
|
||||
public void consume(MavenArtifactDownloader.DownloadResult unresolvedArtifacts) {
|
||||
unresolved[0] = unresolvedArtifacts;
|
||||
}
|
||||
});
|
||||
|
||||
myProjectsManager.scheduleArtifactsDownloading(projects, artifacts, true, true, result);
|
||||
myProjectsManager.waitForArtifactsDownloadingCompletion();
|
||||
|
||||
return unresolved[0];
|
||||
}
|
||||
|
||||
protected void performPostImportTasks() {
|
||||
myProjectsManager.waitForPostImportTasksCompletion();
|
||||
}
|
||||
|
||||
protected void executeGoal(String relativePath, String goal) {
|
||||
VirtualFile dir = myProjectRoot.findFileByRelativePath(relativePath);
|
||||
|
||||
MavenRunnerParameters rp = new MavenRunnerParameters(true, dir.getPath(), Arrays.asList(goal), Collections.<String>emptyList());
|
||||
MavenRunnerSettings rs = new MavenRunnerSettings();
|
||||
MavenExecutor e = new MavenExternalExecutor(myProject, rp, getMavenGeneralSettings(), rs, new SoutMavenConsole());
|
||||
|
||||
e.execute(new EmptyProgressIndicator());
|
||||
}
|
||||
|
||||
protected void removeFromLocalRepository(String relativePath) throws IOException {
|
||||
FileUtil.delete(new File(getRepositoryPath(), relativePath));
|
||||
}
|
||||
|
||||
protected void setupJdkForModules(String... moduleNames) {
|
||||
for (String each : moduleNames) {
|
||||
setupJdkForModule(each);
|
||||
}
|
||||
}
|
||||
|
||||
protected Sdk setupJdkForModule(final String moduleName) {
|
||||
final Sdk sdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
|
||||
ModuleRootModificationUtil.setModuleSdk(getModule(moduleName), sdk);
|
||||
return sdk;
|
||||
}
|
||||
|
||||
protected static Sdk createJdk(String versionName) {
|
||||
return IdeaTestUtil.getMockJdk17(versionName);
|
||||
}
|
||||
|
||||
protected static AtomicInteger configConfirmationForYesAnswer() {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
Messages.setTestDialog(new TestDialog() {
|
||||
@Override
|
||||
public int show(String message) {
|
||||
counter.set(counter.get() + 1);
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
return counter;
|
||||
}
|
||||
|
||||
protected static AtomicInteger configConfirmationForNoAnswer() {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
Messages.setTestDialog(new TestDialog() {
|
||||
@Override
|
||||
public int show(String message) {
|
||||
counter.set(counter.get() + 1);
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
return counter;
|
||||
}
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger
|
||||
|
||||
import com.intellij.debugger.engine.JavaStackFrame
|
||||
import com.intellij.debugger.engine.SuspendContextImpl
|
||||
import com.intellij.debugger.memory.utils.StackFrameItem
|
||||
|
||||
interface KotlinCoroutinesAsyncStackTraceProviderBase {
|
||||
fun getAsyncStackTrace(stackFrame: JavaStackFrame, suspendContext: SuspendContextImpl): List<StackFrameItem>?
|
||||
}
|
||||
-19
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.debugger.breakpoints
|
||||
|
||||
import com.intellij.debugger.engine.DebugProcessImpl
|
||||
import com.intellij.openapi.progress.util.ProgressWindow
|
||||
import com.intellij.xdebugger.XDebuggerManager
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpoint
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpointListener
|
||||
|
||||
object BreakpointListenerConnector {
|
||||
@JvmStatic
|
||||
fun subscribe(debugProcess: DebugProcessImpl, indicator: ProgressWindow, listener: XBreakpointListener<XBreakpoint<*>>) {
|
||||
XDebuggerManager.getInstance(debugProcess.project).breakpointManager.addBreakpointListener(listener, indicator)
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.testFramework
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionType
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
|
||||
|
||||
class Fixture(val project: Project, val editor: Editor, val vFile: VirtualFile) {
|
||||
|
||||
val document: Document
|
||||
get() = TODO()
|
||||
|
||||
fun doHighlighting(): List<HighlightInfo> = TODO()
|
||||
|
||||
fun type(s: String) {
|
||||
TODO()
|
||||
}
|
||||
|
||||
fun complete(type: CompletionType = CompletionType.BASIC, invocationCount: Int = 1): Array<LookupElement> =
|
||||
TODO()
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.testFramework
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.project.ex.ProjectManagerEx
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.impl.PsiDocumentManagerBase
|
||||
import com.intellij.testFramework.EdtTestUtil
|
||||
import com.intellij.testFramework.runInEdtAndWait
|
||||
import com.intellij.util.ThrowableRunnable
|
||||
import com.intellij.util.ui.UIUtil
|
||||
import org.jetbrains.kotlin.idea.parameterInfo.HintType
|
||||
|
||||
fun commitAllDocuments() {
|
||||
ProjectManagerEx.getInstanceEx().openProjects.forEach { project ->
|
||||
val psiDocumentManagerBase = PsiDocumentManager.getInstance(project) as PsiDocumentManagerBase
|
||||
|
||||
EdtTestUtil.runInEdtAndWait(ThrowableRunnable {
|
||||
psiDocumentManagerBase.clearUncommittedDocuments()
|
||||
psiDocumentManagerBase.commitAllDocuments()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun commitDocument(project: Project, document: Document) {
|
||||
val psiDocumentManagerBase = PsiDocumentManager.getInstance(project) as PsiDocumentManagerBase
|
||||
|
||||
EdtTestUtil.runInEdtAndWait(ThrowableRunnable {
|
||||
psiDocumentManagerBase.commitDocument(document)
|
||||
})
|
||||
}
|
||||
|
||||
fun saveDocument(document: Document) {
|
||||
val fileDocumentManager = FileDocumentManager.getInstance()
|
||||
|
||||
runInEdtAndWait {
|
||||
fileDocumentManager.saveDocument(document)
|
||||
}
|
||||
}
|
||||
|
||||
fun enableHints(enable: Boolean) =
|
||||
HintType.values().forEach { it.option.set(enable) }
|
||||
|
||||
fun dispatchAllInvocationEvents() {
|
||||
runInEdtAndWait {
|
||||
UIUtil.dispatchAllInvocationEvents()
|
||||
}
|
||||
}
|
||||
|
||||
fun closeProject(project: Project) {
|
||||
dispatchAllInvocationEvents()
|
||||
val projectManagerEx = ProjectManagerEx.getInstanceEx()
|
||||
projectManagerEx.closeAndDispose(project)
|
||||
}
|
||||
|
||||
fun waitForAllEditorsFinallyLoaded(project: Project) {
|
||||
// 182 does not have this public api
|
||||
}
|
||||
|
||||
fun replaceWithCustomHighlighter(parentDisposable: Disposable, fromImplementationClass: String, toImplementationClass: String) {
|
||||
// 182 does not have this public api
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
<idea-plugin>
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.platformGradleDetector"
|
||||
interface="org.jetbrains.kotlin.idea.inspections.gradle.KotlinPlatformGradleDetector"/>
|
||||
</extensionPoints>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.JvmPluginStartupComponent</implementation-class>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
<project-components>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.compiler.KotlinCompilerManager</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.configuration.ui.KotlinConfigurationCheckerComponent</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<implementation-class>org.jetbrains.kotlin.idea.scratch.ScratchFileModuleInfoProvider</implementation-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<actions>
|
||||
<!-- Kotlin Console REPL-->
|
||||
<action id="KotlinConsoleREPL" class="org.jetbrains.kotlin.console.actions.RunKotlinConsoleAction"
|
||||
text="Kotlin REPL"
|
||||
icon="/org/jetbrains/kotlin/idea/icons/kotlin_launch_configuration.png">
|
||||
<add-to-group group-id="KotlinToolsGroup" anchor="last"/>
|
||||
</action>
|
||||
|
||||
<action id="ConfigureKotlinInProject" class="org.jetbrains.kotlin.idea.actions.ConfigureKotlinJavaInProjectAction"
|
||||
text="Configure Kotlin in Project">
|
||||
<add-to-group group-id="KotlinToolsGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="ConfigureKotlinJsInProject" class="org.jetbrains.kotlin.idea.actions.ConfigureKotlinJsInProjectAction"
|
||||
text="Configure Kotlin (JavaScript) in Project">
|
||||
<add-to-group group-id="KotlinToolsGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="ShowKotlinBytecode" class="org.jetbrains.kotlin.idea.actions.ShowKotlinBytecodeAction"
|
||||
text="Show Kotlin Bytecode">
|
||||
<add-to-group group-id="KotlinToolsGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="CreateIncrementalCompilationBackup"
|
||||
class="org.jetbrains.kotlin.idea.internal.makeBackup.CreateIncrementalCompilationBackup" internal="true">
|
||||
<add-to-group group-id="KotlinInternalGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="ReactivePostOpenProjectActionsAction" class="org.jetbrains.kotlin.idea.actions.internal.ReactivePostOpenProjectActionsAction"
|
||||
text="Kotlin Project Post-Open Activity" internal="true">
|
||||
<add-to-group group-id="KotlinInternalGroup"/>
|
||||
</action>
|
||||
|
||||
<action id="AddToProblemApiInspection" class="org.jetbrains.kotlin.idea.inspections.api.AddIncompatibleApiAction"
|
||||
text="Report as incompatible API">
|
||||
</action>
|
||||
|
||||
<group id="Kotlin.XDebugger.Actions">
|
||||
<action id="Kotlin.XDebugger.ToggleKotlinVariableView"
|
||||
class="org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesView"
|
||||
icon="/org/jetbrains/kotlin/idea/icons/kotlin.png"
|
||||
text="Show Kotlin variables only"
|
||||
/>
|
||||
</group>
|
||||
|
||||
<group id="Kotlin.XDebugger.Watches.Tree.Toolbar">
|
||||
<reference ref="Kotlin.XDebugger.ToggleKotlinVariableView"/>
|
||||
<add-to-group group-id="XDebugger.Watches.Tree.Toolbar" relative-to-action="XDebugger.SwitchWatchesInVariables" anchor="after"/>
|
||||
</group>
|
||||
|
||||
<action id="InspectBreakpointApplicability" class="org.jetbrains.kotlin.idea.debugger.breakpoints.InspectBreakpointApplicabilityAction"
|
||||
text="Inspect Breakpoint Applicability" internal="true">
|
||||
<add-to-group group-id="KotlinInternalGroup"/>
|
||||
</action>
|
||||
</actions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.console.KotlinConsoleKeeper"
|
||||
serviceImplementation="org.jetbrains.kotlin.console.KotlinConsoleKeeper"/>
|
||||
|
||||
<buildProcess.parametersProvider implementation="org.jetbrains.kotlin.idea.compiler.configuration.KotlinBuildProcessParametersProvider"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinDebuggerCaches"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.scratch.ScratchFileAutoRunner"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.scratch.ScratchFileAutoRunner"/>
|
||||
|
||||
<projectService serviceImplementation="org.jetbrains.kotlin.idea.versions.SuppressNotificationState"/>
|
||||
|
||||
<applicationService serviceImplementation="org.jetbrains.kotlin.idea.debugger.ToggleKotlinVariablesState"/>
|
||||
|
||||
<debugger.jvmSmartStepIntoHandler implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSmartStepIntoHandler"/>
|
||||
<debugger.positionManagerFactory implementation="org.jetbrains.kotlin.idea.debugger.KotlinPositionManagerFactory"/>
|
||||
<debugger.codeFragmentFactory implementation="org.jetbrains.kotlin.idea.debugger.evaluate.KotlinCodeFragmentFactory"/>
|
||||
<debuggerEditorTextProvider language="kotlin" implementationClass="org.jetbrains.kotlin.idea.debugger.KotlinEditorTextProvider"/>
|
||||
<debuggerClassFilterProvider implementation="org.jetbrains.kotlin.idea.debugger.filter.KotlinDebuggerInternalClassesFilterProvider"/>
|
||||
<debugger.nodeRenderer implementation="org.jetbrains.kotlin.idea.debugger.render.KotlinClassWithDelegatedPropertyRenderer"/>
|
||||
<debugger.sourcePositionProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinSourcePositionProvider"/>
|
||||
<debugger.sourcePositionHighlighter implementation="org.jetbrains.kotlin.idea.debugger.KotlinSourcePositionHighlighter"/>
|
||||
<debugger.frameExtraVarsProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinFrameExtraVariablesProvider"/>
|
||||
<debugger.extraSteppingFilter implementation="org.jetbrains.kotlin.idea.KotlinExtraSteppingFilter"/>
|
||||
<xdebugger.settings implementation="org.jetbrains.kotlin.idea.debugger.KotlinDebuggerSettings"/>
|
||||
<xdebugger.breakpointType implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpointType"/>
|
||||
<xdebugger.breakpointType implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinLineBreakpointType" order="first"/>
|
||||
<xdebugger.breakpointType implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFunctionBreakpointType"/>
|
||||
<debugger.syntheticProvider implementation="org.jetbrains.kotlin.idea.debugger.filter.KotlinSyntheticTypeComponentProvider"/>
|
||||
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFieldBreakpointHandlerFactory"/>
|
||||
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinLineBreakpointHandlerFactory"/>
|
||||
<debugger.javaBreakpointHandlerFactory implementation="org.jetbrains.kotlin.idea.debugger.breakpoints.KotlinFunctionBreakpointHandlerFactory"/>
|
||||
<debugger.jvmSteppingCommandProvider implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSteppingCommandProvider"/>
|
||||
<debugger.simplePropertyGetterProvider implementation="org.jetbrains.kotlin.idea.debugger.stepping.KotlinSimpleGetterProvider"/>
|
||||
|
||||
<framework.type implementation="org.jetbrains.kotlin.idea.framework.JavaFrameworkType"/>
|
||||
<projectTemplatesFactory implementation="org.jetbrains.kotlin.idea.framework.KotlinTemplatesFactory" />
|
||||
|
||||
<library.presentationProvider implementation="org.jetbrains.kotlin.idea.framework.JavaRuntimePresentationProvider"/>
|
||||
|
||||
<configurationType implementation="org.jetbrains.kotlin.idea.run.KotlinRunConfigurationType"/>
|
||||
<configurationType implementation="org.jetbrains.kotlin.idea.run.script.standalone.KotlinStandaloneScriptRunConfigurationType"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.KotlinRunConfigurationProducer"/>
|
||||
<runConfigurationProducer implementation="org.jetbrains.kotlin.idea.run.script.standalone.KotlinStandaloneScriptRunConfigurationProducer"/>
|
||||
|
||||
<library.type implementation="org.jetbrains.kotlin.idea.framework.JSLibraryType"/>
|
||||
<library.javaSourceRootDetector implementation="org.jetbrains.kotlin.idea.configuration.KotlinSourceRootDetector"/>
|
||||
|
||||
<multipleRunLocationsProvider implementation="org.jetbrains.kotlin.idea.run.multiplatform.KotlinMultiplatformRunLocationsProvider"/>
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.configuration.KotlinSetupEnvironmentNotificationProvider"/>
|
||||
<postStartupActivity implementation="org.jetbrains.kotlin.idea.configuration.JvmStartupActivity"/>
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinAlternativeSourceNotificationProvider"/>
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.inspections.JavaOutsideModuleDetector"/>
|
||||
|
||||
<consoleFilterProvider implementation="org.jetbrains.kotlin.idea.run.KotlinConsoleFilterProvider"/>
|
||||
|
||||
<exceptionFilter implementation="org.jetbrains.kotlin.idea.filters.KotlinExceptionFilterFactory" order="first"/>
|
||||
|
||||
<externalSystemTaskNotificationListener implementation="org.jetbrains.kotlin.idea.configuration.KotlinExternalSystemSyncListener"/>
|
||||
|
||||
<lang.surroundDescriptor language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.debugger.evaluate.surroundWith.KotlinDebuggerExpressionSurroundDescriptor"/>
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.versions.UnsupportedAbiVersionNotificationPanelProvider"/>
|
||||
|
||||
<scratch.creationHelper language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.scratch.KtScratchFileCreationHelper"/>
|
||||
<runLineMarkerContributor language="kotlin"
|
||||
implementationClass="org.jetbrains.kotlin.idea.scratch.actions.ScratchRunLineMarkerContributor"/>
|
||||
|
||||
<localInspection
|
||||
groupName="Plugin DevKit"
|
||||
shortName="IncompatibleAPI"
|
||||
enabledByDefault="false"
|
||||
level="ERROR"
|
||||
displayName="Incompatible API usage"
|
||||
implementationClass="org.jetbrains.kotlin.idea.inspections.api.IncompatibleAPIInspection"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.uast.kotlin.KotlinUastResolveProviderService"
|
||||
serviceImplementation="org.jetbrains.uast.kotlin.internal.IdeaKotlinUastResolveProviderService"/>
|
||||
|
||||
<applicationService
|
||||
serviceInterface="org.jetbrains.kotlin.platform.DefaultIdeTargetPlatformKindProvider"
|
||||
serviceImplementation="org.jetbrains.kotlin.platform.impl.IdeaDefaultIdeTargetPlatformKindProvider"/>
|
||||
|
||||
<applicationService
|
||||
serviceInterface="org.jetbrains.kotlin.idea.j2k.J2KPostProcessingRegistrar"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.j2k.J2KPostProcessingRegistrarImpl"/>
|
||||
|
||||
<registryKey key="kotlin.use.ultra.light.classes"
|
||||
description="Whether to use an experimental implementation of Kotlin-as-Java classes"
|
||||
defaultValue="false"
|
||||
restartRequired="false"/>
|
||||
|
||||
<registryKey key="kotlin.uast.multiresolve.enabled"
|
||||
description="Whether to use multi resolve for UAST in Kotlin provided by `Call.resolveCandidates`, otherwise PsiPolyVariantReference-based multiResolve will be performed"
|
||||
defaultValue="true"
|
||||
restartRequired="false"/>
|
||||
|
||||
<registryKey key="kotlin.jps.instrument.bytecode"
|
||||
description="Enable bytecode instrumentation for Kotlin classes"
|
||||
defaultValue="false"
|
||||
restartRequired="false"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.uast">
|
||||
<uastLanguagePlugin implementation="org.jetbrains.uast.kotlin.KotlinUastLanguagePlugin"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
<diagnosticSuppressor implementation="org.jetbrains.kotlin.idea.debugger.DiagnosticSuppressorForDebugger"/>
|
||||
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.samWithReceiver.ide.IdeSamWithReceiverComponentContributor"/>
|
||||
|
||||
<declarationAttributeAltererExtension implementation="org.jetbrains.kotlin.allopen.ide.IdeAllOpenDeclarationAttributeAltererExtension"/>
|
||||
|
||||
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.noarg.ide.IdeNoArgComponentContainerContributor"/>
|
||||
<expressionCodegenExtension implementation="org.jetbrains.kotlin.noarg.NoArgExpressionCodegenExtension"/>
|
||||
<defaultErrorMessages implementation="org.jetbrains.kotlin.noarg.diagnostic.DefaultErrorMessagesNoArg"/>
|
||||
|
||||
<completionExtension implementation="org.jetbrains.kotlin.idea.properties.PropertyKeyCompletion"/>
|
||||
<newFileHook implementation="org.jetbrains.kotlin.idea.configuration.NewKotlinFileConfigurationHook"/>
|
||||
<quickFixContributor implementation="org.jetbrains.kotlin.idea.quickfix.JvmQuickFixRegistrar"/>
|
||||
<clearBuildState implementation="org.jetbrains.kotlin.idea.compiler.configuration.ClearBuildManagerState"/>
|
||||
<facetValidatorCreator implementation="org.jetbrains.kotlin.idea.facet.KotlinLibraryValidatorCreator"/>
|
||||
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleJavaFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJavaFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJSFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleGroovyFrameworkSupportProvider" />
|
||||
|
||||
<syntheticScopeProviderExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldSyntheticScopeProvider"/>
|
||||
<expressionCodegenExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldExpressionCodegenExtension"/>
|
||||
<completionInformationProvider implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldCompletionInformationProvider" />
|
||||
<kotlinIndicesHelperExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldKotlinIndicesHelperExtension"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -1,80 +0,0 @@
|
||||
<idea-plugin xmlns:xi="http://www.w3.org/2001/XInclude" version="2" url="http://kotlinlang.org" allow-bundled-update="true">
|
||||
<id>org.jetbrains.kotlin</id>
|
||||
|
||||
<name>Kotlin</name>
|
||||
<description><![CDATA[
|
||||
The Kotlin plugin provides language support in IntelliJ IDEA and Android Studio.
|
||||
<br>
|
||||
<a href="http://kotlinlang.org/docs/tutorials/getting-started.html">Getting Started in IntelliJ IDEA</a><br>
|
||||
<a href="http://kotlinlang.org/docs/tutorials/kotlin-android.html">Getting Started in Android Studio</a><br>
|
||||
<a href="http://slack.kotlinlang.org/">Public Slack</a><br>
|
||||
<a href="https://youtrack.jetbrains.com/issues/KT">Issue tracker</a><br>
|
||||
]]></description>
|
||||
<version>@snapshot@</version>
|
||||
<vendor url="http://www.jetbrains.com">JetBrains</vendor>
|
||||
|
||||
<idea-version since-build="182.4323.46" until-build="182.*"/>
|
||||
|
||||
<depends>com.intellij.modules.platform</depends>
|
||||
|
||||
<depends optional="true" config-file="junit.xml">JUnit</depends>
|
||||
<depends optional="true" config-file="gradle.xml">org.jetbrains.plugins.gradle</depends>
|
||||
<depends optional="true" config-file="gradle-java.xml">org.jetbrains.plugins.gradle.java</depends>
|
||||
<depends optional="true" config-file="gradle-groovy.xml">org.intellij.groovy</depends>
|
||||
<depends optional="true" config-file="maven.xml">org.jetbrains.idea.maven</depends>
|
||||
<depends optional="true" config-file="testng-j.xml">TestNG-J</depends>
|
||||
<depends optional="true" config-file="android.xml">org.jetbrains.android</depends>
|
||||
<depends optional="true" config-file="coverage.xml">Coverage</depends>
|
||||
<depends optional="true" config-file="i18n.xml">com.intellij.java-i18n</depends>
|
||||
<depends optional="true" config-file="decompiler.xml">org.jetbrains.java.decompiler</depends>
|
||||
<depends optional="true" config-file="git4idea.xml">Git4Idea</depends>
|
||||
<depends optional="true" config-file="stream-debugger.xml">org.jetbrains.debugger.streams</depends>
|
||||
|
||||
<!-- ULTIMATE-PLUGIN-PLACEHOLDER -->
|
||||
|
||||
<!-- CIDR-PLUGIN-PLACEHOLDER-START -->
|
||||
<depends>com.intellij.modules.idea</depends>
|
||||
<depends>com.intellij.modules.java</depends>
|
||||
<depends optional="true" config-file="javaScriptDebug.xml">JavaScriptDebugger</depends>
|
||||
<depends optional="true" config-file="kotlin-copyright.xml">com.intellij.copyright</depends>
|
||||
<depends optional="true" config-file="injection.xml">org.intellij.intelliLang</depends>
|
||||
<!-- CIDR-PLUGIN-PLACEHOLDER-END -->
|
||||
|
||||
<xi:include href="plugin-common.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<!-- CIDR-PLUGIN-EXCLUDE-START -->
|
||||
<xi:include href="jvm.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<!-- CIDR-PLUGIN-EXCLUDE-END -->
|
||||
|
||||
<xi:include href="native.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
<xi:include href="tipsAndTricks.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="extensions/ide.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<xi:include href="kotlinx-serialization.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<project-components>
|
||||
<component>
|
||||
<!-- This is a workaround for IDEA < 183. For details, see IDEA-200525. -->
|
||||
<implementation-class>org.jetbrains.kotlin.idea.caches.ProjectRootModificationTrackerFixer</implementation-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<extensionPoints>
|
||||
<xi:include href="extensions/compiler.xml" xpointer="xpointer(/idea-plugin/extensionPoints/*)"/>
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.pluginUpdateVerifier"
|
||||
interface="org.jetbrains.kotlin.idea.update.PluginUpdateVerifier"/>
|
||||
</extensionPoints>
|
||||
|
||||
<xi:include href="plugin-kotlin-extensions.xml" xpointer="xpointer(/idea-plugin/*)"/>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij.jvm">
|
||||
<declarationSearcher language="kotlin" implementationClass="org.jetbrains.kotlin.idea.jvm.KotlinDeclarationSearcher"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.core.script.ScriptModificationListener"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea
|
||||
|
||||
import com.intellij.openapi.util.IconLoader
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import com.intellij.psi.impl.ElementPresentationUtil
|
||||
import com.intellij.util.PlatformIcons
|
||||
import javax.swing.Icon
|
||||
|
||||
class KotlinIdeFileIconProviderService : KotlinIconProviderService() {
|
||||
override fun getFileIcon(): Icon = KOTLIN_FILE
|
||||
|
||||
override fun getLightVariableIcon(element: PsiModifierListOwner, flags: Int): Icon {
|
||||
val baseIcon = ElementPresentationUtil.createLayeredIcon(PlatformIcons.VARIABLE_ICON, element, false)
|
||||
return ElementPresentationUtil.addVisibilityIcon(element, flags, baseIcon)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val KOTLIN_FILE = IconLoader.getIcon("/org/jetbrains/kotlin/idea/icons/kotlin_file.png")
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.highlighter.markers
|
||||
|
||||
import com.intellij.icons.AllIcons
|
||||
import javax.swing.Icon
|
||||
|
||||
// BUNCH: 182
|
||||
// BUNCH: as35
|
||||
// BUNCH: as34
|
||||
internal fun createDslStyleIcon(styleId: Int): Icon {
|
||||
return AllIcons.Gutter.Colors
|
||||
}
|
||||
-535
@@ -1,535 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.quickfix.crossLanguage
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory
|
||||
import com.intellij.lang.java.beans.PropertyKind
|
||||
import com.intellij.lang.jvm.*
|
||||
import com.intellij.lang.jvm.actions.*
|
||||
import com.intellij.lang.jvm.types.JvmType
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.text.StringUtilRt
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo
|
||||
import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl
|
||||
import com.intellij.psi.util.PropertyUtil
|
||||
import com.intellij.psi.util.PropertyUtilBase
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.toLightMethods
|
||||
import org.jetbrains.kotlin.asJava.unwrapped
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.core.appendModifier
|
||||
import org.jetbrains.kotlin.idea.quickfix.AddModifierFix
|
||||
import org.jetbrains.kotlin.idea.quickfix.RemoveModifierFix
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.*
|
||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createCallable.CreateCallableFromUsageFix
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
||||
import org.jetbrains.kotlin.load.java.lazy.JavaResolverComponents
|
||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||
import org.jetbrains.kotlin.load.java.lazy.TypeParameterResolver
|
||||
import org.jetbrains.kotlin.load.java.lazy.child
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeAttributes
|
||||
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeImpl
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaTypeParameterImpl
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
import org.jetbrains.kotlin.psi.psiUtil.visibilityModifierType
|
||||
import org.jetbrains.kotlin.resolve.AnnotationChecker
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||
|
||||
class KotlinElementActionsFactory : JvmElementActionsFactory() {
|
||||
companion object {
|
||||
val javaPsiModifiersMapping = mapOf(
|
||||
JvmModifier.PRIVATE to KtTokens.PRIVATE_KEYWORD,
|
||||
JvmModifier.PUBLIC to KtTokens.PUBLIC_KEYWORD,
|
||||
JvmModifier.PROTECTED to KtTokens.PUBLIC_KEYWORD,
|
||||
JvmModifier.ABSTRACT to KtTokens.ABSTRACT_KEYWORD
|
||||
)
|
||||
}
|
||||
|
||||
private class FakeExpressionFromParameter(private val psiParam: PsiParameter) : PsiReferenceExpressionImpl() {
|
||||
override fun getText(): String = psiParam.name!!
|
||||
override fun getProject(): Project = psiParam.project
|
||||
override fun getParent(): PsiElement = psiParam.parent
|
||||
override fun getType(): PsiType? = psiParam.type
|
||||
override fun isValid(): Boolean = true
|
||||
override fun getContainingFile(): PsiFile = psiParam.containingFile
|
||||
override fun getReferenceName(): String? = psiParam.name
|
||||
override fun resolve(): PsiElement? = psiParam
|
||||
}
|
||||
|
||||
private class ModifierBuilder(
|
||||
private val targetContainer: KtElement,
|
||||
private val allowJvmStatic: Boolean = true
|
||||
) {
|
||||
private val psiFactory = KtPsiFactory(targetContainer.project)
|
||||
|
||||
val modifierList = psiFactory.createEmptyModifierList()
|
||||
|
||||
private fun JvmModifier.transformAndAppend(): Boolean {
|
||||
javaPsiModifiersMapping[this]?.let {
|
||||
modifierList.appendModifier(it)
|
||||
return true
|
||||
}
|
||||
|
||||
when (this) {
|
||||
JvmModifier.STATIC -> {
|
||||
if (allowJvmStatic && targetContainer is KtClassOrObject) {
|
||||
addAnnotation(JVM_STATIC_ANNOTATION_FQ_NAME)
|
||||
}
|
||||
}
|
||||
JvmModifier.ABSTRACT -> modifierList.appendModifier(KtTokens.ABSTRACT_KEYWORD)
|
||||
JvmModifier.FINAL -> modifierList.appendModifier(KtTokens.FINAL_KEYWORD)
|
||||
else -> return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
var isValid = true
|
||||
private set
|
||||
|
||||
fun addJvmModifier(modifier: JvmModifier) {
|
||||
isValid = isValid && modifier.transformAndAppend()
|
||||
}
|
||||
|
||||
fun addJvmModifiers(modifiers: Iterable<JvmModifier>) {
|
||||
modifiers.forEach { addJvmModifier(it) }
|
||||
}
|
||||
|
||||
fun addAnnotation(fqName: FqName) {
|
||||
if (!isValid) return
|
||||
modifierList.add(psiFactory.createAnnotationEntry("@${fqName.asString()}"))
|
||||
}
|
||||
}
|
||||
|
||||
class CreatePropertyFix(
|
||||
contextElement: KtElement,
|
||||
propertyInfo: PropertyInfo,
|
||||
private val classOrFileName: String?
|
||||
) : CreateCallableFromUsageFix<KtElement>(contextElement, listOf(propertyInfo)) {
|
||||
override fun getFamilyName() = "Add property"
|
||||
override fun getText(): String {
|
||||
val info = callableInfos.first() as PropertyInfo
|
||||
return buildString {
|
||||
append("Add '")
|
||||
if (info.isLateinitPreferred || info.modifierList?.hasModifier(KtTokens.LATEINIT_KEYWORD) == true) {
|
||||
append("lateinit ")
|
||||
}
|
||||
append(if (info.writable) "var" else "val")
|
||||
append("' property '${info.name}' to '$classOrFileName'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun JvmClass.toKtClassOrFile(): KtElement? {
|
||||
val psi = sourceElement
|
||||
return when (psi) {
|
||||
is KtClassOrObject -> psi
|
||||
is KtLightClassForSourceDeclaration -> psi.kotlinOrigin
|
||||
is KtLightClassForFacade -> psi.files.firstOrNull()
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <reified T : KtElement> JvmElement.toKtElement() = sourceElement?.unwrapped as? T
|
||||
|
||||
private fun fakeParametersExpressions(parameters: List<Pair<SuggestedNameInfo, List<ExpectedType>>>, project: Project): Array<PsiExpression>? =
|
||||
when {
|
||||
parameters.isEmpty() -> emptyArray()
|
||||
else -> JavaPsiFacade
|
||||
.getElementFactory(project)
|
||||
.createParameterList(
|
||||
parameters.map { it.first.names.firstOrNull() }.toTypedArray(),
|
||||
parameters.map { JvmPsiConversionHelper.getInstance(project).asPsiType(it) ?: return null }.toTypedArray()
|
||||
)
|
||||
.parameters
|
||||
.map(::FakeExpressionFromParameter)
|
||||
.toTypedArray()
|
||||
}
|
||||
|
||||
private fun PsiType.collectTypeParameters(): List<PsiTypeParameter> {
|
||||
val results = ArrayList<PsiTypeParameter>()
|
||||
accept(
|
||||
object : PsiTypeVisitor<Unit>() {
|
||||
override fun visitArrayType(arrayType: PsiArrayType) {
|
||||
arrayType.componentType.accept(this)
|
||||
}
|
||||
|
||||
override fun visitClassType(classType: PsiClassType) {
|
||||
(classType.resolve() as? PsiTypeParameter)?.let { results += it }
|
||||
classType.parameters.forEach { it.accept(this) }
|
||||
}
|
||||
|
||||
override fun visitWildcardType(wildcardType: PsiWildcardType) {
|
||||
wildcardType.bound?.accept(this)
|
||||
}
|
||||
}
|
||||
)
|
||||
return results
|
||||
}
|
||||
|
||||
private fun PsiType.resolveToKotlinType(resolutionFacade: ResolutionFacade): KotlinType? {
|
||||
val typeParameters = collectTypeParameters()
|
||||
val components = resolutionFacade.getFrontendService(JavaResolverComponents::class.java)
|
||||
val rootContext = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY) { null }
|
||||
val dummyPackageDescriptor = MutablePackageFragmentDescriptor(resolutionFacade.moduleDescriptor, FqName("dummy"))
|
||||
val dummyClassDescriptor = ClassDescriptorImpl(
|
||||
dummyPackageDescriptor,
|
||||
Name.identifier("Dummy"),
|
||||
Modality.FINAL,
|
||||
ClassKind.CLASS,
|
||||
emptyList(),
|
||||
SourceElement.NO_SOURCE,
|
||||
false,
|
||||
LockBasedStorageManager.NO_LOCKS
|
||||
)
|
||||
val typeParameterResolver = object : TypeParameterResolver {
|
||||
override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? {
|
||||
val psiTypeParameter = (javaTypeParameter as JavaTypeParameterImpl).psi
|
||||
val index = typeParameters.indexOf(psiTypeParameter)
|
||||
if (index < 0) return null
|
||||
return LazyJavaTypeParameterDescriptor(rootContext.child(this), javaTypeParameter, index, dummyClassDescriptor)
|
||||
}
|
||||
}
|
||||
val typeResolver = JavaTypeResolver(rootContext, typeParameterResolver)
|
||||
val attributes = JavaTypeAttributes(TypeUsage.COMMON)
|
||||
return typeResolver.transformJavaType(JavaTypeImpl.create(this), attributes).approximateFlexibleTypes(preferNotNull = true)
|
||||
}
|
||||
|
||||
private fun ExpectedTypes.toKotlinTypeInfo(resolutionFacade: ResolutionFacade): TypeInfo {
|
||||
val candidateTypes = flatMapTo(LinkedHashSet<KotlinType>()) {
|
||||
val ktType = (it.theType as? PsiType)?.resolveToKotlinType(resolutionFacade) ?: return@flatMapTo emptyList()
|
||||
when (it.theKind) {
|
||||
ExpectedType.Kind.EXACT, ExpectedType.Kind.SUBTYPE -> listOf(ktType)
|
||||
ExpectedType.Kind.SUPERTYPE -> listOf(ktType) + ktType.supertypes()
|
||||
}
|
||||
}
|
||||
if (candidateTypes.isEmpty()) {
|
||||
val nullableAnyType = resolutionFacade.moduleDescriptor.builtIns.nullableAnyType
|
||||
return TypeInfo(nullableAnyType, Variance.INVARIANT)
|
||||
}
|
||||
return TypeInfo.ByExplicitCandidateTypes(candidateTypes.toList())
|
||||
}
|
||||
|
||||
override fun createChangeModifierActions(target: JvmModifiersOwner, request: MemberRequest.Modifier): List<IntentionAction> {
|
||||
val kModifierOwner = target.toKtElement<KtModifierListOwner>() ?: return emptyList()
|
||||
|
||||
val modifier = request.modifier
|
||||
val shouldPresent = request.shouldPresent
|
||||
//TODO: make similar to `createAddMethodActions`
|
||||
val (kToken, shouldPresentMapped) = when {
|
||||
modifier == JvmModifier.FINAL -> KtTokens.OPEN_KEYWORD to !shouldPresent
|
||||
modifier == JvmModifier.PUBLIC && shouldPresent ->
|
||||
kModifierOwner.visibilityModifierType()
|
||||
?.takeIf { it != KtTokens.DEFAULT_VISIBILITY_KEYWORD }
|
||||
?.let { it to false } ?: return emptyList()
|
||||
else -> javaPsiModifiersMapping[modifier] to shouldPresent
|
||||
}
|
||||
if (kToken == null) return emptyList()
|
||||
|
||||
val action = if (shouldPresentMapped)
|
||||
AddModifierFix.createIfApplicable(kModifierOwner, kToken)
|
||||
else
|
||||
RemoveModifierFix(kModifierOwner, kToken, false)
|
||||
return listOfNotNull(action)
|
||||
}
|
||||
|
||||
override fun createAddConstructorActions(targetClass: JvmClass, request: CreateConstructorRequest): List<IntentionAction> {
|
||||
val targetKtClass = targetClass.toKtClassOrFile() as? KtClass ?: return emptyList()
|
||||
|
||||
val modifierBuilder = ModifierBuilder(targetKtClass).apply { addJvmModifiers(request.modifiers) }
|
||||
if (!modifierBuilder.isValid) return emptyList()
|
||||
val resolutionFacade = targetKtClass.getResolutionFacade()
|
||||
val nullableAnyType = resolutionFacade.moduleDescriptor.builtIns.nullableAnyType
|
||||
val helper = JvmPsiConversionHelper.getInstance(targetKtClass.project)
|
||||
val parameters = request.parameters as List<Pair<SuggestedNameInfo, List<ExpectedType>>>
|
||||
val parameterInfos = parameters.mapIndexed { index, param: Pair<SuggestedNameInfo, List<ExpectedType>> ->
|
||||
val ktType = helper.asPsiType(param)?.resolveToKotlinType(resolutionFacade) ?: nullableAnyType
|
||||
val name = param.first.names.firstOrNull() ?: "arg${index + 1}"
|
||||
ParameterInfo(TypeInfo(ktType, Variance.IN_VARIANCE), listOf(name))
|
||||
}
|
||||
val needPrimary = !targetKtClass.hasExplicitPrimaryConstructor()
|
||||
val constructorInfo = ConstructorInfo(
|
||||
parameterInfos,
|
||||
targetKtClass,
|
||||
isPrimary = needPrimary,
|
||||
modifierList = modifierBuilder.modifierList,
|
||||
withBody = true
|
||||
)
|
||||
val targetClassName = targetClass.name
|
||||
val addConstructorAction = object : CreateCallableFromUsageFix<KtElement>(targetKtClass, listOf(constructorInfo)) {
|
||||
override fun getFamilyName() = "Add method"
|
||||
override fun getText() = "Add ${if (needPrimary) "primary" else "secondary"} constructor to '$targetClassName'"
|
||||
}
|
||||
|
||||
val changePrimaryConstructorAction = run {
|
||||
val primaryConstructor = targetKtClass.primaryConstructor ?: return@run null
|
||||
val lightMethod = primaryConstructor.toLightMethods().firstOrNull() ?: return@run null
|
||||
val project = targetKtClass.project
|
||||
val fakeParametersExpressions = fakeParametersExpressions(parameters, project) ?: return@run null
|
||||
QuickFixFactory.getInstance()
|
||||
.createChangeMethodSignatureFromUsageFix(
|
||||
lightMethod,
|
||||
fakeParametersExpressions,
|
||||
PsiSubstitutor.EMPTY,
|
||||
targetKtClass,
|
||||
false,
|
||||
2
|
||||
).takeIf { it.isAvailable(project, null, targetKtClass.containingFile) }
|
||||
}
|
||||
|
||||
return listOfNotNull(changePrimaryConstructorAction, addConstructorAction)
|
||||
}
|
||||
|
||||
override fun createAddPropertyActions(targetClass: JvmClass, request: MemberRequest.Property): List<IntentionAction> {
|
||||
val targetContainer = targetClass.toKtClassOrFile() ?: return emptyList()
|
||||
return createAddPropertyActions(
|
||||
targetContainer, listOf(request.visibilityModifier),
|
||||
request.propertyType, request.propertyName, request.setterRequired, targetClass.name
|
||||
)
|
||||
}
|
||||
|
||||
private fun createAddPropertyActions(
|
||||
targetContainer: KtElement,
|
||||
modifiers: Iterable<JvmModifier>,
|
||||
propertyType: JvmType,
|
||||
propertyName: String,
|
||||
setterRequired: Boolean,
|
||||
classOrFileName: String?
|
||||
): List<IntentionAction> {
|
||||
val modifierBuilder = ModifierBuilder(targetContainer).apply { addJvmModifiers(modifiers) }
|
||||
if (!modifierBuilder.isValid) return emptyList()
|
||||
|
||||
val resolutionFacade = targetContainer.getResolutionFacade()
|
||||
val nullableAnyType = resolutionFacade.moduleDescriptor.builtIns.nullableAnyType
|
||||
|
||||
val ktType = (propertyType as? PsiType)?.resolveToKotlinType(resolutionFacade) ?: nullableAnyType
|
||||
val propertyInfo = PropertyInfo(
|
||||
propertyName,
|
||||
TypeInfo.Empty,
|
||||
TypeInfo(ktType, Variance.INVARIANT),
|
||||
setterRequired,
|
||||
listOf(targetContainer),
|
||||
modifierList = modifierBuilder.modifierList,
|
||||
withInitializer = true
|
||||
)
|
||||
val propertyInfos = if (setterRequired) {
|
||||
listOf(propertyInfo, propertyInfo.copyProperty(isLateinitPreferred = true))
|
||||
} else {
|
||||
listOf(propertyInfo)
|
||||
}
|
||||
return propertyInfos.map { CreatePropertyFix(targetContainer, it, classOrFileName) }
|
||||
}
|
||||
|
||||
override fun createAddFieldActions(targetClass: JvmClass, request: CreateFieldRequest): List<IntentionAction> {
|
||||
val targetContainer = targetClass.toKtClassOrFile() ?: return emptyList()
|
||||
|
||||
val resolutionFacade = targetContainer.getResolutionFacade()
|
||||
val typeInfo = request.fieldType.toKotlinTypeInfo(resolutionFacade)
|
||||
val writable = JvmModifier.FINAL !in request.modifiers
|
||||
|
||||
fun propertyInfo(lateinit: Boolean) = PropertyInfo(
|
||||
request.fieldName,
|
||||
TypeInfo.Empty,
|
||||
typeInfo,
|
||||
writable,
|
||||
listOf(targetContainer),
|
||||
isLateinitPreferred = false, // Dont set it to `lateinit` because it works via templates that brings issues in batch field adding
|
||||
isForCompanion = JvmModifier.STATIC in request.modifiers,
|
||||
modifierList = ModifierBuilder(targetContainer, allowJvmStatic = false).apply {
|
||||
addJvmModifiers(request.modifiers)
|
||||
if (modifierList.children.none { it.node.elementType in KtTokens.VISIBILITY_MODIFIERS })
|
||||
addJvmModifier(JvmModifier.PUBLIC)
|
||||
if (lateinit)
|
||||
modifierList.appendModifier(KtTokens.LATEINIT_KEYWORD)
|
||||
if (!request.modifiers.contains(JvmModifier.PRIVATE) && !lateinit)
|
||||
addAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME)
|
||||
}.modifierList,
|
||||
withInitializer = !lateinit
|
||||
)
|
||||
|
||||
val propertyInfos = if (writable) {
|
||||
listOf(propertyInfo(false), propertyInfo(true))
|
||||
}
|
||||
else {
|
||||
listOf(propertyInfo(false))
|
||||
}
|
||||
return propertyInfos.map { CreatePropertyFix(targetContainer, it, targetClass.name) }
|
||||
}
|
||||
|
||||
override fun createAddMethodActions(targetClass: JvmClass, request: CreateMethodRequest): List<IntentionAction> {
|
||||
val targetContainer = targetClass.toKtClassOrFile() ?: return emptyList()
|
||||
|
||||
val modifierBuilder = ModifierBuilder(targetContainer).apply { addJvmModifiers(request.modifiers) }
|
||||
if (!modifierBuilder.isValid) return emptyList()
|
||||
|
||||
val resolutionFacade = KotlinCacheService.getInstance(targetContainer.project)
|
||||
.getResolutionFacadeByFile(targetContainer.containingFile, JvmPlatforms.defaultJvmPlatform) ?: return emptyList()
|
||||
val returnTypeInfo = request.returnType.toKotlinTypeInfo(resolutionFacade)
|
||||
val parameters = request.parameters as List<Pair<SuggestedNameInfo, List<ExpectedType>>>
|
||||
val parameterInfos = parameters.map { (suggestedNames, expectedTypes) ->
|
||||
ParameterInfo(expectedTypes.toKotlinTypeInfo(resolutionFacade), suggestedNames.names.toList())
|
||||
}
|
||||
val methodName = request.methodName
|
||||
val functionInfo = FunctionInfo(
|
||||
methodName,
|
||||
TypeInfo.Empty,
|
||||
returnTypeInfo,
|
||||
listOf(targetContainer),
|
||||
parameterInfos,
|
||||
isForCompanion = JvmModifier.STATIC in request.modifiers,
|
||||
modifierList = modifierBuilder.modifierList,
|
||||
preferEmptyBody = true
|
||||
)
|
||||
val targetClassName = targetClass.name
|
||||
|
||||
val action = object : CreateCallableFromUsageFix<KtElement>(targetContainer, listOf(functionInfo)) {
|
||||
override fun getFamilyName() = "Add method"
|
||||
override fun getText() = "Add method '$methodName' to '$targetClassName'"
|
||||
}
|
||||
|
||||
val nameAndKind = PropertyUtilBase.getPropertyNameAndKind(methodName) ?: return listOf(action)
|
||||
|
||||
val propertyType = (request.expectedParameters.singleOrNull()?.expectedTypes ?: request.returnType)
|
||||
.firstOrNull { JvmPsiConversionHelper.getInstance(targetContainer.project).convertType(it.theType) != PsiType.VOID }
|
||||
?: return listOf(action)
|
||||
|
||||
return createAddPropertyActions(
|
||||
targetContainer,
|
||||
request.modifiers,
|
||||
propertyType.theType,
|
||||
nameAndKind.first,
|
||||
nameAndKind.second == PropertyKind.SETTER,
|
||||
targetClass.name
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
override fun createAddAnnotationActions(target: JvmModifiersOwner, request: AnnotationRequest): List<IntentionAction> {
|
||||
val declaration = (target as? KtLightElement<*, *>)?.kotlinOrigin as? KtModifierListOwner ?: return emptyList()
|
||||
if (declaration.language != KotlinLanguage.INSTANCE) return emptyList()
|
||||
val annotationUseSiteTarget = when (target) {
|
||||
is JvmField -> AnnotationUseSiteTarget.FIELD
|
||||
is JvmMethod -> when {
|
||||
PropertyUtil.isSimplePropertySetter(target as? PsiMethod) -> AnnotationUseSiteTarget.PROPERTY_SETTER
|
||||
PropertyUtil.isSimplePropertyGetter(target as? PsiMethod) -> AnnotationUseSiteTarget.PROPERTY_GETTER
|
||||
else -> null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
return listOf(CreateAnnotationAction(declaration, annotationUseSiteTarget, request))
|
||||
}
|
||||
|
||||
private class CreateAnnotationAction(
|
||||
target: KtModifierListOwner,
|
||||
val annotationTarget: AnnotationUseSiteTarget?,
|
||||
val request: AnnotationRequest
|
||||
) : IntentionAction {
|
||||
|
||||
private val pointer = target.createSmartPointer()
|
||||
|
||||
override fun startInWriteAction(): Boolean = true
|
||||
|
||||
override fun getText(): String =
|
||||
QuickFixBundle.message("create.annotation.text", StringUtilRt.getShortName(request.qualifiedName))
|
||||
|
||||
override fun getFamilyName(): String = QuickFixBundle.message("create.annotation.family")
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean = pointer.element != null
|
||||
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
|
||||
val target = pointer.element ?: return
|
||||
val annotationClass = JavaPsiFacade.getInstance(project).findClass(request.qualifiedName, target.resolveScope)
|
||||
|
||||
val kotlinAnnotation = annotationClass?.language == KotlinLanguage.INSTANCE
|
||||
|
||||
val annotationUseSiteTargetPrefix = run prefixEvaluation@{
|
||||
if (annotationTarget == null) return@prefixEvaluation ""
|
||||
|
||||
val moduleDescriptor = (target as? KtDeclaration)?.resolveToDescriptorIfAny()?.module ?: return@prefixEvaluation ""
|
||||
val annotationClassDescriptor = moduleDescriptor.resolveClassByFqName(
|
||||
FqName(request.qualifiedName), NoLookupLocation.FROM_IDE
|
||||
) ?: return@prefixEvaluation ""
|
||||
|
||||
val applicableTargetSet = AnnotationChecker.applicableTargetSet(annotationClassDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET
|
||||
|
||||
if (KotlinTarget.PROPERTY !in applicableTargetSet) return@prefixEvaluation ""
|
||||
|
||||
"${annotationTarget.renderName}:"
|
||||
}
|
||||
|
||||
val entry = target.addAnnotationEntry(
|
||||
KtPsiFactory(target)
|
||||
.createAnnotationEntry(
|
||||
"@$annotationUseSiteTargetPrefix${request.qualifiedName}${
|
||||
request.attributes.mapIndexed { i, p ->
|
||||
if (!kotlinAnnotation && i == 0 && p.name == "value")
|
||||
renderAttributeValue(p.value).toString()
|
||||
else
|
||||
"${p.name} = ${renderAttributeValue(p.value)}"
|
||||
}.joinToString(", ", "(", ")")
|
||||
}"
|
||||
)
|
||||
)
|
||||
|
||||
ShortenReferences.DEFAULT.process(entry)
|
||||
}
|
||||
|
||||
private fun renderAttributeValue(annotationAttributeRequest: AnnotationAttributeValueRequest) =
|
||||
when (annotationAttributeRequest) {
|
||||
is AnnotationAttributeValueRequest.PrimitiveValue -> annotationAttributeRequest.value
|
||||
is AnnotationAttributeValueRequest.StringValue -> "\"" + annotationAttributeRequest.value + "\""
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun JvmPsiConversionHelper.asPsiType(param: Pair<SuggestedNameInfo, List<ExpectedType>>): PsiType? =
|
||||
param.second.firstOrNull()?.theType?.let { convertType(it) }
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.util.compat;
|
||||
|
||||
import com.intellij.openapi.editor.event.EditorFactoryEvent;
|
||||
import com.intellij.openapi.editor.event.EditorFactoryListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
// Default implementation for interface methods were added in 183.
|
||||
// BUNCH: 182
|
||||
@SuppressWarnings("IncompatibleAPI")
|
||||
public interface EditorFactoryListenerWrapper extends EditorFactoryListener {
|
||||
@Override
|
||||
default void editorCreated(@NotNull EditorFactoryEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
default void editorReleased(@NotNull EditorFactoryEvent event) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.util.compat
|
||||
|
||||
import com.intellij.codeInspection.reference.RefFile
|
||||
import com.intellij.psi.PsiFile
|
||||
|
||||
// BUNCH: 182
|
||||
@Suppress("IncompatibleAPI", "MissingRecentApi")
|
||||
val RefFile.psiFile: PsiFile?
|
||||
get() = element
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
Resolved c()
|
||||
Resolved fieldWithType()
|
||||
Resolved methodWithType()
|
||||
Resolved o()
|
||||
Resolved o()
|
||||
Resolved o.methodNoType()()
|
||||
Resolved o.methodWithType()()
|
||||
Resolved o.methodWithType()()
|
||||
Searched references to GroovyClass
|
||||
Searched references to GroovyClass.fieldWithType in non-Java files
|
||||
Searched references to GroovyClass.methodWithType in non-Java files
|
||||
Searched references to JavaWithGroovyInvoke_0
|
||||
Searched references to JavaWithGroovyInvoke_0.OtherJavaClass
|
||||
Searched references to parameter c of f(c: JavaWithGroovyInvoke_0) in non-Java files
|
||||
Searched references to parameter o of foo(o: JavaWithGroovyInvoke_0.OtherJavaClass) in non-Java files
|
||||
Searched references to parameter o of gr(o: GroovyClass) in non-Java files
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.caches.resolve
|
||||
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightElement
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightModifierList
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.junit.Assert
|
||||
|
||||
object PsiElementChecker {
|
||||
val TEST_DATA_KEY = Key.create<Int>("Test Key")
|
||||
|
||||
fun checkPsiElementStructure(lightClass: PsiClass) {
|
||||
checkPsiElement(lightClass)
|
||||
|
||||
lightClass.methods.forEach {
|
||||
it.parameterList.parameters.forEach { checkPsiElement(it) }
|
||||
checkPsiElement(it)
|
||||
}
|
||||
|
||||
lightClass.fields.forEach { checkPsiElement(it) }
|
||||
|
||||
lightClass.innerClasses.forEach { checkPsiElementStructure(it) }
|
||||
}
|
||||
|
||||
private fun checkPsiElement(element: PsiElement) {
|
||||
if (element !is KtLightElement<*, *> && element !is KtLightModifierList<*>) return
|
||||
|
||||
if (element is PsiModifierListOwner) {
|
||||
val modifierList = element.modifierList
|
||||
if (modifierList != null) {
|
||||
checkPsiElement(modifierList)
|
||||
}
|
||||
}
|
||||
|
||||
if (element is PsiTypeParameterListOwner) {
|
||||
val typeParameterList = element.typeParameterList
|
||||
if (typeParameterList != null) {
|
||||
checkPsiElement(typeParameterList)
|
||||
typeParameterList.typeParameters.forEach { checkPsiElement(it) }
|
||||
}
|
||||
}
|
||||
|
||||
with(element) {
|
||||
try {
|
||||
Assert.assertEquals("Number of methods has changed. Please update test.", 54, PsiElement::class.java.methods.size)
|
||||
|
||||
project
|
||||
Assert.assertTrue(language == KotlinLanguage.INSTANCE)
|
||||
manager
|
||||
children
|
||||
parent
|
||||
firstChild
|
||||
lastChild
|
||||
nextSibling
|
||||
prevSibling
|
||||
containingFile
|
||||
textRange
|
||||
startOffsetInParent
|
||||
textLength
|
||||
findElementAt(0)
|
||||
findReferenceAt(0)
|
||||
textOffset
|
||||
text
|
||||
textToCharArray()
|
||||
navigationElement
|
||||
originalElement
|
||||
textMatches("")
|
||||
Assert.assertTrue(textMatches(this))
|
||||
textContains('a')
|
||||
accept(PsiElementVisitor.EMPTY_VISITOR)
|
||||
acceptChildren(PsiElementVisitor.EMPTY_VISITOR)
|
||||
|
||||
val copy = copy()
|
||||
Assert.assertTrue(copy == null || copy::class.java == this::class.java)
|
||||
|
||||
// Modify methods:
|
||||
// add(this)
|
||||
// addBefore(this, lastChild)
|
||||
// addAfter(firstChild, this)
|
||||
// checkAdd(this)
|
||||
// addRange(firstChild, lastChild)
|
||||
// addRangeBefore(firstChild, lastChild, lastChild)
|
||||
// addRangeAfter(firstChild, lastChild, firstChild)
|
||||
// delete()
|
||||
// checkDelete()
|
||||
// deleteChildRange(firstChild, lastChild)
|
||||
// replace(this)
|
||||
|
||||
Assert.assertTrue(isValid)
|
||||
isWritable
|
||||
reference
|
||||
references
|
||||
putCopyableUserData(TEST_DATA_KEY, 12)
|
||||
|
||||
Assert.assertTrue(getCopyableUserData(TEST_DATA_KEY) == 12)
|
||||
// Assert.assertTrue(copy().getCopyableUserData(TEST_DATA_KEY) == 12) { this } Doesn't work
|
||||
|
||||
// processDeclarations(...)
|
||||
|
||||
context
|
||||
isPhysical
|
||||
resolveScope
|
||||
useScope
|
||||
node
|
||||
toString()
|
||||
Assert.assertTrue(isEquivalentTo(this))
|
||||
}
|
||||
catch (t: Throwable) {
|
||||
throw AssertionErrorWithCause("Failed for ${this::class.java} ${this}", t)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,670 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.lang.jvm.JvmClass
|
||||
import com.intellij.lang.jvm.JvmElement
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.lang.jvm.actions.*
|
||||
import com.intellij.lang.jvm.types.JvmSubstitutor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Pair.pair
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.codeStyle.SuggestedNameInfo
|
||||
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
|
||||
import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.asJava.toLightElements
|
||||
import org.jetbrains.kotlin.idea.search.allScope
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtModifierListOwner
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.jetbrains.uast.toUElement
|
||||
import org.junit.Assert
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
||||
class CommonIntentionActionsTest : LightPlatformCodeInsightFixtureTestCase() {
|
||||
private class SimpleMethodRequest(
|
||||
project: Project,
|
||||
private val methodName: String,
|
||||
private val modifiers: Collection<JvmModifier> = emptyList(),
|
||||
private val returnType: ExpectedTypes = emptyList(),
|
||||
private val annotations: Collection<AnnotationRequest> = emptyList(),
|
||||
@Suppress("MissingRecentApi") parameters: List<ExpectedParameter> = emptyList(),
|
||||
private val targetSubstitutor: JvmSubstitutor = PsiJvmSubstitutor(project, PsiSubstitutor.EMPTY)
|
||||
) : CreateMethodRequest {
|
||||
private val expectedParameters = parameters
|
||||
|
||||
override fun getTargetSubstitutor(): JvmSubstitutor = targetSubstitutor
|
||||
|
||||
override fun getModifiers() = modifiers
|
||||
|
||||
override fun getMethodName() = methodName
|
||||
|
||||
override fun getAnnotations() = annotations
|
||||
|
||||
@Suppress("MissingRecentApi")
|
||||
override fun getExpectedParameters(): List<ExpectedParameter> = expectedParameters
|
||||
|
||||
override fun getReturnType() = returnType
|
||||
|
||||
override fun isValid(): Boolean = true
|
||||
|
||||
}
|
||||
|
||||
private class NameInfo(vararg names: String) : SuggestedNameInfo(names)
|
||||
|
||||
override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
|
||||
|
||||
fun testMakeNotFinal() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
class Foo {
|
||||
fun bar<caret>(){}
|
||||
}
|
||||
""")
|
||||
|
||||
myFixture.launchAction(
|
||||
createModifierActions(
|
||||
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.FINAL, false)
|
||||
).findWithText("Make 'bar' open")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
class Foo {
|
||||
open fun bar(){}
|
||||
}
|
||||
""")
|
||||
}
|
||||
|
||||
fun testMakePrivate() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
class Foo<caret> {
|
||||
fun bar(){}
|
||||
}
|
||||
""")
|
||||
|
||||
myFixture.launchAction(
|
||||
createModifierActions(
|
||||
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PRIVATE, true)
|
||||
).findWithText("Make 'Foo' private")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
private class Foo {
|
||||
fun bar(){}
|
||||
}
|
||||
""")
|
||||
}
|
||||
|
||||
fun testMakeNotPrivate() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
private class Foo<caret> {
|
||||
fun bar(){}
|
||||
}
|
||||
""".trim())
|
||||
|
||||
myFixture.launchAction(
|
||||
createModifierActions(
|
||||
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PRIVATE, false)
|
||||
).findWithText("Remove 'private' modifier")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
class Foo {
|
||||
fun bar(){}
|
||||
}
|
||||
""".trim(), true)
|
||||
}
|
||||
|
||||
fun testMakePrivatePublic() {
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| private fun <caret>bar(){}
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createModifierActions(
|
||||
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PUBLIC, true)
|
||||
).findWithText("Remove 'private' modifier")
|
||||
)
|
||||
myFixture.checkResult(
|
||||
"""class Foo {
|
||||
| fun <caret>bar(){}
|
||||
|}""".trim().trimMargin(), true
|
||||
)
|
||||
}
|
||||
|
||||
fun testMakeProtectedPublic() {
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """open class Foo {
|
||||
| protected fun <caret>bar(){}
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createModifierActions(
|
||||
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PUBLIC, true)
|
||||
).findWithText("Remove 'protected' modifier")
|
||||
)
|
||||
myFixture.checkResult(
|
||||
"""open class Foo {
|
||||
| fun <caret>bar(){}
|
||||
|}""".trim().trimMargin(), true
|
||||
)
|
||||
}
|
||||
|
||||
fun testMakeInternalPublic() {
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| internal fun <caret>bar(){}
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createModifierActions(
|
||||
myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PUBLIC, true)
|
||||
).findWithText("Remove 'internal' modifier")
|
||||
)
|
||||
myFixture.checkResult(
|
||||
"""class Foo {
|
||||
| fun <caret>bar(){}
|
||||
|}""".trim().trimMargin(), true
|
||||
)
|
||||
}
|
||||
|
||||
fun testAddAnnotation() {
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| fun <caret>bar(){}
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createAddAnnotationActions(
|
||||
myFixture.findElementByText("bar", KtModifierListOwner::class.java).toLightElements().single() as PsiMethod,
|
||||
annotationRequest("kotlin.jvm.JvmName", stringAttribute("name", "foo"))
|
||||
).single()
|
||||
)
|
||||
myFixture.checkResult(
|
||||
"""class Foo {
|
||||
| @JvmName(name = "foo")
|
||||
| fun <caret>bar(){}
|
||||
|}""".trim().trimMargin(), true
|
||||
)
|
||||
}
|
||||
|
||||
fun testAddJavaAnnotationValue() {
|
||||
|
||||
myFixture.addFileToProject(
|
||||
"pkg/myannotation/JavaAnnotation.java", """
|
||||
package pkg.myannotation
|
||||
|
||||
public @interface JavaAnnotation {
|
||||
String value();
|
||||
int param() default 0;
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| fun bar(){}
|
||||
| fun baz(){}
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createAddAnnotationActions(
|
||||
myFixture.findElementByText("bar", KtModifierListOwner::class.java).toLightElements().single() as PsiMethod,
|
||||
annotationRequest("pkg.myannotation.JavaAnnotation", stringAttribute("value", "foo"), intAttribute("param", 2))
|
||||
).single()
|
||||
)
|
||||
myFixture.launchAction(
|
||||
createAddAnnotationActions(
|
||||
myFixture.findElementByText("baz", KtModifierListOwner::class.java).toLightElements().single() as PsiMethod,
|
||||
annotationRequest("pkg.myannotation.JavaAnnotation", intAttribute("param", 2), stringAttribute("value", "foo"))
|
||||
).single()
|
||||
)
|
||||
myFixture.checkResult(
|
||||
"""import pkg.myannotation.JavaAnnotation
|
||||
|
|
||||
|class Foo {
|
||||
| @JavaAnnotation("foo", param = 2)
|
||||
| fun bar(){}
|
||||
| @JavaAnnotation(param = 2, value = "foo")
|
||||
| fun baz(){}
|
||||
|}""".trim().trimMargin(), true
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun testAddJavaAnnotationOnFieldWithoutTarget() {
|
||||
|
||||
myFixture.addFileToProject(
|
||||
"pkg/myannotation/JavaAnnotation.java", """
|
||||
package pkg.myannotation
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
//no @Target
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface JavaAnnotation {
|
||||
String value();
|
||||
int param() default 0;
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| val bar: String = null
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createAddAnnotationActions(
|
||||
myFixture.findElementByText("bar", KtModifierListOwner::class.java).toLightElements().single { it is PsiField } as PsiField,
|
||||
annotationRequest("pkg.myannotation.JavaAnnotation")
|
||||
).single()
|
||||
)
|
||||
|
||||
myFixture.checkResult(
|
||||
"""
|
||||
import pkg.myannotation.JavaAnnotation
|
||||
|
||||
class Foo {
|
||||
@field:JavaAnnotation()
|
||||
val bar: String = null
|
||||
}
|
||||
""".trimIndent(), true
|
||||
)
|
||||
|
||||
TestCase.assertEquals(
|
||||
"KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," +
|
||||
" KtUltraLightFieldForSourceDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
|
||||
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun testAddJavaAnnotationOnField() {
|
||||
|
||||
myFixture.addFileToProject(
|
||||
"pkg/myannotation/JavaAnnotation.java", """
|
||||
package pkg.myannotation
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface JavaAnnotation {
|
||||
String value();
|
||||
int param() default 0;
|
||||
}
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| val bar: String = null
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createAddAnnotationActions(
|
||||
myFixture.findElementByText("bar", KtModifierListOwner::class.java).toLightElements().single { it is PsiField } as PsiField,
|
||||
annotationRequest("pkg.myannotation.JavaAnnotation")
|
||||
).single()
|
||||
)
|
||||
|
||||
myFixture.checkResult(
|
||||
"""
|
||||
import pkg.myannotation.JavaAnnotation
|
||||
|
||||
class Foo {
|
||||
@JavaAnnotation()
|
||||
val bar: String = null
|
||||
}
|
||||
""".trimIndent(), true
|
||||
)
|
||||
|
||||
TestCase.assertEquals(
|
||||
"KtUltraLightMethodForSourceDeclaration -> org.jetbrains.annotations.NotNull," +
|
||||
" KtUltraLightFieldForSourceDeclaration -> pkg.myannotation.JavaAnnotation, org.jetbrains.annotations.NotNull",
|
||||
annotationsString(myFixture.findElementByText("bar", KtModifierListOwner::class.java))
|
||||
)
|
||||
}
|
||||
|
||||
private fun annotationsString(findElementByText: KtModifierListOwner) = findElementByText.toLightElements()
|
||||
.joinToString { elem -> "${elem.javaClass.simpleName} -> ${(elem as PsiModifierListOwner).annotations.joinToString { it.qualifiedName!! }}" }
|
||||
|
||||
fun testDontMakePublicPublic() {
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """class Foo {
|
||||
| fun <caret>bar(){}
|
||||
|}""".trim().trimMargin()
|
||||
)
|
||||
|
||||
assertEmpty(createModifierActions(myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.PUBLIC, true)))
|
||||
}
|
||||
|
||||
fun testDontMakeFunInObjectsOpen() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
object Foo {
|
||||
fun bar<caret>(){}
|
||||
}
|
||||
""".trim())
|
||||
assertEmpty(createModifierActions(myFixture.atCaret(), MemberRequest.Modifier(JvmModifier.FINAL, false)))
|
||||
}
|
||||
|
||||
fun testAddVoidVoidMethod() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
|class Foo<caret> {
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin())
|
||||
|
||||
myFixture.launchAction(
|
||||
createMethodActions(
|
||||
myFixture.atCaret(),
|
||||
methodRequest(project, "baz", JvmModifier.PRIVATE, PsiType.VOID)
|
||||
).findWithText("Add method 'baz' to 'Foo'")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
|class Foo {
|
||||
| fun bar() {}
|
||||
| private fun baz() {
|
||||
|
|
||||
| }
|
||||
|}
|
||||
""".trim().trimMargin(), true)
|
||||
}
|
||||
|
||||
fun testAddIntIntMethod() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
|class Foo<caret> {
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin())
|
||||
|
||||
myFixture.launchAction(
|
||||
createMethodActions(
|
||||
myFixture.atCaret(),
|
||||
SimpleMethodRequest(project,
|
||||
methodName = "baz",
|
||||
modifiers = listOf(JvmModifier.PUBLIC),
|
||||
returnType = expectedTypes(PsiType.INT),
|
||||
parameters = expectedParams(PsiType.INT))
|
||||
).findWithText("Add method 'baz' to 'Foo'")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
|class Foo {
|
||||
| fun bar() {}
|
||||
| fun baz(param0: Int): Int {
|
||||
| TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
| }
|
||||
|}
|
||||
""".trim().trimMargin(), true)
|
||||
}
|
||||
|
||||
fun testAddIntPrimaryConstructor() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
|class Foo<caret> {
|
||||
|}
|
||||
""".trim().trimMargin())
|
||||
|
||||
myFixture.launchAction(
|
||||
createConstructorActions(
|
||||
myFixture.atCaret(), constructorRequest(project, listOf(pair("param0", PsiType.INT as PsiType)))
|
||||
).findWithText("Add primary constructor to 'Foo'")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
|class Foo(param0: Int) {
|
||||
|}
|
||||
""".trim().trimMargin(), true)
|
||||
}
|
||||
|
||||
fun testAddIntSecondaryConstructor() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
|class <caret>Foo() {
|
||||
|}
|
||||
""".trim().trimMargin())
|
||||
|
||||
myFixture.launchAction(
|
||||
createConstructorActions(
|
||||
myFixture.atCaret(),
|
||||
constructorRequest(project, listOf(pair("param0", PsiType.INT as PsiType)))
|
||||
).findWithText("Add secondary constructor to 'Foo'")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
|class Foo() {
|
||||
| constructor(param0: Int) {
|
||||
|
|
||||
| }
|
||||
|}
|
||||
""".trim().trimMargin(), true)
|
||||
}
|
||||
|
||||
fun testChangePrimaryConstructorInt() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
|class <caret>Foo() {
|
||||
|}
|
||||
""".trim().trimMargin())
|
||||
|
||||
myFixture.launchAction(
|
||||
createConstructorActions(
|
||||
myFixture.atCaret(),
|
||||
constructorRequest(project, listOf(pair("param0", PsiType.INT as PsiType)))
|
||||
).findWithText("Add 'int' as 1st parameter to method 'Foo'")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
|class Foo(param0: Int) {
|
||||
|}
|
||||
""".trim().trimMargin(), true)
|
||||
}
|
||||
|
||||
fun testRemoveConstructorParameters() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
|class <caret>Foo(i: Int) {
|
||||
|}
|
||||
""".trim().trimMargin())
|
||||
|
||||
myFixture.launchAction(
|
||||
createConstructorActions(
|
||||
myFixture.atCaret(),
|
||||
constructorRequest(project, emptyList())
|
||||
).findWithText("Remove 1st parameter from method 'Foo'")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
|class Foo() {
|
||||
|}
|
||||
""".trim().trimMargin(), true)
|
||||
}
|
||||
|
||||
fun testAddStringVarProperty() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
|class Foo<caret> {
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin())
|
||||
|
||||
myFixture.launchAction(
|
||||
createMethodActions(
|
||||
myFixture.atCaret(),
|
||||
SimpleMethodRequest(
|
||||
project,
|
||||
methodName = "setBaz",
|
||||
modifiers = listOf(JvmModifier.PUBLIC),
|
||||
returnType = expectedTypes(),
|
||||
parameters = expectedParams(PsiType.getTypeByName("java.lang.String", project, project.allScope()))
|
||||
)
|
||||
).findWithText("Add 'var' property 'baz' to 'Foo'")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
|class Foo {
|
||||
| var baz: String = TODO("initialize me")
|
||||
|
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin(), true)
|
||||
}
|
||||
|
||||
fun testAddLateInitStringVarProperty() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
|class Foo<caret> {
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin())
|
||||
|
||||
myFixture.launchAction(
|
||||
createMethodActions(
|
||||
myFixture.atCaret(),
|
||||
SimpleMethodRequest(
|
||||
project,
|
||||
methodName = "setBaz",
|
||||
modifiers = listOf(JvmModifier.PUBLIC),
|
||||
returnType = expectedTypes(),
|
||||
parameters = expectedParams(PsiType.getTypeByName("java.lang.String", project, project.allScope()))
|
||||
)
|
||||
).findWithText("Add 'lateinit var' property 'baz' to 'Foo'")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
|class Foo {
|
||||
| lateinit var baz: String
|
||||
|
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin(), true)
|
||||
}
|
||||
|
||||
fun testAddStringVarField() {
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """
|
||||
|class Foo<caret> {
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin()
|
||||
)
|
||||
myFixture.launchAction(
|
||||
createFieldActions(
|
||||
myFixture.atCaret(),
|
||||
FieldRequest(project, emptyList(), "java.util.Date", "baz")
|
||||
).findWithText("Add 'var' property 'baz' to 'Foo'")
|
||||
)
|
||||
myFixture.checkResult(
|
||||
"""
|
||||
|import java.util.Date
|
||||
|
|
||||
|class Foo {
|
||||
| @JvmField
|
||||
| var baz: Date = TODO("initialize me")
|
||||
|
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin(), true
|
||||
)
|
||||
}
|
||||
|
||||
fun testAddLateInitStringVarField() {
|
||||
myFixture.configureByText(
|
||||
"foo.kt", """
|
||||
|class Foo<caret> {
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin()
|
||||
)
|
||||
|
||||
myFixture.launchAction(
|
||||
createFieldActions(
|
||||
myFixture.atCaret(),
|
||||
FieldRequest(project, listOf(JvmModifier.PRIVATE), "java.lang.String", "baz")
|
||||
).findWithText("Add 'lateinit var' property 'baz' to 'Foo'")
|
||||
)
|
||||
myFixture.checkResult(
|
||||
"""
|
||||
|class Foo {
|
||||
| private lateinit var baz: String
|
||||
|
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin(), true
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun createFieldActions(atCaret: JvmClass, fieldRequest: CreateFieldRequest): List<IntentionAction> =
|
||||
com.intellij.lang.jvm.actions.EP_NAME.extensions.flatMap { it.createAddFieldActions(atCaret, fieldRequest) }
|
||||
|
||||
fun testAddStringValProperty() {
|
||||
myFixture.configureByText("foo.kt", """
|
||||
|class Foo<caret> {
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin())
|
||||
|
||||
myFixture.launchAction(
|
||||
createMethodActions(
|
||||
myFixture.atCaret(),
|
||||
SimpleMethodRequest(
|
||||
project,
|
||||
methodName = "getBaz",
|
||||
modifiers = listOf(JvmModifier.PUBLIC),
|
||||
returnType = expectedTypes(PsiType.getTypeByName("java.lang.String", project, project.allScope())),
|
||||
parameters = expectedParams()
|
||||
)
|
||||
).findWithText("Add 'val' property 'baz' to 'Foo'")
|
||||
)
|
||||
myFixture.checkResult("""
|
||||
|class Foo {
|
||||
| val baz: String = TODO("initialize me")
|
||||
|
|
||||
| fun bar() {}
|
||||
|}
|
||||
""".trim().trimMargin(), true)
|
||||
}
|
||||
|
||||
private fun expectedTypes(vararg psiTypes: PsiType) = psiTypes.map { expectedType(it) }
|
||||
|
||||
private fun expectedParams(vararg psyTypes: PsiType) =
|
||||
psyTypes.mapIndexed { index, psiType -> expectedParameter(expectedTypes(psiType), "param$index") }
|
||||
|
||||
private inline fun <reified T : JvmElement> CodeInsightTestFixture.atCaret() = elementAtCaret.toUElement() as T
|
||||
|
||||
@Suppress("CAST_NEVER_SUCCEEDS")
|
||||
private fun List<IntentionAction>.findWithText(text: String): IntentionAction =
|
||||
this.firstOrNull { it.text == text } ?:
|
||||
Assert.fail("intention with text '$text' was not found, only ${this.joinToString { "\"${it.text}\"" }} available") as Nothing
|
||||
|
||||
class FieldRequest(
|
||||
private val project: Project,
|
||||
val modifiers: List<JvmModifier>,
|
||||
val type: String,
|
||||
val name: String
|
||||
) : CreateFieldRequest {
|
||||
override fun getTargetSubstitutor(): JvmSubstitutor = PsiJvmSubstitutor(project, PsiSubstitutor.EMPTY)
|
||||
|
||||
override fun getModifiers(): Collection<JvmModifier> = modifiers
|
||||
|
||||
override fun isConstant(): Boolean = false
|
||||
|
||||
override fun getFieldType(): List<ExpectedType> =
|
||||
com.intellij.lang.jvm.actions.expectedTypes(PsiType.getTypeByName(type, project, project.allScope()))
|
||||
|
||||
override fun getFieldName(): String = name
|
||||
|
||||
override fun isValid(): Boolean = true
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.scratch
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl
|
||||
|
||||
fun getFoldingData(topEditor: Editor, withCollapseStatus: Boolean): String {
|
||||
return CodeInsightTestFixtureImpl.getTagsFromSegments(
|
||||
topEditor.document.text,
|
||||
topEditor.foldingModel.allFoldRegions.asList(),
|
||||
"fold"
|
||||
) { foldRegion ->
|
||||
"""text='${foldRegion.placeholderText}'${if (withCollapseStatus) """ expand='${foldRegion.isExpanded}'""" else ""}"""
|
||||
}
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin.internal
|
||||
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ProjectRootModificationTracker
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.util.CachedValueProvider.Result
|
||||
import com.intellij.psi.util.CachedValuesManager
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.util.module
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
|
||||
|
||||
class IdeaKotlinUastResolveProviderService : KotlinUastResolveProviderService {
|
||||
override fun getBindingContext(element: KtElement) = element.analyze(BodyResolveMode.PARTIAL_WITH_CFA)
|
||||
|
||||
override fun getTypeMapper(element: KtElement): KotlinTypeMapper? {
|
||||
return KotlinTypeMapper(
|
||||
getBindingContext(element), ClassBuilderMode.LIGHT_CLASSES,
|
||||
JvmProtoBufUtil.DEFAULT_MODULE_NAME, element.languageVersionSettings
|
||||
)
|
||||
}
|
||||
|
||||
override fun isJvmElement(psiElement: PsiElement): Boolean {
|
||||
if (allModulesSupportJvm(psiElement.project)) return true
|
||||
|
||||
val containingFile = psiElement.containingFile
|
||||
if (containingFile is KtFile) {
|
||||
return TargetPlatformDetector.getPlatform(containingFile).isJvm()
|
||||
}
|
||||
|
||||
val module = psiElement.module
|
||||
return module == null || TargetPlatformDetector.getPlatform(module).isJvm()
|
||||
}
|
||||
|
||||
override fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings {
|
||||
return element.languageVersionSettings
|
||||
}
|
||||
|
||||
private fun allModulesSupportJvm(project: Project): Boolean =
|
||||
CachedValuesManager.getManager(project)
|
||||
.getCachedValue(project, {
|
||||
Result.create(
|
||||
ModuleManager.getInstance(project).modules.all { module ->
|
||||
TargetPlatformDetector.getPlatform(module).isJvm()
|
||||
},
|
||||
ProjectRootModificationTracker.getInstance(project)
|
||||
)
|
||||
})
|
||||
|
||||
}
|
||||
@@ -1,596 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kotlin.KotlinConverter.convertDeclaration
|
||||
import org.jetbrains.uast.kotlin.KotlinConverter.convertDeclarationOrElement
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
|
||||
import org.jetbrains.uast.kotlin.expressions.*
|
||||
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiParameter
|
||||
import org.jetbrains.uast.kotlin.psi.UastKotlinPsiVariable
|
||||
|
||||
interface KotlinUastResolveProviderService {
|
||||
fun getBindingContext(element: KtElement): BindingContext
|
||||
fun getTypeMapper(element: KtElement): KotlinTypeMapper?
|
||||
fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings
|
||||
fun isJvmElement(psiElement: PsiElement): Boolean
|
||||
}
|
||||
|
||||
var PsiElement.destructuringDeclarationInitializer: Boolean? by UserDataProperty(Key.create("kotlin.uast.destructuringDeclarationInitializer"))
|
||||
|
||||
class KotlinUastLanguagePlugin : UastLanguagePlugin {
|
||||
override val priority = 10
|
||||
|
||||
override val language: Language
|
||||
get() = KotlinLanguage.INSTANCE
|
||||
|
||||
override fun isFileSupported(fileName: String): Boolean {
|
||||
return fileName.endsWith(".kt", false) || fileName.endsWith(".kts", false)
|
||||
}
|
||||
|
||||
private val PsiElement.isJvmElement: Boolean
|
||||
get() {
|
||||
val resolveProvider = ServiceManager.getService(project, KotlinUastResolveProviderService::class.java)
|
||||
return resolveProvider.isJvmElement(this)
|
||||
}
|
||||
|
||||
override fun convertElement(element: PsiElement, parent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
if (!element.isJvmElement) return null
|
||||
return convertDeclarationOrElement(element, parent, requiredType)
|
||||
}
|
||||
|
||||
override fun convertElementWithParent(element: PsiElement, requiredType: Class<out UElement>?): UElement? {
|
||||
if (!element.isJvmElement) return null
|
||||
if (element is PsiFile) return convertDeclaration(element, null, requiredType)
|
||||
if (element is KtLightClassForFacade) return convertDeclaration(element, null, requiredType)
|
||||
|
||||
return convertDeclarationOrElement(element, null, requiredType)
|
||||
}
|
||||
|
||||
override fun getMethodCallExpression(
|
||||
element: PsiElement,
|
||||
containingClassFqName: String?,
|
||||
methodName: String
|
||||
): UastLanguagePlugin.ResolvedMethod? {
|
||||
if (element !is KtCallExpression) return null
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return null
|
||||
val resultingDescriptor = resolvedCall.resultingDescriptor
|
||||
if (resultingDescriptor !is FunctionDescriptor || resultingDescriptor.name.asString() != methodName) return null
|
||||
|
||||
val parent = element.parent
|
||||
val parentUElement = convertElementWithParent(parent, null) ?: return null
|
||||
|
||||
val uExpression = KotlinUFunctionCallExpression(element, parentUElement, resolvedCall)
|
||||
val method = uExpression.resolve() ?: return null
|
||||
if (method.name != methodName) return null
|
||||
return UastLanguagePlugin.ResolvedMethod(uExpression, method)
|
||||
}
|
||||
|
||||
override fun getConstructorCallExpression(
|
||||
element: PsiElement,
|
||||
fqName: String
|
||||
): UastLanguagePlugin.ResolvedConstructor? {
|
||||
if (element !is KtCallExpression) return null
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return null
|
||||
val resultingDescriptor = resolvedCall.resultingDescriptor
|
||||
if (resultingDescriptor !is ConstructorDescriptor
|
||||
|| resultingDescriptor.returnType.constructor.declarationDescriptor?.name?.asString() != fqName) {
|
||||
return null
|
||||
}
|
||||
|
||||
val parent = KotlinConverter.unwrapElements(element.parent) ?: return null
|
||||
val parentUElement = convertElementWithParent(parent, null) ?: return null
|
||||
|
||||
val uExpression = KotlinUFunctionCallExpression(element, parentUElement, resolvedCall)
|
||||
val method = uExpression.resolve() ?: return null
|
||||
val containingClass = method.containingClass ?: return null
|
||||
return UastLanguagePlugin.ResolvedConstructor(uExpression, method, containingClass)
|
||||
}
|
||||
|
||||
override fun isExpressionValueUsed(element: UExpression): Boolean {
|
||||
return when (element) {
|
||||
is KotlinUSimpleReferenceExpression.KotlinAccessorCallExpression -> element.setterValue != null
|
||||
is KotlinAbstractUExpression -> {
|
||||
val ktElement = element.sourcePsi as? KtElement ?: return false
|
||||
ktElement.analyze()[BindingContext.USED_AS_EXPRESSION, ktElement] ?: false
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal inline fun <reified ActualT : UElement> Class<out UElement>?.el(f: () -> UElement?): UElement? {
|
||||
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
internal inline fun <reified ActualT : UElement> Class<out UElement>?.expr(f: () -> UExpression?): UExpression? {
|
||||
return if (this == null || isAssignableFrom(ActualT::class.java)) f() else null
|
||||
}
|
||||
|
||||
|
||||
|
||||
internal object KotlinConverter {
|
||||
internal tailrec fun unwrapElements(element: PsiElement?): PsiElement? = when (element) {
|
||||
is KtValueArgumentList -> unwrapElements(element.parent)
|
||||
is KtValueArgument -> unwrapElements(element.parent)
|
||||
is KtDeclarationModifierList -> unwrapElements(element.parent)
|
||||
is KtContainerNode -> unwrapElements(element.parent)
|
||||
is KtSimpleNameStringTemplateEntry -> unwrapElements(element.parent)
|
||||
is KtLightParameterList -> unwrapElements(element.parent)
|
||||
is KtTypeElement -> unwrapElements(element.parent)
|
||||
is KtSuperTypeList -> unwrapElements(element.parent)
|
||||
else -> element
|
||||
}
|
||||
|
||||
private val identifiersTokens =
|
||||
setOf(KtTokens.IDENTIFIER, KtTokens.CONSTRUCTOR_KEYWORD, KtTokens.THIS_KEYWORD, KtTokens.SUPER_KEYWORD, KtTokens.OBJECT_KEYWORD)
|
||||
|
||||
internal fun convertPsiElement(element: PsiElement?,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>?): UElement? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? {
|
||||
return {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
ctor(element as P, givenParent)
|
||||
}
|
||||
}
|
||||
|
||||
return with (requiredType) { when (element) {
|
||||
is KtParameterList -> el<UDeclarationsExpression> {
|
||||
val declarationsExpression = KotlinUDeclarationsExpression(givenParent)
|
||||
declarationsExpression.apply {
|
||||
declarations = element.parameters.mapIndexed { i, p ->
|
||||
KotlinUParameter(UastKotlinPsiParameter.create(p, element, declarationsExpression, i), p, this)
|
||||
}
|
||||
}
|
||||
}
|
||||
is KtClassBody -> el<UExpressionList>(build(KotlinUExpressionList.Companion::createClassBody))
|
||||
is KtCatchClause -> el<UCatchClause>(build(::KotlinUCatchClause))
|
||||
is KtVariableDeclaration ->
|
||||
if (element is KtProperty && !element.isLocal) {
|
||||
el<UField> {
|
||||
LightClassUtil.getLightClassBackingField(element)?.let {
|
||||
KotlinUField(it, element, givenParent)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
el<UVariable> {
|
||||
convertVariablesDeclaration(element, givenParent).declarations.singleOrNull()
|
||||
}
|
||||
}
|
||||
|
||||
is KtExpression -> KotlinConverter.convertExpression(element, givenParent, requiredType)
|
||||
is KtLambdaArgument -> element.getLambdaExpression()?.let { KotlinConverter.convertExpression(it, givenParent, requiredType) }
|
||||
is KtLightElementBase -> {
|
||||
val expression = element.kotlinOrigin
|
||||
when (expression) {
|
||||
is KtExpression -> KotlinConverter.convertExpression(expression, givenParent, requiredType)
|
||||
else -> el<UExpression> { UastEmptyExpression(givenParent) }
|
||||
}
|
||||
}
|
||||
is KtLiteralStringTemplateEntry, is KtEscapeStringTemplateEntry -> el<ULiteralExpression>(build(::KotlinStringULiteralExpression))
|
||||
is KtStringTemplateEntry -> element.expression?.let { convertExpression(it, givenParent, requiredType) } ?: expr<UExpression> { UastEmptyExpression }
|
||||
is KtWhenEntry -> el<USwitchClauseExpressionWithBody>(build(::KotlinUSwitchEntry))
|
||||
is KtWhenCondition -> convertWhenCondition(element, givenParent, requiredType)
|
||||
is KtTypeReference -> el<UTypeReferenceExpression> { LazyKotlinUTypeReferenceExpression(element, givenParent) }
|
||||
is KtConstructorDelegationCall ->
|
||||
el<UCallExpression> { KotlinUFunctionCallExpression(element, givenParent) }
|
||||
is KtSuperTypeCallEntry ->
|
||||
el<UExpression> {
|
||||
(element.getParentOfType<KtClassOrObject>(true)?.parent as? KtObjectLiteralExpression)
|
||||
?.toUElementOfType<UExpression>()
|
||||
?: KotlinUFunctionCallExpression(element, givenParent)
|
||||
}
|
||||
is KtImportDirective -> el<UImportStatement>(build(::KotlinUImportStatement))
|
||||
else -> {
|
||||
if (element is LeafPsiElement) {
|
||||
if (element.elementType in identifiersTokens)
|
||||
if (element.elementType != KtTokens.OBJECT_KEYWORD || element.getParentOfType<KtObjectDeclaration>(false)?.nameIdentifier == null)
|
||||
el<UIdentifier>(build(::KotlinUIdentifier))
|
||||
else null
|
||||
else if (element.elementType in KtTokens.OPERATIONS && element.parent is KtOperationReferenceExpression)
|
||||
el<UIdentifier>(build(::KotlinUIdentifier))
|
||||
else if (element.elementType == KtTokens.LBRACKET && element.parent is KtCollectionLiteralExpression)
|
||||
el<UIdentifier> {
|
||||
UIdentifier(
|
||||
element,
|
||||
KotlinUCollectionLiteralExpression(
|
||||
element.parent as KtCollectionLiteralExpression,
|
||||
null
|
||||
)
|
||||
)
|
||||
}
|
||||
else null
|
||||
} else null
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
internal fun convertEntry(entry: KtStringTemplateEntry,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null): UExpression? {
|
||||
return with(requiredType) {
|
||||
if (entry is KtStringTemplateEntryWithExpression) {
|
||||
expr<UExpression> {
|
||||
KotlinConverter.convertOrEmpty(entry.expression, givenParent)
|
||||
}
|
||||
}
|
||||
else {
|
||||
expr<ULiteralExpression> {
|
||||
if (entry is KtEscapeStringTemplateEntry)
|
||||
KotlinStringULiteralExpression(entry, givenParent, entry.unescapedValue)
|
||||
else
|
||||
KotlinStringULiteralExpression(entry, givenParent)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convertExpression(expression: KtExpression,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null): UExpression? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UExpression): () -> UExpression? {
|
||||
return {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
ctor(expression as P, givenParent)
|
||||
}
|
||||
}
|
||||
|
||||
return with (requiredType) { when (expression) {
|
||||
is KtVariableDeclaration -> expr<UDeclarationsExpression>(build(::convertVariablesDeclaration))
|
||||
|
||||
is KtStringTemplateExpression -> {
|
||||
when {
|
||||
expression.entries.isEmpty() -> {
|
||||
expr<ULiteralExpression> { KotlinStringULiteralExpression(expression, givenParent, "") }
|
||||
}
|
||||
expression.entries.size == 1 -> convertEntry(expression.entries[0], givenParent, requiredType)
|
||||
else -> {
|
||||
expr<UExpression> { KotlinStringTemplateUPolyadicExpression(expression, givenParent) }
|
||||
}
|
||||
}
|
||||
}
|
||||
is KtDestructuringDeclaration -> expr<UDeclarationsExpression> {
|
||||
val declarationsExpression = KotlinUDestructuringDeclarationExpression(givenParent, expression)
|
||||
declarationsExpression.apply {
|
||||
val tempAssignment = KotlinULocalVariable(UastKotlinPsiVariable.create(expression, declarationsExpression), expression, declarationsExpression)
|
||||
val destructuringAssignments = expression.entries.mapIndexed { i, entry ->
|
||||
val psiFactory = KtPsiFactory(expression.project)
|
||||
val initializer = psiFactory.createAnalyzableExpression("${tempAssignment.name}.component${i + 1}()",
|
||||
expression.containingFile)
|
||||
initializer.destructuringDeclarationInitializer = true
|
||||
KotlinULocalVariable(UastKotlinPsiVariable.create(entry, tempAssignment.javaPsi, declarationsExpression, initializer), entry, declarationsExpression)
|
||||
}
|
||||
declarations = listOf(tempAssignment) + destructuringAssignments
|
||||
}
|
||||
}
|
||||
is KtLabeledExpression -> expr<ULabeledExpression>(build(::KotlinULabeledExpression))
|
||||
is KtClassLiteralExpression -> expr<UClassLiteralExpression>(build(::KotlinUClassLiteralExpression))
|
||||
is KtObjectLiteralExpression -> expr<UObjectLiteralExpression>(build(::KotlinUObjectLiteralExpression))
|
||||
is KtDotQualifiedExpression -> expr<UQualifiedReferenceExpression>(build(::KotlinUQualifiedReferenceExpression))
|
||||
is KtSafeQualifiedExpression -> expr<UQualifiedReferenceExpression>(build(::KotlinUSafeQualifiedExpression))
|
||||
is KtSimpleNameExpression -> expr<USimpleNameReferenceExpression>(build(::KotlinUSimpleReferenceExpression))
|
||||
is KtCallExpression -> expr<UCallExpression>(build(::KotlinUFunctionCallExpression))
|
||||
is KtCollectionLiteralExpression -> expr<UCallExpression>(build(::KotlinUCollectionLiteralExpression))
|
||||
is KtBinaryExpression -> {
|
||||
if (expression.operationToken == KtTokens.ELVIS) {
|
||||
expr<UExpressionList>(build(::createElvisExpression))
|
||||
}
|
||||
else expr<UBinaryExpression>(build(::KotlinUBinaryExpression))
|
||||
}
|
||||
is KtParenthesizedExpression -> expr<UParenthesizedExpression>(build(::KotlinUParenthesizedExpression))
|
||||
is KtPrefixExpression -> expr<UPrefixExpression>(build(::KotlinUPrefixExpression))
|
||||
is KtPostfixExpression -> expr<UPostfixExpression>(build(::KotlinUPostfixExpression))
|
||||
is KtThisExpression -> expr<UThisExpression>(build(::KotlinUThisExpression))
|
||||
is KtSuperExpression -> expr<USuperExpression>(build(::KotlinUSuperExpression))
|
||||
is KtCallableReferenceExpression -> expr<UCallableReferenceExpression>(build(::KotlinUCallableReferenceExpression))
|
||||
is KtIsExpression -> expr<UBinaryExpressionWithType>(build(::KotlinUTypeCheckExpression))
|
||||
is KtIfExpression -> expr<UIfExpression>(build(::KotlinUIfExpression))
|
||||
is KtWhileExpression -> expr<UWhileExpression>(build(::KotlinUWhileExpression))
|
||||
is KtDoWhileExpression -> expr<UDoWhileExpression>(build(::KotlinUDoWhileExpression))
|
||||
is KtForExpression -> expr<UForEachExpression>(build(::KotlinUForEachExpression))
|
||||
is KtWhenExpression -> expr<USwitchExpression>(build(::KotlinUSwitchExpression))
|
||||
is KtBreakExpression -> expr<UBreakExpression>(build(::KotlinUBreakExpression))
|
||||
is KtContinueExpression -> expr<UContinueExpression>(build(::KotlinUContinueExpression))
|
||||
is KtReturnExpression -> expr<UReturnExpression>(build(::KotlinUReturnExpression))
|
||||
is KtThrowExpression -> expr<UThrowExpression>(build(::KotlinUThrowExpression))
|
||||
is KtBlockExpression -> expr<UBlockExpression> {
|
||||
if (expression.parent is KtFunctionLiteral
|
||||
&& expression.parent.parent is KtLambdaExpression
|
||||
&& givenParent !is KotlinULambdaExpression
|
||||
) {
|
||||
KotlinULambdaExpression(expression.parent.parent as KtLambdaExpression, givenParent).body
|
||||
} else
|
||||
KotlinUBlockExpression(expression, givenParent)
|
||||
}
|
||||
is KtConstantExpression -> expr<ULiteralExpression>(build(::KotlinULiteralExpression))
|
||||
is KtTryExpression -> expr<UTryExpression>(build(::KotlinUTryExpression))
|
||||
is KtArrayAccessExpression -> expr<UArrayAccessExpression>(build(::KotlinUArrayAccessExpression))
|
||||
is KtLambdaExpression -> expr<ULambdaExpression>(build(::KotlinULambdaExpression))
|
||||
is KtBinaryExpressionWithTypeRHS -> expr<UBinaryExpressionWithType>(build(::KotlinUBinaryExpressionWithType))
|
||||
is KtClassOrObject -> expr<UDeclarationsExpression> {
|
||||
expression.toLightClass()?.let { lightClass ->
|
||||
KotlinUDeclarationsExpression(givenParent).apply {
|
||||
declarations = listOf(KotlinUClass.create(lightClass, this))
|
||||
}
|
||||
} ?: UastEmptyExpression(givenParent)
|
||||
}
|
||||
is KtFunction -> if (expression.name.isNullOrEmpty()) {
|
||||
expr<ULambdaExpression>(build(::createLocalFunctionLambdaExpression))
|
||||
}
|
||||
else {
|
||||
expr<UDeclarationsExpression>(build(::createLocalFunctionDeclaration))
|
||||
}
|
||||
|
||||
else -> expr<UExpression>(build(::UnknownKotlinExpression))
|
||||
}}
|
||||
}
|
||||
|
||||
internal fun convertWhenCondition(condition: KtWhenCondition,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>? = null
|
||||
): UExpression? {
|
||||
return with(requiredType) {
|
||||
when (condition) {
|
||||
is KtWhenConditionInRange -> expr<UBinaryExpression> {
|
||||
KotlinCustomUBinaryExpression(condition, givenParent).apply {
|
||||
leftOperand = KotlinStringUSimpleReferenceExpression("it", this)
|
||||
operator = when {
|
||||
condition.isNegated -> KotlinBinaryOperators.NOT_IN
|
||||
else -> KotlinBinaryOperators.IN
|
||||
}
|
||||
rightOperand = KotlinConverter.convertOrEmpty(condition.rangeExpression, this)
|
||||
}
|
||||
}
|
||||
is KtWhenConditionIsPattern -> expr<UBinaryExpression> {
|
||||
KotlinCustomUBinaryExpressionWithType(condition, givenParent).apply {
|
||||
operand = KotlinStringUSimpleReferenceExpression("it", this)
|
||||
operationKind = when {
|
||||
condition.isNegated -> KotlinBinaryExpressionWithTypeKinds.NEGATED_INSTANCE_CHECK
|
||||
else -> UastBinaryExpressionWithTypeKind.INSTANCE_CHECK
|
||||
}
|
||||
val typeRef = condition.typeReference
|
||||
typeReference = typeRef?.let {
|
||||
LazyKotlinUTypeReferenceExpression(it, this) { typeRef.toPsiType(this, boxed = true) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is KtWhenConditionWithExpression ->
|
||||
condition.expression?.let { KotlinConverter.convertExpression(it, givenParent, requiredType) }
|
||||
|
||||
else -> expr<UExpression> { UastEmptyExpression(givenParent) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertEnumEntry(original: KtEnumEntry, givenParent: UElement?): UElement? {
|
||||
return LightClassUtil.getLightClassBackingField(original)?.let { psiField ->
|
||||
if (psiField is KtLightFieldImpl.KtLightEnumConstant) {
|
||||
KotlinUEnumConstant(psiField, psiField.kotlinOrigin, givenParent)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal fun convertDeclaration(
|
||||
element: PsiElement,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>?
|
||||
): UElement? {
|
||||
fun <P : PsiElement> build(ctor: (P, UElement?) -> UElement): () -> UElement? = {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
ctor(element as P, givenParent)
|
||||
}
|
||||
|
||||
fun <P : PsiElement, K : KtElement> buildKt(ktElement: K, ctor: (P, K, UElement?) -> UElement): () -> UElement? = {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
ctor(element as P, ktElement, givenParent)
|
||||
}
|
||||
|
||||
fun <P : PsiElement, K : KtElement> buildKtOpt(ktElement: K?, ctor: (P, K?, UElement?) -> UElement): () -> UElement? = {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
ctor(element as P, ktElement, givenParent)
|
||||
}
|
||||
|
||||
val original = element.originalElement
|
||||
return with(requiredType) {
|
||||
when (original) {
|
||||
is KtLightMethod -> el<UMethod>(build(KotlinUMethod.Companion::create)) // .Companion is needed because of KT-13934
|
||||
is KtLightClass -> when (original.kotlinOrigin) {
|
||||
is KtEnumEntry -> el<UEnumConstant> {
|
||||
convertEnumEntry(original.kotlinOrigin as KtEnumEntry, givenParent)
|
||||
}
|
||||
else -> el<UClass> { KotlinUClass.create(original, givenParent) }
|
||||
}
|
||||
is KtLightFieldImpl.KtLightEnumConstant -> el<UEnumConstant>(buildKtOpt(original.kotlinOrigin, ::KotlinUEnumConstant))
|
||||
is KtLightField -> el<UField>(buildKtOpt(original.kotlinOrigin, ::KotlinUField))
|
||||
is KtLightParameter -> el<UParameter>(buildKtOpt(original.kotlinOrigin, ::KotlinUParameter))
|
||||
is UastKotlinPsiParameter -> el<UParameter>(buildKt(original.ktParameter, ::KotlinUParameter))
|
||||
is UastKotlinPsiVariable -> el<UVariable>(buildKt(original.ktElement, ::KotlinUVariable))
|
||||
|
||||
is KtEnumEntry -> el<UEnumConstant> {
|
||||
convertEnumEntry(original, givenParent)
|
||||
}
|
||||
is KtClassOrObject -> el<UClass> {
|
||||
original.toLightClass()?.let { lightClass ->
|
||||
KotlinUClass.create(lightClass, givenParent)
|
||||
}
|
||||
}
|
||||
is KtFunction ->
|
||||
if (original.isLocal) {
|
||||
el<ULambdaExpression> {
|
||||
val parent = original.parent
|
||||
if (parent is KtLambdaExpression) {
|
||||
KotlinULambdaExpression(parent, givenParent) // your parent is the ULambdaExpression
|
||||
} else if (original.name.isNullOrEmpty()) {
|
||||
createLocalFunctionLambdaExpression(original, givenParent)
|
||||
}
|
||||
else {
|
||||
val uDeclarationsExpression = createLocalFunctionDeclaration(original, givenParent)
|
||||
val localFunctionVar = uDeclarationsExpression.declarations.single() as KotlinLocalFunctionUVariable
|
||||
localFunctionVar.uastInitializer
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
el<UMethod> {
|
||||
val lightMethod = LightClassUtil.getLightClassMethod(original) ?: return null
|
||||
convertDeclaration(lightMethod, givenParent, requiredType)
|
||||
}
|
||||
}
|
||||
|
||||
is KtPropertyAccessor -> el<UMethod> {
|
||||
val lightMethod = LightClassUtil.getLightClassAccessorMethod(original) ?: return null
|
||||
convertDeclaration(lightMethod, givenParent, requiredType)
|
||||
}
|
||||
|
||||
is KtProperty ->
|
||||
if (original.isLocal) {
|
||||
KotlinConverter.convertPsiElement(element, givenParent, requiredType)
|
||||
}
|
||||
else {
|
||||
convertNonLocalProperty(original, givenParent, requiredType)
|
||||
}
|
||||
|
||||
is KtParameter -> el<UParameter> {
|
||||
val lightMethod = when (val ownerFunction = original.ownerFunction) {
|
||||
is KtFunction -> LightClassUtil.getLightClassMethod(ownerFunction)
|
||||
is KtPropertyAccessor -> LightClassUtil.getLightClassAccessorMethod(ownerFunction)
|
||||
else -> null
|
||||
} ?: return null
|
||||
val lightParameter = lightMethod.parameterList.parameters.find { it.name == original.name } ?: return null
|
||||
KotlinUParameter(lightParameter, original, givenParent)
|
||||
}
|
||||
|
||||
is KtFile -> el<UFile> { KotlinUFile(original) }
|
||||
is FakeFileForLightClass -> el<UFile> { KotlinUFile(original.navigationElement) }
|
||||
is KtAnnotationEntry -> el<UAnnotation>(build(::KotlinUAnnotation))
|
||||
is KtCallExpression ->
|
||||
if (requiredType != null && UAnnotation::class.java.isAssignableFrom(requiredType)) {
|
||||
el<UAnnotation> { KotlinUNestedAnnotation.tryCreate(original, givenParent) }
|
||||
} else null
|
||||
is KtLightAnnotationForSourceEntry -> convertDeclarationOrElement(original.kotlinOrigin, givenParent, requiredType)
|
||||
is KtDelegatedSuperTypeEntry -> el<KotlinSupertypeDelegationUExpression> {
|
||||
KotlinSupertypeDelegationUExpression(original, givenParent)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun convertDeclarationOrElement(element: PsiElement, givenParent: UElement?, requiredType: Class<out UElement>?): UElement? {
|
||||
if (element is UElement) return element
|
||||
|
||||
if (element.isValid) {
|
||||
element.getUserData(KOTLIN_CACHED_UELEMENT_KEY)?.get()?.let { cachedUElement ->
|
||||
return if (requiredType == null || requiredType.isInstance(cachedUElement)) cachedUElement else null
|
||||
}
|
||||
}
|
||||
|
||||
val uElement = convertDeclaration(element, givenParent, requiredType)
|
||||
?: KotlinConverter.convertPsiElement(element, givenParent, requiredType)
|
||||
/*
|
||||
if (uElement != null) {
|
||||
element.putUserData(KOTLIN_CACHED_UELEMENT_KEY, WeakReference(uElement))
|
||||
}
|
||||
*/
|
||||
return uElement
|
||||
}
|
||||
|
||||
private fun convertNonLocalProperty(
|
||||
property: KtProperty,
|
||||
givenParent: UElement?,
|
||||
requiredType: Class<out UElement>?
|
||||
): UElement? {
|
||||
val methods = LightClassUtil.getLightClassPropertyMethods(property)
|
||||
return methods.backingField?.let { backingField ->
|
||||
with(requiredType) {
|
||||
el<UField> { KotlinUField(backingField, (backingField as? KtLightElement<*,*>)?.kotlinOrigin, givenParent) }
|
||||
}
|
||||
} ?: methods.getter?.let { getter ->
|
||||
convertDeclaration(getter, givenParent, requiredType)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun convertOrEmpty(expression: KtExpression?, parent: UElement?): UExpression {
|
||||
return expression?.let { convertExpression(it, parent, null) } ?: UastEmptyExpression
|
||||
}
|
||||
|
||||
internal fun convertOrNull(expression: KtExpression?, parent: UElement?): UExpression? {
|
||||
return if (expression != null) convertExpression(expression, parent, null) else null
|
||||
}
|
||||
|
||||
internal fun KtPsiFactory.createAnalyzableExpression(text: String, context: PsiElement): KtExpression =
|
||||
createAnalyzableProperty("val x = $text", context).initializer ?: error("Failed to create expression from text: '$text'")
|
||||
|
||||
internal fun KtPsiFactory.createAnalyzableProperty(text: String, context: PsiElement): KtProperty =
|
||||
createAnalyzableDeclaration(text, context)
|
||||
|
||||
internal fun <TDeclaration : KtDeclaration> KtPsiFactory.createAnalyzableDeclaration(text: String, context: PsiElement): TDeclaration {
|
||||
val file = createAnalyzableFile("dummy.kt", text, context)
|
||||
val declarations = file.declarations
|
||||
assert(declarations.size == 1) { "${declarations.size} declarations in $text" }
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return declarations.first() as TDeclaration
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertVariablesDeclaration(
|
||||
psi: KtVariableDeclaration,
|
||||
parent: UElement?
|
||||
): UDeclarationsExpression {
|
||||
val declarationsExpression = parent as? KotlinUDeclarationsExpression
|
||||
?: psi.parent.toUElementOfType<UDeclarationsExpression>() as? KotlinUDeclarationsExpression
|
||||
?: KotlinUDeclarationsExpression(null, parent, psi)
|
||||
val parentPsiElement = parent?.javaPsi //TODO: looks weird. mb look for the first non-null `javaPsi` in `parents` ?
|
||||
val variable = KotlinUAnnotatedLocalVariable(
|
||||
UastKotlinPsiVariable.create(psi, parentPsiElement, declarationsExpression), psi, declarationsExpression) { annotationParent ->
|
||||
psi.annotationEntries.map { KotlinUAnnotation(it, annotationParent) }
|
||||
}
|
||||
return declarationsExpression.apply { declarations = listOf(variable) }
|
||||
}
|
||||
|
||||
val kotlinUastPlugin get() = UastLanguagePlugin.getInstances().find { it.language == KotlinLanguage.INSTANCE } ?: KotlinUastLanguagePlugin()
|
||||
-159
@@ -1,159 +0,0 @@
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiAnnotation
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.asJava.toLightAnnotation
|
||||
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.source.getPsi
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUMethod
|
||||
|
||||
abstract class KotlinUAnnotationBase<T : KtCallElement>(
|
||||
final override val sourcePsi: T,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUElement(givenParent), UAnnotationEx, UAnchorOwner {
|
||||
|
||||
abstract override val javaPsi: PsiAnnotation?
|
||||
|
||||
final override val psi: PsiElement = sourcePsi
|
||||
|
||||
protected abstract fun annotationUseSiteTarget(): AnnotationUseSiteTarget?
|
||||
|
||||
private val resolvedCall: ResolvedCall<*>? get () = sourcePsi.getResolvedCall(sourcePsi.analyze())
|
||||
|
||||
override val qualifiedName: String? by lz {
|
||||
computeClassDescriptor().takeUnless(ErrorUtils::isError)
|
||||
?.fqNameUnsafe
|
||||
?.takeIf(FqNameUnsafe::isSafe)
|
||||
?.toSafe()
|
||||
?.toString()
|
||||
}
|
||||
|
||||
override val attributeValues: List<UNamedExpression> by lz {
|
||||
resolvedCall?.valueArguments?.entries?.mapNotNull {
|
||||
val arguments = it.value.arguments
|
||||
val name = it.key.name.asString()
|
||||
when {
|
||||
arguments.size == 1 ->
|
||||
KotlinUNamedExpression.create(name, arguments.first(), this)
|
||||
arguments.size > 1 ->
|
||||
KotlinUNamedExpression.create(name, arguments, this)
|
||||
else -> null
|
||||
}
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
protected abstract fun computeClassDescriptor(): ClassDescriptor?
|
||||
|
||||
override fun resolve(): PsiClass? = computeClassDescriptor()?.toSource()?.getMaybeLightElement() as? PsiClass
|
||||
|
||||
override fun findAttributeValue(name: String?): UExpression? =
|
||||
findDeclaredAttributeValue(name) ?: findAttributeDefaultValue(name ?: "value")
|
||||
|
||||
fun findAttributeValueExpression(arg: ValueArgument): UExpression? {
|
||||
val mapping = resolvedCall?.getArgumentMapping(arg)
|
||||
return (mapping as? ArgumentMatch)?.let { match ->
|
||||
val namedExpression = attributeValues.find { it.name == match.valueParameter.name.asString() }
|
||||
namedExpression?.expression as? KotlinUVarargExpression ?: namedExpression
|
||||
}
|
||||
}
|
||||
|
||||
override fun findDeclaredAttributeValue(name: String?): UExpression? {
|
||||
return attributeValues.find {
|
||||
it.name == name ||
|
||||
(name == null && it.name == "value") ||
|
||||
(name == "value" && it.name == null)
|
||||
}?.expression
|
||||
}
|
||||
|
||||
private fun findAttributeDefaultValue(name: String): UExpression? {
|
||||
val parameter = computeClassDescriptor()
|
||||
?.unsubstitutedPrimaryConstructor
|
||||
?.valueParameters
|
||||
?.find { it.name.asString() == name } ?: return null
|
||||
|
||||
val defaultValue = (parameter.source.getPsi() as? KtParameter)?.defaultValue ?: return null
|
||||
return getLanguagePlugin().convertWithParent(defaultValue)
|
||||
}
|
||||
|
||||
override fun convertParent(): UElement? {
|
||||
val superParent = super.convertParent() ?: return null
|
||||
if (annotationUseSiteTarget() == AnnotationUseSiteTarget.RECEIVER) {
|
||||
(superParent.uastParent as? KotlinUMethod)?.uastParameters?.firstIsInstance<KotlinReceiverUParameter>()?.let {
|
||||
return it
|
||||
}
|
||||
}
|
||||
return superParent
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinUAnnotation(
|
||||
annotationEntry: KtAnnotationEntry,
|
||||
givenParent: UElement?
|
||||
) : KotlinUAnnotationBase<KtAnnotationEntry>(annotationEntry, givenParent), UAnnotation {
|
||||
|
||||
override val javaPsi = annotationEntry.toLightAnnotation()
|
||||
|
||||
override fun computeClassDescriptor(): ClassDescriptor? =
|
||||
sourcePsi.analyze()[BindingContext.ANNOTATION, sourcePsi]?.annotationClass
|
||||
|
||||
override fun annotationUseSiteTarget() = sourcePsi.useSiteTarget?.getAnnotationUseSiteTarget()
|
||||
|
||||
override val uastAnchor by lazy {
|
||||
KotlinUIdentifier(
|
||||
javaPsi?.nameReferenceElement,
|
||||
annotationEntry.typeReference?.nameElement,
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class KotlinUNestedAnnotation private constructor(
|
||||
original: KtCallExpression,
|
||||
givenParent: UElement?
|
||||
) : KotlinUAnnotationBase<KtCallExpression>(original, givenParent) {
|
||||
override val javaPsi: PsiAnnotation? by lazy { original.toLightAnnotation() }
|
||||
|
||||
override fun computeClassDescriptor(): ClassDescriptor? = classDescriptor(sourcePsi)
|
||||
|
||||
override fun annotationUseSiteTarget(): AnnotationUseSiteTarget? = null
|
||||
|
||||
override val uastAnchor by lazy {
|
||||
KotlinUIdentifier(
|
||||
javaPsi?.nameReferenceElement?.referenceNameElement,
|
||||
(original.calleeExpression as? KtNameReferenceExpression)?.getReferencedNameElement(),
|
||||
this
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun tryCreate(original: KtCallExpression, givenParent: UElement?): KotlinUNestedAnnotation? {
|
||||
if (classDescriptor(original)?.kind == ClassKind.ANNOTATION_CLASS)
|
||||
return KotlinUNestedAnnotation(original, givenParent)
|
||||
else
|
||||
return null
|
||||
}
|
||||
|
||||
private fun classDescriptor(original: KtCallExpression) =
|
||||
(original.getResolvedCall(original.analyze())?.resultingDescriptor as? ClassConstructorDescriptor)?.constructedClass
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
-49
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS
|
||||
import org.jetbrains.uast.UCallableReferenceExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UExpression
|
||||
|
||||
class KotlinUCallableReferenceExpression(
|
||||
override val sourcePsi: KtCallableReferenceExpression,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent), UCallableReferenceExpression, KotlinUElementWithType {
|
||||
override val qualifierExpression: UExpression?
|
||||
get() {
|
||||
if (qualifierType != null) return null
|
||||
val receiverExpression = sourcePsi.receiverExpression ?: return null
|
||||
return KotlinConverter.convertExpression(receiverExpression, this)
|
||||
}
|
||||
|
||||
override val qualifierType by lz {
|
||||
val ktType = sourcePsi.analyze()[DOUBLE_COLON_LHS, sourcePsi.receiverExpression]?.type ?: return@lz null
|
||||
ktType.toPsiType(this, sourcePsi, boxed = true)
|
||||
}
|
||||
|
||||
override val callableName: String
|
||||
get() = sourcePsi.callableReference.getReferencedName()
|
||||
|
||||
override val resolvedName: String?
|
||||
get() = (resolve() as? PsiNamedElement)?.name
|
||||
|
||||
override fun resolve() = sourcePsi.callableReference.resolveCallToDeclaration()
|
||||
}
|
||||
-200
@@ -1,200 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import com.intellij.psi.PsiType
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
import org.jetbrains.kotlin.resolve.CompileTimeConstantUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.uast.*
|
||||
import org.jetbrains.uast.internal.acceptList
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
import org.jetbrains.uast.visitor.UastVisitor
|
||||
|
||||
class KotlinUFunctionCallExpression(
|
||||
override val sourcePsi: KtCallElement,
|
||||
givenParent: UElement?,
|
||||
private val _resolvedCall: ResolvedCall<*>?
|
||||
) : KotlinAbstractUExpression(givenParent), UCallExpressionEx, KotlinUElementWithType {
|
||||
|
||||
constructor(psi: KtCallElement, uastParent: UElement?) : this(psi, uastParent, null)
|
||||
|
||||
private val resolvedCall
|
||||
get() = _resolvedCall ?: sourcePsi.getResolvedCall(sourcePsi.analyze())
|
||||
|
||||
override val receiverType by lz {
|
||||
val resolvedCall = this.resolvedCall ?: return@lz null
|
||||
val receiver = resolvedCall.dispatchReceiver ?: resolvedCall.extensionReceiver ?: return@lz null
|
||||
receiver.type.toPsiType(this, sourcePsi, boxed = true)
|
||||
}
|
||||
|
||||
override val methodName by lz { resolvedCall?.resultingDescriptor?.name?.asString() }
|
||||
|
||||
override val classReference by lz {
|
||||
KotlinClassViaConstructorUSimpleReferenceExpression(sourcePsi, methodName.orAnonymous("class"), this)
|
||||
}
|
||||
|
||||
override val methodIdentifier by lz {
|
||||
val calleeExpression = sourcePsi.calleeExpression
|
||||
when (calleeExpression) {
|
||||
null -> null
|
||||
is KtNameReferenceExpression ->
|
||||
KotlinUIdentifier(calleeExpression.getReferencedNameElement(), this)
|
||||
is KtConstructorDelegationReferenceExpression ->
|
||||
KotlinUIdentifier(calleeExpression.firstChild ?: calleeExpression, this)
|
||||
is KtConstructorCalleeExpression ->
|
||||
KotlinUIdentifier(
|
||||
calleeExpression.constructorReferenceExpression?.getReferencedNameElement() ?: calleeExpression, this
|
||||
)
|
||||
else -> KotlinUIdentifier(calleeExpression, this)
|
||||
}
|
||||
}
|
||||
|
||||
override val valueArgumentCount: Int
|
||||
get() = sourcePsi.valueArguments.size
|
||||
|
||||
override val valueArguments by lz { sourcePsi.valueArguments.map { KotlinConverter.convertOrEmpty(it.getArgumentExpression(), this) } }
|
||||
|
||||
override fun getArgumentForParameter(i: Int): UExpression? {
|
||||
val resolvedCall = resolvedCall ?: return null
|
||||
val actualParamIndex = if (resolvedCall.extensionReceiver == null) i else i - 1
|
||||
if (actualParamIndex == -1) return receiver
|
||||
return getArgumentExpressionByIndex(actualParamIndex, resolvedCall, this)
|
||||
}
|
||||
|
||||
|
||||
override val typeArgumentCount: Int
|
||||
get() = sourcePsi.typeArguments.size
|
||||
|
||||
override val typeArguments by lz { sourcePsi.typeArguments.map { it.typeReference.toPsiType(this, boxed = true) } }
|
||||
|
||||
override val returnType: PsiType?
|
||||
get() = getExpressionType()
|
||||
|
||||
override val kind: UastCallKind by lz {
|
||||
val resolvedCall = resolvedCall ?: return@lz UastCallKind.METHOD_CALL
|
||||
when {
|
||||
resolvedCall.resultingDescriptor is ConstructorDescriptor -> UastCallKind.CONSTRUCTOR_CALL
|
||||
this.isAnnotationArgumentArrayInitializer() -> UastCallKind.NESTED_ARRAY_INITIALIZER
|
||||
else -> UastCallKind.METHOD_CALL
|
||||
}
|
||||
}
|
||||
|
||||
override val receiver: UExpression?
|
||||
get() {
|
||||
(uastParent as? UQualifiedReferenceExpression)?.let {
|
||||
if (it.selector == this) return it.receiver
|
||||
}
|
||||
|
||||
val ktNameReferenceExpression = sourcePsi.calleeExpression as? KtNameReferenceExpression ?: return null
|
||||
val variableCallDescriptor =
|
||||
(resolvedCall as? VariableAsFunctionResolvedCall)?.variableCall?.resultingDescriptor
|
||||
?: (resolvedCall?.resultingDescriptor as? FunctionDescriptor)?.takeIf { it.visibility == Visibilities.LOCAL }
|
||||
?: return null
|
||||
|
||||
// an implicit receiver for variables calls (KT-25524)
|
||||
return object : KotlinAbstractUExpression(this), UReferenceExpression {
|
||||
|
||||
private val resolvedDeclaration = variableCallDescriptor.toSource()
|
||||
|
||||
override val psi: KtNameReferenceExpression get() = ktNameReferenceExpression
|
||||
|
||||
override val resolvedName: String? get() = (resolvedDeclaration as? PsiNamedElement)?.name
|
||||
|
||||
override fun resolve(): PsiElement? = resolvedDeclaration
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun resolve(): PsiMethod? {
|
||||
val descriptor = resolvedCall?.resultingDescriptor ?: return null
|
||||
val source = descriptor.toSource()
|
||||
return resolveSource(sourcePsi, descriptor, source)
|
||||
}
|
||||
|
||||
override fun accept(visitor: UastVisitor) {
|
||||
if (visitor.visitCallExpression(this)) return
|
||||
methodIdentifier?.accept(visitor)
|
||||
classReference.accept(visitor)
|
||||
valueArguments.acceptList(visitor)
|
||||
|
||||
visitor.afterVisitCallExpression(this)
|
||||
}
|
||||
|
||||
private fun isAnnotationArgumentArrayInitializer(): Boolean {
|
||||
// KtAnnotationEntry (or KtCallExpression when annotation is nested) -> KtValueArgumentList -> KtValueArgument -> arrayOf call
|
||||
val isAnnotationArgument = when (val elementAt2 = sourcePsi.parents.elementAtOrNull(2)) {
|
||||
is KtAnnotationEntry -> true
|
||||
is KtCallExpression -> elementAt2.getParentOfType<KtAnnotationEntry>(true, KtDeclaration::class.java) != null
|
||||
else -> false
|
||||
}
|
||||
if (!isAnnotationArgument) return false
|
||||
|
||||
val resolvedCall = resolvedCall ?: return false
|
||||
return CompileTimeConstantUtils.isArrayFunctionCall(resolvedCall)
|
||||
}
|
||||
|
||||
override fun convertParent(): UElement? = super.convertParent().let { result ->
|
||||
when (result) {
|
||||
is UMethod -> result.uastBody ?: result
|
||||
is UClass ->
|
||||
result.methods
|
||||
.filterIsInstance<KotlinConstructorUMethod>()
|
||||
.firstOrNull { it.isPrimary }
|
||||
?.uastBody
|
||||
?: result
|
||||
else -> result
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal fun getArgumentExpressionByIndex(
|
||||
actualParamIndex: Int,
|
||||
resolvedCall: ResolvedCall<out CallableDescriptor>,
|
||||
parent: UElement
|
||||
): UExpression? {
|
||||
val (parameter, resolvedArgument) = resolvedCall.valueArguments.entries.find { it.key.index == actualParamIndex } ?: return null
|
||||
val arguments = resolvedArgument.arguments
|
||||
if (arguments.isEmpty()) return null
|
||||
if (arguments.size == 1) {
|
||||
val argument = arguments.single()
|
||||
val expression = argument.getArgumentExpression()
|
||||
if (parameter.varargElementType != null && argument.getSpreadElement() == null) {
|
||||
return createVarargsHolder(arguments, parent)
|
||||
}
|
||||
return KotlinConverter.convertOrEmpty(expression, parent)
|
||||
}
|
||||
return createVarargsHolder(arguments, parent)
|
||||
}
|
||||
|
||||
private fun createVarargsHolder(arguments: List<ValueArgument>, parent: UElement?): KotlinUExpressionList =
|
||||
KotlinUExpressionList(null, UastSpecialExpressionKind.VARARGS, parent).apply {
|
||||
expressions = arguments.map { KotlinConverter.convertOrEmpty(it.getArgumentExpression(), parent) }
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import org.jetbrains.kotlin.psi.KtSafeQualifiedExpression
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UQualifiedReferenceExpression
|
||||
|
||||
class KotlinUSafeQualifiedExpression(
|
||||
override val sourcePsi: KtSafeQualifiedExpression,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent), UQualifiedReferenceExpression,
|
||||
KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val receiver by lz { KotlinConverter.convertOrEmpty(sourcePsi.receiverExpression, this) }
|
||||
override val selector by lz { KotlinConverter.convertOrEmpty(sourcePsi.selectorExpression, this) }
|
||||
override val accessType = KotlinQualifiedExpressionAccessTypes.SAFE
|
||||
|
||||
override val resolvedName: String?
|
||||
get() = (resolve() as? PsiNamedElement)?.name
|
||||
|
||||
override fun resolve() = sourcePsi.selectorExpression?.resolveCallToDeclaration()
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtThisExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UIdentifier
|
||||
import org.jetbrains.uast.UThisExpression
|
||||
import org.jetbrains.uast.kotlin.declarations.KotlinUIdentifier
|
||||
import org.jetbrains.uast.kotlin.internal.DelegatedMultiResolve
|
||||
|
||||
class KotlinUThisExpression(
|
||||
override val sourcePsi: KtThisExpression,
|
||||
givenParent: UElement?
|
||||
) : KotlinAbstractUExpression(givenParent), UThisExpression, DelegatedMultiResolve, KotlinUElementWithType, KotlinEvaluatableUElement {
|
||||
override val label: String?
|
||||
get() = sourcePsi.getLabelName()
|
||||
|
||||
override val labelIdentifier: UIdentifier?
|
||||
get() = sourcePsi.getTargetLabel()?.let { KotlinUIdentifier(it, this) }
|
||||
|
||||
override fun resolve() = sourcePsi.analyze()[BindingContext.LABEL_TARGET, sourcePsi.getTargetLabel()]
|
||||
}
|
||||
-86
@@ -1,86 +0,0 @@
|
||||
package org.jetbrains.uast.kotlin.internal
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
|
||||
import org.jetbrains.kotlin.container.ComponentProvider
|
||||
import org.jetbrains.kotlin.container.get
|
||||
import org.jetbrains.kotlin.context.ProjectContext
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||
import org.jetbrains.uast.kotlin.KotlinUastResolveProviderService
|
||||
|
||||
class CliKotlinUastResolveProviderService : KotlinUastResolveProviderService {
|
||||
val Project.analysisCompletedHandler: UastAnalysisHandlerExtension?
|
||||
get() = getExtensions(AnalysisHandlerExtension.extensionPointName)
|
||||
.filterIsInstance<UastAnalysisHandlerExtension>()
|
||||
.firstOrNull()
|
||||
|
||||
override fun getBindingContext(element: KtElement): BindingContext {
|
||||
return element.project.analysisCompletedHandler?.getBindingContext() ?: BindingContext.EMPTY
|
||||
}
|
||||
|
||||
override fun getTypeMapper(element: KtElement): KotlinTypeMapper? {
|
||||
return element.project.analysisCompletedHandler?.getTypeMapper()
|
||||
}
|
||||
|
||||
override fun isJvmElement(psiElement: PsiElement) = true
|
||||
|
||||
override fun getLanguageVersionSettings(element: KtElement): LanguageVersionSettings {
|
||||
return element.project.analysisCompletedHandler?.getLanguageVersionSettings() ?: LanguageVersionSettingsImpl.DEFAULT
|
||||
}
|
||||
}
|
||||
|
||||
class UastAnalysisHandlerExtension : AnalysisHandlerExtension {
|
||||
private var context: BindingContext? = null
|
||||
private var typeMapper: KotlinTypeMapper? = null
|
||||
private var languageVersionSettings: LanguageVersionSettings? = null
|
||||
|
||||
fun getBindingContext() = context
|
||||
|
||||
fun getLanguageVersionSettings() = languageVersionSettings
|
||||
|
||||
fun getTypeMapper(): KotlinTypeMapper? {
|
||||
if (typeMapper != null) return typeMapper
|
||||
val bindingContext = context ?: return null
|
||||
|
||||
val typeMapper = KotlinTypeMapper(
|
||||
bindingContext, ClassBuilderMode.LIGHT_CLASSES,
|
||||
JvmProtoBufUtil.DEFAULT_MODULE_NAME,
|
||||
KotlinTypeMapper.LANGUAGE_VERSION_SETTINGS_DEFAULT // TODO use proper LanguageVersionSettings
|
||||
)
|
||||
this.typeMapper = typeMapper
|
||||
return typeMapper
|
||||
}
|
||||
|
||||
override fun doAnalysis(
|
||||
project: Project,
|
||||
module: ModuleDescriptor,
|
||||
projectContext: ProjectContext,
|
||||
files: Collection<KtFile>,
|
||||
bindingTrace: BindingTrace,
|
||||
componentProvider: ComponentProvider
|
||||
): AnalysisResult? {
|
||||
languageVersionSettings = componentProvider.get<LanguageVersionSettings>()
|
||||
return super.doAnalysis(project, module, projectContext, files, bindingTrace, componentProvider)
|
||||
}
|
||||
|
||||
override fun analysisCompleted(
|
||||
project: Project,
|
||||
module: ModuleDescriptor,
|
||||
bindingTrace: BindingTrace,
|
||||
files: Collection<KtFile>
|
||||
): AnalysisResult? {
|
||||
context = bindingTrace.bindingContext
|
||||
return null
|
||||
}
|
||||
}
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.kotlin.internal
|
||||
|
||||
import org.jetbrains.uast.UResolvable
|
||||
|
||||
|
||||
//Dummy holder until idea 183
|
||||
interface DelegatedMultiResolve : UResolvable
|
||||
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.uast.test.kotlin
|
||||
|
||||
import com.intellij.psi.PsiClassType
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.uast.UQualifiedReferenceExpression
|
||||
import org.jetbrains.uast.test.env.kotlin.findUElementByTextFromPsi
|
||||
import org.jetbrains.kotlin.test.JUnit3WithIdeaConfigurationRunner
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
@RunWith(JUnit3WithIdeaConfigurationRunner::class)
|
||||
class KotlinUastResolveApiTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor =
|
||||
KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||
|
||||
fun testResolveStringFromUast() {
|
||||
val file = myFixture.addFileToProject(
|
||||
"s.kt", """fun foo(){
|
||||
val s = "abc"
|
||||
s.toUpperCase()
|
||||
}
|
||||
""${'"'}"""
|
||||
)
|
||||
|
||||
val refs = file.findUElementByTextFromPsi<UQualifiedReferenceExpression>("s.toUpperCase()")
|
||||
TestCase.assertNotNull((refs.receiver.getExpressionType() as PsiClassType).resolve())
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user