mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
get rid of manual XML read/write — ShortenCommandLine.readShortenClasspathMethod, support enum in DSL (schema and read)
This commit is contained in:
@@ -61,7 +61,7 @@ public abstract class JavaTestConfigurationBase extends ModuleBasedConfiguration
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShortenCommandLine(ShortenCommandLine shortenCommandLine) {
|
||||
public void setShortenCommandLine(@Nullable ShortenCommandLine shortenCommandLine) {
|
||||
myShortenCommandLine = shortenCommandLine;
|
||||
}
|
||||
|
||||
|
||||
+23
-9
@@ -9,6 +9,7 @@ import com.intellij.execution.junit.RefactoringListeners;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.execution.util.JavaParametersUtil;
|
||||
import com.intellij.execution.util.ProgramParametersUtil;
|
||||
import com.intellij.openapi.components.BaseState;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.options.SettingsEditor;
|
||||
import com.intellij.openapi.options.SettingsEditorGroup;
|
||||
@@ -35,14 +36,18 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
|
||||
RefactoringListenerProvider, InputRedirectAware {
|
||||
|
||||
/* deprecated, but 3rd-party used variables */
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated public String MAIN_CLASS_NAME;
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated public String PROGRAM_PARAMETERS;
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated public String WORKING_DIRECTORY;
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated public boolean ALTERNATIVE_JRE_PATH_ENABLED;
|
||||
@SuppressWarnings("DeprecatedIsStillUsed")
|
||||
@Deprecated public String ALTERNATIVE_JRE_PATH;
|
||||
/* */
|
||||
|
||||
private ShortenCommandLine myShortenCommandLine = null;
|
||||
private final InputRedirectAware.InputRedirectOptions myInputRedirectOptions = new InputRedirectOptions();
|
||||
|
||||
public ApplicationConfiguration(String name, @NotNull Project project, @NotNull ApplicationConfigurationType configurationType) {
|
||||
@@ -275,11 +280,19 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
|
||||
return JavaRunConfigurationModule.getModulesForClass(getProject(), getMainClassName());
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void readExternal(@NotNull final Element element) {
|
||||
super.readExternal(element);
|
||||
|
||||
syncOldStateFields();
|
||||
|
||||
JavaRunConfigurationExtensionManager.getInstance().readExternal(this, element);
|
||||
setShortenCommandLine(ShortenCommandLine.readShortenClasspathMethod(element));
|
||||
myInputRedirectOptions.readExternal(element);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void syncOldStateFields() {
|
||||
JvmMainMethodRunConfigurationOptions options = getOptions();
|
||||
|
||||
String workingDirectory = options.getWorkingDirectory();
|
||||
@@ -295,10 +308,12 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
|
||||
WORKING_DIRECTORY = workingDirectory;
|
||||
ALTERNATIVE_JRE_PATH = options.getAlternativeJrePath();
|
||||
ALTERNATIVE_JRE_PATH_ENABLED = options.isAlternativeJrePathEnabled();
|
||||
}
|
||||
|
||||
JavaRunConfigurationExtensionManager.getInstance().readExternal(this, element);
|
||||
setShortenCommandLine(ShortenCommandLine.readShortenClasspathMethod(element));
|
||||
myInputRedirectOptions.readExternal(element);
|
||||
@Override
|
||||
public void setState(@NotNull BaseState state) {
|
||||
super.setState(state);
|
||||
syncOldStateFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -306,19 +321,18 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
|
||||
super.writeExternal(element);
|
||||
|
||||
JavaRunConfigurationExtensionManager.getInstance().writeExternal(this, element);
|
||||
ShortenCommandLine.writeShortenClasspathMethod(element, myShortenCommandLine);
|
||||
myInputRedirectOptions.writeExternal(element);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ShortenCommandLine getShortenCommandLine() {
|
||||
return myShortenCommandLine;
|
||||
return getOptions().getShortenClasspath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShortenCommandLine(ShortenCommandLine mode) {
|
||||
myShortenCommandLine = mode;
|
||||
public void setShortenCommandLine(@Nullable ShortenCommandLine mode) {
|
||||
getOptions().setShortenClasspath(mode);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+11
-5
@@ -2,26 +2,32 @@
|
||||
package com.intellij.execution.application
|
||||
|
||||
import com.intellij.execution.JvmConfigurationOptions
|
||||
import com.intellij.execution.ShortenCommandLine
|
||||
import com.intellij.util.xmlb.annotations.OptionTag
|
||||
import com.intellij.util.xmlb.annotations.XMap
|
||||
import java.util.*
|
||||
|
||||
open class JvmMainMethodRunConfigurationOptions : JvmConfigurationOptions() {
|
||||
@get:OptionTag("PROGRAM_PARAMETERS")
|
||||
open var programParameters: String? by string()
|
||||
open var programParameters by string()
|
||||
|
||||
@get:OptionTag("WORKING_DIRECTORY")
|
||||
open var workingDirectory: String? by string()
|
||||
open var workingDirectory by string()
|
||||
|
||||
@get:OptionTag("INCLUDE_PROVIDED_SCOPE")
|
||||
var includeProvidedScope: Boolean by property(false)
|
||||
var includeProvidedScope by property(false)
|
||||
|
||||
@get:OptionTag("ENABLE_SWING_INSPECTOR")
|
||||
var isSwingInspectorEnabled: Boolean by property(false)
|
||||
var isSwingInspectorEnabled by property(false)
|
||||
|
||||
@get:OptionTag("PASS_PARENT_ENVS")
|
||||
var isPassParentEnv: Boolean by property(true)
|
||||
var isPassParentEnv by property(true)
|
||||
|
||||
@get:XMap(propertyElementName = "envs", entryTagName = "env", keyAttributeName = "name")
|
||||
var env: MutableMap<String, String> by property(LinkedHashMap())
|
||||
|
||||
// see ConfigurationWithCommandLineShortener - "null if option was not selected explicitly, legacy user-local options to be used"
|
||||
// so, we cannot use NONE as default value
|
||||
@get:OptionTag(nameAttribute = "", valueAttribute = "name")
|
||||
var shortenClasspath by enum<ShortenCommandLine>()
|
||||
}
|
||||
+1
-1
@@ -238,7 +238,7 @@ public abstract class TestDiscoveryConfigurationProducer extends JavaRunConfigur
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setShortenCommandLine(ShortenCommandLine mode) {
|
||||
public void setShortenCommandLine(@Nullable ShortenCommandLine mode) {
|
||||
myConfiguration.setShortenCommandLine(mode);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,4 @@
|
||||
// Copyright 2000-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 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.execution;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -74,6 +62,7 @@ public enum ShortenCommandLine {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void writeShortenClasspathMethod(@NotNull Element element, ShortenCommandLine shortenCommandLine) {
|
||||
if (shortenCommandLine != null) {
|
||||
element.addContent(new Element("shortenClasspath").setAttribute("name", shortenCommandLine.name()));
|
||||
|
||||
+3
-1
@@ -21,6 +21,7 @@ import com.intellij.util.SmartList;
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -215,7 +216,8 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements
|
||||
myOptions = XmlSerializer.deserialize(element, getOptionsClass());
|
||||
}
|
||||
|
||||
public final void setState(@NotNull BaseState state) {
|
||||
@ApiStatus.Experimental
|
||||
public void setState(@NotNull BaseState state) {
|
||||
myOptions = (RunConfigurationOptions)state;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.execution;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -14,7 +14,7 @@ public interface ConfigurationWithCommandLineShortener {
|
||||
/**
|
||||
* Called from UI, when user explicitly selects method to be used to shorten the command line or from the deserialization
|
||||
*/
|
||||
void setShortenCommandLine(ShortenCommandLine mode);
|
||||
void setShortenCommandLine(@Nullable ShortenCommandLine mode);
|
||||
|
||||
Project getProject();
|
||||
}
|
||||
|
||||
+29
-1
@@ -4,9 +4,10 @@ package com.intellij.configurationStore.properties
|
||||
import com.intellij.openapi.components.*
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
internal abstract class ObjectStateStoredPropertyBase<T>(protected var value: T) : StoredPropertyBase<T>() {
|
||||
abstract class ObjectStateStoredPropertyBase<T>(protected var value: T) : StoredPropertyBase<T>() {
|
||||
override val jsonType: JsonSchemaType
|
||||
get() = JsonSchemaType.OBJECT
|
||||
|
||||
@@ -55,6 +56,33 @@ internal open class ObjectStoredProperty<T>(private val defaultValue: T) : Objec
|
||||
}
|
||||
}
|
||||
|
||||
class EnumStoredProperty<T : Enum<*>>(private val defaultValue: T?, val clazz: Class<T>) : ObjectStateStoredPropertyBase<T?>(defaultValue), ScalarProperty {
|
||||
override val jsonType: JsonSchemaType
|
||||
get() = JsonSchemaType.STRING
|
||||
|
||||
override fun isEqualToDefault() = value === defaultValue
|
||||
|
||||
override fun getModificationCount() = 0L
|
||||
|
||||
override fun setValue(thisRef: BaseState, property: KProperty<*>, @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE") newValue: T?) {
|
||||
val v = newValue ?: defaultValue
|
||||
if (value !== v) {
|
||||
thisRef.intIncrementModificationCount()
|
||||
value = v
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun parseAndSetValue(rawValue: String?) {
|
||||
if (rawValue == null) {
|
||||
value = defaultValue
|
||||
}
|
||||
else {
|
||||
value = XmlSerializerUtil.stringToEnum(rawValue, clazz, true /* lowercase in YAML by default */) as T? ?: defaultValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class StateObjectStoredProperty<T : BaseState?>(initialValue: T) : ObjectStateStoredPropertyBase<T>(initialValue) {
|
||||
override fun isEqualToDefault(): Boolean {
|
||||
val value = value
|
||||
|
||||
@@ -32,7 +32,7 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
|
||||
properties.add(p as StoredProperty<Any>)
|
||||
}
|
||||
|
||||
fun <T> property(): StoredPropertyBase<T?> {
|
||||
protected fun <T> property(): StoredPropertyBase<T?> {
|
||||
val result = ObjectStoredProperty<T?>(null)
|
||||
addProperty(result)
|
||||
return result
|
||||
@@ -42,7 +42,7 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
|
||||
* Value considered as default only if all properties have default values.
|
||||
* Passed instance is not used for `isDefault` check. It is just an initial value.
|
||||
*/
|
||||
fun <T : BaseState?> property(initialValue: T): StoredPropertyBase<T> {
|
||||
protected fun <T : BaseState?> property(initialValue: T): StoredPropertyBase<T> {
|
||||
val result = StateObjectStoredProperty(initialValue)
|
||||
addProperty(result)
|
||||
return result
|
||||
@@ -51,7 +51,7 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
|
||||
/**
|
||||
* For non-BaseState classes explicit `isDefault` must be provided, because no other way to check.
|
||||
*/
|
||||
fun <T> property(initialValue: T, isDefault: (value: T) -> Boolean): StoredPropertyBase<T> {
|
||||
protected fun <T> property(initialValue: T, isDefault: (value: T) -> Boolean): StoredPropertyBase<T> {
|
||||
val result = object : ObjectStoredProperty<T>(initialValue) {
|
||||
override fun isEqualToDefault() = isDefault(value)
|
||||
}
|
||||
@@ -64,7 +64,7 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
|
||||
* Collection considered as default if empty. It is *your* responsibility to call `incrementModificationCount` on collection modification.
|
||||
* You cannot set value to a new collection - on set current collection is cleared and new collection is added to current.
|
||||
*/
|
||||
fun <E, C : MutableCollection<E>> property(initialValue: C): StoredPropertyBase<C> {
|
||||
protected fun <E, C : MutableCollection<E>> property(initialValue: C): StoredPropertyBase<C> {
|
||||
val result = CollectionStoredProperty(initialValue)
|
||||
addProperty(result)
|
||||
return result
|
||||
@@ -73,7 +73,7 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
|
||||
/**
|
||||
* Charset is an immutable, so, it is safe to use it as default value.
|
||||
*/
|
||||
fun <T : Charset> property(initialValue: T): StoredPropertyBase<T> {
|
||||
protected fun <T : Charset> property(initialValue: T): StoredPropertyBase<T> {
|
||||
val result = ObjectStoredProperty(initialValue)
|
||||
addProperty(result)
|
||||
return result
|
||||
@@ -82,27 +82,41 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
|
||||
/**
|
||||
* Enum is an immutable, so, it is safe to use it as default value.
|
||||
*/
|
||||
fun <T : Enum<*>> property(defaultValue: T): StoredPropertyBase<T> {
|
||||
protected fun <T : Enum<*>> property(defaultValue: T): StoredPropertyBase<T> {
|
||||
val result = ObjectStoredProperty(defaultValue)
|
||||
addProperty(result)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* `null` is always normalized to null.
|
||||
*/
|
||||
protected inline fun <reified T : Enum<*>> enum(defaultValue: T? = null): StoredPropertyBase<T?> {
|
||||
return doEnum(defaultValue, T::class.java)
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun <T : Enum<*>> doEnum(defaultValue: T? = null, clazz: Class<T>): StoredPropertyBase<T?> {
|
||||
val result = EnumStoredProperty(defaultValue, clazz)
|
||||
addProperty(result)
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Not-null list. Initialized as SmartList.
|
||||
*/
|
||||
fun <T : Any> list(): StoredPropertyBase<MutableList<T>> {
|
||||
protected fun <T : Any> list(): StoredPropertyBase<MutableList<T>> {
|
||||
val result = ListStoredProperty<T>()
|
||||
addProperty(result)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return result as StoredPropertyBase<MutableList<T>>
|
||||
}
|
||||
|
||||
fun <K : Any, V: Any> property(value: MutableMap<K, V>): StoredPropertyBase<MutableMap<K, V>> {
|
||||
protected fun <K : Any, V: Any> property(value: MutableMap<K, V>): StoredPropertyBase<MutableMap<K, V>> {
|
||||
return map(value)
|
||||
}
|
||||
|
||||
fun <K : Any, V: Any> map(value: MutableMap<K, V> = THashMap()): StoredPropertyBase<MutableMap<K, V>> {
|
||||
protected fun <K : Any, V: Any> map(value: MutableMap<K, V> = THashMap()): StoredPropertyBase<MutableMap<K, V>> {
|
||||
val result = MapStoredProperty(value)
|
||||
addProperty(result)
|
||||
return result
|
||||
@@ -111,36 +125,36 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
|
||||
/**
|
||||
* Empty string is always normalized to null.
|
||||
*/
|
||||
fun property(defaultValue: String?): StoredPropertyBase<String?> = string(defaultValue)
|
||||
protected fun property(defaultValue: String?): StoredPropertyBase<String?> = string(defaultValue)
|
||||
|
||||
/**
|
||||
* Empty string is always normalized to null.
|
||||
*/
|
||||
fun string(defaultValue: String? = null): StoredPropertyBase<String?> {
|
||||
protected fun string(defaultValue: String? = null): StoredPropertyBase<String?> {
|
||||
val result = NormalizedStringStoredProperty(defaultValue)
|
||||
addProperty(result)
|
||||
return result
|
||||
}
|
||||
|
||||
fun property(defaultValue: Int = 0): StoredPropertyBase<Int> {
|
||||
protected fun property(defaultValue: Int = 0): StoredPropertyBase<Int> {
|
||||
val result = IntStoredProperty(defaultValue, null)
|
||||
addProperty(result)
|
||||
return result
|
||||
}
|
||||
|
||||
fun property(defaultValue: Long = 0): StoredPropertyBase<Long> {
|
||||
protected fun property(defaultValue: Long = 0): StoredPropertyBase<Long> {
|
||||
val result = LongStoredProperty(defaultValue, null)
|
||||
addProperty(result)
|
||||
return result
|
||||
}
|
||||
|
||||
fun property(defaultValue: Float = 0f, valueNormalizer: ((value: Float) -> Float)? = null): StoredPropertyBase<Float> {
|
||||
protected fun property(defaultValue: Float = 0f, valueNormalizer: ((value: Float) -> Float)? = null): StoredPropertyBase<Float> {
|
||||
val result = FloatStoredProperty(defaultValue, valueNormalizer)
|
||||
addProperty(result)
|
||||
return result
|
||||
}
|
||||
|
||||
fun property(defaultValue: Boolean = false): StoredPropertyBase<Boolean> {
|
||||
protected fun property(defaultValue: Boolean = false): StoredPropertyBase<Boolean> {
|
||||
val result = ObjectStoredProperty(defaultValue)
|
||||
addProperty(result)
|
||||
return result
|
||||
@@ -217,26 +231,8 @@ abstract class BaseState : SerializationFilter, ModificationTracker {
|
||||
}
|
||||
}
|
||||
|
||||
fun getProperties() = properties
|
||||
}
|
||||
|
||||
// move buildJsonSchema and other such functions from BaseState to exclude from completion
|
||||
// internal usage only
|
||||
@ApiStatus.Experimental
|
||||
fun buildJsonSchema(state: BaseState, builder: StringBuilder) {
|
||||
val properties = state.getProperties()
|
||||
// todo object definition
|
||||
for (property in properties) {
|
||||
builder.jsonEscapedString(property.name!!).append(':').append('{')
|
||||
builder.jsonEscapedString("type").append(':').jsonEscapedString(property.jsonType.jsonName)
|
||||
builder.append('}')
|
||||
if (property !== properties.last()) {
|
||||
builder.append(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun StringBuilder.jsonEscapedString(value: String): StringBuilder {
|
||||
append('"').append(value).append('"')
|
||||
return this
|
||||
// internal usage only
|
||||
@Suppress("FunctionName")
|
||||
@ApiStatus.Experimental
|
||||
fun __getProperties() = properties
|
||||
}
|
||||
@@ -255,20 +255,8 @@ public final class XmlSerializerImpl {
|
||||
accessor.setShort(host, Short.parseShort(value));
|
||||
}
|
||||
else if (valueClass.isEnum()) {
|
||||
Object deserializedValue = null;
|
||||
for (Object enumConstant : valueClass.getEnumConstants()) {
|
||||
if (enumConstant.toString().equals(value)) {
|
||||
deserializedValue = enumConstant;
|
||||
}
|
||||
}
|
||||
if (deserializedValue == null) {
|
||||
for (Object enumConstant : valueClass.getEnumConstants()) {
|
||||
if (enumConstant.toString().equalsIgnoreCase(value)) {
|
||||
deserializedValue = enumConstant;
|
||||
}
|
||||
}
|
||||
}
|
||||
accessor.set(host, deserializedValue);
|
||||
//noinspection unchecked
|
||||
accessor.set(host, XmlSerializerUtil.stringToEnum(value, (Class<? extends Enum<?>>)valueClass, false));
|
||||
}
|
||||
else if (Date.class.isAssignableFrom(valueClass)) {
|
||||
try {
|
||||
|
||||
@@ -1,22 +1,9 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.util.xmlb;
|
||||
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -48,4 +35,22 @@ public class XmlSerializerUtil {
|
||||
public static List<MutableAccessor> getAccessors(@NotNull Class<?> aClass) {
|
||||
return BeanBinding.getAccessors(aClass);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Object stringToEnum(@NotNull String value, @NotNull Class<? extends Enum<?>> valueClass, boolean isAlwaysIgnoreCase) {
|
||||
Enum<?>[] enumConstants = valueClass.getEnumConstants();
|
||||
if (!isAlwaysIgnoreCase) {
|
||||
for (Object enumConstant : enumConstants) {
|
||||
if (enumConstant.toString().equals(value)) {
|
||||
return enumConstant;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Object enumConstant : enumConstants) {
|
||||
if (enumConstant.toString().equalsIgnoreCase(value)) {
|
||||
return enumConstant;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,16 +76,24 @@ internal class JsonObjectBuilder(private val builder: StringBuilder) {
|
||||
}
|
||||
|
||||
fun rawMap(key: CharSequence, build: (StringBuilder) -> Unit) {
|
||||
mapOrArray('{', '}', key, build)
|
||||
}
|
||||
|
||||
fun rawArray(key: CharSequence, build: (StringBuilder) -> Unit) {
|
||||
mapOrArray('[', ']', key, build)
|
||||
}
|
||||
|
||||
private fun mapOrArray(openChar: Char, closeChar: Char, key: CharSequence, build: (StringBuilder) -> Unit) {
|
||||
builder
|
||||
.appendCommaIfNeed()
|
||||
.jsonEscapedString(key)
|
||||
.append(':')
|
||||
.append('{')
|
||||
.append(openChar)
|
||||
.append('\n')
|
||||
build(builder)
|
||||
builder
|
||||
.append('\n')
|
||||
.append('}')
|
||||
.append(closeChar)
|
||||
}
|
||||
|
||||
fun rawBuilder(key: CharSequence, child: JsonObjectBuilder) {
|
||||
|
||||
+29
-2
@@ -1,8 +1,9 @@
|
||||
package com.intellij.configurationScript
|
||||
|
||||
import com.intellij.configurationStore.properties.EnumStoredProperty
|
||||
import com.intellij.execution.configurations.ConfigurationFactory
|
||||
import com.intellij.execution.configurations.ConfigurationType
|
||||
import com.intellij.openapi.components.buildJsonSchema
|
||||
import com.intellij.openapi.components.BaseState
|
||||
import com.intellij.openapi.diagnostic.debug
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.util.ReflectionUtil
|
||||
@@ -175,12 +176,38 @@ internal class RunConfigurationJsonSchemaGenerator {
|
||||
if (description != null) {
|
||||
"description" toUnescaped description
|
||||
}
|
||||
rawMap("properties") { buildJsonSchema(state, it) }
|
||||
map("properties") { buildJsonSchema(state, this) }
|
||||
}
|
||||
"additionalProperties" to false
|
||||
}
|
||||
}
|
||||
|
||||
// move buildJsonSchema and other such functions from BaseState to exclude from completion
|
||||
private fun buildJsonSchema(state: BaseState, builder: JsonObjectBuilder) {
|
||||
val properties = state.__getProperties()
|
||||
// todo object definition
|
||||
for (property in properties) {
|
||||
builder.map(property.name!!) {
|
||||
"type" to property.jsonType.jsonName
|
||||
if (property is EnumStoredProperty<*>) {
|
||||
describeEnum(property)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun JsonObjectBuilder.describeEnum(property: EnumStoredProperty<*>) {
|
||||
rawArray("enum") { stringBuilder ->
|
||||
val enumConstants = property.clazz.enumConstants
|
||||
for (enum in enumConstants) {
|
||||
stringBuilder.append('"').append(enum.toString().toLowerCase()).append('"')
|
||||
if (enum !== enumConstants.last()) {
|
||||
stringBuilder.append(',')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns null if id is not valid
|
||||
internal fun rcTypeIdToPropertyName(configurationType: ConfigurationType): CharSequence? {
|
||||
val result = idToPropertyName(configurationType.tag, configurationType, null) ?: return null
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ internal class RunConfigurationListReader(private val processor: (factory: Confi
|
||||
|
||||
private fun readRc(optionsClass: Class<out BaseState>, node: MappingNode, factory: ConfigurationFactory) {
|
||||
val state = ReflectionUtil.newInstance(optionsClass)
|
||||
val properties = state.getProperties()
|
||||
val properties = state.__getProperties()
|
||||
for (tuple in node.value) {
|
||||
val valueNode = tuple.valueNode
|
||||
val key = (tuple.keyNode as ScalarNode).value
|
||||
|
||||
@@ -119,7 +119,7 @@ class ConfigurationFileTest {
|
||||
}
|
||||
}
|
||||
|
||||
private fun parse(@Language("YAML") data: String, isTemplatesOnly: Boolean = false): List<Any> {
|
||||
internal fun parse(@Language("YAML") data: String, isTemplatesOnly: Boolean = false): List<Any> {
|
||||
val list = SmartList<Any>()
|
||||
parseConfigurationFile(data.trimIndent().reader(), isTemplatesOnly) { _, state ->
|
||||
list.add(state)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.intellij.configurationScript
|
||||
|
||||
import com.intellij.execution.ShortenCommandLine
|
||||
import com.intellij.execution.application.JvmMainMethodRunConfigurationOptions
|
||||
import com.intellij.testFramework.ProjectRule
|
||||
import com.intellij.testFramework.assertions.Assertions.assertThat
|
||||
import org.junit.ClassRule
|
||||
import org.junit.Test
|
||||
|
||||
class PropertyValueReaderTest {
|
||||
companion object {
|
||||
@JvmField
|
||||
@ClassRule
|
||||
val projectRule = ProjectRule()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `enum`() {
|
||||
val result = parse("""
|
||||
runConfigurations:
|
||||
jvmMainMethod:
|
||||
shortenClasspath: MANIFEST
|
||||
""")
|
||||
val options = JvmMainMethodRunConfigurationOptions()
|
||||
options.shortenClasspath = ShortenCommandLine.MANIFEST
|
||||
assertThat(result).containsExactly(options)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user