Introduce keys to control applicability of coroutines
By default now we produce warnings on coroutines
This commit is contained in:
committed by
Stanislav Erokhin
parent
30710955dc
commit
664485f4bb
+10
-1
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -70,6 +70,15 @@ public abstract class CommonCompilerArguments {
|
|||||||
@Argument(value = "Xno-check-impl", description = "Do not check presence of 'impl' modifier in multi-platform projects")
|
@Argument(value = "Xno-check-impl", description = "Do not check presence of 'impl' modifier in multi-platform projects")
|
||||||
public boolean noCheckImpl;
|
public boolean noCheckImpl;
|
||||||
|
|
||||||
|
@Argument(value = "Xcoroutines=warn")
|
||||||
|
public boolean coroutinesWarn;
|
||||||
|
|
||||||
|
@Argument(value = "Xcoroutines=error")
|
||||||
|
public boolean coroutinesError;
|
||||||
|
|
||||||
|
@Argument(value = "Xcoroutines=enable")
|
||||||
|
public boolean coroutinesEnable;
|
||||||
|
|
||||||
@Argument(value = "P", description = "Pass an option to a plugin")
|
@Argument(value = "P", description = "Pass an option to a plugin")
|
||||||
@ValueDescription(PLUGIN_OPTION_FORMAT)
|
@ValueDescription(PLUGIN_OPTION_FORMAT)
|
||||||
public String[] pluginOptions;
|
public String[] pluginOptions;
|
||||||
|
|||||||
@@ -285,12 +285,41 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
|
|||||||
extraLanguageFeatures.add(LanguageFeature.MultiPlatformDoNotCheckImpl);
|
extraLanguageFeatures.add(LanguageFeature.MultiPlatformDoNotCheckImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LanguageFeature coroutinesApplicabilityLevel = chooseCoroutinesApplicabilityLevel(configuration, arguments);
|
||||||
|
if (coroutinesApplicabilityLevel != null) {
|
||||||
|
extraLanguageFeatures.add(coroutinesApplicabilityLevel);
|
||||||
|
}
|
||||||
|
|
||||||
configuration.put(
|
configuration.put(
|
||||||
CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS,
|
CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS,
|
||||||
new LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion), extraLanguageFeatures)
|
new LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion), extraLanguageFeatures)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static LanguageFeature chooseCoroutinesApplicabilityLevel(
|
||||||
|
@NotNull CompilerConfiguration configuration, @NotNull CommonCompilerArguments arguments) {
|
||||||
|
if (!arguments.coroutinesEnable && !arguments.coroutinesError && !arguments.coroutinesWarn) {
|
||||||
|
return LanguageFeature.WarnOnCoroutines;
|
||||||
|
}
|
||||||
|
else if (arguments.coroutinesError && !arguments.coroutinesWarn && !arguments.coroutinesEnable) {
|
||||||
|
return LanguageFeature.ErrorOnCoroutines;
|
||||||
|
}
|
||||||
|
else if (arguments.coroutinesWarn && !arguments.coroutinesError && !arguments.coroutinesEnable) {
|
||||||
|
return LanguageFeature.WarnOnCoroutines;
|
||||||
|
}
|
||||||
|
else if (arguments.coroutinesEnable && !arguments.coroutinesWarn && !arguments.coroutinesError) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
String message = "The -Xcoroutines can only have one value";
|
||||||
|
configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(
|
||||||
|
CompilerMessageSeverity.ERROR, message, CompilerMessageLocation.NO_LOCATION
|
||||||
|
);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static LanguageVersion parseVersion(
|
private static LanguageVersion parseVersion(
|
||||||
@NotNull CompilerConfiguration configuration, @Nullable String value, @NotNull String versionOf
|
@NotNull CompilerConfiguration configuration, @Nullable String value, @NotNull String versionOf
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -29,13 +29,22 @@ class Usage {
|
|||||||
// The magic number 29 corresponds to the similar padding width in javac and scalac command line compilers
|
// The magic number 29 corresponds to the similar padding width in javac and scalac command line compilers
|
||||||
private static final int OPTION_NAME_PADDING_WIDTH = 29;
|
private static final int OPTION_NAME_PADDING_WIDTH = 29;
|
||||||
|
|
||||||
|
private static final String coroutinesKeyDescription = "Enable coroutines or report warnings or report errors on declarations and use sites of suspend modifier";
|
||||||
|
|
||||||
public static void print(@NotNull PrintStream target, @NotNull CommonCompilerArguments arguments, boolean extraHelp) {
|
public static void print(@NotNull PrintStream target, @NotNull CommonCompilerArguments arguments, boolean extraHelp) {
|
||||||
target.println("Usage: " + arguments.executableScriptFileName() + " <options> <source files>");
|
target.println("Usage: " + arguments.executableScriptFileName() + " <options> <source files>");
|
||||||
target.println("where " + (extraHelp ? "advanced" : "possible") + " options include:");
|
target.println("where " + (extraHelp ? "advanced" : "possible") + " options include:");
|
||||||
|
boolean coroutinesUsagePrinted = false;
|
||||||
for (Class<?> clazz = arguments.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
|
for (Class<?> clazz = arguments.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
|
||||||
for (Field field : clazz.getDeclaredFields()) {
|
for (Field field : clazz.getDeclaredFields()) {
|
||||||
String usage = fieldUsage(field, extraHelp);
|
String usage = fieldUsage(field, extraHelp);
|
||||||
if (usage != null) {
|
if (usage != null) {
|
||||||
|
boolean coroutinesUsage = usage.contains("Xcoroutines");
|
||||||
|
if (coroutinesUsage && coroutinesUsagePrinted) {
|
||||||
|
continue;
|
||||||
|
} else if (coroutinesUsage) {
|
||||||
|
coroutinesUsagePrinted = true;
|
||||||
|
}
|
||||||
target.println(usage);
|
target.println(usage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -51,9 +60,13 @@ class Usage {
|
|||||||
private static String fieldUsage(@NotNull Field field, boolean extraHelp) {
|
private static String fieldUsage(@NotNull Field field, boolean extraHelp) {
|
||||||
Argument argument = field.getAnnotation(Argument.class);
|
Argument argument = field.getAnnotation(Argument.class);
|
||||||
if (argument == null) return null;
|
if (argument == null) return null;
|
||||||
|
|
||||||
ValueDescription description = field.getAnnotation(ValueDescription.class);
|
ValueDescription description = field.getAnnotation(ValueDescription.class);
|
||||||
|
|
||||||
String value = argument.value();
|
String argumentValue = argument.value();
|
||||||
|
// TODO: this is a dirty hack, provide better mechanism for keys that can have several values
|
||||||
|
boolean isXCoroutinesKey = argumentValue.contains("Xcoroutines");
|
||||||
|
String value = isXCoroutinesKey ? "Xcoroutines={enable|warn|error}" : argument.value();
|
||||||
boolean extraOption = value.startsWith("X") && value.length() > 1;
|
boolean extraOption = value.startsWith("X") && value.length() > 1;
|
||||||
if (extraHelp != extraOption) return null;
|
if (extraHelp != extraOption) return null;
|
||||||
|
|
||||||
@@ -73,6 +86,11 @@ class Usage {
|
|||||||
sb.append(description.value());
|
sb.append(description.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isXCoroutinesKey) {
|
||||||
|
sb.append(" ");
|
||||||
|
sb.append(coroutinesKeyDescription);
|
||||||
|
}
|
||||||
|
|
||||||
int width = OPTION_NAME_PADDING_WIDTH - 1;
|
int width = OPTION_NAME_PADDING_WIDTH - 1;
|
||||||
if (sb.length() >= width + 5) { // Break the line if it's too long
|
if (sb.length() >= width + 5) { // Break the line if it's too long
|
||||||
sb.append("\n");
|
sb.append("\n");
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ public interface Errors {
|
|||||||
DiagnosticFactory1<PsiElement, LanguageFeature> UNSUPPORTED_FEATURE = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, LanguageFeature> UNSUPPORTED_FEATURE = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory1<PsiElement, Throwable> EXCEPTION_FROM_ANALYZER = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, Throwable> EXCEPTION_FROM_ANALYZER = DiagnosticFactory1.create(ERROR);
|
||||||
|
|
||||||
|
DiagnosticFactory1<PsiElement, LanguageFeature> EXPERIMENTAL_FEATURE_WARNING = DiagnosticFactory1.create(WARNING);
|
||||||
|
DiagnosticFactory1<PsiElement, LanguageFeature> EXPERIMENTAL_FEATURE_ERROR = DiagnosticFactory1.create(ERROR);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Generic errors/warnings: applicable in many contexts
|
// Generic errors/warnings: applicable in many contexts
|
||||||
|
|||||||
+14
@@ -589,6 +589,20 @@ public class DefaultErrorMessages {
|
|||||||
: "experimental and should be turned on explicitly via a command line option or in IDE settings: " + feature.getPresentableText();
|
: "experimental and should be turned on explicitly via a command line option or in IDE settings: " + feature.getPresentableText();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
MAP.put(EXPERIMENTAL_FEATURE_WARNING, "The feature is experimental: {0}", new DiagnosticParameterRenderer<LanguageFeature>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String render(LanguageFeature feature, @NotNull RenderingContext renderingContext) {
|
||||||
|
return feature.getPresentableText();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
MAP.put(EXPERIMENTAL_FEATURE_ERROR, "The experimental feature is disabled: {0}", new DiagnosticParameterRenderer<LanguageFeature>() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String render(LanguageFeature feature, @NotNull RenderingContext renderingContext) {
|
||||||
|
return feature.getPresentableText();
|
||||||
|
}
|
||||||
|
});
|
||||||
MAP.put(EXCEPTION_FROM_ANALYZER, "Internal Error occurred while analyzing this expression:\n{0}", THROWABLE);
|
MAP.put(EXCEPTION_FROM_ANALYZER, "Internal Error occurred while analyzing this expression:\n{0}", THROWABLE);
|
||||||
MAP.put(UNNECESSARY_SAFE_CALL, "Unnecessary safe call on a non-null receiver of type {0}", RENDER_TYPE);
|
MAP.put(UNNECESSARY_SAFE_CALL, "Unnecessary safe call on a non-null receiver of type {0}", RENDER_TYPE);
|
||||||
MAP.put(UNEXPECTED_SAFE_CALL, "Safe-call is not allowed here");
|
MAP.put(UNEXPECTED_SAFE_CALL, "Safe-call is not allowed here");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -100,6 +100,14 @@ object ModifierCheckerCore {
|
|||||||
IMPL_KEYWORD to LanguageFeature.MultiPlatformProjects
|
IMPL_KEYWORD to LanguageFeature.MultiPlatformProjects
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val errorOnFeature = mapOf(
|
||||||
|
LanguageFeature.Coroutines to LanguageFeature.ErrorOnCoroutines
|
||||||
|
)
|
||||||
|
|
||||||
|
val warningOnFeature = mapOf(
|
||||||
|
LanguageFeature.Coroutines to LanguageFeature.WarnOnCoroutines
|
||||||
|
)
|
||||||
|
|
||||||
val featureDependenciesTargets = mapOf(
|
val featureDependenciesTargets = mapOf(
|
||||||
LanguageFeature.InlineProperties to setOf(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER)
|
LanguageFeature.InlineProperties to setOf(PROPERTY, PROPERTY_GETTER, PROPERTY_SETTER)
|
||||||
)
|
)
|
||||||
@@ -266,15 +274,29 @@ object ModifierCheckerCore {
|
|||||||
|
|
||||||
val dependency = featureDependencies[modifier] ?: return true
|
val dependency = featureDependencies[modifier] ?: return true
|
||||||
|
|
||||||
if (!languageVersionSettings.supportsFeature(dependency)) {
|
val errorOnDependencyFeature = errorOnFeature[dependency]?.let { languageVersionSettings.supportsFeature(it) } ?: false
|
||||||
|
val supportsFeature = languageVersionSettings.supportsFeature(dependency)
|
||||||
|
|
||||||
|
if (!supportsFeature || errorOnDependencyFeature) {
|
||||||
val restrictedTargets = featureDependenciesTargets[dependency]
|
val restrictedTargets = featureDependenciesTargets[dependency]
|
||||||
if (restrictedTargets != null && actualTargets.intersect(restrictedTargets).isEmpty()) {
|
if (restrictedTargets != null && actualTargets.intersect(restrictedTargets).isEmpty()) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
trace.report(Errors.UNSUPPORTED_FEATURE.on(node.psi, dependency))
|
|
||||||
|
if (!supportsFeature) {
|
||||||
|
trace.report(Errors.UNSUPPORTED_FEATURE.on(node.psi, dependency))
|
||||||
|
}
|
||||||
|
else if (errorOnDependencyFeature) {
|
||||||
|
trace.report(Errors.EXPERIMENTAL_FEATURE_ERROR.on(node.psi, dependency))
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val pairedWarningFeature = warningOnFeature[dependency]
|
||||||
|
if (pairedWarningFeature != null && languageVersionSettings.supportsFeature(pairedWarningFeature)) {
|
||||||
|
trace.report(Errors.EXPERIMENTAL_FEATURE_WARNING.on(node.psi, dependency))
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+16
-3
@@ -18,11 +18,13 @@ package org.jetbrains.kotlin.resolve.calls.checkers
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.coroutines.hasSuspendFunctionType
|
import org.jetbrains.kotlin.coroutines.hasSuspendFunctionType
|
||||||
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -80,9 +82,20 @@ object CoroutineSuspendCallChecker : CallChecker {
|
|||||||
object BuilderFunctionsCallChecker : CallChecker {
|
object BuilderFunctionsCallChecker : CallChecker {
|
||||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||||
val descriptor = resolvedCall.candidateDescriptor as? FunctionDescriptor ?: return
|
val descriptor = resolvedCall.candidateDescriptor as? FunctionDescriptor ?: return
|
||||||
if (descriptor.valueParameters.any { it.hasSuspendFunctionType } &&
|
if (descriptor.valueParameters.any { it.hasSuspendFunctionType }) {
|
||||||
!context.languageVersionSettings.supportsFeature(LanguageFeature.Coroutines)) {
|
checkCoroutinesFeature(context.languageVersionSettings, context.trace, reportOn)
|
||||||
context.trace.report(Errors.UNSUPPORTED_FEATURE.on(reportOn, LanguageFeature.Coroutines))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkCoroutinesFeature(languageVersionSettings: LanguageVersionSettings, diagnosticHolder: DiagnosticSink, reportOn: PsiElement) {
|
||||||
|
if (!languageVersionSettings.supportsFeature(LanguageFeature.Coroutines)) {
|
||||||
|
diagnosticHolder.report(Errors.UNSUPPORTED_FEATURE.on(reportOn, LanguageFeature.Coroutines))
|
||||||
|
}
|
||||||
|
else if (languageVersionSettings.supportsFeature(LanguageFeature.ErrorOnCoroutines)) {
|
||||||
|
diagnosticHolder.report(Errors.EXPERIMENTAL_FEATURE_ERROR.on(reportOn, LanguageFeature.Coroutines))
|
||||||
|
}
|
||||||
|
else if (languageVersionSettings.supportsFeature(LanguageFeature.WarnOnCoroutines)) {
|
||||||
|
diagnosticHolder.report(Errors.EXPERIMENTAL_FEATURE_WARNING.on(reportOn, LanguageFeature.Coroutines))
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -5,6 +5,8 @@ where advanced options include:
|
|||||||
-Xplugin <path> Load plugins from the given classpath
|
-Xplugin <path> Load plugins from the given classpath
|
||||||
-Xmulti-platform Enable experimental language support for multi-platform projects
|
-Xmulti-platform Enable experimental language support for multi-platform projects
|
||||||
-Xno-check-impl Do not check presence of 'impl' modifier in multi-platform projects
|
-Xno-check-impl Do not check presence of 'impl' modifier in multi-platform projects
|
||||||
|
-Xcoroutines={enable|warn|error} Enable coroutines or report warnings or report errors on declarations and use sites of suspend modifier
|
||||||
|
|
||||||
|
|
||||||
Advanced options are non-standard and may be changed or removed without any notice.
|
Advanced options are non-standard and may be changed or removed without any notice.
|
||||||
OK
|
OK
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
$TESTDATA_DIR$/simple.kt
|
||||||
|
-Xcoroutines=enable
|
||||||
|
-Xcoroutines=warn
|
||||||
|
-Xcoroutines=error
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
error: the -Xcoroutines can only have one value
|
||||||
|
COMPILATION_ERROR
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
$TESTDATA_DIR$/simple.kt
|
||||||
|
-Xcoroutines=error
|
||||||
|
-Xcoroutines=enable
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
error: the -Xcoroutines can only have one value
|
||||||
|
COMPILATION_ERROR
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
$TESTDATA_DIR$/simple.kt
|
||||||
|
-Xcoroutines=warn
|
||||||
|
-Xcoroutines=enable
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
error: the -Xcoroutines can only have one value
|
||||||
|
COMPILATION_ERROR
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
$TESTDATA_DIR$/simple.kt
|
||||||
|
-Xcoroutines=warn
|
||||||
|
-Xcoroutines=error
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
error: the -Xcoroutines can only have one value
|
||||||
|
COMPILATION_ERROR
|
||||||
+2
@@ -18,6 +18,8 @@ where advanced options include:
|
|||||||
-Xplugin <path> Load plugins from the given classpath
|
-Xplugin <path> Load plugins from the given classpath
|
||||||
-Xmulti-platform Enable experimental language support for multi-platform projects
|
-Xmulti-platform Enable experimental language support for multi-platform projects
|
||||||
-Xno-check-impl Do not check presence of 'impl' modifier in multi-platform projects
|
-Xno-check-impl Do not check presence of 'impl' modifier in multi-platform projects
|
||||||
|
-Xcoroutines={enable|warn|error} Enable coroutines or report warnings or report errors on declarations and use sites of suspend modifier
|
||||||
|
|
||||||
|
|
||||||
Advanced options are non-standard and may be changed or removed without any notice.
|
Advanced options are non-standard and may be changed or removed without any notice.
|
||||||
OK
|
OK
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// !LANGUAGE: +ErrorOnCoroutines
|
||||||
|
|
||||||
|
<!EXPERIMENTAL_FEATURE_ERROR!>suspend<!> fun suspendHere(): String = "OK"
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var result = ""
|
||||||
|
|
||||||
|
<!EXPERIMENTAL_FEATURE_ERROR!>builder<!> {
|
||||||
|
suspendHere()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun box(): kotlin.String
|
||||||
|
public fun builder(/*0*/ c: suspend () -> kotlin.Unit): kotlin.Unit
|
||||||
|
public suspend fun suspendHere(): kotlin.String
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// !LANGUAGE: +WarnOnCoroutines
|
||||||
|
|
||||||
|
<!EXPERIMENTAL_FEATURE_WARNING!>suspend<!> fun suspendHere(): String = "OK"
|
||||||
|
|
||||||
|
fun builder(c: suspend () -> Unit) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
var result = ""
|
||||||
|
|
||||||
|
<!EXPERIMENTAL_FEATURE_WARNING!>builder<!> {
|
||||||
|
suspendHere()
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun box(): kotlin.String
|
||||||
|
public fun builder(/*0*/ c: suspend () -> kotlin.Unit): kotlin.Unit
|
||||||
|
public suspend fun suspendHere(): kotlin.String
|
||||||
@@ -4258,6 +4258,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/coroutines"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/coroutines"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutinesDisabled.kt")
|
||||||
|
public void testCoroutinesDisabled() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/coroutinesDisabled.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutinesEnabledWithWarning.kt")
|
||||||
|
public void testCoroutinesEnabledWithWarning() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/coroutinesEnabledWithWarning.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("illegalSuspendCalls.kt")
|
@TestMetadata("illegalSuspendCalls.kt")
|
||||||
public void testIllegalSuspendCalls() throws Exception {
|
public void testIllegalSuspendCalls() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/illegalSuspendCalls.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/illegalSuspendCalls.kt");
|
||||||
|
|||||||
@@ -116,6 +116,30 @@ public class CliTestGenerated extends AbstractCliTest {
|
|||||||
doJvmTest(fileName);
|
doJvmTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutinesEnableWarnAndErrorClash.args")
|
||||||
|
public void testCoroutinesEnableWarnAndErrorClash() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesEnableWarnAndErrorClash.args");
|
||||||
|
doJvmTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutinesErrorAndEnableClash.args")
|
||||||
|
public void testCoroutinesErrorAndEnableClash() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesErrorAndEnableClash.args");
|
||||||
|
doJvmTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutinesWarnAndEnableClash.args")
|
||||||
|
public void testCoroutinesWarnAndEnableClash() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesWarnAndEnableClash.args");
|
||||||
|
doJvmTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("coroutinesWarnAndErrorClash.args")
|
||||||
|
public void testCoroutinesWarnAndErrorClash() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesWarnAndErrorClash.args");
|
||||||
|
doJvmTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("diagnosticsOrder.args")
|
@TestMetadata("diagnosticsOrder.args")
|
||||||
public void testDiagnosticsOrder() throws Exception {
|
public void testDiagnosticsOrder() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/diagnosticsOrder.args");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/diagnosticsOrder.args");
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ enum class LanguageFeature(val sinceVersion: LanguageVersion?) {
|
|||||||
// Experimental features
|
// Experimental features
|
||||||
MultiPlatformProjects(null),
|
MultiPlatformProjects(null),
|
||||||
MultiPlatformDoNotCheckImpl(null),
|
MultiPlatformDoNotCheckImpl(null),
|
||||||
|
|
||||||
|
WarnOnCoroutines(null),
|
||||||
|
ErrorOnCoroutines(null)
|
||||||
;
|
;
|
||||||
|
|
||||||
val presentableText: String
|
val presentableText: String
|
||||||
|
|||||||
Reference in New Issue
Block a user