Add language feature for extended main convention

- suspend
- parameterless

 #KT-17679 Fixed
 #KT-26574 Fixed
This commit is contained in:
Denis Zharkov
2018-09-06 19:19:40 +03:00
parent f79fbe778f
commit 1cc0c12f87
18 changed files with 132 additions and 10 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.idea
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.name.FqName
@@ -138,6 +139,8 @@ class MainFunctionDetector {
}
}
if (descriptor.isSuspend && !languageVersionSettings.supportsFeature(LanguageFeature.ExtendedMainConvention)) return false
if (checkReturnType && !isMainReturnType(descriptor)) return false
if (DescriptorUtils.isTopLevelDeclaration(descriptor)) return true
@@ -173,17 +176,17 @@ class MainFunctionDetector {
private fun findMainFunction(declarations: List<KtDeclaration>) =
declarations.filterIsInstance<KtNamedFunction>().find { isMain(it) }
companion object {
private fun isParameterNumberSuitsForMain(
parametersCount: Int,
isTopLevel: Boolean,
allowParameterless: Boolean
) = when (parametersCount) {
1 -> true
0 -> isTopLevel && allowParameterless
else -> false
}
private fun isParameterNumberSuitsForMain(
parametersCount: Int,
isTopLevel: Boolean,
allowParameterless: Boolean
) = when (parametersCount) {
1 -> true
0 -> isTopLevel && allowParameterless && languageVersionSettings.supportsFeature(LanguageFeature.ExtendedMainConvention)
else -> false
}
companion object {
private fun isMainReturnType(descriptor: FunctionDescriptor): Boolean {
val returnType = descriptor.returnType
return returnType != null && KotlinBuiltIns.isUnit(returnType)
@@ -0,0 +1,3 @@
// WITH_RUNTIME
fun main() {}
@@ -0,0 +1,5 @@
@kotlin.Metadata
public final class ParameterlessMainKt {
public final static method main(): void
public synthetic static method main(p0: java.lang.String[]): void
}
@@ -0,0 +1,4 @@
// !LANGUAGE: -ExtendedMainConvention
// WITH_RUNTIME
fun main() {}
@@ -0,0 +1,4 @@
@kotlin.Metadata
public final class ParameterlessMain_beforeKt {
public final static method main(): void
}
@@ -0,0 +1,3 @@
// WITH_RUNTIME
suspend fun main(args: Array<String>) {}
@@ -0,0 +1,12 @@
@kotlin.Metadata
synthetic final class SuspendMainKt$$$main {
private final field args: java.lang.String[]
synthetic method <init>(p0: java.lang.String[]): void
public synthetic final method invoke(p0: java.lang.Object): java.lang.Object
}
@kotlin.Metadata
public final class SuspendMainKt {
public final static @org.jetbrains.annotations.Nullable method main(@org.jetbrains.annotations.NotNull p0: java.lang.String[], @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
public synthetic static method main(p0: java.lang.String[]): void
}
@@ -0,0 +1,4 @@
// !LANGUAGE: -ExtendedMainConvention -ReleaseCoroutines
// WITH_RUNTIME
suspend fun main(args: Array<String>) {}
@@ -0,0 +1,4 @@
@kotlin.Metadata
public final class SuspendMain_beforeKt {
public final static @org.jetbrains.annotations.Nullable method main(@org.jetbrains.annotations.NotNull p0: java.lang.String[], @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.experimental.Continuation): java.lang.Object
}
@@ -0,0 +1,7 @@
// !LANGUAGE: -ExtendedMainConvention
// FILE: a.kt
<!CONFLICTING_OVERLOADS!>fun main()<!> {}
// FILE: b.kt
<!CONFLICTING_OVERLOADS!>fun main()<!> {}
@@ -0,0 +1,4 @@
package
public fun main(): kotlin.Unit
public fun main(): kotlin.Unit
@@ -0,0 +1,7 @@
// !LANGUAGE: -ExtendedMainConvention
// FILE: a.kt
<!CONFLICTING_OVERLOADS!>suspend fun main(<!UNUSED_PARAMETER!>args<!>: Array<String>)<!> {}
// FILE: b.kt
<!CONFLICTING_OVERLOADS!>suspend fun main(<!UNUSED_PARAMETER!>args<!>: Array<String>)<!> {}
@@ -0,0 +1,4 @@
package
public suspend fun main(/*0*/ args: kotlin.Array<kotlin.String>): kotlin.Unit
public suspend fun main(/*0*/ args: kotlin.Array<kotlin.String>): kotlin.Unit
@@ -15936,11 +15936,21 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclarationParameterlessMainInvalid.kt");
}
@TestMetadata("RedeclarationParameterlessMain_before.kt")
public void testRedeclarationParameterlessMain_before() throws Exception {
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclarationParameterlessMain_before.kt");
}
@TestMetadata("RedeclarationSuspendMainInMultiFile.kt")
public void testRedeclarationSuspendMainInMultiFile() throws Exception {
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclarationSuspendMainInMultiFile.kt");
}
@TestMetadata("RedeclarationSuspendMainInMultiFile_before.kt")
public void testRedeclarationSuspendMainInMultiFile_before() throws Exception {
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclarationSuspendMainInMultiFile_before.kt");
}
@TestMetadata("Redeclarations.kt")
public void testRedeclarations() throws Exception {
runTest("compiler/testData/diagnostics/tests/redeclarations/Redeclarations.kt");
@@ -15936,11 +15936,21 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclarationParameterlessMainInvalid.kt");
}
@TestMetadata("RedeclarationParameterlessMain_before.kt")
public void testRedeclarationParameterlessMain_before() throws Exception {
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclarationParameterlessMain_before.kt");
}
@TestMetadata("RedeclarationSuspendMainInMultiFile.kt")
public void testRedeclarationSuspendMainInMultiFile() throws Exception {
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclarationSuspendMainInMultiFile.kt");
}
@TestMetadata("RedeclarationSuspendMainInMultiFile_before.kt")
public void testRedeclarationSuspendMainInMultiFile_before() throws Exception {
runTest("compiler/testData/diagnostics/tests/redeclarations/RedeclarationSuspendMainInMultiFile_before.kt");
}
@TestMetadata("Redeclarations.kt")
public void testRedeclarations() throws Exception {
runTest("compiler/testData/diagnostics/tests/redeclarations/Redeclarations.kt");
@@ -320,6 +320,39 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
}
}
@TestMetadata("compiler/testData/codegen/bytecodeListing/main")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Main extends AbstractBytecodeListingTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
}
public void testAllFilesPresentInMain() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/main"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("parameterlessMain.kt")
public void testParameterlessMain() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/main/parameterlessMain.kt");
}
@TestMetadata("parameterlessMain_before.kt")
public void testParameterlessMain_before() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/main/parameterlessMain_before.kt");
}
@TestMetadata("suspendMain.kt")
public void testSuspendMain() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/main/suspendMain.kt");
}
@TestMetadata("suspendMain_before.kt")
public void testSuspendMain_before() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/main/suspendMain_before.kt");
}
}
@TestMetadata("compiler/testData/codegen/bytecodeListing/multiplatform")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -88,6 +88,7 @@ enum class LanguageFeature(
DslMarkerOnFunctionTypeReceiver(KOTLIN_1_4, kind = BUG_FIX),
ProhibitErroneousExpressionsInAnnotationsWithUseSiteTargets(KOTLIN_1_3, kind = BUG_FIX),
NewCapturedReceiverFieldNamingConvention(KOTLIN_1_3, kind = BUG_FIX),
ExtendedMainConvention(KOTLIN_1_3),
RestrictReturnStatementTarget(KOTLIN_1_4, kind = BUG_FIX),
NoConstantValueAttributeForNonConstVals(KOTLIN_1_4, kind = BUG_FIX),
@@ -39,6 +39,7 @@ import org.jetbrains.kotlin.idea.stubindex.KotlinTopLevelFunctionFqnNameIndex
import org.jetbrains.kotlin.idea.test.ConfigLibraryUtil
import org.jetbrains.kotlin.idea.test.KotlinCodeInsightTestCase
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase.*
import org.jetbrains.kotlin.idea.test.configureLanguageAndApiVersion
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.allChildren
@@ -55,6 +56,9 @@ class RunConfigurationTest: KotlinCodeInsightTestCase() {
fun testMainInTest() {
val createResult = configureModule(moduleDirPath("module"), getTestProject().baseDir!!)
configureLanguageAndApiVersion(
createResult.module.project, createResult.module, LanguageVersionSettingsImpl.DEFAULT.languageVersion.versionString
)
ConfigLibraryUtil.configureKotlinRuntimeAndSdk(createResult.module, addJdk(testRootDisposable, ::mockJdk))
val runConfiguration = createConfigurationFromMain("some.main")