Add multi-platform projects as experimental language feature

This commit is contained in:
Alexander Udalov
2016-10-24 17:48:07 +03:00
parent 525e6e53fe
commit 73f872172f
6 changed files with 67 additions and 36 deletions
@@ -64,6 +64,9 @@ public abstract class CommonCompilerArguments {
@ValueDescription("<path>")
public String[] pluginClasspaths;
@Argument(value = "Xmulti-platform", description = "Enable experimental language support for multi-platform projects")
public boolean multiPlatform;
@Argument(value = "P", description = "Pass an option to a plugin")
@ValueDescription(PLUGIN_OPTION_FORMAT)
public String[] pluginOptions;
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStat
import org.jetbrains.kotlin.utils.StringsKt;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
@@ -248,33 +249,46 @@ public abstract class CLICompiler<A extends CommonCompilerArguments> {
configuration.put(CLIConfigurationKeys.COMPILER_JAR_LOCATOR, locator);
}
LanguageVersion languageVersion = parseVersion(configuration, arguments.languageVersion, "language");
LanguageVersion apiVersion = parseVersion(configuration, arguments.apiVersion, "API");
if (languageVersion != null || apiVersion != null) {
if (languageVersion == null) {
// If only "-api-version" is specified, language version is assumed to be the latest
languageVersion = LanguageVersion.LATEST;
}
if (apiVersion == null) {
// If only "-language-version" is specified, API version is assumed to be equal to the language version
// (API version cannot be greater than the language version)
apiVersion = languageVersion;
}
if (apiVersion.compareTo(languageVersion) > 0) {
configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(
CompilerMessageSeverity.ERROR,
"-api-version (" + apiVersion.getVersionString() + ") cannot be greater than " +
"-language-version (" + languageVersion.getVersionString() + ")",
CompilerMessageLocation.NO_LOCATION
);
}
configuration.put(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS,
new LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion)));
}
setupLanguageVersionSettings(configuration, arguments);
}
private static void setupLanguageVersionSettings(
@NotNull CompilerConfiguration configuration, @NotNull CommonCompilerArguments arguments
) {
LanguageVersion languageVersion = parseVersion(configuration, arguments.languageVersion, "language");
LanguageVersion apiVersion = parseVersion(configuration, arguments.apiVersion, "API");
if (languageVersion == null) {
// If only "-api-version" is specified, language version is assumed to be the latest
languageVersion = LanguageVersion.LATEST;
}
if (apiVersion == null) {
// If only "-language-version" is specified, API version is assumed to be equal to the language version
// (API version cannot be greater than the language version)
apiVersion = languageVersion;
}
if (apiVersion.compareTo(languageVersion) > 0) {
configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(
CompilerMessageSeverity.ERROR,
"-api-version (" + apiVersion.getVersionString() + ") cannot be greater than " +
"-language-version (" + languageVersion.getVersionString() + ")",
CompilerMessageLocation.NO_LOCATION
);
}
List<LanguageFeature> extraLanguageFeatures = new ArrayList<LanguageFeature>(0);
if (arguments.multiPlatform) {
extraLanguageFeatures.add(LanguageFeature.MultiPlatformProjects);
}
configuration.put(
CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS,
new LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion), extraLanguageFeatures)
);
}
@Nullable
private static LanguageVersion parseVersion(
@NotNull CompilerConfiguration configuration, @Nullable String value, @NotNull String versionOf
) {
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.TestOnly;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.config.LanguageVersion;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory;
import org.jetbrains.kotlin.diagnostics.Errors;
@@ -517,11 +518,14 @@ public class DefaultErrorMessages {
MAP.put(UNSAFE_IMPLICIT_INVOKE_CALL, "Reference has a nullable type ''{0}'', use explicit ''?.invoke()'' to make a function-like call instead", RENDER_TYPE);
MAP.put(AMBIGUOUS_LABEL, "Ambiguous label");
MAP.put(UNSUPPORTED, "Unsupported [{0}]", STRING);
MAP.put(UNSUPPORTED_FEATURE, "The feature is only available since Kotlin {0}", new DiagnosticParameterRenderer<LanguageFeature>() {
MAP.put(UNSUPPORTED_FEATURE, "The feature is {0}", new DiagnosticParameterRenderer<LanguageFeature>() {
@NotNull
@Override
public String render(LanguageFeature feature, @NotNull RenderingContext renderingContext) {
return feature.getSinceVersion().getVersionString() + ": " + feature.getPresentableText();
LanguageVersion version = feature.getSinceVersion();
return version != null
? "only available since Kotlin " + version.getVersionString() + ": " + feature.getPresentableText()
: "experimental and should be turned on explicitly via a command line option or in IDE settings: " + feature.getPresentableText();
}
});
MAP.put(EXCEPTION_FROM_ANALYZER, "Internal Error occurred while analyzing this expression:\n{0}", THROWABLE);
+1
View File
@@ -3,6 +3,7 @@ where advanced options include:
-Xno-inline Disable method inlining
-Xrepeat <count> Repeat compilation (for performance analysis)
-Xplugin <path> Load plugins from the given classpath
-Xmulti-platform Enable experimental language support for multi-platform projects
Advanced options are non-standard and may be changed or removed without any notice.
OK
+1
View File
@@ -16,6 +16,7 @@ where advanced options include:
-Xno-inline Disable method inlining
-Xrepeat <count> Repeat compilation (for performance analysis)
-Xplugin <path> Load plugins from the given classpath
-Xmulti-platform Enable experimental language support for multi-platform projects
Advanced options are non-standard and may be changed or removed without any notice.
OK
@@ -16,13 +16,11 @@
package org.jetbrains.kotlin.config
import com.intellij.openapi.module.Module
import com.intellij.util.text.VersionComparatorUtil
import org.jetbrains.kotlin.config.LanguageVersion.KOTLIN_1_1
import org.jetbrains.kotlin.utils.DescriptionAware
enum class LanguageFeature(val sinceVersion: LanguageVersion) {
// Note: names of these entries are also used in diagnostic tests
enum class LanguageFeature(val sinceVersion: LanguageVersion?) {
// Note: names of these entries are also used in diagnostic tests and in user-visible messages (see presentableText below)
TypeAliases(KOTLIN_1_1),
BoundCallableReferences(KOTLIN_1_1),
LocalDelegatedProperties(KOTLIN_1_1),
@@ -34,7 +32,10 @@ enum class LanguageFeature(val sinceVersion: LanguageVersion) {
DestructuringLambdaParameters(KOTLIN_1_1),
SingleUnderscoreForParameterName(KOTLIN_1_1),
DslMarkersSupport(KOTLIN_1_1),
UnderscoresInNumericLiterals(KOTLIN_1_1)
UnderscoresInNumericLiterals(KOTLIN_1_1),
// Experimental features
MultiPlatformProjects(null),
;
val presentableText: String
@@ -74,15 +75,22 @@ interface LanguageVersionSettings {
val apiVersion: ApiVersion
}
class LanguageVersionSettingsImpl(
class LanguageVersionSettingsImpl @JvmOverloads constructor(
private val languageVersion: LanguageVersion,
override val apiVersion: ApiVersion
override val apiVersion: ApiVersion,
additionalFeatures: Collection<LanguageFeature> = emptySet()
) : LanguageVersionSettings {
private val additionalFeatures = additionalFeatures.toSet()
override fun supportsFeature(feature: LanguageFeature): Boolean {
return languageVersion >= feature.sinceVersion
val since = feature.sinceVersion
return (since != null && languageVersion >= since) || feature in additionalFeatures
}
override fun toString() = "Language = $languageVersion, API = $apiVersion"
override fun toString() = buildString {
append("Language = $languageVersion, API = $apiVersion")
additionalFeatures.forEach { feature -> append(" +$feature") }
}
companion object {
@JvmField