mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-30 00:21:30 +00:00
Compare commits
41 Commits
petukhov/j
...
build-1.3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
28570a681f | ||
|
|
23c77c4432 | ||
|
|
871cb5708d | ||
|
|
76ebfd4f02 | ||
|
|
dc7763804d | ||
|
|
e087fdff6c | ||
|
|
13b87924ba | ||
|
|
a4f4199314 | ||
|
|
19b3836b88 | ||
|
|
c49fedf84b | ||
|
|
69d794591a | ||
|
|
10c0eedf9d | ||
|
|
7fba7e299d | ||
|
|
25cf276591 | ||
|
|
c0520b9f9d | ||
|
|
f95e9f2057 | ||
|
|
1d33d1bdc1 | ||
|
|
90dbd3bc79 | ||
|
|
213611ee14 | ||
|
|
a731b0e3ab | ||
|
|
9087bdb244 | ||
|
|
c5626b7600 | ||
|
|
7c52292b28 | ||
|
|
02b4370132 | ||
|
|
fef22e58c7 | ||
|
|
255dd2fa74 | ||
|
|
7aba6e36cb | ||
|
|
87e7da4414 | ||
|
|
44fb1dd3e0 | ||
|
|
cdc165c019 | ||
|
|
0713dc3152 | ||
|
|
3b87a770fb | ||
|
|
9d640362ee | ||
|
|
a15e286a44 | ||
|
|
5a82573452 | ||
|
|
b7b152f944 | ||
|
|
d19fdb2008 | ||
|
|
4f27cc0efb | ||
|
|
226bdfe993 | ||
|
|
293eb56a9f | ||
|
|
8442ecc368 |
8511
ChangeLog.md
8511
ChangeLog.md
File diff suppressed because it is too large
Load Diff
@@ -182,7 +182,7 @@ extra["versions.trove4j"] = "1.0.20181211"
|
||||
extra["versions.ktor-network"] = "1.0.1"
|
||||
|
||||
if (!project.hasProperty("versions.kotlin-native")) {
|
||||
extra["versions.kotlin-native"] = "1.3.50-dev-11052"
|
||||
extra["versions.kotlin-native"] = "1.3.50-eap-11415"
|
||||
}
|
||||
|
||||
val isTeamcityBuild = project.kotlinBuildProperties.isTeamcityBuild
|
||||
|
||||
@@ -23,6 +23,17 @@ if (flags.includeCidrPlugins) {
|
||||
logger.info("NOT including CIDR plugins in buildSrc/settings.gradle")
|
||||
}
|
||||
|
||||
if (flags.hasKotlinUltimate) {
|
||||
logger.info("Including extension for IJ Ultimate in buildSrc/settings.gradle")
|
||||
include ":prepare-deps:lldb-frontend"
|
||||
include ":prepare-deps:native-debug-plugin"
|
||||
project(":prepare-deps:lldb-frontend").projectDir = file("${flags.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/lldb-frontend")
|
||||
project(":prepare-deps:native-debug-plugin").projectDir = file("${flags.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/native-debug-plugin")
|
||||
} else {
|
||||
logger.info("Not including extension for IJ Ultimate in buildSrc/settings.gradle")
|
||||
}
|
||||
|
||||
|
||||
class LocalBuildPropertiesProvider {
|
||||
private Settings settings
|
||||
private Properties localProperties = new Properties()
|
||||
@@ -57,8 +68,11 @@ class LocalBuildProperties {
|
||||
|
||||
boolean includeCidrPlugins
|
||||
|
||||
boolean hasKotlinUltimate
|
||||
|
||||
LocalBuildProperties(Settings settings) {
|
||||
propertiesProvider = new LocalBuildPropertiesProvider(settings)
|
||||
includeCidrPlugins = propertiesProvider.getBoolean('cidrPluginsEnabled') && new File(propertiesProvider.rootProjectDir, 'kotlin-ultimate').exists()
|
||||
hasKotlinUltimate = new File(propertiesProvider.rootProjectDir, 'kotlin-ultimate').exists()
|
||||
includeCidrPlugins = propertiesProvider.getBoolean('cidrPluginsEnabled') && hasKotlinUltimate
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,9 +57,7 @@ class KotlinBuildProperties(
|
||||
val useBootstrapStdlib: Boolean
|
||||
get() = isInJpsBuildIdeaSync || getBoolean("kotlin.build.useBootstrapStdlib", false)
|
||||
|
||||
val kotlinUltimateExists: Boolean = propertiesProvider.rootProjectDir.resolve("kotlin-ultimate").exists()
|
||||
|
||||
val includeCidrPlugins: Boolean = kotlinUltimateExists && getBoolean("cidrPluginsEnabled")
|
||||
private val kotlinUltimateExists: Boolean = propertiesProvider.rootProjectDir.resolve("kotlin-ultimate").exists()
|
||||
|
||||
val isTeamcityBuild: Boolean = getBoolean("teamcity") || System.getenv("TEAMCITY_VERSION") != null
|
||||
|
||||
@@ -72,6 +70,10 @@ class KotlinBuildProperties(
|
||||
return kotlinUltimateExists && (explicitlyEnabled || isTeamcityBuild)
|
||||
}
|
||||
|
||||
val includeCidrPlugins: Boolean = kotlinUltimateExists && getBoolean("cidrPluginsEnabled")
|
||||
|
||||
val includeUltimate: Boolean = kotlinUltimateExists && (isTeamcityBuild || intellijUltimateEnabled)
|
||||
|
||||
val postProcessing: Boolean get() = isTeamcityBuild || getBoolean("kotlin.build.postprocessing", true)
|
||||
|
||||
val relocation: Boolean get() = postProcessing
|
||||
|
||||
@@ -1159,6 +1159,34 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/annotations/functionalTypes")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FunctionalTypes extends AbstractFirDiagnosticsSmokeTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFunctionalTypes() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/annotations/functionalTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonParenthesizedAnnotationsWithError.kt")
|
||||
public void testNonParenthesizedAnnotationsWithError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/nonParenthesizedAnnotationsWithError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonParenthesizedAnnotationsWithoutError.kt")
|
||||
public void testNonParenthesizedAnnotationsWithoutError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/nonParenthesizedAnnotationsWithoutError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("parenthesizedAnnotations.kt")
|
||||
public void testParenthesizedAnnotations() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/parenthesizedAnnotations.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/annotations/options")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -268,6 +268,8 @@ public interface Errors {
|
||||
DiagnosticFactory1<PsiElement, FqName> EXPERIMENTAL_UNSIGNED_LITERALS = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, FqName> EXPERIMENTAL_UNSIGNED_LITERALS_ERROR = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Const
|
||||
DiagnosticFactory0<PsiElement> CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> CONST_VAL_WITH_GETTER = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
@@ -159,6 +159,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS, "Unsigned literals are experimental and their usages should be marked with ''@{0}'' or ''@UseExperimental({0}::class)''", TO_STRING);
|
||||
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS_ERROR, "Unsigned literals are experimental and their usages must be marked with ''@{0}'' or ''@UseExperimental({0}::class)''", TO_STRING);
|
||||
|
||||
MAP.put(NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES, "Non-parenthesized annotations on function types without receiver aren't yet supported (see KT-31734 for details)");
|
||||
|
||||
MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING);
|
||||
MAP.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members");
|
||||
MAP.put(REDUNDANT_MODIFIER_IN_GETTER, "Visibility modifiers are redundant in getter");
|
||||
|
||||
@@ -34,6 +34,9 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
|
||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||
import org.jetbrains.kotlin.psi.psiUtil.checkReservedYield
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
import org.jetbrains.kotlin.resolve.PossiblyBareType.bare
|
||||
import org.jetbrains.kotlin.resolve.PossiblyBareType.type
|
||||
@@ -69,6 +72,9 @@ class TypeResolver(
|
||||
private val platformToKotlinClassMap: PlatformToKotlinClassMap,
|
||||
private val languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
private val isNonParenthesizedAnnotationsOnFunctionalTypesEnabled =
|
||||
languageVersionSettings.getFeatureSupport(LanguageFeature.NonParenthesizedAnnotationsOnFunctionalTypes) == LanguageFeature.State.ENABLED
|
||||
|
||||
open class TypeTransformerForTests {
|
||||
open fun transformType(kotlinType: KotlinType): KotlinType? = null
|
||||
}
|
||||
@@ -129,12 +135,54 @@ class TypeResolver(
|
||||
internal fun KtElementImplStub<*>.getAllModifierLists(): Array<out KtDeclarationModifierList> =
|
||||
getStubOrPsiChildren(KtStubElementTypes.MODIFIER_LIST, KtStubElementTypes.MODIFIER_LIST.arrayFactory)
|
||||
|
||||
// TODO: remove this method and its usages in 1.4
|
||||
private fun checkNonParenthesizedAnnotationsOnFunctionalType(
|
||||
typeElement: KtFunctionType,
|
||||
annotationEntries: List<KtAnnotationEntry>,
|
||||
trace: BindingTrace
|
||||
) {
|
||||
val lastAnnotationEntry = annotationEntries.lastOrNull()
|
||||
val isAnnotationsGroupedUsingBrackets =
|
||||
lastAnnotationEntry?.getNextSiblingIgnoringWhitespaceAndComments()?.node?.elementType == KtTokens.RBRACKET
|
||||
val hasAnnotationParentheses = lastAnnotationEntry?.valueArgumentList != null
|
||||
val isFunctionalTypeStartingWithParentheses = typeElement.firstChild is KtParameterList
|
||||
val hasSuspendModifierBeforeParentheses =
|
||||
typeElement.getPrevSiblingIgnoringWhitespaceAndComments().run { this is KtDeclarationModifierList && hasSuspendModifier() }
|
||||
|
||||
if (lastAnnotationEntry != null &&
|
||||
isFunctionalTypeStartingWithParentheses &&
|
||||
!hasAnnotationParentheses &&
|
||||
!isAnnotationsGroupedUsingBrackets &&
|
||||
!hasSuspendModifierBeforeParentheses
|
||||
) {
|
||||
trace.report(Errors.NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES.on(lastAnnotationEntry))
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveTypeAnnotations(c: TypeResolutionContext, modifierListsOwner: KtElementImplStub<*>): Annotations {
|
||||
val modifierLists = modifierListsOwner.getAllModifierLists()
|
||||
|
||||
var result = Annotations.EMPTY
|
||||
var isSplitModifierList = false
|
||||
|
||||
if (!isNonParenthesizedAnnotationsOnFunctionalTypesEnabled) {
|
||||
val targetType = when (modifierListsOwner) {
|
||||
is KtNullableType -> modifierListsOwner.innerType
|
||||
is KtTypeReference -> modifierListsOwner.typeElement
|
||||
else -> null
|
||||
}
|
||||
val annotationEntries = when (modifierListsOwner) {
|
||||
is KtNullableType -> modifierListsOwner.modifierList?.annotationEntries
|
||||
is KtTypeReference -> modifierListsOwner.annotationEntries
|
||||
else -> null
|
||||
}
|
||||
|
||||
// `targetType.stub == null` means that we don't apply this check for files that are built with stubs (that aren't opened in IDE and not in compile time)
|
||||
if (targetType is KtFunctionType && targetType.stub == null && annotationEntries != null) {
|
||||
checkNonParenthesizedAnnotationsOnFunctionalType(targetType, annotationEntries, c.trace)
|
||||
}
|
||||
}
|
||||
|
||||
for (modifierList in modifierLists) {
|
||||
if (isSplitModifierList) {
|
||||
c.trace.report(MODIFIER_LIST_NOT_ALLOWED.on(modifierList))
|
||||
|
||||
@@ -509,24 +509,36 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
}
|
||||
|
||||
private boolean parseTypeModifierList() {
|
||||
return doParseModifierList(null, TYPE_MODIFIER_KEYWORDS, DEFAULT, TokenSet.EMPTY);
|
||||
return doParseModifierList(null, TYPE_MODIFIER_KEYWORDS, TYPE_CONTEXT, TokenSet.EMPTY);
|
||||
}
|
||||
|
||||
private boolean parseTypeArgumentModifierList() {
|
||||
return doParseModifierList(null, TYPE_ARGUMENT_MODIFIER_KEYWORDS, NO_ANNOTATIONS, TokenSet.create(COMMA, COLON, GT));
|
||||
}
|
||||
|
||||
private boolean doParseModifierList(
|
||||
private boolean doParseModifierListBody(
|
||||
@Nullable Consumer<IElementType> tokenConsumer,
|
||||
@NotNull TokenSet modifierKeywords,
|
||||
@NotNull AnnotationParsingMode annotationParsingMode,
|
||||
@NotNull TokenSet noModifiersBefore
|
||||
) {
|
||||
PsiBuilder.Marker list = mark();
|
||||
boolean empty = true;
|
||||
PsiBuilder.Marker beforeAnnotationMarker;
|
||||
while (!eof()) {
|
||||
if (at(AT) && annotationParsingMode.allowAnnotations) {
|
||||
parseAnnotationOrList(annotationParsingMode);
|
||||
beforeAnnotationMarker = mark();
|
||||
|
||||
boolean isAnnotationParsed = parseAnnotationOrList(annotationParsingMode);
|
||||
|
||||
if (!isAnnotationParsed && !annotationParsingMode.withSignificantWhitespaceBeforeArguments) {
|
||||
beforeAnnotationMarker.rollbackTo();
|
||||
// try parse again, but with significant whitespace
|
||||
doParseModifierListBody(tokenConsumer, modifierKeywords, WITH_SIGNIFICANT_WHITESPACE_BEFORE_ARGUMENTS, noModifiersBefore);
|
||||
empty = false;
|
||||
break;
|
||||
} else {
|
||||
beforeAnnotationMarker.drop();
|
||||
}
|
||||
}
|
||||
else if (tryParseModifier(tokenConsumer, noModifiersBefore, modifierKeywords)) {
|
||||
// modifier advanced
|
||||
@@ -536,6 +548,25 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
}
|
||||
empty = false;
|
||||
}
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
private boolean doParseModifierList(
|
||||
@Nullable Consumer<IElementType> tokenConsumer,
|
||||
@NotNull TokenSet modifierKeywords,
|
||||
@NotNull AnnotationParsingMode annotationParsingMode,
|
||||
@NotNull TokenSet noModifiersBefore
|
||||
) {
|
||||
PsiBuilder.Marker list = mark();
|
||||
|
||||
boolean empty = doParseModifierListBody(
|
||||
tokenConsumer,
|
||||
modifierKeywords,
|
||||
annotationParsingMode,
|
||||
noModifiersBefore
|
||||
);
|
||||
|
||||
if (empty) {
|
||||
list.drop();
|
||||
}
|
||||
@@ -796,8 +827,27 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
|
||||
parseTypeArgumentList();
|
||||
|
||||
if (at(LPAR)) {
|
||||
boolean whitespaceAfterAnnotation = WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(-1));
|
||||
boolean shouldBeParsedNextAsFunctionalType = at(LPAR) && whitespaceAfterAnnotation && mode.withSignificantWhitespaceBeforeArguments;
|
||||
|
||||
if (at(LPAR) && !shouldBeParsedNextAsFunctionalType) {
|
||||
myExpressionParsing.parseValueArgumentList();
|
||||
|
||||
/*
|
||||
* There are two problem cases relating to parsing of annotations on a functional type:
|
||||
* - Annotation on a functional type was parsed correctly with the capture parentheses of the functional type,
|
||||
* e.g. @Anno () -> Unit
|
||||
* ^ Parse error only here: Type expected
|
||||
* - It wasn't parsed, e.g. @Anno (x: kotlin.Any) -> Unit
|
||||
* ^ Parse error: Expecting ')'
|
||||
*
|
||||
* In both cases, parser should rollback to start parsing of annotation and tries parse it with significant whitespace.
|
||||
* A marker is set here which means that we must to rollback.
|
||||
*/
|
||||
if (mode.typeContext && (getLastToken() != RPAR || at(ARROW))) {
|
||||
annotation.done(ANNOTATION_ENTRY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
annotation.done(ANNOTATION_ENTRY);
|
||||
|
||||
@@ -1995,7 +2045,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
else if (at(LPAR)) {
|
||||
PsiBuilder.Marker functionOrParenthesizedType = mark();
|
||||
|
||||
// This may be a function parameter list or just a prenthesized type
|
||||
// This may be a function parameter list or just a parenthesized type
|
||||
advance(); // LPAR
|
||||
parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed
|
||||
|
||||
@@ -2423,20 +2473,28 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
}
|
||||
|
||||
enum AnnotationParsingMode {
|
||||
DEFAULT(false, true),
|
||||
FILE_ANNOTATIONS_BEFORE_PACKAGE(true, true),
|
||||
FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED(true, true),
|
||||
NO_ANNOTATIONS(false, false);
|
||||
DEFAULT(false, true, false, false),
|
||||
FILE_ANNOTATIONS_BEFORE_PACKAGE(true, true, false, false),
|
||||
FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED(true, true, false, false),
|
||||
TYPE_CONTEXT(false, true, true, false),
|
||||
WITH_SIGNIFICANT_WHITESPACE_BEFORE_ARGUMENTS(false, true, true, true),
|
||||
NO_ANNOTATIONS(false, false, false, false);
|
||||
|
||||
boolean isFileAnnotationParsingMode;
|
||||
boolean allowAnnotations;
|
||||
boolean withSignificantWhitespaceBeforeArguments;
|
||||
boolean typeContext;
|
||||
|
||||
AnnotationParsingMode(
|
||||
boolean isFileAnnotationParsingMode,
|
||||
boolean allowAnnotations
|
||||
boolean allowAnnotations,
|
||||
boolean typeContext,
|
||||
boolean withSignificantWhitespaceBeforeArguments
|
||||
) {
|
||||
this.isFileAnnotationParsingMode = isFileAnnotationParsingMode;
|
||||
this.allowAnnotations = allowAnnotations;
|
||||
this.typeContext = typeContext;
|
||||
this.withSignificantWhitespaceBeforeArguments = withSignificantWhitespaceBeforeArguments;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -CAST_NEVER_SUCCEEDS -CANNOT_CHECK_FOR_ERASED -UNCHECKED_CAST -UNUSED_ANONYMOUS_PARAMETER
|
||||
// SKIP_TXT
|
||||
// Issue: KT-31734
|
||||
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@Repeatable
|
||||
annotation class Foo
|
||||
|
||||
fun foo1(x: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit) = x as Iterable<<!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit>?
|
||||
|
||||
fun foo2() = null as <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit
|
||||
|
||||
fun foo3(x: Any?) {
|
||||
if (x is (<!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@<!DEBUG_INFO_MISSING_UNRESOLVED!>Foo<!><!> () -> Unit)?) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun foo4(x: Any) = x is <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> (() -> Unit?)
|
||||
|
||||
fun foo5(x: Any): <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit = x as @Foo() @[Foo Foo()] <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit
|
||||
|
||||
fun foo6() {
|
||||
val x: @Foo() @[Foo Foo()] <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo7() {
|
||||
val x: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> (<!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit) -> Unit = { x: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit -> }
|
||||
}
|
||||
|
||||
fun foo8(<!UNUSED_PARAMETER!>x<!>: Any?) {
|
||||
val <!NAME_SHADOWING!>x<!>: (<!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit)? = {}
|
||||
}
|
||||
|
||||
fun foo9(x: (<!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit)?) = x as Iterable<(<!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit?)?>?
|
||||
|
||||
fun foo10(x: @[Foo] () -> Unit) = x as Iterable<@Foo() () -> Unit>?
|
||||
|
||||
fun foo11(x: @[Foo ] () -> Unit) = x as Iterable<@Foo() () -> Unit>?
|
||||
|
||||
fun foo12(x: @[Foo/**/] () -> Unit) = x as Iterable<@Foo() () -> Unit>?
|
||||
|
||||
val foo13: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> (x: @Foo Any) -> Unit get() = {}
|
||||
|
||||
val foo14: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> (x: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit) -> Unit get() = {}
|
||||
|
||||
val foo15: @Foo () <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit get() = {}
|
||||
|
||||
val foo16: @Foo @Foo () <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit get() = {}
|
||||
|
||||
val foo17: @Foo() @Foo () <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit get() = {}
|
||||
|
||||
val foo18: @Foo()@Foo () <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit get() = {}
|
||||
|
||||
val foo19: @Foo@Foo () <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit get() = {}
|
||||
|
||||
val foo20: @Foo<!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit get() = {}
|
||||
|
||||
val foo21: @Foo()<!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit get() = {}
|
||||
|
||||
val foo22: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> (x: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit) -> Unit get() = {}
|
||||
|
||||
val foo23: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> (<!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit) -> Unit get() = {}
|
||||
|
||||
val foo24: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> (<!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit, <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> () -> Unit) -> Unit get() = {x, y -> }
|
||||
|
||||
val foo25: <!NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES!>@Foo<!> (x: @Foo Any, @Foo Any) -> Unit get() = {x, y -> }
|
||||
|
||||
val foo26: @Foo suspend () -> Unit = {}
|
||||
@@ -0,0 +1,67 @@
|
||||
// !LANGUAGE: +NonParenthesizedAnnotationsOnFunctionalTypes
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -CAST_NEVER_SUCCEEDS -CANNOT_CHECK_FOR_ERASED -UNCHECKED_CAST -UNUSED_ANONYMOUS_PARAMETER
|
||||
// SKIP_TXT
|
||||
// Issue: KT-31734
|
||||
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@Repeatable
|
||||
annotation class Foo
|
||||
|
||||
class MyClass
|
||||
|
||||
fun foo1(x: @Foo () -> Unit) = x as Iterable<@Foo () -> Unit>?
|
||||
|
||||
fun foo2() = null as @Foo () -> Unit
|
||||
|
||||
fun foo3(x: Any?) {
|
||||
if (x is (@<!DEBUG_INFO_MISSING_UNRESOLVED!>Foo<!> () -> Unit)?) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun foo4(x: Any) = x is @Foo () -> (() -> Unit?)
|
||||
|
||||
fun foo5(x: Any): @Foo () -> Unit = x as @Foo() @[Foo Foo()] @Foo () -> Unit
|
||||
|
||||
fun foo6() {
|
||||
val x: @Foo() @[Foo Foo()] @Foo () -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo7() {
|
||||
val x: @Foo (@Foo () -> Unit) -> Unit = { x: @Foo () -> Unit -> }
|
||||
}
|
||||
|
||||
fun foo10(x: @[Foo()] () -> Unit) = x as Iterable<@Foo() () -> Unit>?
|
||||
|
||||
fun foo11(x: @[Foo] () -> Unit) = x as Iterable<@Foo() () -> Unit>?
|
||||
|
||||
fun foo12(x: @[Foo ] () -> Unit) = x as Iterable<@Foo() () -> Unit>?
|
||||
|
||||
fun foo13(x: @[Foo/**/] () -> Unit) = x as Iterable<@Foo() () -> Unit>?
|
||||
|
||||
val foo14: @Foo (x: @Foo () -> Unit) -> Unit get() = {}
|
||||
|
||||
val foo15: @Foo () @Foo () -> Unit get() = {}
|
||||
|
||||
val foo16: @Foo @Foo () @Foo () -> Unit get() = {}
|
||||
|
||||
val foo17: @Foo() @Foo () @Foo () -> Unit get() = {}
|
||||
|
||||
val foo18: @Foo()@Foo () @Foo () -> Unit get() = {}
|
||||
|
||||
val foo19: @Foo@Foo () @Foo () -> Unit get() = {}
|
||||
|
||||
val foo20: @Foo@Foo () -> Unit get() = {}
|
||||
|
||||
val foo21: @Foo()@Foo () -> Unit get() = {}
|
||||
|
||||
val foo22: @Foo (x: @Foo () -> Unit) -> Unit get() = {}
|
||||
|
||||
val foo23: @Foo (@Foo () -> Unit) -> Unit get() = {}
|
||||
|
||||
val foo24: @Foo (@Foo () -> Unit, @Foo () -> Unit) -> Unit get() = {x, y -> }
|
||||
|
||||
val foo25: @Foo (x: @Foo Any, @Foo Any) -> Unit get() = {x, y -> }
|
||||
|
||||
val foo26: @Foo suspend () -> Unit = {}
|
||||
46
compiler/testData/diagnostics/tests/annotations/functionalTypes/parenthesizedAnnotations.kt
vendored
Normal file
46
compiler/testData/diagnostics/tests/annotations/functionalTypes/parenthesizedAnnotations.kt
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -CAST_NEVER_SUCCEEDS -CANNOT_CHECK_FOR_ERASED -UNCHECKED_CAST -UNUSED_ANONYMOUS_PARAMETER
|
||||
// SKIP_TXT
|
||||
// Issue: KT-31734
|
||||
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
@Repeatable
|
||||
annotation class Foo
|
||||
|
||||
fun foo1(x: @Foo() () -> Unit) = x as Iterable<@Foo() () -> Unit>?
|
||||
|
||||
fun foo2() = null as @Foo() () -> Unit
|
||||
|
||||
fun foo3(x: Any?) {
|
||||
if (x is (@<!DEBUG_INFO_MISSING_UNRESOLVED!>Foo<!>() () -> Unit)?) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun foo4(x: Any) = x is @Foo() () -> (() -> Unit?)
|
||||
|
||||
fun foo5(x: Any): @Foo() () -> Unit = x as @Foo () @[Foo Foo ()] @Foo() () -> Unit
|
||||
|
||||
fun foo6() {
|
||||
val x: @Foo() @[Foo Foo()] @Foo() () -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo7() {
|
||||
val x: @Foo() (@Foo() () -> Unit) -> Unit = { x: @Foo() () -> Unit -> }
|
||||
}
|
||||
|
||||
fun foo8(x: @[Foo() ] () -> Unit) = x as Iterable<@Foo() () -> Unit>?
|
||||
|
||||
fun foo9(x: @[Foo()] () -> Unit) = x as Iterable<@Foo() () -> Unit>?
|
||||
|
||||
fun foo10() {
|
||||
val x: @Foo () @Foo () () -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo11() {
|
||||
val x: @Foo @Foo () () -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo12() {
|
||||
val x: @Foo() @Foo () () -> Unit = {}
|
||||
}
|
||||
11
compiler/testData/psi/annotation/functionalTypes/regressionForSimilarSyntax/forDestructuring.kt
vendored
Normal file
11
compiler/testData/psi/annotation/functionalTypes/regressionForSimilarSyntax/forDestructuring.kt
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
// Issue: KT-31734
|
||||
|
||||
fun foo() {
|
||||
for (@Foo (i: Int) in y) {}
|
||||
for (@Foo (i: () -> Unit) in y) {}
|
||||
for (@Foo (i) in y) {}
|
||||
for (@Foo (i, j) in y) {}
|
||||
for (@Foo (i, j: Int) in y) {}
|
||||
for (@Foo i: Int in y) {}
|
||||
for (@Foo i in y) {}
|
||||
}
|
||||
282
compiler/testData/psi/annotation/functionalTypes/regressionForSimilarSyntax/forDestructuring.txt
vendored
Normal file
282
compiler/testData/psi/annotation/functionalTypes/regressionForSimilarSyntax/forDestructuring.txt
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
KtFile: forDestructuring.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
IMPORT_LIST
|
||||
<empty list>
|
||||
PsiComment(EOL_COMMENT)('// Issue: KT-31734')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
FOR
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_PARAMETER
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiErrorElement:Unexpected type specification
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Int')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(in)('in')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('y')
|
||||
PsiErrorElement:Expecting 'in'
|
||||
<empty list>
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BODY
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
FOR
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_PARAMETER
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiErrorElement:Expecting ')'
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
DESTRUCTURING_DECLARATION
|
||||
PsiElement(LPAR)('(')
|
||||
PsiErrorElement:Expecting a name
|
||||
<empty list>
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Expecting 'in'
|
||||
PsiElement(ARROW)('->')
|
||||
PsiErrorElement:Expecting ')'
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
BODY
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Unit')
|
||||
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(in)('in')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('y')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
BLOCK
|
||||
<empty list>
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
FOR
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_PARAMETER
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(in)('in')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('y')
|
||||
PsiErrorElement:Expecting 'in'
|
||||
<empty list>
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BODY
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
FOR
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_PARAMETER
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('j')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(in)('in')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('y')
|
||||
PsiErrorElement:Expecting 'in'
|
||||
<empty list>
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BODY
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
FOR
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_PARAMETER
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('j')
|
||||
PsiErrorElement:Unexpected type specification
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Int')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(in)('in')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('y')
|
||||
PsiErrorElement:Expecting 'in'
|
||||
<empty list>
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BODY
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
FOR
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_PARAMETER
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Int')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(in)('in')
|
||||
PsiWhiteSpace(' ')
|
||||
LOOP_RANGE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('y')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BODY
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
FOR
|
||||
PsiElement(for)('for')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_PARAMETER
|
||||
MODIFIER_LIST
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(in)('in')
|
||||
PsiWhiteSpace(' ')
|
||||
LOOP_RANGE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('y')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BODY
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -0,0 +1,9 @@
|
||||
// Issue: KT-31734
|
||||
|
||||
fun foo() {
|
||||
val x = { @Foo (foo, bar) -> }
|
||||
val x = { @Foo (foo: kotlin.Any, bar) -> }
|
||||
val x = { @Foo (foo, bar: Any) -> }
|
||||
val x = { @Foo ((foo, bar: Any)) -> }
|
||||
val x = { @Foo () -> Unit }
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
KtFile: lambdaParameterDeclaration.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
IMPORT_LIST
|
||||
<empty list>
|
||||
PsiComment(EOL_COMMENT)('// Issue: KT-31734')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('x')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
||||
PsiElement(ARROW)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('x')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiErrorElement:Unexpected type specification
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('kotlin')
|
||||
PsiErrorElement:Expecting ')'
|
||||
PsiElement(DOT)('.')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Any')
|
||||
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(ARROW)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('x')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiErrorElement:Unexpected type specification
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Any')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
||||
PsiElement(ARROW)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('x')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
PARENTHESIZED
|
||||
PsiElement(LPAR)('(')
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
PsiErrorElement:Expecting ')'
|
||||
<empty list>
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiErrorElement:Unexpected type specification
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Any')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(ARROW)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('x')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
LAMBDA_EXPRESSION
|
||||
FUNCTION_LITERAL
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
ANNOTATED_EXPRESSION
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiErrorElement:Expecting an element
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
||||
PsiElement(ARROW)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Unit')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
@@ -0,0 +1,9 @@
|
||||
// Issue: KT-31734
|
||||
|
||||
fun foo() {
|
||||
val @Foo (i) = Pair(1, 2)
|
||||
var @Foo (i: () -> Unit) = Pair(1, 2)
|
||||
var @Foo (i: Int) = Pair(1, 2)
|
||||
val @Foo (i, j) = Pair(1, 2)
|
||||
val @Foo (i, j: Int) = Pair(1, 2)
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
KtFile: variableDestructuring.kt
|
||||
PACKAGE_DIRECTIVE
|
||||
<empty list>
|
||||
IMPORT_LIST
|
||||
<empty list>
|
||||
PsiComment(EOL_COMMENT)('// Issue: KT-31734')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Annotations are not allowed in this position
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiErrorElement:Expecting property name or receiver type
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Pair')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('2')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
DESTRUCTURING_DECLARATION
|
||||
PsiElement(var)('var')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Annotations are not allowed in this position
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiErrorElement:Expecting ')'
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(LPAR)('(')
|
||||
PsiErrorElement:Expecting a name
|
||||
<empty list>
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Unexpected tokens (use ';' to separate expressions on the same line)
|
||||
PsiElement(ARROW)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Unit')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Pair')
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(INTEGER_LITERAL)('2')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(var)('var')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Annotations are not allowed in this position
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiErrorElement:Unexpected type specification
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Int')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiErrorElement:Expecting property name or receiver type
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Pair')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('2')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Annotations are not allowed in this position
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('j')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiErrorElement:Expecting property name or receiver type
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Pair')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('2')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n ')
|
||||
PROPERTY
|
||||
PsiElement(val)('val')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Annotations are not allowed in this position
|
||||
ANNOTATION_ENTRY
|
||||
PsiElement(AT)('@')
|
||||
CONSTRUCTOR_CALLEE
|
||||
TYPE_REFERENCE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('i')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('j')
|
||||
PsiErrorElement:Unexpected type specification
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(IDENTIFIER)('Int')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiErrorElement:Expecting property name or receiver type
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
CALL_EXPRESSION
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('Pair')
|
||||
VALUE_ARGUMENT_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
VALUE_ARGUMENT
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('1')
|
||||
PsiElement(COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
VALUE_ARGUMENT
|
||||
INTEGER_CONSTANT
|
||||
PsiElement(INTEGER_LITERAL)('2')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace('\n')
|
||||
PsiElement(RBRACE)('}')
|
||||
47
compiler/testData/psi/annotation/functionalTypes/withParentheses/withParameter.kt
vendored
Normal file
47
compiler/testData/psi/annotation/functionalTypes/withParentheses/withParameter.kt
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Issue: KT-31734
|
||||
|
||||
val x: (@Foo(10) suspend (Int) -> Unit) get() = {}
|
||||
|
||||
val x: @Foo({}) ((x: @Foo(10) (@Foo(11) () -> Int) -> Int) -> Unit) get() = {}
|
||||
|
||||
val x: suspend @Foo(10) (x: @Foo(10) (@Foo("") (x: kotlin.Any) -> Int) -> Int) -> Unit get() = {}
|
||||
|
||||
val x: Comparable<@Foo(10) @Bar(10) @Foo(listOf(10)) (x: kotlin.Any = {}) -> Unit> get() = {}
|
||||
|
||||
val x: Any = {} as @Foo({ x: Int -> 10}) suspend (x: @Foo(10) Foo) -> (y: @Foo(10) Bar) -> Unit
|
||||
|
||||
fun foo(x: (@Foo(10) (@Foo({ x: Int -> 10}) kotlin.Any)->()->Unit)) = x
|
||||
|
||||
fun foo(x: suspend @Foo(10) @Bar(10 + @Foo 3) (kotlin.Any) -> Unit = { x: Int -> x }) {}
|
||||
|
||||
fun foo() {
|
||||
val x: @Foo(10) suspend @Bar(throw Exception()) (Coomparable<kotlin.Any>) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val x = { x: suspend @Foo(null) (Coomparable<@Foo(10) @Bar(10) @Foo(10) () -> Unit>) -> () -> Unit -> x }
|
||||
}
|
||||
|
||||
abstract class A {
|
||||
abstract var x: @Foo(10 as @Foo suspend (Int) -> ((Int) -> Unit)) suspend (suspend (Int) -> ((Int) -> Unit)) -> Int
|
||||
}
|
||||
|
||||
fun foo(vararg x: @Foo(10) @Bar(10) @Foo(Any) (Any) -> Unit) = 10
|
||||
|
||||
fun foo(): @Foo.Bar(@Foo x) suspend (Nothing) -> Unit = {}
|
||||
|
||||
fun foo(): () -> @Foo.Bar('1') suspend (Bar) -> Unit = {}
|
||||
|
||||
val x: Any get() = fun(): @Foo("") (Coomparable<Nothing>) -> Unit {}
|
||||
|
||||
fun foo() {
|
||||
var x: (@Foo(object {}) (()->Unit)-> ()->Unit) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo(x: Any) {
|
||||
if (x as @Foo({}) @Bar(10) @Foo(10) (()->Unit) -> Unit is suspend @Foo(10) @Bar(10) @Foo(10) (()->Unit) -> Unit) {}
|
||||
}
|
||||
|
||||
fun foo(y: Any) {
|
||||
var x = y as (@Foo({}) suspend (()->Unit) -> (()->Unit) -> Unit) -> Unit
|
||||
}
|
||||
1774
compiler/testData/psi/annotation/functionalTypes/withParentheses/withParameter.txt
vendored
Normal file
1774
compiler/testData/psi/annotation/functionalTypes/withParentheses/withParameter.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
47
compiler/testData/psi/annotation/functionalTypes/withParentheses/withoutParameter.kt
vendored
Normal file
47
compiler/testData/psi/annotation/functionalTypes/withParentheses/withoutParameter.kt
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Issue: KT-31734
|
||||
|
||||
val x: (@Foo() () -> Unit) get() = {}
|
||||
|
||||
val x: @Foo() (() -> Unit) get() = {}
|
||||
|
||||
val x: @Foo() () -> Unit get() = {}
|
||||
|
||||
val x: Comparable<@Fo() @Bar(10) @Foo() () -> Unit> get() = {}
|
||||
|
||||
val x: Any = {} as @Foo() () -> Unit
|
||||
|
||||
fun foo(x: (@Foo() () -> Unit)) = x
|
||||
|
||||
fun foo(x: @Foo(10) @Bar() () -> Unit = { x: Int -> x }) {}
|
||||
|
||||
fun foo() {
|
||||
val x: @Foo() @Bar() () -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val x = { x: @Foo() () -> () -> Unit -> x }
|
||||
}
|
||||
|
||||
abstract class A {
|
||||
abstract var x: @Foo() (() -> (() -> Unit)) -> Int
|
||||
}
|
||||
|
||||
fun foo(vararg x: @Foo() @Bar(10) @Foo() () -> Unit) = 10
|
||||
|
||||
fun foo(): @Foo.Bar() () -> Unit = {}
|
||||
|
||||
fun foo(): () -> @Foo.Bar() () -> Unit = {}
|
||||
|
||||
val x: Any get() = fun(): @Foo() () -> Unit {}
|
||||
|
||||
fun foo() {
|
||||
var x: (@Foo() ()->()->Unit) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo(x: Any) {
|
||||
if (x as @Foo() @Bar(10) @Foo() () -> Unit is @Foo() @Bar(10) @Foo() () -> Unit) {}
|
||||
}
|
||||
|
||||
fun foo(y: Any) {
|
||||
var x = y as (@Foo() () -> () -> Unit) -> Unit
|
||||
}
|
||||
1116
compiler/testData/psi/annotation/functionalTypes/withParentheses/withoutParameter.txt
vendored
Normal file
1116
compiler/testData/psi/annotation/functionalTypes/withParentheses/withoutParameter.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
51
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/annotationList.kt
vendored
Normal file
51
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/annotationList.kt
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Issue: KT-31734
|
||||
|
||||
val x: (@[Foo] suspend (Int) -> Unit) get() = {}
|
||||
|
||||
val x: (@[Foo] () -> Unit) get() = {}
|
||||
|
||||
val x: (@[Foo] suspend () -> Unit) get() = {}
|
||||
|
||||
val x: @[Foo] ((x: @[Foo] (@[Foo Foo] () -> Int) -> Int) -> Unit) get() = {}
|
||||
|
||||
val x: suspend @[Foo] (x: @[Foo Foo] (@[Foo Foo] (x: kotlin.Any) -> Int) -> Int) -> Unit get() = {}
|
||||
|
||||
val x: Comparable<@[Foo] @[Bar(10)] @[Foo] () -> Unit> get() = {}
|
||||
|
||||
val x: Any = {} as @[Foo Foo] suspend (x: @[Foo] Foo) -> (y: @[Foo] Bar) -> Unit
|
||||
|
||||
fun foo(x: (@Foo ()->()->Unit)) = x
|
||||
|
||||
fun foo(x: suspend @[Foo Foo(10)] @[Bar] (kotlin.Any) -> Unit = { x: Int -> x }) {}
|
||||
|
||||
fun foo() {
|
||||
val x: @[Foo(10)] @[Bar] (Coomparable<kotlin.Any>) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val x = { x: suspend @[Foo Bar] (Coomparable<@[Foo Bar Bar Bar Bar Bar] @[Bar(10)] @[Foo Bar] () -> Unit>) -> () -> Unit -> x }
|
||||
}
|
||||
|
||||
abstract class A {
|
||||
abstract var x: @[Foo Bar] suspend (() -> ((Int) -> Unit)) -> Int
|
||||
}
|
||||
|
||||
fun foo(vararg x: @[Foo Bar] @[Bar(10)] @[Foo Bar] () -> Unit) = 10
|
||||
|
||||
fun foo(): @[Foo.Bar Foo.Bar(1)] suspend () -> Unit = {}
|
||||
|
||||
fun foo(): () -> @[Foo.Bar] () -> Unit = {}
|
||||
|
||||
val x: Any get() = fun(): @[Foo()] (Coomparable<Nothing>) -> Unit {}
|
||||
|
||||
fun foo() {
|
||||
var x: (@[Foo Bar] (()->Unit)-> ()->Unit) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo(x: Any) {
|
||||
if (x as @[Foo] @[Bar(10) Bar] @[Foo Bar] (()->Unit) -> Unit is suspend @[Foo] @[Bar (10)] @[Foo Bar (10)] (()->Unit) -> Unit) {}
|
||||
}
|
||||
|
||||
fun foo(y: Any) {
|
||||
var x = y as (@[Foo Bar] suspend (()->Unit) -> (()->Unit) -> Unit) -> Unit
|
||||
}
|
||||
1752
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/annotationList.txt
vendored
Normal file
1752
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/annotationList.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
47
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withParameter.kt
vendored
Normal file
47
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withParameter.kt
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Issue: KT-31734
|
||||
|
||||
val x: (@Foo suspend (Int) -> Unit) get() = {}
|
||||
|
||||
val x: @Foo ((x: @Foo (@Foo () -> Int) -> Int) -> Unit) get() = {}
|
||||
|
||||
val x: suspend @Foo (x: @Foo (@Foo (x: kotlin.Any) -> Int) -> Int) -> Unit get() = {}
|
||||
|
||||
val x: Comparable<@Foo @Bar(10) @Foo (x: kotlin.Any = {}) -> Unit> get() = {}
|
||||
|
||||
val x: Any = {} as @Foo suspend (x: @Foo Foo) -> (y: @Foo Bar) -> Unit
|
||||
|
||||
fun foo(x: (@Foo (@Foo kotlin.Any)->()->Unit)) = x
|
||||
|
||||
fun foo(x: suspend @Foo(10) @Bar (kotlin.Any) -> Unit = { x: Int -> x }) {}
|
||||
|
||||
fun foo() {
|
||||
val x: @Foo suspend @Bar (Coomparable<kotlin.Any>) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val x = { x: suspend @Foo (Coomparable<@Foo @Bar(10) @Foo () -> Unit>) -> () -> Unit -> x }
|
||||
}
|
||||
|
||||
abstract class A {
|
||||
abstract var x: @Foo suspend (suspend (Int) -> ((Int) -> Unit)) -> Int
|
||||
}
|
||||
|
||||
fun foo(vararg x: @Foo @Bar(10) @Foo (Any) -> Unit) = 10
|
||||
|
||||
fun foo(): @Foo.Bar suspend (Nothing) -> Unit = {}
|
||||
|
||||
fun foo(): () -> @Foo.Bar suspend (Bar) -> Unit = {}
|
||||
|
||||
val x: Any get() = fun(): @Foo (Coomparable<Nothing>) -> Unit {}
|
||||
|
||||
fun foo() {
|
||||
var x: (@Foo (()->Unit)-> ()->Unit) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo(x: Any) {
|
||||
if (x as @Foo @Bar(10) @Foo (()->Unit) -> Unit is suspend @Foo @Bar(10) @Foo (()->Unit) -> Unit) {}
|
||||
}
|
||||
|
||||
fun foo(y: Any) {
|
||||
var x = y as (@Foo suspend (()->Unit) -> (()->Unit) -> Unit) -> Unit
|
||||
}
|
||||
1440
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withParameter.txt
vendored
Normal file
1440
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withParameter.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
51
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withReveiver.kt
vendored
Normal file
51
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withReveiver.kt
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Issue: KT-31734
|
||||
|
||||
val x: (@Foo suspend Int.() -> Unit) get() = {}
|
||||
|
||||
val x: @Foo Int.() -> Unit get() = {}
|
||||
|
||||
val x: @Foo Int.(x: kotlin.Int) -> Unit get() = {}
|
||||
|
||||
val x: @Foo ((x: @Foo (@Foo () -> Int) -> Int.(@Foo () -> Int) -> Int) -> Unit) get() = {}
|
||||
|
||||
val x: suspend @Foo (x: @Foo (@Foo ((x: kotlin.Any) -> Int).(x: kotlin.Any) -> Int) -> Int) -> Unit get() = {}
|
||||
|
||||
val x: Comparable<@Foo @Bar(10) @Foo Unit.(x: kotlin.Any = {}) -> Unit> get() = {}
|
||||
|
||||
val x: Any = {} as @Foo suspend Int.(x: @Foo Foo) -> (y: @Foo Bar) -> Unit
|
||||
|
||||
fun foo(x: (@Foo ((@Foo kotlin.Any)->(Int)).(@Foo kotlin.Any)->()->Unit)) = x
|
||||
|
||||
fun foo(x: suspend @Foo(10) @Bar Comparable<T>.(kotlin.Any) -> Unit = { x: Int -> x }) {}
|
||||
|
||||
fun foo() {
|
||||
val x: @Foo suspend @Bar (Coomparable<kotlin.Any>) -> Unit.(Coomparable<kotlin.Any>) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val x = { x: suspend @Foo @Foo () -> Unit.(Coomparable<@Foo @Bar(10) @Foo () -> Unit>) -> () -> Unit -> x }
|
||||
}
|
||||
|
||||
abstract class A {
|
||||
abstract var x: @Foo suspend (@Foo () -> Unit).(suspend (Int) -> ((Int) -> Unit)) -> Int
|
||||
}
|
||||
|
||||
fun foo(vararg x: @Foo @Bar(10) @Foo Any.(Any) -> Unit) = 10
|
||||
|
||||
fun foo(): @Foo.Bar suspend Nothing.(Nothing) -> Unit = {}
|
||||
|
||||
fun foo(): () -> @Foo.Bar suspend Iterable<@Foo.Bar Int.(Bar) -> Unit>.(Bar) -> Unit = {}
|
||||
|
||||
val x: Any get() = fun(): @Foo (@Foo (Coomparable<Nothing>) -> Unit).(Coomparable<Nothing>) -> Unit {}
|
||||
|
||||
fun foo() {
|
||||
var x: (@Foo (()->Unit)-> @Foo Int.()->Unit) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo(x: Any) {
|
||||
if (x as @Foo @Bar(10) @Foo ()->Unit.(()->Unit) -> Unit is suspend @Foo @Bar(10) @Foo ((()->Unit).()->Unit) -> Unit) {}
|
||||
}
|
||||
|
||||
fun foo(y: Any) {
|
||||
var x = y as (@Foo suspend (suspend (()->Unit)->Int).(()->Unit) -> (Float.()->Unit) -> Unit) -> Unit
|
||||
}
|
||||
1922
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withReveiver.txt
vendored
Normal file
1922
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withReveiver.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
47
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withoutParameter.kt
vendored
Normal file
47
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withoutParameter.kt
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Issue: KT-31734
|
||||
|
||||
val x: (@Foo () -> Unit) get() = {}
|
||||
|
||||
val x: @Foo (() -> Unit) get() = {}
|
||||
|
||||
val x: @Foo () -> Unit get() = {}
|
||||
|
||||
val x: Comparable<@Foo @Bar(10) @Foo () -> Unit> get() = {}
|
||||
|
||||
val x: Any = {} as @Foo () -> Unit
|
||||
|
||||
fun foo(x: (@Foo () -> Unit)) = x
|
||||
|
||||
fun foo(x: @Foo(10) @Bar () -> Unit = { x: Int -> x }) {}
|
||||
|
||||
fun foo() {
|
||||
val x: @Foo @Bar () -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val x = { x: @Foo () -> () -> Unit -> x }
|
||||
}
|
||||
|
||||
abstract class A {
|
||||
abstract var x: @Foo (() -> (() -> Unit)) -> Int
|
||||
}
|
||||
|
||||
fun foo(vararg x: @Foo @Bar(10) @Foo () -> Unit) = 10
|
||||
|
||||
fun foo(): @Foo.Bar () -> Unit = {}
|
||||
|
||||
fun foo(): () -> @Foo.Bar () -> Unit = {}
|
||||
|
||||
val x: Any get() = fun(): @Foo () -> Unit {}
|
||||
|
||||
fun foo() {
|
||||
var x: (@Foo ()->()->Unit) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo(x: Any) {
|
||||
if (x as @Foo @Bar(10) @Foo () -> Unit is @Foo @Bar(10) @Foo () -> Unit) {}
|
||||
}
|
||||
|
||||
fun foo(y: Any) {
|
||||
var x = y as (@Foo () -> () -> Unit) -> Unit
|
||||
}
|
||||
1047
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withoutParameter.txt
vendored
Normal file
1047
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withoutParameter.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
47
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withoutParameterOnSuspend.kt
vendored
Normal file
47
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withoutParameterOnSuspend.kt
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
// Issue: KT-31734
|
||||
|
||||
val x: (@Foo suspend () -> Unit) get() = {}
|
||||
|
||||
val x: @Foo (suspend () -> Unit) get() = {}
|
||||
|
||||
val x: suspend @Foo () -> Unit get() = {}
|
||||
|
||||
val x: Comparable<@Foo suspend @Bar(10) @Foo () -> Unit> get() = {}
|
||||
|
||||
val x: Any = {} as @Foo suspend () -> Unit
|
||||
|
||||
fun foo(x: (suspend @Foo () -> Unit)) = x
|
||||
|
||||
fun foo(x: suspend @Foo(10) @Bar () -> Unit = { x: Int -> x }) {}
|
||||
|
||||
fun foo() {
|
||||
val x: @Foo suspend @Bar () -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo() {
|
||||
val x = { x: suspend @Foo () -> () -> Unit -> x }
|
||||
}
|
||||
|
||||
abstract class A {
|
||||
abstract var x: @Foo suspend (suspend () -> (() -> Unit)) -> Int
|
||||
}
|
||||
|
||||
fun foo(vararg x: @Foo @Bar(10) @Foo () -> Unit) = 10
|
||||
|
||||
fun foo(): @Foo.Bar suspend () -> Unit = {}
|
||||
|
||||
fun foo(): () -> @Foo.Bar suspend () -> Unit = {}
|
||||
|
||||
val x: Any get() = fun(): @Foo suspend () -> Unit {}
|
||||
|
||||
fun foo() {
|
||||
var x: (@Foo ()->suspend ()->Unit) -> Unit = {}
|
||||
}
|
||||
|
||||
fun foo(x: Any) {
|
||||
if (x as @Foo @Bar(10) suspend @Foo () -> Unit is suspend @Foo @Bar(10) @Foo () -> Unit) {}
|
||||
}
|
||||
|
||||
fun foo(y: Any) {
|
||||
var x = y as (@Foo suspend () -> () -> Unit) -> Unit
|
||||
}
|
||||
1086
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withoutParameterOnSuspend.txt
vendored
Normal file
1086
compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withoutParameterOnSuspend.txt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1166,6 +1166,34 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/annotations/functionalTypes")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FunctionalTypes extends AbstractDiagnosticsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFunctionalTypes() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/annotations/functionalTypes"), Pattern.compile("^(.*)\\.kts?$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonParenthesizedAnnotationsWithError.kt")
|
||||
public void testNonParenthesizedAnnotationsWithError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/nonParenthesizedAnnotationsWithError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonParenthesizedAnnotationsWithoutError.kt")
|
||||
public void testNonParenthesizedAnnotationsWithoutError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/nonParenthesizedAnnotationsWithoutError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("parenthesizedAnnotations.kt")
|
||||
public void testParenthesizedAnnotations() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/parenthesizedAnnotations.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/annotations/options")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -1161,6 +1161,34 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/annotations/functionalTypes")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FunctionalTypes extends AbstractDiagnosticsUsingJavacTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFunctionalTypes() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/annotations/functionalTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonParenthesizedAnnotationsWithError.kt")
|
||||
public void testNonParenthesizedAnnotationsWithError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/nonParenthesizedAnnotationsWithError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonParenthesizedAnnotationsWithoutError.kt")
|
||||
public void testNonParenthesizedAnnotationsWithoutError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/nonParenthesizedAnnotationsWithoutError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("parenthesizedAnnotations.kt")
|
||||
public void testParenthesizedAnnotations() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/parenthesizedAnnotations.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/annotations/options")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -901,6 +901,108 @@ public class ParsingTestGenerated extends AbstractParsingTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/psi/annotation/functionalTypes")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FunctionalTypes extends AbstractParsingTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doParsingTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFunctionalTypes() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/psi/annotation/functionalTypes"), Pattern.compile("^(.*)\\.kts?$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/psi/annotation/functionalTypes/regressionForSimilarSyntax")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class RegressionForSimilarSyntax extends AbstractParsingTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doParsingTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInRegressionForSimilarSyntax() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/psi/annotation/functionalTypes/regressionForSimilarSyntax"), Pattern.compile("^(.*)\\.kts?$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("forDestructuring.kt")
|
||||
public void testForDestructuring() throws Exception {
|
||||
runTest("compiler/testData/psi/annotation/functionalTypes/regressionForSimilarSyntax/forDestructuring.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaParameterDeclaration.kt")
|
||||
public void testLambdaParameterDeclaration() throws Exception {
|
||||
runTest("compiler/testData/psi/annotation/functionalTypes/regressionForSimilarSyntax/lambdaParameterDeclaration.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("variableDestructuring.kt")
|
||||
public void testVariableDestructuring() throws Exception {
|
||||
runTest("compiler/testData/psi/annotation/functionalTypes/regressionForSimilarSyntax/variableDestructuring.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/psi/annotation/functionalTypes/withParentheses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class WithParentheses extends AbstractParsingTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doParsingTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInWithParentheses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/psi/annotation/functionalTypes/withParentheses"), Pattern.compile("^(.*)\\.kts?$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("withParameter.kt")
|
||||
public void testWithParameter() throws Exception {
|
||||
runTest("compiler/testData/psi/annotation/functionalTypes/withParentheses/withParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withoutParameter.kt")
|
||||
public void testWithoutParameter() throws Exception {
|
||||
runTest("compiler/testData/psi/annotation/functionalTypes/withParentheses/withoutParameter.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/psi/annotation/functionalTypes/withoutParentheses")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class WithoutParentheses extends AbstractParsingTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doParsingTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInWithoutParentheses() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/psi/annotation/functionalTypes/withoutParentheses"), Pattern.compile("^(.*)\\.kts?$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("annotationList.kt")
|
||||
public void testAnnotationList() throws Exception {
|
||||
runTest("compiler/testData/psi/annotation/functionalTypes/withoutParentheses/annotationList.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withParameter.kt")
|
||||
public void testWithParameter() throws Exception {
|
||||
runTest("compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withReveiver.kt")
|
||||
public void testWithReveiver() throws Exception {
|
||||
runTest("compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withReveiver.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withoutParameter.kt")
|
||||
public void testWithoutParameter() throws Exception {
|
||||
runTest("compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withoutParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withoutParameterOnSuspend.kt")
|
||||
public void testWithoutParameterOnSuspend() throws Exception {
|
||||
runTest("compiler/testData/psi/annotation/functionalTypes/withoutParentheses/withoutParameterOnSuspend.kt");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/psi/annotation/list")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -102,6 +102,7 @@ enum class LanguageFeature(
|
||||
ProhibitUseSiteTargetAnnotationsOnSuperTypes(KOTLIN_1_4, kind = BUG_FIX),
|
||||
ProhibitTypeParametersInClassLiteralsInAnnotationArguments(KOTLIN_1_4, kind = BUG_FIX),
|
||||
ProhibitComparisonOfIncompatibleEnums(KOTLIN_1_4, kind = BUG_FIX),
|
||||
NonParenthesizedAnnotationsOnFunctionalTypes(KOTLIN_1_4),
|
||||
|
||||
ProperVisibilityForCompanionObjectInstanceField(sinceVersion = null, kind = BUG_FIX),
|
||||
// Temporarily disabled, see KT-27084/KT-22379
|
||||
|
||||
@@ -924,7 +924,7 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
|
||||
testClass<AbstractCompletionCharFilterTest> {
|
||||
model("handlers/charFilter")
|
||||
model("handlers/charFilter", pattern = KT_WITHOUT_DOTS_IN_NAME)
|
||||
}
|
||||
|
||||
testClass<AbstractMultiFileJvmBasicCompletionTest> {
|
||||
@@ -1219,7 +1219,7 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
|
||||
testClass<AbstractPerformanceCompletionCharFilterTest> {
|
||||
model("handlers/charFilter", testMethod = "doPerfTest")
|
||||
model("handlers/charFilter", testMethod = "doPerfTest", pattern = KT_WITHOUT_DOTS_IN_NAME)
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.idea.caches
|
||||
|
||||
import com.intellij.ProjectTopics
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
@@ -87,7 +86,7 @@ class KotlinPackageContentModificationListener(private val project: Project) {
|
||||
class KotlinPackageStatementPsiTreeChangePreprocessor(private val project: Project) : PsiTreeChangePreprocessor {
|
||||
override fun treeChanged(event: PsiTreeChangeEventImpl) {
|
||||
val eFile = event.file ?: event.child as? PsiFile
|
||||
if (eFile == null) LOG.debugIfEnabled(project, "Got PsiEvent: $event without file", true)
|
||||
if (eFile == null) LOG.debugIfEnabled(project, true) { "Got PsiEvent: $event without file" }
|
||||
val file = eFile as? KtFile ?: return
|
||||
|
||||
when (event.code) {
|
||||
@@ -96,7 +95,7 @@ class KotlinPackageStatementPsiTreeChangePreprocessor(private val project: Proje
|
||||
PsiTreeChangeEventImpl.PsiEventType.CHILD_REPLACED,
|
||||
PsiTreeChangeEventImpl.PsiEventType.CHILD_REMOVED -> {
|
||||
val child = event.child ?: run {
|
||||
LOG.debugIfEnabled(project, "Got PsiEvent: $event without child", true)
|
||||
LOG.debugIfEnabled(project, true) { "Got PsiEvent: $event without child" }
|
||||
return
|
||||
}
|
||||
if (child.getParentOfType<KtPackageDirective>(false) != null)
|
||||
@@ -104,10 +103,13 @@ class KotlinPackageStatementPsiTreeChangePreprocessor(private val project: Proje
|
||||
}
|
||||
PsiTreeChangeEventImpl.PsiEventType.CHILDREN_CHANGED -> {
|
||||
val parent = event.parent ?: run {
|
||||
LOG.debugIfEnabled(project, "Got PsiEvent: $event without parent", true)
|
||||
LOG.debugIfEnabled(project, true) { "Got PsiEvent: $event without parent" }
|
||||
return
|
||||
}
|
||||
if (parent.getChildrenOfType<KtPackageDirective>().any())
|
||||
val childrenOfType = parent.getChildrenOfType<KtPackageDirective>()
|
||||
if ((!event.isGenericChange && (childrenOfType.any() || parent is KtPackageDirective)) ||
|
||||
(childrenOfType.any { it.name.isEmpty() } && parent is KtFile)
|
||||
)
|
||||
ServiceManager.getService(project, PerModulePackageCacheService::class.java).notifyPackageChange(file)
|
||||
}
|
||||
else -> {
|
||||
@@ -244,7 +246,7 @@ class PerModulePackageCacheService(private val project: Project) {
|
||||
}
|
||||
|
||||
private fun invalidateCacheForModuleSourceInfo(moduleSourceInfo: ModuleSourceInfo) {
|
||||
LOG.debugIfEnabled(project, "Invalidated cache for $moduleSourceInfo", false)
|
||||
LOG.debugIfEnabled(project) { "Invalidated cache for $moduleSourceInfo" }
|
||||
val perSourceInfoData = cache[moduleSourceInfo.module] ?: return
|
||||
val dataForSourceInfo = perSourceInfoData[moduleSourceInfo] ?: return
|
||||
dataForSourceInfo.clear()
|
||||
@@ -264,14 +266,14 @@ class PerModulePackageCacheService(private val project: Project) {
|
||||
if (sourceRootUrls.any { url ->
|
||||
vfile.containedInOrContains(url)
|
||||
}) {
|
||||
LOG.debugIfEnabled(project, "Invalidated cache for $module")
|
||||
LOG.debugIfEnabled(project) { "Invalidated cache for $module" }
|
||||
data.clear()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val infoByVirtualFile = getModuleInfoByVirtualFile(project, vfile)
|
||||
if (infoByVirtualFile == null || infoByVirtualFile !is ModuleSourceInfo) {
|
||||
LOG.debugIfEnabled(project, "Skip $vfile as it has mismatched ModuleInfo=$infoByVirtualFile")
|
||||
LOG.debugIfEnabled(project) { "Skip $vfile as it has mismatched ModuleInfo=$infoByVirtualFile" }
|
||||
}
|
||||
(infoByVirtualFile as? ModuleSourceInfo)?.let {
|
||||
invalidateCacheForModuleSourceInfo(it)
|
||||
@@ -283,13 +285,13 @@ class PerModulePackageCacheService(private val project: Project) {
|
||||
|
||||
pendingKtFileChanges.processPending { file ->
|
||||
if (file.virtualFile != null && file.virtualFile !in projectScope) {
|
||||
LOG.debugIfEnabled(project, "Skip $file without vFile, or not in scope: ${file.virtualFile?.let { it !in projectScope }}")
|
||||
LOG.debugIfEnabled(project) { "Skip $file without vFile, or not in scope: ${file.virtualFile?.let { it !in projectScope }}" }
|
||||
return@processPending
|
||||
}
|
||||
val nullableModuleInfo = file.getNullableModuleInfo()
|
||||
(nullableModuleInfo as? ModuleSourceInfo)?.let { invalidateCacheForModuleSourceInfo(it) }
|
||||
if (nullableModuleInfo == null || nullableModuleInfo !is ModuleSourceInfo) {
|
||||
LOG.debugIfEnabled(project, "Skip $file as it has mismatched ModuleInfo=$nullableModuleInfo")
|
||||
LOG.debugIfEnabled(project) { "Skip $file as it has mismatched ModuleInfo=$nullableModuleInfo" }
|
||||
}
|
||||
implicitPackagePrefixCache.update(file)
|
||||
}
|
||||
@@ -329,7 +331,7 @@ class PerModulePackageCacheService(private val project: Project) {
|
||||
|
||||
return cacheForCurrentModuleInfo.getOrPut(packageFqName) {
|
||||
val packageExists = PackageIndexUtil.packageExists(packageFqName, moduleInfo.contentScope(), project)
|
||||
LOG.debugIfEnabled(project, "Computed cache value for $packageFqName in $moduleInfo is $packageExists")
|
||||
LOG.debugIfEnabled(project) { "Computed cache value for $packageFqName in $moduleInfo is $packageExists" }
|
||||
packageExists
|
||||
}
|
||||
}
|
||||
@@ -351,16 +353,14 @@ class PerModulePackageCacheService(private val project: Project) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private fun Logger.debugIfEnabled(project: Project, message: String, withCurrentTrace: Boolean = false) {
|
||||
private fun Logger.debugIfEnabled(project: Project, withCurrentTrace: Boolean = false, message: () -> String) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode && project.DEBUG_LOG_ENABLE_PerModulePackageCache) {
|
||||
val msg = message()
|
||||
if (withCurrentTrace) {
|
||||
val e = Exception().apply { fillInStackTrace() }
|
||||
this.debug(message, e)
|
||||
this.debug(msg, e)
|
||||
} else {
|
||||
this.debug(message)
|
||||
this.debug(msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,8 +51,8 @@ import org.jetbrains.kotlin.idea.core.script.dependencies.ScriptAdditionalIdeaDe
|
||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.platform.DefaultIdeTargetPlatformKindProvider
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.contains
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -109,8 +109,7 @@ class KotlinCacheServiceImpl(val project: Project) : KotlinCacheService {
|
||||
syntheticFiles: Collection<KtFile> = listOf()
|
||||
): ProjectResolutionFacade {
|
||||
val sdk = dependenciesModuleInfo.sdk
|
||||
val platform = /* Fallback to Common platform in CIDR (Java is not supported there) */
|
||||
DefaultIdeTargetPlatformKindProvider.defaultPlatform // TODO: Js scripts?
|
||||
val platform = JvmPlatforms.defaultJvmPlatform // TODO: Js scripts?
|
||||
val settings = PlatformAnalysisSettings(
|
||||
platform, sdk, true,
|
||||
LanguageFeature.ReleaseCoroutines.defaultState == LanguageFeature.State.ENABLED
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||
import org.jetbrains.kotlin.idea.util.isRunningInCidrIde
|
||||
import org.jetbrains.kotlin.psi.KtCodeFragment
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import kotlin.script.experimental.dependencies.ScriptReport
|
||||
import kotlin.script.experimental.api.ScriptDiagnostic
|
||||
|
||||
object KotlinHighlightingUtil {
|
||||
fun shouldHighlight(psiElement: PsiElement): Boolean {
|
||||
@@ -71,7 +71,7 @@ object KotlinHighlightingUtil {
|
||||
private fun shouldHighlightScript(ktFile: KtFile): Boolean {
|
||||
if (isRunningInCidrIde) return false // There is no Java support in CIDR. So do not highlight errors in KTS if running in CIDR.
|
||||
if (!ScriptsCompilationConfigurationUpdater.areDependenciesCached(ktFile)) return false
|
||||
if (IdeScriptReportSink.getReports(ktFile.virtualFile).any { it.severity == ScriptReport.Severity.FATAL }) {
|
||||
if (IdeScriptReportSink.getReports(ktFile.virtualFile).any { it.severity == ScriptDiagnostic.Severity.FATAL }) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@file:Suppress("PackageDirectoryMismatch")
|
||||
// TODO: move to scripting-idea module
|
||||
package org.jetbrains.kotlin.idea.script
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
import kotlin.script.experimental.api.ScriptDiagnostic
|
||||
|
||||
interface ScriptDiagnosticFixProvider {
|
||||
|
||||
fun provideFixes(annotation: ScriptDiagnostic): List<IntentionAction>
|
||||
|
||||
companion object {
|
||||
val EP_NAME = ExtensionPointName.create<ScriptDiagnosticFixProvider>("org.jetbrains.kotlin.scriptDiagnosticFixProvider")
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,7 @@ 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.script.ScriptDiagnosticFixProvider
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import kotlin.script.experimental.api.ScriptDiagnostic
|
||||
import kotlin.script.experimental.api.SourceCode
|
||||
@@ -54,19 +55,25 @@ class ScriptExternalHighlightingPass(
|
||||
|
||||
val reports = IdeScriptReportSink.getReports(file.virtualFile)
|
||||
|
||||
val annotations = reports.mapNotNull { (message, severity, _ , location) ->
|
||||
val (startOffset, endOffset) = location?.let { computeOffsets(document, it) } ?: 0 to 0
|
||||
val annotations = reports.mapNotNull { scriptDiagnostic ->
|
||||
val (startOffset, endOffset) = scriptDiagnostic.location?.let { computeOffsets(document, it) } ?: 0 to 0
|
||||
val annotation = Annotation(
|
||||
startOffset,
|
||||
endOffset,
|
||||
severity.convertSeverity() ?: return@mapNotNull null,
|
||||
message,
|
||||
message
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ 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
|
||||
@@ -75,19 +76,25 @@ class ScriptExternalHighlightingPass(
|
||||
|
||||
val reports = IdeScriptReportSink.getReports(file.virtualFile)
|
||||
|
||||
val annotations = reports.mapNotNull { (message, severity, _ , location) ->
|
||||
val (startOffset, endOffset) = location?.let { computeOffsets(document, it) } ?: 0 to 0
|
||||
val annotations = reports.mapNotNull { scriptDiagnostic ->
|
||||
val (startOffset, endOffset) = scriptDiagnostic.location?.let { computeOffsets(document, it) } ?: 0 to 0
|
||||
val annotation = Annotation(
|
||||
startOffset,
|
||||
endOffset,
|
||||
severity.convertSeverity() ?: return@mapNotNull null,
|
||||
message,
|
||||
message
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
5
idea/idea-completion/testData/handlers/charFilter/MessageBundle1.dependency.kt
vendored
Normal file
5
idea/idea-completion/testData/handlers/charFilter/MessageBundle1.dependency.kt
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
package org.jetbrains.annotations
|
||||
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
@Target(AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.FIELD)
|
||||
public annotation class PropertyKey(public val resourceBundle: String)
|
||||
3
idea/idea-completion/testData/handlers/charFilter/MessageBundle1.dependency.properties
vendored
Normal file
3
idea/idea-completion/testData/handlers/charFilter/MessageBundle1.dependency.properties
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
foobar = 0
|
||||
foo.bar = 1
|
||||
bar.baz = 2
|
||||
10
idea/idea-completion/testData/handlers/charFilter/MessageBundle1.kt
vendored
Normal file
10
idea/idea-completion/testData/handlers/charFilter/MessageBundle1.kt
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import org.jetbrains.annotations.PropertyKey
|
||||
|
||||
fun message(@PropertyKey(resourceBundle = "MessageBundle1.dependency") key: String) = key
|
||||
|
||||
fun test() {
|
||||
message("<caret>")
|
||||
}
|
||||
|
||||
// ELEMENT: foo.bar
|
||||
// CHARS: 'foo\n'
|
||||
10
idea/idea-completion/testData/handlers/charFilter/MessageBundle1.kt.after
vendored
Normal file
10
idea/idea-completion/testData/handlers/charFilter/MessageBundle1.kt.after
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import org.jetbrains.annotations.PropertyKey
|
||||
|
||||
fun message(@PropertyKey(resourceBundle = "MessageBundle1.dependency") key: String) = key
|
||||
|
||||
fun test() {
|
||||
message("foo.bar")
|
||||
}
|
||||
|
||||
// ELEMENT: foo.bar
|
||||
// CHARS: 'foo\n'
|
||||
@@ -24,6 +24,7 @@ abstract class AbstractCompletionHandlerTest(private val defaultCompletionType:
|
||||
private val ELEMENT_TEXT_PREFIX = "ELEMENT_TEXT:"
|
||||
private val TAIL_TEXT_PREFIX = "TAIL_TEXT:"
|
||||
private val COMPLETION_CHAR_PREFIX = "CHAR:"
|
||||
private val COMPLETION_CHARS_PREFIX = "CHARS:"
|
||||
private val CODE_STYLE_SETTING_PREFIX = "CODE_STYLE_SETTING:"
|
||||
|
||||
protected open fun doTest(testPath: String) {
|
||||
@@ -42,12 +43,10 @@ abstract class AbstractCompletionHandlerTest(private val defaultCompletionType:
|
||||
val itemText = InTextDirectivesUtils.findStringWithPrefixes(fileText, ELEMENT_TEXT_PREFIX)
|
||||
val tailText = InTextDirectivesUtils.findStringWithPrefixes(fileText, TAIL_TEXT_PREFIX)
|
||||
|
||||
val completionCharString = InTextDirectivesUtils.findStringWithPrefixes(fileText, COMPLETION_CHAR_PREFIX)
|
||||
val completionChar = when(completionCharString) {
|
||||
"\\n", null -> '\n'
|
||||
"\\t" -> '\t'
|
||||
else -> completionCharString.singleOrNull() ?: error("Incorrect completion char: \"$completionCharString\"")
|
||||
}
|
||||
val completionChars = completionChars(
|
||||
char = InTextDirectivesUtils.findStringWithPrefixes(fileText, COMPLETION_CHAR_PREFIX),
|
||||
chars = InTextDirectivesUtils.findStringWithPrefixes(fileText, COMPLETION_CHARS_PREFIX)
|
||||
)
|
||||
|
||||
val completionType = ExpectedCompletionUtils.getCompletionType(fileText) ?: defaultCompletionType
|
||||
|
||||
@@ -70,7 +69,15 @@ abstract class AbstractCompletionHandlerTest(private val defaultCompletionType:
|
||||
}
|
||||
}
|
||||
|
||||
doTestWithTextLoaded(completionType, invocationCount, lookupString, itemText, tailText, completionChar, File(testPath).name + ".after")
|
||||
doTestWithTextLoaded(
|
||||
completionType,
|
||||
invocationCount,
|
||||
lookupString,
|
||||
itemText,
|
||||
tailText,
|
||||
completionChars,
|
||||
File(testPath).name + ".after"
|
||||
)
|
||||
} finally {
|
||||
if (configured) {
|
||||
rollbackCompilerOptions(project, module)
|
||||
|
||||
@@ -31,7 +31,7 @@ class BasicCompletionHandlerTest : CompletionHandlerTestBase(){
|
||||
|
||||
private fun doTest(time: Int, lookupString: String?, itemText: String?, tailText: String?, completionChar: Char) {
|
||||
fixture.configureByFile(fileName())
|
||||
doTestWithTextLoaded(CompletionType.BASIC, time, lookupString, itemText, tailText, completionChar, fileName() + ".after")
|
||||
doTestWithTextLoaded(CompletionType.BASIC, time, lookupString, itemText, tailText, completionChar.toString(), fileName() + ".after")
|
||||
}
|
||||
|
||||
fun testClassCompletionImport() = doTest(2, "SortedSet", null, '\n')
|
||||
|
||||
@@ -26,7 +26,7 @@ public class CompletionCharFilterTestGenerated extends AbstractCompletionCharFil
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCharFilter() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/charFilter"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/charFilter"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("Colon.kt")
|
||||
@@ -144,6 +144,11 @@ public class CompletionCharFilterTestGenerated extends AbstractCompletionCharFil
|
||||
runTest("idea/idea-completion/testData/handlers/charFilter/LParenth.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MessageBundle1.kt")
|
||||
public void testMessageBundle1() throws Exception {
|
||||
runTest("idea/idea-completion/testData/handlers/charFilter/MessageBundle1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NamedParameter1.kt")
|
||||
public void testNamedParameter1() throws Exception {
|
||||
runTest("idea/idea-completion/testData/handlers/charFilter/NamedParameter1.kt");
|
||||
|
||||
@@ -20,26 +20,40 @@ abstract class CompletionHandlerTestBase() : KotlinLightCodeInsightFixtureTestCa
|
||||
get() = myFixture
|
||||
|
||||
protected fun doTestWithTextLoaded(
|
||||
completionType: CompletionType,
|
||||
time: Int,
|
||||
lookupString: String?,
|
||||
itemText: String?,
|
||||
tailText: String?,
|
||||
completionChar: Char,
|
||||
afterFilePath: String
|
||||
completionType: CompletionType,
|
||||
time: Int,
|
||||
lookupString: String?,
|
||||
itemText: String?,
|
||||
tailText: String?,
|
||||
completionChars: String,
|
||||
afterFilePath: String
|
||||
) {
|
||||
for (idx in 0 until completionChars.length - 1) {
|
||||
fixture.type(completionChars[idx])
|
||||
}
|
||||
|
||||
fixture.complete(completionType, time)
|
||||
|
||||
if (lookupString != null || itemText != null || tailText != null) {
|
||||
val item = getExistentLookupElement(lookupString, itemText, tailText)
|
||||
if (item != null) {
|
||||
selectItem(item, completionChar)
|
||||
selectItem(item, completionChars.last())
|
||||
}
|
||||
}
|
||||
|
||||
fixture.checkResultByFile(afterFilePath)
|
||||
}
|
||||
|
||||
protected fun completionChars(char: String?, chars: String?): String =
|
||||
when (char) {
|
||||
null -> when (chars) {
|
||||
null -> "\n"
|
||||
else -> chars.replace("\\n", "\n").replace("\\t", "\t")
|
||||
}
|
||||
"\\n" -> "\n"
|
||||
"\\t" -> "\t"
|
||||
else -> char.single().toString() ?: error("Incorrect completion char: \"$char\"")
|
||||
}
|
||||
|
||||
protected fun getExistentLookupElement(lookupString: String?, itemText: String?, tailText: String?): LookupElement? {
|
||||
val lookup = LookupManager.getInstance(project)?.activeLookup as LookupImpl? ?: return null
|
||||
val items = lookup.items
|
||||
|
||||
@@ -14,7 +14,7 @@ fun CodeInsightTestFixture.configureWithExtraFile(path: String, vararg extraName
|
||||
val fileName = File(path).name
|
||||
|
||||
val noExtensionPath = FileUtil.getNameWithoutExtension(fileName)
|
||||
val extensions = arrayOf("kt", "java")
|
||||
val extensions = arrayOf("kt", "java", "properties")
|
||||
val extraPaths: List<String> = extraNameParts
|
||||
.flatMap { extensions.map { ext -> "$noExtensionPath$it.$ext" } }
|
||||
.mapNotNull { File(testDataPath, it).takeIf { it.exists() }?.name }
|
||||
|
||||
@@ -13,10 +13,12 @@ import com.intellij.openapi.module.ModuleUtil
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.roots.ModulePackageIndex
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.vfs.LocalFileSystem
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.util.Query
|
||||
import com.intellij.util.io.parentSystemIndependentPath
|
||||
import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootProperties
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||
@@ -31,6 +33,8 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
import java.nio.file.Paths
|
||||
|
||||
fun PsiDirectory.getPackage(): PsiPackage? = JavaDirectoryService.getInstance()!!.getPackage(this)
|
||||
|
||||
@@ -110,13 +114,21 @@ private fun Module.getOrConfigureKotlinSourceRoots(): List<VirtualFile> {
|
||||
return sourceRoots
|
||||
}
|
||||
return runWriteAction {
|
||||
val rootDir = rootManager.contentRoots.firstOrNull()
|
||||
rootDir?.createChildDirectory(project, "kotlin")
|
||||
getOrCreateRootDirectory()?.createChildDirectory(project, "kotlin")
|
||||
project.invalidateProjectRoots()
|
||||
getNonGeneratedKotlinSourceRoots()
|
||||
}
|
||||
}
|
||||
|
||||
private fun Module.getOrCreateRootDirectory(): VirtualFile? {
|
||||
val contentEntry = rootManager.contentEntries.firstOrNull() ?: return null
|
||||
contentEntry.file?.let { return it }
|
||||
|
||||
val path = Paths.get(URI.create(contentEntry.url))
|
||||
val rootParent = LocalFileSystem.getInstance().findFileByPath(path.parentSystemIndependentPath)
|
||||
return rootParent?.createChildDirectory(project, name.takeLastWhile { it != '.' })
|
||||
}
|
||||
|
||||
private fun getPackageDirectoriesInModule(rootPackage: PsiPackage, module: Module): Array<PsiDirectory> =
|
||||
rootPackage.getDirectories(GlobalSearchScope.moduleScope(module))
|
||||
|
||||
|
||||
@@ -147,7 +147,10 @@ class ScriptDefinitionsManager(private val project: Project) : LazyScriptDefinit
|
||||
}
|
||||
|
||||
fun isReady(): Boolean {
|
||||
return definitionsBySource.keys.all { source ->
|
||||
if (definitions == null) {
|
||||
reloadScriptDefinitions()
|
||||
}
|
||||
return definitions != null && definitionsBySource.keys.all { source ->
|
||||
// TODO: implement another API for readiness checking
|
||||
(source as? ScriptDefinitionContributor)?.isReady() != false
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.idea.caches.project.getAllProjectSdks
|
||||
import org.jetbrains.kotlin.idea.core.script.dependencies.SyncScriptDependenciesLoader
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDependenciesProvider
|
||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
|
||||
import java.io.File
|
||||
@@ -125,7 +126,8 @@ class ScriptDependenciesManager internal constructor(
|
||||
@TestOnly
|
||||
fun updateScriptDependenciesSynchronously(virtualFile: VirtualFile, project: Project) {
|
||||
val loader = SyncScriptDependenciesLoader(project)
|
||||
loader.loadDependencies(virtualFile)
|
||||
val scriptDefinition = virtualFile.findScriptDefinition(project) ?: return
|
||||
loader.loadDependencies(virtualFile, scriptDefinition)
|
||||
loader.notifyRootsChanged()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.util.Alarm
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.core.script.dependencies.AsyncScriptDependenciesLoader
|
||||
import org.jetbrains.kotlin.idea.core.script.dependencies.FromFileAttributeScriptDependenciesLoader
|
||||
import org.jetbrains.kotlin.idea.core.script.dependencies.OutsiderFileDependenciesLoader
|
||||
@@ -43,6 +42,7 @@ import org.jetbrains.kotlin.psi.NotNullableUserDataProperty
|
||||
import org.jetbrains.kotlin.scripting.definitions.KotlinScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.definitions.isNonScript
|
||||
import org.jetbrains.kotlin.scripting.resolve.LegacyResolverWrapper
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult
|
||||
import kotlin.script.experimental.dependencies.AsyncDependenciesResolver
|
||||
@@ -101,7 +101,8 @@ class ScriptsCompilationConfigurationUpdater(
|
||||
if (!ScriptDefinitionsManager.getInstance(project).isReady()) return
|
||||
if (!cache.shouldRunDependenciesUpdate(file)) return
|
||||
|
||||
loaders.filter { it.isApplicable(file) }.forEach { it.loadDependencies(file) }
|
||||
val scriptDefinition = file.findScriptDefinition(project) ?: return
|
||||
loaders.filter { it.isApplicable(file, scriptDefinition) }.forEach { it.loadDependencies(file, scriptDefinition) }
|
||||
}
|
||||
|
||||
private fun makeRootsChangeIfNeeded() {
|
||||
@@ -161,7 +162,7 @@ class ScriptsCompilationConfigurationUpdater(
|
||||
}
|
||||
|
||||
private fun shouldStartUpdate(file: VirtualFile): Boolean {
|
||||
if (project.isDisposed || !file.isValid || file.fileType != KotlinFileType.INSTANCE) {
|
||||
if (project.isDisposed || !file.isValid || file.isNonScript()) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import kotlinx.coroutines.Runnable
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptsCompilationConfigurationUpdater
|
||||
import org.jetbrains.kotlin.idea.core.script.settings.KotlinScriptingSettings
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
||||
import org.jetbrains.kotlin.scripting.resolve.refineScriptCompilationConfiguration
|
||||
@@ -28,12 +29,17 @@ class AsyncScriptDependenciesLoader internal constructor(project: Project) : Scr
|
||||
private var notifyRootChange: Boolean = false
|
||||
private var backgroundTasksQueue: LoaderBackgroundTask? = null
|
||||
|
||||
override fun isApplicable(file: VirtualFile): Boolean {
|
||||
val scriptDefinition = file.findScriptDefinition(project) ?: return false
|
||||
override fun isApplicable(
|
||||
file: VirtualFile,
|
||||
scriptDefinition: ScriptDefinition
|
||||
): Boolean {
|
||||
return ScriptsCompilationConfigurationUpdater.getInstance(project).isAsyncDependencyResolver(scriptDefinition)
|
||||
}
|
||||
|
||||
override fun loadDependencies(file: VirtualFile) {
|
||||
override fun loadDependencies(
|
||||
file: VirtualFile,
|
||||
scriptDefinition: ScriptDefinition
|
||||
) {
|
||||
lock.write {
|
||||
if (backgroundTasksQueue == null) {
|
||||
backgroundTasksQueue = LoaderBackgroundTask()
|
||||
|
||||
@@ -9,7 +9,7 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.core.script.scriptCompilationConfiguration
|
||||
import org.jetbrains.kotlin.idea.core.script.scriptDependencies
|
||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
|
||||
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
||||
import kotlin.script.experimental.api.asSuccess
|
||||
@@ -17,22 +17,31 @@ import kotlin.script.experimental.api.asSuccess
|
||||
// TODO: rename and provide alias for compatibility - this is not only about dependencies anymore
|
||||
class FromFileAttributeScriptDependenciesLoader(project: Project) : ScriptDependenciesLoader(project) {
|
||||
|
||||
override fun isApplicable(file: VirtualFile): Boolean {
|
||||
override fun isApplicable(
|
||||
file: VirtualFile,
|
||||
scriptDefinition: ScriptDefinition
|
||||
): Boolean {
|
||||
return file.scriptDependencies != null || file.scriptCompilationConfiguration != null
|
||||
}
|
||||
|
||||
override fun loadDependencies(file: VirtualFile) {
|
||||
override fun loadDependencies(
|
||||
file: VirtualFile,
|
||||
scriptDefinition: ScriptDefinition
|
||||
) {
|
||||
file.scriptCompilationConfiguration?.let {
|
||||
ScriptCompilationConfigurationWrapper.FromCompilationConfiguration(VirtualFileScriptSource(file), it).apply {
|
||||
debug(file) { "refined configuration from fileAttributes = $it" }
|
||||
}
|
||||
} ?: file.scriptDependencies?.let {
|
||||
ScriptCompilationConfigurationWrapper.FromLegacy(VirtualFileScriptSource(file), it, file.findScriptDefinition(project)).apply {
|
||||
ScriptCompilationConfigurationWrapper.FromLegacy(VirtualFileScriptSource(file), it, scriptDefinition).apply {
|
||||
debug(file) { "dependencies from fileAttributes = $it" }
|
||||
}
|
||||
}?.let {
|
||||
if (areDependenciesValid(file, it)) {
|
||||
saveToCache(file, it.asSuccess(), skipSaveToAttributes = true)
|
||||
} else {
|
||||
file.scriptCompilationConfiguration = null
|
||||
file.scriptDependencies = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,13 +10,20 @@ import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptDependenciesManager
|
||||
import org.jetbrains.kotlin.idea.highlighter.OutsidersPsiFileSupportUtils
|
||||
import org.jetbrains.kotlin.idea.highlighter.OutsidersPsiFileSupportWrapper
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||
|
||||
class OutsiderFileDependenciesLoader(project: Project) : ScriptDependenciesLoader(project) {
|
||||
override fun isApplicable(file: VirtualFile): Boolean {
|
||||
override fun isApplicable(
|
||||
file: VirtualFile,
|
||||
scriptDefinition: ScriptDefinition
|
||||
): Boolean {
|
||||
return OutsidersPsiFileSupportWrapper.isOutsiderFile(file)
|
||||
}
|
||||
|
||||
override fun loadDependencies(file: VirtualFile) {
|
||||
override fun loadDependencies(
|
||||
file: VirtualFile,
|
||||
scriptDefinition: ScriptDefinition
|
||||
) {
|
||||
val fileOrigin = OutsidersPsiFileSupportUtils.getOutsiderFileOrigin(project, file) ?: return
|
||||
val compilationConfiguration = ScriptDependenciesManager.getInstance(project).getRefinedCompilationConfiguration(fileOrigin) ?: return
|
||||
saveToCache(file, compilationConfiguration)
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.intellij.openapi.util.EmptyRunnable
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.core.script.*
|
||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationResult
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptCompilationConfigurationWrapper
|
||||
import org.jetbrains.kotlin.scripting.resolve.ScriptReportSink
|
||||
@@ -24,8 +25,8 @@ import kotlin.script.experimental.api.valueOrNull
|
||||
// TODO: rename and provide alias for compatibility - this is not only about dependencies anymore
|
||||
abstract class ScriptDependenciesLoader(protected val project: Project) {
|
||||
|
||||
abstract fun isApplicable(file: VirtualFile): Boolean
|
||||
abstract fun loadDependencies(file: VirtualFile)
|
||||
abstract fun isApplicable(file: VirtualFile, scriptDefinition: ScriptDefinition): Boolean
|
||||
abstract fun loadDependencies(file: VirtualFile, scriptDefinition: ScriptDefinition)
|
||||
|
||||
protected abstract fun shouldShowNotification(): Boolean
|
||||
|
||||
|
||||
@@ -8,20 +8,24 @@ package org.jetbrains.kotlin.idea.core.script.dependencies
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.idea.core.script.ScriptsCompilationConfigurationUpdater
|
||||
import org.jetbrains.kotlin.scripting.definitions.findScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.definitions.ScriptDefinition
|
||||
import org.jetbrains.kotlin.scripting.resolve.VirtualFileScriptSource
|
||||
import org.jetbrains.kotlin.scripting.resolve.refineScriptCompilationConfiguration
|
||||
|
||||
class SyncScriptDependenciesLoader(project: Project) : ScriptDependenciesLoader(project) {
|
||||
override fun isApplicable(file: VirtualFile): Boolean {
|
||||
val scriptDefinition = file.findScriptDefinition(project) ?: return false
|
||||
override fun isApplicable(
|
||||
file: VirtualFile,
|
||||
scriptDefinition: ScriptDefinition
|
||||
): Boolean {
|
||||
return !ScriptsCompilationConfigurationUpdater.getInstance(project).isAsyncDependencyResolver(scriptDefinition)
|
||||
}
|
||||
|
||||
override fun loadDependencies(file: VirtualFile) {
|
||||
val scriptDef = file.findScriptDefinition(project) ?: return
|
||||
override fun loadDependencies(
|
||||
file: VirtualFile,
|
||||
scriptDefinition: ScriptDefinition
|
||||
) {
|
||||
debug(file) { "start sync dependencies loading" }
|
||||
val result = refineScriptCompilationConfiguration(VirtualFileScriptSource(file), scriptDef, project)
|
||||
val result = refineScriptCompilationConfiguration(VirtualFileScriptSource(file), scriptDefinition, project)
|
||||
debug(file) { "finish sync dependencies loading" }
|
||||
processRefinedConfiguration(result, file)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.actions
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.ide.actions.ShowFilePathAction
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.ui.MessageType
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory
|
||||
import com.intellij.openapi.util.SystemInfo
|
||||
import com.intellij.openapi.wm.WindowManager
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.ui.BrowserHyperlinkListener
|
||||
import java.io.File
|
||||
|
||||
class ShowKotlinGradleDslLogs : IntentionAction, AnAction(), DumbAware {
|
||||
override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
|
||||
openLogsDirIfPresent(project)
|
||||
}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
openLogsDirIfPresent(e.project)
|
||||
}
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?) = ShowFilePathAction.isSupported()
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
val presentation = e.presentation
|
||||
presentation.isVisible = ShowFilePathAction.isSupported()
|
||||
presentation.text = NAME
|
||||
}
|
||||
|
||||
private fun openLogsDirIfPresent(project: Project?) {
|
||||
val logsDir = findLogsDir()
|
||||
if (logsDir != null) {
|
||||
ShowFilePathAction.openDirectory(logsDir)
|
||||
} else {
|
||||
val parent = WindowManager.getInstance().getStatusBar(project)?.component
|
||||
?: WindowManager.getInstance().findVisibleFrame().rootPane
|
||||
JBPopupFactory.getInstance()
|
||||
.createHtmlTextBalloonBuilder(
|
||||
"Gradle DSL Logs cannot be found automatically.<br/>See how to find logs <a href=\"$gradleTroubleshootingLink\">here</a>.",
|
||||
MessageType.ERROR,
|
||||
BrowserHyperlinkListener.INSTANCE
|
||||
)
|
||||
.setFadeoutTime(5000)
|
||||
.createBalloon()
|
||||
.showInCenterOf(parent)
|
||||
}
|
||||
}
|
||||
|
||||
/** The way how to find Gradle logs is described here
|
||||
* @see org.jetbrains.kotlin.idea.actions.ShowKotlinGradleDslLogs.gradleTroubleshootingLink
|
||||
*/
|
||||
private fun findLogsDir(): File? {
|
||||
val userHome = System.getProperty("user.home")
|
||||
return when {
|
||||
SystemInfo.isMac -> File("$userHome/Library/Logs/gradle-kotlin-dsl")
|
||||
SystemInfo.isLinux -> File("$userHome/.gradle-kotlin-dsl/logs")
|
||||
SystemInfo.isWindows -> File("$userHome/AppData/Local/gradle-kotlin-dsl/log")
|
||||
else -> null
|
||||
}.takeIf { it?.exists() == true }
|
||||
}
|
||||
|
||||
override fun startInWriteAction() = false
|
||||
|
||||
override fun getText() = NAME
|
||||
|
||||
override fun getFamilyName() = NAME
|
||||
|
||||
companion object {
|
||||
private const val gradleTroubleshootingLink = "https://docs.gradle.org/current/userguide/kotlin_dsl.html#troubleshooting"
|
||||
|
||||
val NAME = "Show Kotlin Gradle DSL Logs in ${ShowFilePathAction.getFileManagerName()}"
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,16 @@ fun GradleBuildScriptManipulator<*>.useNewSyntax(kotlinPluginName: String, gradl
|
||||
return !hasOldApply
|
||||
}
|
||||
|
||||
fun GradleBuildScriptManipulator<*>.usesNewMultiplatform(): Boolean {
|
||||
val fileText = runReadAction { scriptFile.text }
|
||||
return fileText.contains("multiplatform")
|
||||
}
|
||||
|
||||
fun LanguageFeature.State.assertApplicableInMultiplatform() {
|
||||
if (this == LanguageFeature.State.ENABLED_WITH_ERROR || this == LanguageFeature.State.DISABLED)
|
||||
throw UnsupportedOperationException("Disabling the language feature is unsupported for multiplatform")
|
||||
}
|
||||
|
||||
private val MIN_GRADLE_VERSION_FOR_API_AND_IMPLEMENTATION = GradleVersion.version("3.4")
|
||||
|
||||
fun GradleVersion.scope(directive: String): String {
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.jetbrains.plugins.gradle.frameworkSupport.BuildScriptDataBuilder
|
||||
import org.jetbrains.plugins.gradle.frameworkSupport.GradleFrameworkSupportProvider
|
||||
import javax.swing.Icon
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.JLabel
|
||||
import javax.swing.JTextPane
|
||||
|
||||
abstract class GradleKotlinFrameworkSupportProvider(
|
||||
val frameworkTypeId: String,
|
||||
@@ -57,7 +57,11 @@ abstract class GradleKotlinFrameworkSupportProvider(
|
||||
configurable.addSupport(module, rootModel, modifiableModelsProvider)
|
||||
}
|
||||
|
||||
override fun createComponent(): JComponent = JLabel(getDescription())
|
||||
override fun createComponent(): JComponent {
|
||||
val jTextPane = JTextPane()
|
||||
jTextPane.text = getDescription()
|
||||
return jTextPane
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +188,7 @@ open class GradleKotlinJavaFrameworkSupportProvider(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDescription() = "A Kotlin library or application targeting the JVM"
|
||||
override fun getDescription() = "A single-platform Kotlin library or application targeting the JVM"
|
||||
}
|
||||
|
||||
abstract class GradleKotlinJSFrameworkSupportProvider(
|
||||
@@ -209,7 +213,7 @@ abstract class GradleKotlinJSFrameworkSupportProvider(
|
||||
override fun getPluginExpression() = "id 'org.jetbrains.kotlin.js'"
|
||||
override fun getDependencies(sdk: Sdk?) = listOf(MAVEN_JS_STDLIB_ID)
|
||||
override fun getTestDependencies() = listOf(MAVEN_JS_TEST_ID)
|
||||
override fun getDescription() = "A Kotlin library or application targeting JavaScript"
|
||||
override fun getDescription() = "A single-platform Kotlin library or application targeting JavaScript"
|
||||
}
|
||||
|
||||
open class GradleKotlinJSBrowserFrameworkSupportProvider(
|
||||
@@ -219,7 +223,7 @@ open class GradleKotlinJSBrowserFrameworkSupportProvider(
|
||||
override val jsSubTargetName: String
|
||||
get() = "browser"
|
||||
|
||||
override fun getDescription() = "A Kotlin library or application targeting JavaScript for browser"
|
||||
override fun getDescription() = "A single-platform Kotlin library or application targeting JavaScript for browser"
|
||||
}
|
||||
|
||||
open class GradleKotlinJSNodeFrameworkSupportProvider(
|
||||
@@ -229,11 +233,11 @@ open class GradleKotlinJSNodeFrameworkSupportProvider(
|
||||
override val jsSubTargetName: String
|
||||
get() = "nodejs"
|
||||
|
||||
override fun getDescription() = "A Kotlin library or application targeting JavaScript for Node.js"
|
||||
override fun getDescription() = "A single-platform Kotlin library or application targeting JavaScript for Node.js"
|
||||
}
|
||||
|
||||
class GradleKotlinMPPFrameworkSupportProvider : GradleKotlinFrameworkSupportProvider(
|
||||
"KOTLIN_MPP", "Kotlin (Multiplatform - Experimental)", KotlinIcons.MPP
|
||||
open class GradleKotlinMPPFrameworkSupportProvider : GradleKotlinFrameworkSupportProvider(
|
||||
"KOTLIN_MPP", "Kotlin/Multiplatform", KotlinIcons.MPP
|
||||
) {
|
||||
override fun getPluginId() = "org.jetbrains.kotlin.multiplatform"
|
||||
override fun getPluginExpression() = "id 'org.jetbrains.kotlin.multiplatform'"
|
||||
@@ -241,6 +245,43 @@ class GradleKotlinMPPFrameworkSupportProvider : GradleKotlinFrameworkSupportProv
|
||||
override fun getDependencies(sdk: Sdk?): List<String> = listOf()
|
||||
override fun getTestDependencies(): List<String> = listOf()
|
||||
|
||||
override fun getDescription() = "Kotlin multiplatform code"
|
||||
override fun getDescription() =
|
||||
"Multi-targeted (JVM, JS, iOS, etc.) project with shared code in common modules. " +
|
||||
"The targets can be configured in the project's build script."
|
||||
}
|
||||
|
||||
open class GradleKotlinMPPSourceSetsFrameworkSupportProvider : GradleKotlinMPPFrameworkSupportProvider() {
|
||||
|
||||
override fun addSupport(
|
||||
buildScriptData: BuildScriptDataBuilder,
|
||||
module: Module,
|
||||
sdk: Sdk?,
|
||||
specifyPluginVersionIfNeeded: Boolean,
|
||||
explicitPluginVersion: String?
|
||||
) {
|
||||
super.addSupport(buildScriptData, module, sdk, specifyPluginVersionIfNeeded, explicitPluginVersion)
|
||||
|
||||
buildScriptData.addOther(
|
||||
"""kotlin {
|
||||
/* Targets configuration omitted.
|
||||
* To find out how to configure the targets, please follow the link:
|
||||
* https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#setting-up-targets */
|
||||
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
implementation kotlin('stdlib-common')
|
||||
}
|
||||
}
|
||||
commonTest {
|
||||
dependencies {
|
||||
implementation kotlin('test-common')
|
||||
implementation kotlin('test-annotations-common')
|
||||
}
|
||||
}
|
||||
}
|
||||
}"""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.configuration
|
||||
@@ -165,6 +154,15 @@ class GroovyBuildScriptManipulator(
|
||||
state: LanguageFeature.State,
|
||||
forTests: Boolean
|
||||
): PsiElement? {
|
||||
if (usesNewMultiplatform()) {
|
||||
state.assertApplicableInMultiplatform()
|
||||
val kotlinBlock = scriptFile.getBlockOrCreate("kotlin")
|
||||
val sourceSetsBlock = kotlinBlock.getBlockOrCreate("sourceSets")
|
||||
val allBlock = sourceSetsBlock.getBlockOrCreate("all")
|
||||
allBlock.addLastExpressionInBlockIfNeeded("languageSettings.enableLanguageFeature(\"${feature.name}\")")
|
||||
return allBlock.statements.lastOrNull()
|
||||
}
|
||||
|
||||
val featureArgumentString = feature.buildArgumentString(state)
|
||||
val parameterName = "freeCompilerArgs"
|
||||
return addOrReplaceKotlinTaskParameter(
|
||||
@@ -253,11 +251,6 @@ class GroovyBuildScriptManipulator(
|
||||
)
|
||||
}
|
||||
|
||||
private fun usesNewMultiplatform(): Boolean {
|
||||
val fileText = runReadAction { scriptFile.text }
|
||||
return fileText.contains("kotlin-multiplatform")
|
||||
}
|
||||
|
||||
private fun GrClosableBlock.addParameterAssignment(
|
||||
parameterName: String,
|
||||
defaultValue: String,
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.configuration
|
||||
@@ -146,13 +135,13 @@ class KotlinBuildScriptManipulator(
|
||||
|
||||
private fun KtBlockExpression.addCompileStdlibIfMissing(stdlibArtifactName: String): KtCallExpression? =
|
||||
findStdLibDependency()
|
||||
?: addExpressionIfMissing(
|
||||
getCompileDependencySnippet(
|
||||
KOTLIN_GROUP_ID,
|
||||
stdlibArtifactName,
|
||||
version = "\$$GSK_KOTLIN_VERSION_PROPERTY_NAME"
|
||||
)
|
||||
) as? KtCallExpression
|
||||
?: addExpressionIfMissing(
|
||||
getCompileDependencySnippet(
|
||||
KOTLIN_GROUP_ID,
|
||||
stdlibArtifactName,
|
||||
version = "\$$GSK_KOTLIN_VERSION_PROPERTY_NAME"
|
||||
)
|
||||
) as? KtCallExpression
|
||||
|
||||
private fun addPluginRepositoryExpression(expression: String) {
|
||||
scriptFile.getPluginManagementBlock()?.findOrCreateBlock("repositories")?.addExpressionIfMissing(expression)
|
||||
@@ -172,7 +161,7 @@ class KotlinBuildScriptManipulator(
|
||||
?.findOrCreateBlock("resolutionStrategy")
|
||||
?.findOrCreateBlock("eachPlugin")
|
||||
?.addExpressionIfMissing(
|
||||
"""
|
||||
"""
|
||||
if (requested.id.id == "$pluginId") {
|
||||
useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${'$'}{requested.version}")
|
||||
}
|
||||
@@ -181,7 +170,12 @@ class KotlinBuildScriptManipulator(
|
||||
}
|
||||
|
||||
private fun KtBlockExpression.addNoVersionCompileStdlibIfMissing(stdlibArtifactName: String): KtCallExpression? =
|
||||
findStdLibDependency() ?: addExpressionIfMissing("implementation(${getKotlinModuleDependencySnippet(stdlibArtifactName, null)})") as? KtCallExpression
|
||||
findStdLibDependency() ?: addExpressionIfMissing(
|
||||
"implementation(${getKotlinModuleDependencySnippet(
|
||||
stdlibArtifactName,
|
||||
null
|
||||
)})"
|
||||
) as? KtCallExpression
|
||||
|
||||
private fun KtFile.containsCompileStdLib(): Boolean =
|
||||
findScriptInitializer("dependencies")?.getBlock()?.findStdLibDependency() != null
|
||||
@@ -200,10 +194,10 @@ class KotlinBuildScriptManipulator(
|
||||
|
||||
private fun KtBlockExpression.findPluginInPluginsGroup(pluginName: String): KtCallExpression? {
|
||||
return PsiTreeUtil.getChildrenOfAnyType(
|
||||
this,
|
||||
KtCallExpression::class.java,
|
||||
KtBinaryExpression::class.java,
|
||||
KtDotQualifiedExpression::class.java
|
||||
this,
|
||||
KtCallExpression::class.java,
|
||||
KtBinaryExpression::class.java,
|
||||
KtDotQualifiedExpression::class.java
|
||||
).mapNotNull {
|
||||
when (it) {
|
||||
is KtCallExpression -> it
|
||||
@@ -233,15 +227,14 @@ class KotlinBuildScriptManipulator(
|
||||
}
|
||||
|
||||
private fun KtScriptInitializer.getBlock(): KtBlockExpression? =
|
||||
PsiTreeUtil.findChildOfType<KtCallExpression>(this, KtCallExpression::class.java)?.getBlock()
|
||||
PsiTreeUtil.findChildOfType(this, KtCallExpression::class.java)?.getBlock()
|
||||
|
||||
private fun KtCallExpression.getBlock(): KtBlockExpression? =
|
||||
(valueArguments.singleOrNull()?.getArgumentExpression() as? KtLambdaExpression)?.bodyExpression
|
||||
|
||||
private fun KtFile.getKotlinStdlibVersion(): String? {
|
||||
return findScriptInitializer("dependencies")?.getBlock()?.let {
|
||||
val expression = it.findStdLibDependency()?.valueArguments?.firstOrNull()?.getArgumentExpression()
|
||||
when (expression) {
|
||||
when (val expression = it.findStdLibDependency()?.valueArguments?.firstOrNull()?.getArgumentExpression()) {
|
||||
is KtCallExpression -> expression.valueArguments.getOrNull(1)?.text?.trim('\"')
|
||||
is KtStringTemplateExpression -> expression.text?.trim('\"')?.substringAfterLast(":")?.removePrefix("$")
|
||||
else -> null
|
||||
@@ -253,7 +246,7 @@ class KotlinBuildScriptManipulator(
|
||||
return PsiTreeUtil.getChildrenOfType(this, KtCallExpression::class.java)?.find {
|
||||
val calleeText = it.calleeExpression?.text
|
||||
calleeText in PRODUCTION_DEPENDENCY_STATEMENTS && (it.valueArguments.firstOrNull()?.getArgumentExpression()?.isKotlinStdLib()
|
||||
?: false)
|
||||
?: false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,22 +260,18 @@ class KotlinBuildScriptManipulator(
|
||||
else -> false
|
||||
}
|
||||
|
||||
private fun KtFile.getPluginManagementBlock(): KtBlockExpression? =
|
||||
findScriptInitializer("pluginManagement")?.getBlock() ?: addTopLevelBlock("pluginManagement", true)
|
||||
private fun KtFile.getPluginManagementBlock(): KtBlockExpression? = findOrCreateScriptInitializer("pluginManagement", true)
|
||||
|
||||
private fun KtFile.getRepositoriesBlock(): KtBlockExpression? =
|
||||
findScriptInitializer("repositories")?.getBlock() ?: addTopLevelBlock("repositories")
|
||||
private fun KtFile.getRepositoriesBlock(): KtBlockExpression? = findOrCreateScriptInitializer("repositories")
|
||||
|
||||
private fun KtFile.getDependenciesBlock(): KtBlockExpression? =
|
||||
findScriptInitializer("dependencies")?.getBlock() ?: addTopLevelBlock("dependencies")
|
||||
private fun KtFile.getDependenciesBlock(): KtBlockExpression? = findOrCreateScriptInitializer("dependencies")
|
||||
|
||||
private fun KtFile.getPluginsBlock(): KtBlockExpression? =
|
||||
findScriptInitializer("plugins")?.getBlock() ?: addTopLevelBlock("plugins", true)
|
||||
private fun KtFile.getPluginsBlock(): KtBlockExpression? = findOrCreateScriptInitializer("plugins", true)
|
||||
|
||||
private fun KtFile.createPluginInPluginsGroupIfMissing(pluginName: String, version: String): KtCallExpression? =
|
||||
getPluginsBlock()?.let {
|
||||
it.findPluginInPluginsGroup(pluginName)
|
||||
?: it.addExpressionIfMissing("$pluginName version \"$version\"") as? KtCallExpression
|
||||
?: it.addExpressionIfMissing("$pluginName version \"$version\"") as? KtCallExpression
|
||||
}
|
||||
|
||||
private fun KtFile.createApplyBlock(): KtBlockExpression? {
|
||||
@@ -300,7 +289,7 @@ class KotlinBuildScriptManipulator(
|
||||
|
||||
private fun KtFile.changeCoroutineConfiguration(coroutineOption: String): PsiElement? {
|
||||
val snippet = "experimental.coroutines = Coroutines.${coroutineOption.toUpperCase()}"
|
||||
val kotlinBlock = findScriptInitializer("kotlin")?.getBlock() ?: addTopLevelBlock("kotlin") ?: return null
|
||||
val kotlinBlock = findOrCreateScriptInitializer("kotlin") ?: return null
|
||||
addImportIfMissing("org.jetbrains.kotlin.gradle.dsl.Coroutines")
|
||||
val statement = kotlinBlock.statements.find { it.text.startsWith("experimental.coroutines") }
|
||||
return if (statement != null) {
|
||||
@@ -315,6 +304,14 @@ class KotlinBuildScriptManipulator(
|
||||
state: LanguageFeature.State,
|
||||
forTests: Boolean
|
||||
): PsiElement? {
|
||||
if (usesNewMultiplatform()) {
|
||||
state.assertApplicableInMultiplatform()
|
||||
return findOrCreateScriptInitializer("kotlin")
|
||||
?.findOrCreateBlock("sourceSets")
|
||||
?.findOrCreateBlock("all")
|
||||
?.addExpressionIfMissing("languageSettings.enableLanguageFeature(\"${feature.name}\")")
|
||||
}
|
||||
|
||||
val featureArgumentString = feature.buildArgumentString(state)
|
||||
val parameterName = "freeCompilerArgs"
|
||||
return addOrReplaceKotlinTaskParameter(
|
||||
@@ -363,14 +360,14 @@ class KotlinBuildScriptManipulator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtFile.getBuildScriptBlock(): KtBlockExpression? =
|
||||
findScriptInitializer("buildscript")?.getBlock() ?: addTopLevelBlock("buildscript", true)
|
||||
private fun KtFile.getBuildScriptBlock(): KtBlockExpression? = findOrCreateScriptInitializer("buildscript", true)
|
||||
|
||||
private fun KtBlockExpression.getRepositoriesBlock(): KtBlockExpression? =
|
||||
findBlock("repositories") ?: addBlock("repositories")
|
||||
private fun KtFile.findOrCreateScriptInitializer(name: String, first: Boolean = false): KtBlockExpression? =
|
||||
findScriptInitializer(name)?.getBlock() ?: addTopLevelBlock(name, first)
|
||||
|
||||
private fun KtBlockExpression.getDependenciesBlock(): KtBlockExpression? =
|
||||
findBlock("dependencies") ?: addBlock("dependencies")
|
||||
private fun KtBlockExpression.getRepositoriesBlock(): KtBlockExpression? = findOrCreateBlock("repositories")
|
||||
|
||||
private fun KtBlockExpression.getDependenciesBlock(): KtBlockExpression? = findOrCreateBlock("dependencies")
|
||||
|
||||
private fun KtBlockExpression.addRepositoryIfMissing(version: String): KtCallExpression? {
|
||||
val snippet = getRepositorySnippet(version) ?: return null
|
||||
@@ -425,17 +422,15 @@ class KotlinBuildScriptManipulator(
|
||||
|
||||
private fun KtFile.addImportIfMissing(path: String): KtImportDirective =
|
||||
importDirectives.find { it.importPath?.pathStr == path } ?: importList?.add(
|
||||
psiFactory.createImportDirective(
|
||||
ImportPath.fromString(
|
||||
path
|
||||
)
|
||||
psiFactory.createImportDirective(
|
||||
ImportPath.fromString(
|
||||
path
|
||||
)
|
||||
)
|
||||
) as KtImportDirective
|
||||
|
||||
private fun KtBlockExpression.addExpressionAfterIfMissing(text: String, after: PsiElement): KtExpression = addStatementIfMissing(text) {
|
||||
psiFactory.createExpression(it).let { created ->
|
||||
addAfter(created, after)
|
||||
}
|
||||
addAfter(psiFactory.createExpression(it), after)
|
||||
}
|
||||
|
||||
private fun KtBlockExpression.addExpressionIfMissing(text: String, first: Boolean = false): KtExpression = addStatementIfMissing(text) {
|
||||
@@ -494,8 +489,8 @@ class KotlinBuildScriptManipulator(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val STDLIB_ARTIFACT_PREFIX = "org.jetbrains.kotlin:kotlin-stdlib"
|
||||
val GSK_KOTLIN_VERSION_PROPERTY_NAME = "kotlin_version"
|
||||
private const val STDLIB_ARTIFACT_PREFIX = "org.jetbrains.kotlin:kotlin-stdlib"
|
||||
const val GSK_KOTLIN_VERSION_PROPERTY_NAME = "kotlin_version"
|
||||
|
||||
fun getKotlinGradlePluginClassPathSnippet(): String =
|
||||
"classpath(${getKotlinModuleDependencySnippet("gradle-plugin", "\$$GSK_KOTLIN_VERSION_PROPERTY_NAME")})"
|
||||
|
||||
@@ -80,7 +80,6 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
|
||||
|
||||
buildScriptData
|
||||
.addPluginDefinitionInPluginsGroup(getPluginDefinition() + " version \"$kotlinVersion\"")
|
||||
.addDependencyNotation(getRuntimeLibrary(rootModel, null))
|
||||
} else {
|
||||
if (additionalRepository != null) {
|
||||
val repository = additionalRepository.toKotlinRepositorySnippet()
|
||||
@@ -95,7 +94,6 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
|
||||
.addBuildscriptRepositoriesDefinition("mavenCentral()")
|
||||
// TODO: in gradle > 4.1 this could be single declaration e.g. 'val kotlin_version: String by extra { "1.1.11" }'
|
||||
.addBuildscriptPropertyDefinition("var $GSK_KOTLIN_VERSION_PROPERTY_NAME: String by extra\n $GSK_KOTLIN_VERSION_PROPERTY_NAME = \"$kotlinVersion\"")
|
||||
.addDependencyNotation(getRuntimeLibrary(rootModel, "\$$GSK_KOTLIN_VERSION_PROPERTY_NAME"))
|
||||
.addBuildscriptDependencyNotation(getKotlinGradlePluginClassPathSnippet())
|
||||
}
|
||||
|
||||
@@ -112,10 +110,15 @@ abstract class KotlinDslGradleKotlinFrameworkSupportProvider(
|
||||
|
||||
private fun RepositoryDescription.toKotlinRepositorySnippet() = "maven { setUrl(\"$url\") }"
|
||||
|
||||
protected abstract fun getRuntimeLibrary(rootModel: ModifiableRootModel, version: String?): String
|
||||
|
||||
protected abstract fun getOldSyntaxPluginDefinition(): String
|
||||
protected abstract fun getPluginDefinition(): String
|
||||
|
||||
protected fun composeDependency(buildScriptData: BuildScriptDataBuilder, artifactId: String): String {
|
||||
return if (buildScriptData.gradleVersion >= MIN_GRADLE_VERSION_FOR_NEW_PLUGIN_SYNTAX)
|
||||
"implementation(${getKotlinModuleDependencySnippet(artifactId, null)})"
|
||||
else
|
||||
"implementation(${getKotlinModuleDependencySnippet(artifactId, "\$$GSK_KOTLIN_VERSION_PROPERTY_NAME")})"
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinDslGradleKotlinJavaFrameworkSupportProvider :
|
||||
@@ -124,9 +127,6 @@ class KotlinDslGradleKotlinJavaFrameworkSupportProvider :
|
||||
override fun getOldSyntaxPluginDefinition() = "plugin(\"${KotlinGradleModuleConfigurator.KOTLIN}\")"
|
||||
override fun getPluginDefinition() = "kotlin(\"jvm\")"
|
||||
|
||||
override fun getRuntimeLibrary(rootModel: ModifiableRootModel, version: String?) =
|
||||
"implementation(${getKotlinModuleDependencySnippet(getStdlibArtifactId(rootModel.sdk, bundledRuntimeVersion()), version)})"
|
||||
|
||||
override fun addSupport(
|
||||
projectId: ProjectId,
|
||||
module: Module,
|
||||
@@ -141,6 +141,9 @@ class KotlinDslGradleKotlinJavaFrameworkSupportProvider :
|
||||
.addImport("import org.jetbrains.kotlin.gradle.tasks.KotlinCompile")
|
||||
.addOther("tasks.withType<KotlinCompile> {\n kotlinOptions.jvmTarget = \"1.8\"\n}\n")
|
||||
}
|
||||
|
||||
val artifactId = getStdlibArtifactId(rootModel.sdk, bundledRuntimeVersion())
|
||||
buildScriptData.addDependencyNotation(composeDependency(buildScriptData, artifactId))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,13 +163,13 @@ abstract class AbstractKotlinDslGradleKotlinJSFrameworkSupportProvider(
|
||||
super.addSupport(projectId, module, rootModel, modifiableModelsProvider, buildScriptData)
|
||||
|
||||
buildScriptData.addOther("kotlin.target.$jsSubTargetName { }")
|
||||
val artifactId = MAVEN_JS_STDLIB_ID.removePrefix("kotlin-")
|
||||
buildScriptData.addDependencyNotation(composeDependency(buildScriptData, artifactId))
|
||||
}
|
||||
|
||||
override fun getOldSyntaxPluginDefinition(): String = "plugin(\"${KotlinJsGradleModuleConfigurator.KOTLIN_JS}\")"
|
||||
override fun getPluginDefinition(): String = "id(\"org.jetbrains.kotlin.js\")"
|
||||
|
||||
override fun getRuntimeLibrary(rootModel: ModifiableRootModel, version: String?) =
|
||||
"implementation(${getKotlinModuleDependencySnippet(MAVEN_JS_STDLIB_ID.removePrefix("kotlin-"), version)})"
|
||||
}
|
||||
|
||||
class KotlinDslGradleKotlinJSBrowserFrameworkSupportProvider :
|
||||
@@ -180,3 +183,42 @@ class KotlinDslGradleKotlinJSNodeFrameworkSupportProvider :
|
||||
override val jsSubTargetName: String
|
||||
get() = "nodejs"
|
||||
}
|
||||
|
||||
class KotlinDslGradleKotlinMPPFrameworkSupportProvider :
|
||||
KotlinDslGradleKotlinFrameworkSupportProvider("KOTLIN_MPP", "Kotlin/Multiplatform", KotlinIcons.MPP) {
|
||||
|
||||
override fun getOldSyntaxPluginDefinition() = "plugin(\"org.jetbrains.kotlin.multiplatform\")"
|
||||
override fun getPluginDefinition() = "kotlin(\"multiplatform\")"
|
||||
|
||||
override fun addSupport(
|
||||
projectId: ProjectId,
|
||||
module: Module,
|
||||
rootModel: ModifiableRootModel,
|
||||
modifiableModelsProvider: ModifiableModelsProvider,
|
||||
buildScriptData: BuildScriptDataBuilder
|
||||
) {
|
||||
super.addSupport(projectId, module, rootModel, modifiableModelsProvider, buildScriptData)
|
||||
|
||||
buildScriptData.addOther(
|
||||
"""kotlin {
|
||||
/* Targets configuration omitted.
|
||||
* To find out how to configure the targets, please follow the link:
|
||||
* https://kotlinlang.org/docs/reference/building-mpp-with-gradle.html#setting-up-targets */
|
||||
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib-common"))
|
||||
}
|
||||
}
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}"""
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -57,6 +57,8 @@ var DataNode<out ModuleData>.isHmpp
|
||||
by NotNullableCopyableDataNodeUserDataProperty(Key.create<Boolean>("IS_HMPP_MODULE"), false)
|
||||
var DataNode<ModuleData>.platformPluginId
|
||||
by CopyableDataNodeUserDataProperty(Key.create<String>("PLATFORM_PLUGIN_ID"))
|
||||
var DataNode<ModuleData>.kotlinNativeHome
|
||||
by CopyableDataNodeUserDataProperty(Key.create<String>("KOTLIN_NATIVE_HOME"))
|
||||
var DataNode<out ModuleData>.implementedModuleNames
|
||||
by NotNullableCopyableDataNodeUserDataProperty(Key.create<List<String>>("IMPLEMENTED_MODULE_NAME"), emptyList())
|
||||
// Project is usually the same during all import, thus keeping Map Project->Dependencies makes model a bit more complicated but allows to avoid future problems
|
||||
|
||||
@@ -15,10 +15,7 @@ import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.gradle.KotlinModule
|
||||
import org.jetbrains.kotlin.gradle.KotlinPlatform
|
||||
import org.jetbrains.kotlin.gradle.KotlinPlatformContainer
|
||||
import org.jetbrains.kotlin.gradle.KotlinPlatformContainerImpl
|
||||
import org.jetbrains.kotlin.gradle.*
|
||||
import org.jetbrains.kotlin.idea.util.CopyableDataNodeUserDataProperty
|
||||
import org.jetbrains.plugins.gradle.util.GradleConstants
|
||||
import java.io.File
|
||||
@@ -59,6 +56,7 @@ class KotlinAndroidSourceSetData(
|
||||
class KotlinTargetData(name: String) : AbstractNamedData(GradleConstants.SYSTEM_ID, name) {
|
||||
var moduleIds: Set<String> = emptySet()
|
||||
var archiveFile: File? = null
|
||||
var konanArtifacts: Collection<KonanArtifactModel>? = null
|
||||
|
||||
companion object {
|
||||
val KEY = ExternalKey.create(KotlinTargetData::class.java, ProjectKeys.MODULE.processingWeight + 1)
|
||||
|
||||
@@ -206,6 +206,8 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
val mppModel = resolverCtx.getMppModel(gradleModule)
|
||||
if (mppModel == null || externalProject == null) return
|
||||
|
||||
mainModuleNode.kotlinNativeHome = mppModel.kotlinNativeHome
|
||||
|
||||
val jdkName = gradleModule.jdkNameIfAny
|
||||
|
||||
// save artefacts locations.
|
||||
@@ -244,6 +246,7 @@ open class KotlinMPPGradleProjectResolver : AbstractProjectResolverExtension() {
|
||||
if (target.name == KotlinTarget.METADATA_TARGET_NAME) continue
|
||||
val targetData = KotlinTargetData(target.name).also {
|
||||
it.archiveFile = target.jar?.archiveFile
|
||||
it.konanArtifacts = target.konanArtifacts
|
||||
}
|
||||
val targetDataNode = mainModuleNode.createChild<KotlinTargetData>(KotlinTargetData.KEY, targetData)
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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.script
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import org.jetbrains.kotlin.idea.actions.ShowKotlinGradleDslLogs
|
||||
import kotlin.script.experimental.api.ScriptDiagnostic
|
||||
|
||||
class GradleScriptDiagnosticFixProvider : ScriptDiagnosticFixProvider {
|
||||
override fun provideFixes(annotation: ScriptDiagnostic): List<IntentionAction> {
|
||||
if (gradleMessagesForQuickFix.any { annotation.message.contains(it) }) {
|
||||
return listOf(ShowKotlinGradleDslLogs())
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
private val gradleMessagesForQuickFix = arrayListOf(
|
||||
"This script caused build configuration to fail",
|
||||
"see IDE logs for more information",
|
||||
"Script dependencies resolution failed"
|
||||
)
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,7 @@ class GradleConfiguratorPlatformSpecificTest : GradleImportingTestCase() {
|
||||
|
||||
@TargetVersions("4.7+")
|
||||
@Test
|
||||
fun testEnableFeatureSupportMultiplatformWithDots() {
|
||||
fun testEnableFeatureSupportMultiplatform2() {
|
||||
val files = importProjectFromTestData()
|
||||
|
||||
runInEdtAndWait {
|
||||
@@ -61,6 +61,22 @@ class GradleConfiguratorPlatformSpecificTest : GradleImportingTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
@TargetVersions("4.7+")
|
||||
@Test
|
||||
fun testEnableFeatureSupportMultiplatformKts() {
|
||||
val files = importProjectFromTestData()
|
||||
|
||||
runInEdtAndWait {
|
||||
myTestFixture.project.executeWriteCommand("") {
|
||||
KotlinWithGradleConfigurator.changeFeatureConfiguration(
|
||||
myTestFixture.module, LanguageFeature.InlineClasses, LanguageFeature.State.ENABLED, false
|
||||
)
|
||||
}
|
||||
|
||||
checkFiles(files)
|
||||
}
|
||||
}
|
||||
|
||||
override fun testDataDirName(): String {
|
||||
return "configurator"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2000-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.
|
||||
*/
|
||||
|
||||
@@ -584,22 +584,6 @@ class GradleConfiguratorTest : GradleImportingTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
@TargetVersions("4.7+")
|
||||
@Test
|
||||
fun testDisableFeatureSupportMultiplatform() {
|
||||
val files = importProjectFromTestData()
|
||||
|
||||
runInEdtAndWait {
|
||||
myTestFixture.project.executeWriteCommand("") {
|
||||
KotlinWithGradleConfigurator.changeFeatureConfiguration(
|
||||
myTestFixture.module, LanguageFeature.InlineClasses, LanguageFeature.State.DISABLED, false
|
||||
)
|
||||
}
|
||||
|
||||
checkFiles(files)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testEnableFeatureSupport() {
|
||||
val files = importProjectFromTestData()
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.inspections
|
||||
|
||||
import com.intellij.ide.highlighter.JavaFileType
|
||||
import com.intellij.openapi.fileEditor.FileEditor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.ui.EditorNotificationPanel
|
||||
import com.intellij.ui.EditorNotifications
|
||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||
import org.jetbrains.kotlin.idea.framework.isGradleModule
|
||||
import org.jetbrains.kotlin.idea.util.findModule
|
||||
import org.jetbrains.kotlin.idea.util.sourceRoots
|
||||
|
||||
class JavaOutsideModuleDetector(private val project: Project) : EditorNotifications.Provider<EditorNotificationPanel>() {
|
||||
override fun getKey(): Key<EditorNotificationPanel> = KEY
|
||||
|
||||
override fun createNotificationPanel(file: VirtualFile, fileEditor: FileEditor): EditorNotificationPanel? {
|
||||
if (file.fileType != JavaFileType.INSTANCE) return null
|
||||
val module = file.findModule(project) ?: return null
|
||||
if (!module.isGradleModule()) return null
|
||||
val facetSettings = KotlinFacet.get(module)?.configuration?.settings ?: return null
|
||||
|
||||
val filePath = file.path
|
||||
val nonKotlinPath = module.sourceRoots.map { it.path } - facetSettings.pureKotlinSourceFolders
|
||||
if (nonKotlinPath.any { filePath.startsWith(it) }) return null
|
||||
return EditorNotificationPanel().apply {
|
||||
setText("This .java file is outside of Java source roots and won't be added to the class-path.")
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val KEY = Key.create<EditorNotificationPanel>("JavaOutsideModuleDetector")
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
|
||||
@@ -38,10 +38,11 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
class NativePlatformKindResolution : IdePlatformKindResolution {
|
||||
|
||||
override fun createLibraryInfo(project: Project, library: Library): List<LibraryInfo> {
|
||||
return library.getFiles(OrderRootType.CLASSES)
|
||||
.mapNotNull { file -> PathUtil.getLocalPath(file) }
|
||||
.map { path -> File(path) }
|
||||
.map { file -> NativeLibraryInfo(project, library, file) }
|
||||
return library.getFiles(OrderRootType.CLASSES).mapNotNull { file ->
|
||||
if (!isLibraryFileForPlatform(file)) return@createLibraryInfo emptyList()
|
||||
val path = PathUtil.getLocalPath(file) ?: return@createLibraryInfo emptyList()
|
||||
NativeLibraryInfo(project, library, File(path))
|
||||
}
|
||||
}
|
||||
|
||||
override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean {
|
||||
|
||||
@@ -119,7 +119,7 @@ enum class KotlinPlatform(val id: String) {
|
||||
}
|
||||
}
|
||||
|
||||
interface KotlinPlatformContainer: Serializable {
|
||||
interface KotlinPlatformContainer : Serializable {
|
||||
val platforms: Collection<KotlinPlatform>
|
||||
|
||||
fun supports(simplePlatform: KotlinPlatform): Boolean
|
||||
@@ -142,6 +142,7 @@ interface KotlinTarget : Serializable {
|
||||
val compilations: Collection<KotlinCompilation>
|
||||
val testTasks: Collection<KotlinTestTask>
|
||||
val jar: KotlinTargetJar?
|
||||
val konanArtifacts: List<KonanArtifactModel>
|
||||
|
||||
companion object {
|
||||
const val METADATA_TARGET_NAME = "metadata"
|
||||
@@ -167,4 +168,29 @@ interface KotlinMPPGradleModel : Serializable {
|
||||
companion object {
|
||||
const val NO_KOTLIN_NATIVE_HOME = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface KonanArtifactModel : Serializable {
|
||||
val targetName: String
|
||||
val executableName: String
|
||||
val type: String // represents org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
val targetPlatform: String
|
||||
val file: File
|
||||
val buildTaskPath: String
|
||||
val runConfiguration: KonanRunConfigurationModel
|
||||
val isTests: Boolean
|
||||
}
|
||||
|
||||
interface KonanRunConfigurationModel : Serializable {
|
||||
val workingDirectory: String
|
||||
val programParameters: List<String>
|
||||
val environmentVariables: Map<String, String>
|
||||
|
||||
fun isNotEmpty() = workingDirectory.isNotEmpty() || programParameters.isNotEmpty() || environmentVariables.isNotEmpty()
|
||||
|
||||
companion object {
|
||||
const val NO_WORKING_DIRECTORY = ""
|
||||
val NO_PROGRAM_PARAMETERS = emptyList<String>()
|
||||
val NO_ENVIRONMENT_VARIABLES = emptyMap<String, String>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.gradle.api.file.FileCollection
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.provider.Provider
|
||||
import org.gradle.api.tasks.Exec
|
||||
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModel.Companion.NO_KOTLIN_NATIVE_HOME
|
||||
import org.jetbrains.plugins.gradle.model.*
|
||||
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
|
||||
@@ -218,6 +220,53 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
|
||||
return project.getTargets()?.mapNotNull { buildTarget(it, sourceSetMap, dependencyResolver, project, dependencyMapper) }
|
||||
}
|
||||
|
||||
private operator fun Any?.get(methodName: String, vararg params: Any): Any? {
|
||||
return this[methodName, params.map { it.javaClass }, params.toList()]
|
||||
}
|
||||
|
||||
private operator fun Any?.get(methodName: String, paramTypes: List<Class<*>>, params: List<Any?>): Any? {
|
||||
if (this == null) return null
|
||||
return this::class.java.getMethodOrNull(methodName, *paramTypes.toTypedArray())?.invoke(this, *params.toTypedArray())
|
||||
}
|
||||
|
||||
private fun buildArtifact(
|
||||
executableName: String,
|
||||
linkTask: Task,
|
||||
runConfiguration: KonanRunConfigurationModel
|
||||
): KonanArtifactModel? {
|
||||
val outputKind = linkTask["getOutputKind"]["name"] as? String ?: return null
|
||||
val konanTargetName = linkTask["getTarget"] as? String ?: error("No arch target found")
|
||||
val outputFile = (linkTask["getOutputFile"] as? Provider<*>)?.orNull as? File ?: return null
|
||||
val compilationTarget = linkTask["getCompilation"]["getTarget"]
|
||||
val compilationTargetName = compilationTarget["getName"] as? String ?: return null
|
||||
val isTests = linkTask["getProcessTests"] as? Boolean ?: return null
|
||||
|
||||
return KonanArtifactModelImpl(
|
||||
compilationTargetName,
|
||||
executableName,
|
||||
outputKind,
|
||||
konanTargetName,
|
||||
outputFile,
|
||||
linkTask.path,
|
||||
runConfiguration,
|
||||
isTests
|
||||
)
|
||||
}
|
||||
|
||||
private fun konanArtifacts(target: Named): List<KonanArtifactModel> {
|
||||
val result = ArrayList<KonanArtifactModel>()
|
||||
|
||||
val binaries = target["getBinaries"] as? Collection<*> ?: return result
|
||||
binaries.forEach { binary ->
|
||||
val executableName = binary["getBaseName"] as? String ?: ""
|
||||
val linkTask = binary["getLinkTask"] as? Task ?: return@forEach
|
||||
val runConfiguration = KonanRunConfigurationModelImpl(binary["getRunTask"] as? Exec)
|
||||
buildArtifact(executableName, linkTask, runConfiguration)?.let { result.add(it) }
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun buildTarget(
|
||||
gradleTarget: Named,
|
||||
sourceSetMap: Map<String, KotlinSourceSet>,
|
||||
@@ -247,7 +296,17 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
|
||||
}
|
||||
val jar = buildTargetJar(gradleTarget, project)
|
||||
val testTasks = buildTestTasks(project, gradleTarget)
|
||||
val target = KotlinTargetImpl(gradleTarget.name, targetPresetName, disambiguationClassifier, platform, compilations, testTasks, jar)
|
||||
val artifacts = konanArtifacts(gradleTarget)
|
||||
val target = KotlinTargetImpl(
|
||||
gradleTarget.name,
|
||||
targetPresetName,
|
||||
disambiguationClassifier,
|
||||
platform,
|
||||
compilations,
|
||||
testTasks,
|
||||
jar,
|
||||
artifacts
|
||||
)
|
||||
compilations.forEach {
|
||||
it.disambiguationClassifier = target.disambiguationClassifier
|
||||
it.platform = target.platform
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.gradle
|
||||
|
||||
import org.gradle.api.tasks.Exec
|
||||
import java.io.File
|
||||
import kotlin.collections.HashSet
|
||||
|
||||
@@ -133,7 +134,8 @@ data class KotlinTargetImpl(
|
||||
override val platform: KotlinPlatform,
|
||||
override val compilations: Collection<KotlinCompilation>,
|
||||
override val testTasks: Collection<KotlinTestTask>,
|
||||
override val jar: KotlinTargetJar?
|
||||
override val jar: KotlinTargetJar?,
|
||||
override val konanArtifacts: List<KonanArtifactModel>
|
||||
) : KotlinTarget {
|
||||
override fun toString() = name
|
||||
|
||||
@@ -152,7 +154,8 @@ data class KotlinTargetImpl(
|
||||
cloningCache[initialTestTask] = it
|
||||
}
|
||||
},
|
||||
KotlinTargetJarImpl(target.jar?.archiveFile)
|
||||
KotlinTargetJarImpl(target.jar?.archiveFile),
|
||||
target.konanArtifacts.map { KonanArtifactModelImpl(it) }.toList()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -209,3 +212,44 @@ class KotlinPlatformContainerImpl() : KotlinPlatformContainer {
|
||||
(myPlatforms ?: HashSet<KotlinPlatform>().apply { myPlatforms = this }).addAll(platforms)
|
||||
}
|
||||
}
|
||||
|
||||
data class KonanArtifactModelImpl(
|
||||
override val targetName: String,
|
||||
override val executableName: String,
|
||||
override val type: String,
|
||||
override val targetPlatform: String,
|
||||
override val file: File,
|
||||
override val buildTaskPath: String,
|
||||
override val runConfiguration: KonanRunConfigurationModel,
|
||||
override val isTests: Boolean
|
||||
) : KonanArtifactModel {
|
||||
constructor(artifact: KonanArtifactModel) : this(
|
||||
artifact.targetName,
|
||||
artifact.executableName,
|
||||
artifact.type,
|
||||
artifact.targetPlatform,
|
||||
artifact.file,
|
||||
artifact.buildTaskPath,
|
||||
KonanRunConfigurationModelImpl(artifact.runConfiguration),
|
||||
artifact.isTests
|
||||
)
|
||||
}
|
||||
|
||||
data class KonanRunConfigurationModelImpl(
|
||||
override val workingDirectory: String,
|
||||
override val programParameters: List<String>,
|
||||
override val environmentVariables: Map<String, String>
|
||||
) : KonanRunConfigurationModel {
|
||||
constructor(configuration: KonanRunConfigurationModel) : this(
|
||||
configuration.workingDirectory,
|
||||
ArrayList(configuration.programParameters),
|
||||
HashMap(configuration.environmentVariables)
|
||||
)
|
||||
|
||||
constructor(runTask: Exec?) : this(
|
||||
runTask?.workingDir?.path ?: KonanRunConfigurationModel.NO_WORKING_DIRECTORY,
|
||||
runTask?.args as List<String>? ?: KonanRunConfigurationModel.NO_PROGRAM_PARAMETERS,
|
||||
(runTask?.environment as Map<String, Any>?)
|
||||
?.mapValues { it.value.toString() } ?: KonanRunConfigurationModel.NO_ENVIRONMENT_VARIABLES
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.gradle
|
||||
import org.gradle.api.Project
|
||||
|
||||
// KT-29613, KT-29783
|
||||
internal object KotlinNativeHomeEvaluator {
|
||||
object KotlinNativeHomeEvaluator {
|
||||
private const val KOTLIN_NATIVE_HOME_PRIVATE_PROPERTY = "konanHome"
|
||||
|
||||
private const val FALLBACK_ACCESSOR_CLASS = "org.jetbrains.kotlin.compilerRunner.KotlinNativeToolRunnerKt"
|
||||
private const val FALLBACK_ACCESSOR_METHOD = "getKonanHome"
|
||||
|
||||
internal fun getKotlinNativeHome(project: Project): String? =
|
||||
fun getKotlinNativeHome(project: Project): String? =
|
||||
getKotlinNativeHomePrimary(project) ?: getKotlinNativeHomeFallback(project)
|
||||
|
||||
// Read Kotlin/Native home from the predefined property in Gradle plugin.
|
||||
|
||||
@@ -22,7 +22,7 @@ import org.junit.AfterClass
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* inspired by @see AbstractCompletionHandlerTest
|
||||
* inspired by @see AbstractCompletionHandlerTests
|
||||
*/
|
||||
abstract class AbstractPerformanceCompletionHandlerTests(
|
||||
private val defaultCompletionType: CompletionType,
|
||||
@@ -34,6 +34,7 @@ abstract class AbstractPerformanceCompletionHandlerTests(
|
||||
private val ELEMENT_TEXT_PREFIX = "ELEMENT_TEXT:"
|
||||
private val TAIL_TEXT_PREFIX = "TAIL_TEXT:"
|
||||
private val COMPLETION_CHAR_PREFIX = "CHAR:"
|
||||
private val COMPLETION_CHARS_PREFIX = "CHARS:"
|
||||
private val CODE_STYLE_SETTING_PREFIX = "CODE_STYLE_SETTING:"
|
||||
|
||||
companion object {
|
||||
@@ -74,12 +75,10 @@ abstract class AbstractPerformanceCompletionHandlerTests(
|
||||
val itemText = InTextDirectivesUtils.findStringWithPrefixes(fileText, ELEMENT_TEXT_PREFIX)
|
||||
val tailText = InTextDirectivesUtils.findStringWithPrefixes(fileText, TAIL_TEXT_PREFIX)
|
||||
|
||||
val completionCharString = InTextDirectivesUtils.findStringWithPrefixes(fileText, COMPLETION_CHAR_PREFIX)
|
||||
val completionChar = when(completionCharString) {
|
||||
"\\n", null -> '\n'
|
||||
"\\t" -> '\t'
|
||||
else -> completionCharString.singleOrNull() ?: error("Incorrect completion char: \"$completionCharString\"")
|
||||
}
|
||||
val completionChars = completionChars(
|
||||
char = InTextDirectivesUtils.findStringWithPrefixes(fileText, COMPLETION_CHAR_PREFIX),
|
||||
chars = InTextDirectivesUtils.findStringWithPrefixes(fileText, COMPLETION_CHARS_PREFIX)
|
||||
)
|
||||
|
||||
val completionType = ExpectedCompletionUtils.getCompletionType(fileText) ?: defaultCompletionType
|
||||
|
||||
@@ -102,7 +101,7 @@ abstract class AbstractPerformanceCompletionHandlerTests(
|
||||
}
|
||||
|
||||
doPerfTestWithTextLoaded(
|
||||
testPath, completionType, invocationCount, lookupString, itemText, tailText, completionChar
|
||||
testPath, completionType, invocationCount, lookupString, itemText, tailText, completionChars
|
||||
)
|
||||
} finally {
|
||||
if (configured) {
|
||||
@@ -120,7 +119,7 @@ abstract class AbstractPerformanceCompletionHandlerTests(
|
||||
lookupString: String?,
|
||||
itemText: String?,
|
||||
tailText: String?,
|
||||
completionChar: Char
|
||||
completionChars: String
|
||||
) {
|
||||
|
||||
val testName = getTestName(false)
|
||||
@@ -132,7 +131,7 @@ abstract class AbstractPerformanceCompletionHandlerTests(
|
||||
setUpFixture(testPath)
|
||||
},
|
||||
test = {
|
||||
perfTestCore(completionType, time, lookupString, itemText, tailText, completionChar)
|
||||
perfTestCore(completionType, time, lookupString, itemText, tailText, completionChars)
|
||||
},
|
||||
tearDown = {
|
||||
runWriteAction {
|
||||
@@ -147,14 +146,20 @@ abstract class AbstractPerformanceCompletionHandlerTests(
|
||||
lookupString: String?,
|
||||
itemText: String?,
|
||||
tailText: String?,
|
||||
completionChar: Char
|
||||
completionChars: String
|
||||
) {
|
||||
completionChars?.let {
|
||||
for (idx in 0 until it.length - 1) {
|
||||
fixture.type(it[idx])
|
||||
}
|
||||
}
|
||||
|
||||
fixture.complete(completionType, time)
|
||||
|
||||
if (lookupString != null || itemText != null || tailText != null) {
|
||||
val item = getExistentLookupElement(lookupString, itemText, tailText)
|
||||
if (item != null) {
|
||||
selectItem(item, completionChar)
|
||||
selectItem(item, completionChars.last())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,16 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
protected fun warmUpProject(stats: Stats) {
|
||||
val project = innerPerfOpenProject("helloKotlin", stats, "warm-up")
|
||||
try {
|
||||
val perfHighlightFile = perfHighlightFile(project, "src/HelloMain.kt", stats, "warm-up")
|
||||
assertTrue("kotlin project has been not imported properly", perfHighlightFile.isNotEmpty())
|
||||
} finally {
|
||||
closeProject(project)
|
||||
}
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
RunAll(
|
||||
ThrowableRunnable { super.tearDown() },
|
||||
@@ -122,6 +132,9 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
||||
return if (lastIndexOf >= 0) fileName.substring(lastIndexOf + 1) else fileName
|
||||
}
|
||||
|
||||
protected fun perfOpenKotlinProject(stats: Stats) =
|
||||
perfOpenProject("perfTestProject", stats = stats, path = "..")
|
||||
|
||||
protected fun perfOpenProject(name: String, stats: Stats, path: String = "idea/testData/perfTest") {
|
||||
myProject = innerPerfOpenProject(name, stats, path = path, note = "")
|
||||
}
|
||||
@@ -291,8 +304,8 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
||||
stats: Stats,
|
||||
note: String = ""
|
||||
): List<HighlightInfo> {
|
||||
var highlightInfos: List<HighlightInfo> = emptyList()
|
||||
IdentifierHighlighterPassFactory.doWithHighlightingEnabled {
|
||||
return highlightFile {
|
||||
var highlightInfos: List<HighlightInfo> = emptyList()
|
||||
stats.perfTest<EditorFile, List<HighlightInfo>>(
|
||||
testName = "highlighting ${if (note.isNotEmpty()) "$note " else ""}${simpleFilename(fileName)}",
|
||||
setUp = {
|
||||
@@ -309,9 +322,21 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
||||
PsiManager.getInstance(project).dropPsiCaches()
|
||||
}
|
||||
)
|
||||
highlightInfos
|
||||
}
|
||||
//println("${"-".repeat(40)}\n$fileName ->\n${highlightInfos.joinToString("\n")}\n")
|
||||
}
|
||||
|
||||
fun highlightFile(psiFile: PsiFile): List<HighlightInfo> {
|
||||
return highlightFile {
|
||||
highlightFile(myProject!!, psiFile)
|
||||
}
|
||||
}
|
||||
|
||||
private fun highlightFile(block: () -> List<HighlightInfo>): List<HighlightInfo> {
|
||||
var highlightInfos: List<HighlightInfo> = emptyList()
|
||||
IdentifierHighlighterPassFactory.doWithHighlightingEnabled {
|
||||
highlightInfos = block()
|
||||
}
|
||||
return highlightInfos
|
||||
}
|
||||
|
||||
@@ -392,7 +417,7 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun openFileInEditor(project: Project, name: String): EditorFile {
|
||||
fun openFileInEditor(project: Project, name: String): EditorFile {
|
||||
val fileDocumentManager = FileDocumentManager.getInstance()
|
||||
val fileEditorManager = FileEditorManager.getInstance(project)
|
||||
|
||||
@@ -421,6 +446,6 @@ abstract class AbstractPerformanceProjectsTest : UsefulTestCase() {
|
||||
return virtualFile!!.toPsiFile(project)!!
|
||||
}
|
||||
|
||||
private data class EditorFile(val psiFile: PsiFile, val document: Document)
|
||||
data class EditorFile(val psiFile: PsiFile, val document: Document)
|
||||
|
||||
}
|
||||
@@ -26,7 +26,7 @@ public class PerformanceCompletionCharFilterTestGenerated extends AbstractPerfor
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCharFilter() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/charFilter"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/idea-completion/testData/handlers/charFilter"), Pattern.compile("^([^.]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("Colon.kt")
|
||||
@@ -144,6 +144,11 @@ public class PerformanceCompletionCharFilterTestGenerated extends AbstractPerfor
|
||||
runTest("idea/idea-completion/testData/handlers/charFilter/LParenth.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("MessageBundle1.kt")
|
||||
public void testMessageBundle1() throws Exception {
|
||||
runTest("idea/idea-completion/testData/handlers/charFilter/MessageBundle1.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("NamedParameter1.kt")
|
||||
public void testNamedParameter1() throws Exception {
|
||||
runTest("idea/idea-completion/testData/handlers/charFilter/NamedParameter1.kt");
|
||||
|
||||
@@ -35,10 +35,7 @@ class PerformanceProjectsTest : AbstractPerformanceProjectsTest() {
|
||||
super.setUp()
|
||||
// warm up: open simple small project
|
||||
if (!warmedUp) {
|
||||
val project = innerPerfOpenProject("helloKotlin", hwStats, "warm-up")
|
||||
val perfHighlightFile = perfHighlightFile(project, "src/HelloMain.kt", hwStats, "warm-up")
|
||||
assertTrue("kotlin project has been not imported properly", perfHighlightFile.isNotEmpty())
|
||||
closeProject(project)
|
||||
warmUpProject(hwStats)
|
||||
|
||||
warmedUp = true
|
||||
}
|
||||
@@ -58,7 +55,7 @@ class PerformanceProjectsTest : AbstractPerformanceProjectsTest() {
|
||||
tcSuite("Kotlin project") {
|
||||
val stats = Stats("kotlin project")
|
||||
stats.use {
|
||||
perfOpenProject("perfTestProject", stats = it, path = "..")
|
||||
perfOpenKotlinProject(it)
|
||||
|
||||
perfHighlightFile("compiler/psi/src/org/jetbrains/kotlin/psi/KtFile.kt", stats = it)
|
||||
|
||||
@@ -71,7 +68,7 @@ class PerformanceProjectsTest : AbstractPerformanceProjectsTest() {
|
||||
tcSuite("Kotlin project highlight build gradle") {
|
||||
val stats = Stats("kotlin project highlight build gradle")
|
||||
stats.use {
|
||||
perfOpenProject("perfTestProject", stats = it, path = "..")
|
||||
perfOpenKotlinProject(it)
|
||||
|
||||
enableAnnotatorsAndLoadDefinitions()
|
||||
|
||||
|
||||
@@ -52,6 +52,9 @@
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.j2kConverterExtension"
|
||||
interface="org.jetbrains.kotlin.j2k.J2kConverterExtension"/>
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptDiagnosticFixProvider"
|
||||
interface="org.jetbrains.kotlin.idea.script.ScriptDiagnosticFixProvider"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
|
||||
@@ -60,6 +60,9 @@
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.j2kConverterExtension"
|
||||
interface="org.jetbrains.kotlin.j2k.J2kConverterExtension"/>
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptDiagnosticFixProvider"
|
||||
interface="org.jetbrains.kotlin.idea.script.ScriptDiagnosticFixProvider"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
|
||||
@@ -47,11 +47,14 @@
|
||||
interface="org.jetbrains.kotlin.synthetic.SyntheticScopeProviderExtension"
|
||||
area="IDEA_PROJECT"/>
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.resolveScopeEnlarger"
|
||||
interface="org.jetbrains.kotlin.idea.caches.resolve.util.KotlinResolveScopeEnlarger"/>
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.j2kConverterExtension"
|
||||
interface="org.jetbrains.kotlin.j2k.J2kConverterExtension"/>
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.resolveScopeEnlarger"
|
||||
interface="org.jetbrains.kotlin.idea.caches.resolve.util.KotlinResolveScopeEnlarger"/>
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptDiagnosticFixProvider"
|
||||
interface="org.jetbrains.kotlin.idea.script.ScriptDiagnosticFixProvider"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
|
||||
@@ -47,11 +47,14 @@
|
||||
interface="org.jetbrains.kotlin.synthetic.SyntheticScopeProviderExtension"
|
||||
area="IDEA_PROJECT"/>
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.resolveScopeEnlarger"
|
||||
interface="org.jetbrains.kotlin.idea.caches.resolve.util.KotlinResolveScopeEnlarger"/>
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.j2kConverterExtension"
|
||||
interface="org.jetbrains.kotlin.j2k.J2kConverterExtension"/>
|
||||
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.resolveScopeEnlarger"
|
||||
interface="org.jetbrains.kotlin.idea.caches.resolve.util.KotlinResolveScopeEnlarger"/>
|
||||
<extensionPoint qualifiedName="org.jetbrains.kotlin.scriptDiagnosticFixProvider"
|
||||
interface="org.jetbrains.kotlin.idea.script.ScriptDiagnosticFixProvider"/>
|
||||
</extensionPoints>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPSourceSetsFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinMPPFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPSourceSetsFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinMPPFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPSourceSetsFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinMPPFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<idea-plugin>
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinMPPSourceSetsFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<frameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.GradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinMPPFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJavaFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSBrowserFrameworkSupportProvider"/>
|
||||
<kotlinDslFrameworkSupport implementation="org.jetbrains.kotlin.idea.configuration.KotlinDslGradleKotlinJSNodeFrameworkSupportProvider"/>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
<buildSystemTypeDetector implementation="org.jetbrains.kotlin.idea.configuration.GradleDetector"/>
|
||||
<scriptDiagnosticFixProvider implementation="org.jetbrains.kotlin.idea.script.GradleScriptDiagnosticFixProvider"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
@@ -22,4 +23,10 @@
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectSettingsDataService"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
<action id="Kotlin.Gradle.ShowDslLogs" class="org.jetbrains.kotlin.idea.actions.ShowKotlinGradleDslLogs"
|
||||
text="Show Kotlin Gradle DSL Logs" description="Show Kotlin Gradle DSL logs">
|
||||
</action>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
<buildSystemTypeDetector implementation="org.jetbrains.kotlin.idea.configuration.GradleDetector"/>
|
||||
<scriptDiagnosticFixProvider implementation="org.jetbrains.kotlin.idea.script.GradleScriptDiagnosticFixProvider"/>
|
||||
</extensions>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.plugins.gradle">
|
||||
@@ -21,4 +22,10 @@
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinSourceSetDataService"/>
|
||||
<externalProjectDataService implementation="org.jetbrains.kotlin.idea.configuration.KotlinGradleProjectSettingsDataService"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
<action id="Kotlin.Gradle.ShowDslLogs" class="org.jetbrains.kotlin.idea.actions.ShowKotlinGradleDslLogs"
|
||||
text="Show Kotlin Gradle DSL Logs" description="Show Kotlin Gradle DSL logs">
|
||||
</action>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.configuration.KotlinSetupEnvironmentNotificationProvider"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinAlternativeSourceNotificationProvider"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.inspections.JavaOutsideModuleDetector"/>
|
||||
|
||||
<consoleFilterProvider implementation="org.jetbrains.kotlin.idea.run.KotlinConsoleFilterProvider"/>
|
||||
|
||||
@@ -192,7 +193,7 @@
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
<diagnosticSuppressor implementation="org.jetbrains.kotlin.idea.debugger.DiagnosticSuppressorForDebugger"/>
|
||||
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.samWithReceiver.ide.IdeSamWithReceiverComponentContributor"/>
|
||||
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.samWithReceiver.ide.IdeSamWithReceiverComponentContributor"/>
|
||||
|
||||
<declarationAttributeAltererExtension implementation="org.jetbrains.kotlin.allopen.ide.IdeAllOpenDeclarationAttributeAltererExtension"/>
|
||||
|
||||
@@ -211,12 +212,6 @@
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJSFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleGroovyFrameworkSupportProvider" />
|
||||
|
||||
<idePlatformKind implementation="org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind"/>
|
||||
<idePlatformKind implementation="org.jetbrains.kotlin.platform.impl.JsIdePlatformKind"/>
|
||||
|
||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JvmIdePlatformKindTooling"/>
|
||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JsIdePlatformKindTooling"/>
|
||||
|
||||
<syntheticScopeProviderExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldSyntheticScopeProvider"/>
|
||||
<expressionCodegenExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldExpressionCodegenExtension"/>
|
||||
<completionInformationProvider implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldCompletionInformationProvider" />
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.configuration.KotlinSetupEnvironmentNotificationProvider"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinAlternativeSourceNotificationProvider"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.inspections.JavaOutsideModuleDetector"/>
|
||||
|
||||
<consoleFilterProvider implementation="org.jetbrains.kotlin.idea.run.KotlinConsoleFilterProvider"/>
|
||||
|
||||
@@ -186,7 +187,7 @@
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
<diagnosticSuppressor implementation="org.jetbrains.kotlin.idea.debugger.DiagnosticSuppressorForDebugger"/>
|
||||
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.samWithReceiver.ide.IdeSamWithReceiverComponentContributor"/>
|
||||
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.samWithReceiver.ide.IdeSamWithReceiverComponentContributor"/>
|
||||
|
||||
<declarationAttributeAltererExtension implementation="org.jetbrains.kotlin.allopen.ide.IdeAllOpenDeclarationAttributeAltererExtension"/>
|
||||
|
||||
@@ -205,12 +206,6 @@
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJSFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleGroovyFrameworkSupportProvider" />
|
||||
|
||||
<idePlatformKind implementation="org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind"/>
|
||||
<idePlatformKind implementation="org.jetbrains.kotlin.platform.impl.JsIdePlatformKind"/>
|
||||
|
||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JvmIdePlatformKindTooling"/>
|
||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JsIdePlatformKindTooling"/>
|
||||
|
||||
<syntheticScopeProviderExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldSyntheticScopeProvider"/>
|
||||
<expressionCodegenExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldExpressionCodegenExtension"/>
|
||||
<completionInformationProvider implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldCompletionInformationProvider" />
|
||||
|
||||
@@ -129,6 +129,7 @@
|
||||
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.configuration.KotlinSetupEnvironmentNotificationProvider"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.debugger.KotlinAlternativeSourceNotificationProvider"/>
|
||||
<editorNotificationProvider implementation="org.jetbrains.kotlin.idea.inspections.JavaOutsideModuleDetector"/>
|
||||
|
||||
<consoleFilterProvider implementation="org.jetbrains.kotlin.idea.run.KotlinConsoleFilterProvider"/>
|
||||
|
||||
@@ -187,7 +188,7 @@
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
<diagnosticSuppressor implementation="org.jetbrains.kotlin.idea.debugger.DiagnosticSuppressorForDebugger"/>
|
||||
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.samWithReceiver.ide.IdeSamWithReceiverComponentContributor"/>
|
||||
<storageComponentContainerContributor implementation="org.jetbrains.kotlin.samWithReceiver.ide.IdeSamWithReceiverComponentContributor"/>
|
||||
|
||||
<declarationAttributeAltererExtension implementation="org.jetbrains.kotlin.allopen.ide.IdeAllOpenDeclarationAttributeAltererExtension"/>
|
||||
|
||||
@@ -206,12 +207,6 @@
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleKotlinDSLKotlinJSFrameworkSupportProvider" />
|
||||
<gradleFrameworkSupport implementation="org.jetbrains.kotlin.gradle.kdsl.frameworkSupport.GradleGroovyFrameworkSupportProvider" />
|
||||
|
||||
<idePlatformKind implementation="org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind"/>
|
||||
<idePlatformKind implementation="org.jetbrains.kotlin.platform.impl.JsIdePlatformKind"/>
|
||||
|
||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JvmIdePlatformKindTooling"/>
|
||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JsIdePlatformKindTooling"/>
|
||||
|
||||
<syntheticScopeProviderExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldSyntheticScopeProvider"/>
|
||||
<expressionCodegenExtension implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldExpressionCodegenExtension"/>
|
||||
<completionInformationProvider implementation="org.jetbrains.kotlin.idea.debugger.evaluate.DebuggerFieldCompletionInformationProvider" />
|
||||
|
||||
@@ -3396,11 +3396,10 @@
|
||||
groupPath="Kotlin"
|
||||
groupName="Style issues"
|
||||
enabledByDefault="true"
|
||||
level="WEAK WARNING"
|
||||
level="INFORMATION"
|
||||
language="kotlin"
|
||||
/>
|
||||
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.RedundantEmptyInitializerBlockInspection"
|
||||
displayName="Redundant empty initializer block"
|
||||
groupPath="Kotlin"
|
||||
@@ -3466,4 +3465,13 @@
|
||||
|
||||
<navbar implementation="org.jetbrains.kotlin.idea.navigationToolbar.KotlinNavBarModelExtension" order="first"/>
|
||||
</extensions>
|
||||
</idea-plugin>
|
||||
|
||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||
<idePlatformKind implementation="org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind"/>
|
||||
<idePlatformKind implementation="org.jetbrains.kotlin.platform.impl.JsIdePlatformKind"/>
|
||||
|
||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JvmIdePlatformKindTooling"/>
|
||||
<idePlatformKindTooling implementation="org.jetbrains.kotlin.idea.core.platform.impl.JsIdePlatformKindTooling"/>
|
||||
</extensions>
|
||||
|
||||
</idea-plugin>
|
||||
|
||||
@@ -36,31 +36,64 @@ import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||
|
||||
// Based on com.intellij.refactoring.OptimizeImportsRefactoringHelper
|
||||
class KotlinOptimizeImportsRefactoringHelper : RefactoringHelper<Set<KtFile>> {
|
||||
internal class OptimizeImportsTask(
|
||||
private val task: SequentialModalProgressTask,
|
||||
pointers: Set<SmartPsiElementPointer<KtImportDirective>>
|
||||
internal class CollectUnusedImportsTask(
|
||||
private val task: SequentialModalProgressTask,
|
||||
private val dumbService: DumbService,
|
||||
private val unusedImports: MutableSet<SmartPsiElementPointer<KtImportDirective>>,
|
||||
operationData: Set<KtFile>
|
||||
) : SequentialTask {
|
||||
private val pointerIterator = pointers.iterator()
|
||||
private val myTotalCount = operationData.size
|
||||
private val operationIterator = operationData.withIndex().iterator()
|
||||
|
||||
override fun prepare() {}
|
||||
|
||||
override fun stop() {}
|
||||
|
||||
override fun isDone(): Boolean = !operationIterator.hasNext()
|
||||
|
||||
override fun iteration(): Boolean {
|
||||
val (counter, file) = operationIterator.next()
|
||||
if (!file.isValid) return isDone
|
||||
val virtualFile = file.virtualFile ?: return isDone
|
||||
|
||||
with(task.indicator) {
|
||||
text2 = virtualFile.presentableUrl
|
||||
fraction = counter.toDouble() / myTotalCount
|
||||
}
|
||||
|
||||
dumbService.runReadActionInSmartMode {
|
||||
KotlinUnusedImportInspection.analyzeImports(file)?.unusedImports?.mapTo(unusedImports) { it.createSmartPointer() }
|
||||
}
|
||||
return isDone
|
||||
}
|
||||
}
|
||||
|
||||
internal class OptimizeImportsTask(
|
||||
private val task: SequentialModalProgressTask,
|
||||
pointers: Set<SmartPsiElementPointer<KtImportDirective>>
|
||||
) : SequentialTask {
|
||||
private val pointerIterator = pointers.withIndex().iterator()
|
||||
private val myTotal: Int = pointers.size
|
||||
private var myCount: Int = 0
|
||||
|
||||
override fun prepare() {}
|
||||
|
||||
override fun isDone() = !pointerIterator.hasNext()
|
||||
|
||||
override fun iteration(): Boolean {
|
||||
task.indicator?.fraction = myCount++.toDouble() / myTotal
|
||||
val (counter, pointer) = pointerIterator.next()
|
||||
|
||||
val pointer = pointerIterator.next()
|
||||
task.indicator?.fraction = counter.toDouble() / myTotal
|
||||
|
||||
val directive = pointer.element
|
||||
if (directive == null || !directive.isValid) return isDone
|
||||
|
||||
try {
|
||||
directive.delete()
|
||||
}
|
||||
catch (e: IncorrectOperationException) {
|
||||
LOG.error(e)
|
||||
if (directive?.isValid == true) {
|
||||
task.indicator?.text2 = directive.containingFile.virtualFile.presentableUrl
|
||||
runWriteAction {
|
||||
try {
|
||||
directive.delete()
|
||||
} catch (e: IncorrectOperationException) {
|
||||
LOG.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isDone
|
||||
@@ -74,7 +107,8 @@ class KotlinOptimizeImportsRefactoringHelper : RefactoringHelper<Set<KtFile>> {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val REMOVING_REDUNDANT_IMPORTS_TITLE = "Removing redundant imports"
|
||||
private const val COLLECT_UNUSED_IMPORTS_TITLE = "Collect unused imports"
|
||||
private const val REMOVING_REDUNDANT_IMPORTS_TITLE = "Removing redundant imports"
|
||||
}
|
||||
|
||||
override fun prepareOperation(usages: Array<UsageInfo>): Set<KtFile> {
|
||||
@@ -90,33 +124,26 @@ class KotlinOptimizeImportsRefactoringHelper : RefactoringHelper<Set<KtFile>> {
|
||||
|
||||
if (operationData.isEmpty()) return
|
||||
|
||||
val unusedImports = LinkedHashSet<SmartPsiElementPointer<KtImportDirective>>()
|
||||
val findRedundantImports = {
|
||||
DumbService.getInstance(project).runReadActionInSmartMode {
|
||||
val progressIndicator = ProgressManager.getInstance().progressIndicator
|
||||
val fileCount = operationData.size
|
||||
for ((i, file) in operationData.withIndex()) {
|
||||
if (!file.isValid) continue
|
||||
val virtualFile = file.virtualFile ?: continue
|
||||
val unusedImports = mutableSetOf<SmartPsiElementPointer<KtImportDirective>>()
|
||||
|
||||
progressIndicator?.text2 = virtualFile.presentableUrl
|
||||
progressIndicator?.fraction = i.toDouble() / fileCount
|
||||
val progressManager = ProgressManager.getInstance()
|
||||
|
||||
val fileImportData = KotlinUnusedImportInspection.analyzeImports(file) ?: continue
|
||||
fileImportData.unusedImports.mapTo(unusedImports) { it.createSmartPointer() }
|
||||
val dumbService = DumbService.getInstance(project)
|
||||
|
||||
val collectTask = object : SequentialModalProgressTask(project, COLLECT_UNUSED_IMPORTS_TITLE, false) {
|
||||
override fun onSuccess() {
|
||||
val progressTask = SequentialModalProgressTask(project, REMOVING_REDUNDANT_IMPORTS_TITLE, false)
|
||||
with(progressTask) {
|
||||
setMinIterationTime(200)
|
||||
setTask(OptimizeImportsTask(this, unusedImports))
|
||||
}
|
||||
progressManager.run(progressTask)
|
||||
}
|
||||
}
|
||||
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||
findRedundantImports, REMOVING_REDUNDANT_IMPORTS_TITLE, false, project
|
||||
)) return
|
||||
|
||||
runWriteAction {
|
||||
val progressTask = SequentialModalProgressTask(project, REMOVING_REDUNDANT_IMPORTS_TITLE, false).apply {
|
||||
setMinIterationTime(200)
|
||||
setTask(OptimizeImportsTask(this, unusedImports))
|
||||
}
|
||||
ProgressManager.getInstance().run(progressTask)
|
||||
with(collectTask) {
|
||||
setMinIterationTime(200)
|
||||
setTask(CollectUnusedImportsTask(this, dumbService, unusedImports, operationData))
|
||||
}
|
||||
progressManager.run(collectTask)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.PsiMember
|
||||
import com.intellij.psi.PsiMethod
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
@@ -31,7 +32,8 @@ class RemoveRedundantQualifierNameInspection : AbstractKotlinInspection(), Clean
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor =
|
||||
object : KtVisitorVoid() {
|
||||
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression) {
|
||||
if (expression.parent is KtDotQualifiedExpression || expression.isInImportDirective()) return
|
||||
val expressionParent = expression.parent
|
||||
if (expressionParent is KtDotQualifiedExpression || expressionParent is KtPackageDirective || expressionParent is KtImportDirective) return
|
||||
val expressionForAnalyze = expression.firstExpressionWithoutReceiver() ?: return
|
||||
|
||||
val parent = expressionForAnalyze.parent
|
||||
@@ -72,7 +74,8 @@ private tailrec fun KtDotQualifiedExpression.firstExpressionWithoutReceiver(): K
|
||||
val element = getQualifiedElementSelector()?.mainReference?.resolve() ?: return null
|
||||
return if (element is KtClassOrObject ||
|
||||
element is KtCallableDeclaration && element.receiverTypeReference == null ||
|
||||
element is PsiMember && element.hasModifier(JvmModifier.STATIC)
|
||||
element is PsiMember && element.hasModifier(JvmModifier.STATIC) ||
|
||||
element is PsiMethod && element.isConstructor
|
||||
) this else (receiverExpression as? KtDotQualifiedExpression)?.firstExpressionWithoutReceiver()
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user