unsafe polymorphic types

GitOrigin-RevId: 4ff1cb0f480e018760fec4d934b6252a34b59a01
This commit is contained in:
Vladimir Krivosheev
2019-05-13 22:08:52 +03:00
committed by intellij-monorepo-bot
parent 1f10a8e56f
commit b6e3ff604a
26 changed files with 520 additions and 394 deletions
@@ -124,7 +124,7 @@ public class DataNode<T> implements UserDataHolderEx {
try {
MultiLoaderWrapper classLoader = new MultiLoaderWrapper(getClass().getClassLoader(), classLoaders);
//noinspection unchecked
data = ObjectSerializer.getInstance().read((Class<T>)classLoader.findClass(dataClassName), rawData, SerializationKt.getExternalSystemBeanConstructed());
data = ObjectSerializer.getInstance().read((Class<T>)classLoader.findClass(dataClassName), rawData, SerializationKt.createDataNodeReadConfiguration(classLoader));
assert data != null;
clearRawData();
}
@@ -232,7 +232,7 @@ public class DataNode<T> implements UserDataHolderEx {
else {
LOG.assertTrue(!(data instanceof Proxy));
dataClassName = data.getClass().getName();
rawData = ObjectSerializer.getInstance().writeAsBytes(data);
rawData = ObjectSerializer.getInstance().writeAsBytes(data, SerializationKt.getDataNodeWriteConfiguration());
}
}
@@ -92,24 +92,30 @@ public final class ContentRootData extends AbstractExternalEntityData {
public static class SourceRoot implements Serializable {
@NotNull
private final String myPath;
private final String path;
@Nullable
private final String myPackagePrefix;
private final String packagePrefix;
public SourceRoot(@NotNull String path, @Nullable String prefix) {
myPath = path;
myPackagePrefix = prefix;
this.path = path;
packagePrefix = prefix;
}
@SuppressWarnings("unused")
private SourceRoot() {
path = "";
packagePrefix = "";
}
@NotNull
public String getPath() {
return myPath;
return path;
}
@Nullable
public String getPackagePrefix() {
return myPackagePrefix;
return packagePrefix;
}
@Override
@@ -117,24 +123,24 @@ public final class ContentRootData extends AbstractExternalEntityData {
if (this == o) return true;
if (!(o instanceof SourceRoot)) return false;
SourceRoot root = (SourceRoot)o;
if (myPackagePrefix != null ? !myPackagePrefix.equals(root.myPackagePrefix) : root.myPackagePrefix != null) return false;
if (!myPath.equals(root.myPath)) return false;
if (packagePrefix != null ? !packagePrefix.equals(root.packagePrefix) : root.packagePrefix != null) return false;
if (!path.equals(root.path)) return false;
return true;
}
@Override
public int hashCode() {
int result = myPath.hashCode();
result = 31 * result + (myPackagePrefix != null ? myPackagePrefix.hashCode() : 0);
int result = path.hashCode();
result = 31 * result + (packagePrefix != null ? packagePrefix.hashCode() : 0);
return result;
}
@Override
public String toString() {
StringBuilder buffer = new StringBuilder("source_root(");
buffer.append(myPath);
if (myPackagePrefix != null) {
buffer.append(", ").append(myPackagePrefix);
buffer.append(path);
if (packagePrefix != null) {
buffer.append(", ").append(packagePrefix);
}
buffer.append(")");
return buffer.toString();
@@ -146,7 +152,7 @@ public final class ContentRootData extends AbstractExternalEntityData {
@Override
public int compare(@NotNull SourceRoot o1, @NotNull SourceRoot o2) {
return StringUtil.naturalCompare(o1.myPath, o2.myPath);
return StringUtil.naturalCompare(o1.path, o2.path);
}
}
}
@@ -2,6 +2,8 @@
package com.intellij.openapi.externalSystem.model
import com.intellij.serialization.BeanConstructed
import com.intellij.serialization.ReadConfiguration
import com.intellij.serialization.WriteConfiguration
val externalSystemBeanConstructed: BeanConstructed = {
if (it is ProjectSystemId) {
@@ -10,4 +12,10 @@ val externalSystemBeanConstructed: BeanConstructed = {
else {
it
}
}
}
fun createDataNodeReadConfiguration(classLoader: ClassLoader): ReadConfiguration {
return ReadConfiguration(allowAnySubTypes = true, classLoader = classLoader, beanConstructed = externalSystemBeanConstructed)
}
val dataNodeWriteConfiguration = WriteConfiguration(allowAnySubTypes = true)
@@ -54,7 +54,7 @@ import static com.intellij.openapi.externalSystem.model.ProjectKeys.PROJECT;
public class ExternalProjectsDataStorage implements SettingsSavingComponentJavaAdapter, PersistentStateComponent<ExternalProjectsDataStorage.State> {
private static final Logger LOG = Logger.getInstance(ExternalProjectsDataStorage.class);
private static final int STORAGE_VERSION = 3;
private static final int STORAGE_VERSION = 4;
@NotNull
private final Project myProject;
@@ -365,7 +365,7 @@ public class ExternalProjectsDataStorage implements SettingsSavingComponentJavaA
if (isInvalidated(cacheFile.getFile(), fileAttributes)) {
throw new IOException("External projects data storage was invalidated");
}
return ContainerUtil.notNullize(cacheFile.readList(InternalExternalProjectInfo.class));
return ContainerUtil.notNullize(cacheFile.readList(InternalExternalProjectInfo.class, SerializationKt.getExternalSystemBeanConstructed()));
}
private static boolean isInvalidated(@NotNull Path configurationFile, @NotNull BasicFileAttributes fileAttributes) throws IOException {
@@ -65,7 +65,7 @@ class DataNodeTest {
val out = BufferExposingByteArrayOutputStream()
ObjectSerializer.instance.writeList(dataNodes, DataNode::class.java, out)
val bytes = out.toByteArray()
val deserializedList = ObjectSerializer.instance.readList(DataNode::class.java, bytes, beanConstructed = externalSystemBeanConstructed)
val deserializedList = ObjectSerializer.instance.readList(DataNode::class.java, bytes, createDataNodeReadConfiguration(javaClass.classLoader))
assertThat(deserializedList).hasSize(2)
assertThat(deserializedList[0].data === deserializedList[1].data)
@@ -98,6 +98,10 @@ internal class BeanBinding(beanClass: Class<*>) : BaseBeanBinding(beanClass), Ro
reader.next()
val subReadContext = context.createSubContext(reader)
readStruct(reader) { fieldName, type ->
if (type == IonType.NULL) {
return@readStruct
}
if (type == IonType.INT && fieldName == ID_FIELD_NAME) {
id = reader.intValue()
return@readStruct
@@ -135,7 +139,7 @@ internal class BeanBinding(beanClass: Class<*>) : BaseBeanBinding(beanClass), Ro
readIntoObject(instance, context.createSubContext(reader), checkId = false /* already registered */) { !names.contains(it) }
}
}
return context.beanConstructed?.let { it(instance) } ?: instance
return context.configuration.beanConstructed?.let { it(instance) } ?: instance
}
override fun deserialize(context: ReadContext): Any {
@@ -166,7 +170,7 @@ internal class BeanBinding(beanClass: Class<*>) : BaseBeanBinding(beanClass), Ro
readIntoObject(instance, context)
return context.beanConstructed?.let { it(instance) } ?: instance
return context.configuration.beanConstructed?.let { it(instance) } ?: instance
}
private fun readIntoObject(instance: Any, context: ReadContext, checkId: Boolean = true, filter: ((fieldName: String) -> Boolean)? = null) {
@@ -10,12 +10,8 @@ import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.util.function.Consumer
internal fun createBindingByType(type: Type, context: BindingInitializationContext): RootBinding {
return context.bindingProducer.getRootBinding(ClassUtil.typeToClass(type), type)
}
internal abstract class BaseCollectionBinding(itemType: Type, context: BindingInitializationContext) : RootBinding, NestedBinding {
private val itemBinding = createBindingByType(itemType, context)
private val itemBinding = createElementBindingByType(itemType, context)
final override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
write(hostObject, property, context) {
@@ -7,25 +7,23 @@ import com.intellij.util.SystemProperties
import com.intellij.util.containers.ContainerUtil
import gnu.trove.THashMap
import java.io.File
import java.lang.reflect.Modifier
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import java.nio.file.FileSystems
import java.nio.file.Path
import java.util.*
private typealias NestedBindingFactory = (accessor: MutableAccessor) -> NestedBinding
private typealias RootBindingFactory = () -> RootBinding
internal typealias NestedBindingFactory = (accessor: MutableAccessor) -> NestedBinding
internal typealias RootBindingFactory = () -> RootBinding
internal class IonBindingProducer(override val propertyCollector: PropertyCollector) : BindingProducer<RootBinding>(), BindingInitializationContext {
companion object {
private val classToNestedBindingFactory = THashMap<Class<*>, NestedBindingFactory>(32, ContainerUtil.identityStrategy())
private val classToRootBindingFactory = THashMap<Class<*>, RootBindingFactory>(32, ContainerUtil.identityStrategy())
private fun resolved(binding: NestedBinding): NestedBindingFactory = { binding }
init {
// for root resolved factory doesn't make sense because root bindings will be cached
classToRootBindingFactory.put(java.lang.String::class.java) { StringBinding() }
classToRootBindingFactory.put(File::class.java) { FileBinding() }
classToRootBindingFactory.put(Path::class.java) { PathBinding() }
classToRootBindingFactory.put(Date::class.java) { DateBinding() }
@@ -36,31 +34,10 @@ internal class IonBindingProducer(override val propertyCollector: PropertyCollec
classToRootBindingFactory.put(java.lang.Integer::class.java, numberFactory)
classToRootBindingFactory.put(java.lang.Long::class.java, numberFactory)
// java.lang.Float cannot be cast to java.lang.Double
classToRootBindingFactory.put(java.lang.Float::class.java) { FloatAsObjectBinding() }
classToRootBindingFactory.put(java.lang.Double::class.java) { DoubleAsObjectBinding() }
classToRootBindingFactory.put(java.lang.Boolean::class.java) { BooleanAsObjectBinding() }
val map = classToNestedBindingFactory
map.put(java.lang.Short.TYPE, resolved(ShortBinding()))
map.put(Integer.TYPE, resolved(IntBinding()))
map.put(java.lang.Long.TYPE, resolved(LongBinding()))
map.put(java.lang.Float.TYPE, resolved(FloatBinding()))
map.put(java.lang.Double.TYPE, resolved(DoubleBinding()))
map.put(java.lang.Boolean.TYPE, resolved(BooleanBinding()))
val char: NestedBindingFactory = { throw UnsupportedOperationException("char is not supported") }
map.put(Character.TYPE, char)
map.put(Character::class.java, char)
val byte: NestedBindingFactory = { throw UnsupportedOperationException("byte is not supported") }
map.put(java.lang.Byte.TYPE, byte)
map.put(java.lang.Byte::class.java, byte)
registerPrimitiveBindings(classToRootBindingFactory, classToNestedBindingFactory)
classToRootBindingFactory.forEachEntry { key, factory ->
map.put(key) { PropertyBinding(factory()) }
classToNestedBindingFactory.put(key) { PropertyBinding(factory()) }
true
}
}
@@ -82,30 +59,7 @@ internal class IonBindingProducer(override val propertyCollector: PropertyCollec
}
override fun createRootBinding(aClass: Class<*>, type: Type, cacheKey: Type, map: MutableMap<Type, RootBinding>): RootBinding {
val binding = if (Collection::class.java.isAssignableFrom(aClass)) {
createCollectionBinding(type)
}
else {
val custom = classToRootBindingFactory.get(aClass)?.invoke()
@Suppress("IfThenToElvis")
if (custom == null) {
when {
aClass.isArray -> ArrayBinding(aClass.componentType, this)
aClass.isEnum -> {
@Suppress("UNCHECKED_CAST")
EnumBinding(aClass as Class<out Enum<*>>)
}
else -> {
assert(cacheKey === aClass)
BeanBinding(aClass)
}
}
}
else {
custom
}
}
val binding = doCreateRootBinding(aClass, type, cacheKey)
map.put(cacheKey, binding)
try {
binding.init(type, this)
@@ -117,6 +71,35 @@ internal class IonBindingProducer(override val propertyCollector: PropertyCollec
return binding
}
private fun doCreateRootBinding(aClass: Class<*>, type: Type, cacheKey: Type): RootBinding {
val customFactory = classToRootBindingFactory.get(aClass)
if (customFactory != null) {
return customFactory.invoke()
}
return when {
Collection::class.java.isAssignableFrom(aClass) -> createCollectionBinding(type)
Map::class.java.isAssignableFrom(aClass) -> {
val typeArguments = (type as ParameterizedType).actualTypeArguments
MapBinding(typeArguments[0], typeArguments[1], this)
}
aClass.isArray -> ArrayBinding(aClass.componentType, this)
aClass.isEnum -> {
@Suppress("UNCHECKED_CAST")
EnumBinding(aClass as Class<out Enum<*>>)
}
else -> {
assert(cacheKey === aClass)
if (aClass.isInterface || Modifier.isAbstract(aClass.modifiers)) {
PolymorphicBinding(aClass)
}
else {
BeanBinding(aClass)
}
}
}
}
// note about field name - Ion binary writer interns string automatically, no need to intern (text writer doesn't support symbol tables)
override fun getNestedBinding(accessor: MutableAccessor): NestedBinding {
val type = accessor.genericType
@@ -137,9 +120,14 @@ internal class IonBindingProducer(override val propertyCollector: PropertyCollec
}
aClass.isArray -> ArrayBinding(aClass.componentType, this)
java.lang.Number::class.java.isAssignableFrom(aClass) -> PropertyBinding(NumberAsObjectBinding())
aClass.isInterface -> {
aClass.isInterface || Modifier.isAbstract(aClass.modifiers) -> {
val annotation = accessor.getAnnotation(Property::class.java)
?: throw SerializationException("Allowed types are not specified", linkedMapOf("accessor" to accessor))
if (annotation == null) {
// todo respect configuration
return PropertyBinding(getRootBinding(aClass, type))
// throw SerializationException("Allowed types are not specified", linkedMapOf("accessor" to accessor))
}
// even if annotation in Java, Kotlin forces to use Klass, so, use java bridge
val allowedTypes = PropertyAnnotationUtil.getAllowedClass(annotation)
if (allowedTypes.isEmpty()) {
@@ -158,150 +146,6 @@ internal class IonBindingProducer(override val propertyCollector: PropertyCollec
}
}
private class FloatAsObjectBinding : RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeFloat((obj as Float).toDouble())
}
override fun deserialize(context: ReadContext) = context.reader.doubleValue().toFloat()
}
private class DoubleAsObjectBinding : RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeFloat(obj as Double)
}
override fun deserialize(context: ReadContext) = context.reader.doubleValue()
}
private class NumberAsObjectBinding : RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeInt((obj as Number).toLong())
}
override fun deserialize(context: ReadContext) = context.reader.intValue()
}
private class BooleanAsObjectBinding : RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeBool(obj as Boolean)
}
override fun deserialize(context: ReadContext) = context.reader.booleanValue()
}
private class BooleanBinding : NestedBinding, RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeBool(obj as Boolean)
}
override fun deserialize(context: ReadContext) = context.reader.booleanValue()
override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
val writer = context.writer
writer.setFieldName(property.name)
writer.writeBool(property.readBoolean(hostObject))
}
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setBoolean(hostObject, context.reader.booleanValue())
}
}
private open class IntBinding : NestedBinding, RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeInt(obj as Long)
}
override fun deserialize(context: ReadContext) = context.reader.intValue()
override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
val writer = context.writer
writer.setFieldName(property.name)
writer.writeInt(property.readInt(hostObject).toLong())
}
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setInt(hostObject, context.reader.intValue())
}
}
private class ShortBinding : IntBinding() {
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setShort(hostObject, context.reader.intValue().toShort())
}
}
private class LongBinding : NestedBinding, RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeInt(obj as Long)
}
override fun deserialize(context: ReadContext) = context.reader.longValue()
override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
val writer = context.writer
writer.setFieldName(property.name)
writer.writeInt(property.readLong(hostObject))
}
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setLong(hostObject, context.reader.longValue())
}
}
private class FloatBinding : NestedBinding, RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeFloat(obj as Double)
}
override fun deserialize(context: ReadContext) = context.reader.doubleValue()
override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
val writer = context.writer
writer.setFieldName(property.name)
writer.writeFloat(property.readFloat(hostObject).toDouble())
}
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setFloat(hostObject, context.reader.doubleValue().toFloat())
}
}
private class DoubleBinding : NestedBinding, RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeFloat(obj as Double)
}
override fun deserialize(context: ReadContext) = context.reader.doubleValue()
override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
val writer = context.writer
writer.setFieldName(property.name)
writer.writeFloat(property.readDouble(hostObject))
}
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setDouble(hostObject, context.reader.doubleValue())
}
}
private class StringBinding : RootBinding {
override fun deserialize(context: ReadContext): Any {
return context.reader.stringValue()
}
override fun serialize(obj: Any, context: WriteContext) {
val s = obj as String
if (s.length < 64) {
context.writer.writeSymbol(s)
}
else {
context.writer.writeString(s)
}
}
}
private class FileBinding : RootBinding {
override fun deserialize(context: ReadContext): Any {
return File(context.reader.stringValue())
@@ -380,4 +224,8 @@ private class ByteArrayBinding : RootBinding {
override fun deserialize(context: ReadContext): Any {
return context.reader.newBytes()
}
}
internal fun createElementBindingByType(type: Type, context: BindingInitializationContext): RootBinding {
return context.bindingProducer.getRootBinding(ClassUtil.typeToClass(type), type)
}
@@ -19,7 +19,7 @@ import java.lang.reflect.Type
import java.nio.file.Path
import kotlin.experimental.or
private const val FORMAT_VERSION = 0
private const val FORMAT_VERSION = 1
internal class IonObjectSerializer {
val readerBuilder: IonReaderBuilder = IonReaderBuilder.standard().immutable()
@@ -48,7 +48,7 @@ internal class IonObjectSerializer {
}
@Throws(IOException::class)
fun <T : Any> readVersioned(objectClass: Class<T>, file: Path, expectedVersion: Int, beanConstructed: BeanConstructed? = null, originalType: Type? = null): T? {
fun <T : Any> readVersioned(objectClass: Class<T>, file: Path, expectedVersion: Int, configuration: ReadConfiguration, originalType: Type? = null): T? {
readerBuilder.build(file.inputStream().buffered()).use { reader ->
@Suppress("UNUSED_VARIABLE")
var isVersionChecked = 0
@@ -93,7 +93,7 @@ internal class IonObjectSerializer {
return null
}
return doRead(objectClass, originalType, reader, beanConstructed)
return doRead(objectClass, originalType, reader, configuration)
}
else -> LOG.warn("Unknown field: $fieldName (file=$file, expectedVersion=$expectedVersion, objectClass=$objectClass)")
}
@@ -116,33 +116,33 @@ internal class IonObjectSerializer {
bindingProducer.getRootBinding(aClass, originalType ?: aClass).serialize(obj, writeContext)
}
fun <T> read(objectClass: Class<T>, reader: ValueReader, beanConstructed: BeanConstructed? = null, originalType: Type? = null): T {
fun <T> read(objectClass: Class<T>, reader: ValueReader, configuration: ReadConfiguration, originalType: Type? = null): T {
reader.use {
reader.next()
return doRead(objectClass, originalType, reader, beanConstructed)
return doRead(objectClass, originalType, reader, configuration)
}
}
// reader cursor must be already pointed to struct
private fun <T> doRead(objectClass: Class<T>, originalType: Type?, reader: ValueReader, beanConstructed: BeanConstructed?): T {
private fun <T> doRead(objectClass: Class<T>, originalType: Type?, reader: ValueReader, configuration: ReadConfiguration): T {
when (reader.type) {
IonType.NULL -> throw SerializationException("root value is null")
null -> throw SerializationException("empty input")
else -> {
val binding = bindingProducer.getRootBinding(objectClass, originalType ?: objectClass)
@Suppress("UNCHECKED_CAST")
return bindingProducer.getRootBinding(objectClass, originalType ?: objectClass).deserialize(
createReadContext(reader, beanConstructed)) as T
return binding.deserialize(createReadContext(reader, configuration)) as T
}
}
}
fun <T> readList(itemClass: Class<T>, reader: ValueReader, beanConstructed: BeanConstructed?): List<T> {
fun <T> readList(itemClass: Class<T>, reader: ValueReader, configuration: ReadConfiguration): List<T> {
@Suppress("UNCHECKED_CAST")
return read(List::class.java, reader, beanConstructed, ParameterizedTypeImpl(List::class.java, itemClass)) as List<T>
return read(List::class.java, reader, configuration, ParameterizedTypeImpl(List::class.java, itemClass)) as List<T>
}
private fun createReadContext(reader: ValueReader, beanConstructed: BeanConstructed? = null): ReadContext {
return ReadContextImpl(reader, ObjectIdReader(), bindingProducer, beanConstructed)
private fun createReadContext(reader: ValueReader, configuration: ReadConfiguration): ReadContext {
return ReadContextImpl(reader, ObjectIdReader(), bindingProducer, configuration)
}
}
@@ -153,7 +153,7 @@ private val DEFAULT_FILTER = object : SerializationFilter {
private data class ReadContextImpl(override val reader: ValueReader,
override val objectIdReader: ObjectIdReader,
override val bindingProducer: BindingProducer<RootBinding>,
override val beanConstructed: BeanConstructed?) : ReadContext {
override val configuration: ReadConfiguration) : ReadContext {
private var byteArrayOutputStream: BufferExposingByteArrayOutputStream? = null
override fun allocateByteArrayOutputStream(): BufferExposingByteArrayOutputStream {
@@ -168,7 +168,7 @@ private data class ReadContextImpl(override val reader: ValueReader,
return result
}
override fun createSubContext(reader: ValueReader) = ReadContextImpl(reader, objectIdReader, bindingProducer, beanConstructed)
override fun createSubContext(reader: ValueReader) = ReadContextImpl(reader, objectIdReader, bindingProducer, configuration)
}
private val binaryWriterBuilder by lazy { IonBinaryWriterBuilder.standard().immutable() }
+2 -2
View File
@@ -8,8 +8,8 @@ import java.lang.reflect.Type
import java.util.*
internal class MapBinding(keyType: Type, valueType: Type, context: BindingInitializationContext) : RootBinding, NestedBinding {
private val keyBinding = createBindingByType(keyType, context)
private val valueBinding = createBindingByType(valueType, context)
private val keyBinding = createElementBindingByType(keyType, context)
private val valueBinding = createElementBindingByType(valueType, context)
private val isKeyComparable = Comparable::class.java.isAssignableFrom(ClassUtil.typeToClass(keyType))
@@ -25,6 +25,8 @@ annotation class PropertyMapping(val value: Array<String>)
internal val defaultWriteConfiguration = WriteConfiguration()
val defaultReadConfiguration = ReadConfiguration()
/**
* @see [VersionedFile]
*/
@@ -56,67 +58,42 @@ class ObjectSerializer {
serializer.write(obj, outputStream, configuration, ParameterizedTypeImpl(Collection::class.java, itemClass))
}
fun <T> read(objectClass: Class<T>, bytes: ByteArray, beanConstructed: BeanConstructed? = null): T {
return serializer.read(objectClass, readerBuilder.build(bytes), beanConstructed)
fun <T> read(objectClass: Class<T>, bytes: ByteArray, configuration: ReadConfiguration = defaultReadConfiguration): T {
return serializer.read(objectClass, readerBuilder.build(bytes), configuration)
}
fun <T> read(objectClass: Class<T>, inputStream: InputStream): T {
return serializer.read(objectClass, readerBuilder.build(inputStream))
fun <T> read(objectClass: Class<T>, inputStream: InputStream, configuration: ReadConfiguration = defaultReadConfiguration): T {
return serializer.read(objectClass, readerBuilder.build(inputStream), configuration)
}
fun <T> read(objectClass: Class<T>, reader: Reader): T {
return serializer.read(objectClass, readerBuilder.build(reader))
fun <T> read(objectClass: Class<T>, reader: Reader, configuration: ReadConfiguration = defaultReadConfiguration): T {
return serializer.read(objectClass, readerBuilder.build(reader), configuration)
}
fun <T> read(objectClass: Class<T>, text: String): T {
return serializer.read(objectClass, readerBuilder.build(text))
fun <T> read(objectClass: Class<T>, text: String, configuration: ReadConfiguration = defaultReadConfiguration): T {
return serializer.read(objectClass, readerBuilder.build(text), configuration)
}
fun <T> readList(itemClass: Class<T>, reader: Reader, beanConstructed: BeanConstructed? = null): List<T> {
return serializer.readList(itemClass, readerBuilder.build(reader), beanConstructed)
fun <T> readList(itemClass: Class<T>, reader: Reader, configuration: ReadConfiguration = defaultReadConfiguration): List<T> {
return serializer.readList(itemClass, readerBuilder.build(reader), configuration)
}
@JvmOverloads
fun <T> readList(itemClass: Class<T>, bytes: ByteArray, beanConstructed: BeanConstructed? = null): List<T> {
return serializer.readList(itemClass, readerBuilder.build(bytes), beanConstructed)
fun <T> readList(itemClass: Class<T>, bytes: ByteArray, configuration: ReadConfiguration = defaultReadConfiguration): List<T> {
return serializer.readList(itemClass, readerBuilder.build(bytes), configuration)
}
@JvmOverloads
fun <T> readList(itemClass: Class<T>, input: InputStream, beanConstructed: BeanConstructed? = null): List<T> {
return serializer.readList(itemClass, readerBuilder.build(input), beanConstructed)
fun <T> readList(itemClass: Class<T>, input: InputStream, configuration: ReadConfiguration = defaultReadConfiguration): List<T> {
return serializer.readList(itemClass, readerBuilder.build(input), configuration)
}
}
data class WriteConfiguration(val binary: Boolean = true,
val filter: SerializationFilter? = null,
val orderMapEntriesByKeys: Boolean = false)
// not finished concept because not required for object graph serialization
interface SerializationFilter {
fun isSkipped(value: Any?): Boolean
}
data class WriteContext(val writer: ValueWriter,
val filter: SerializationFilter,
val objectIdWriter: ObjectIdWriter?,
val configuration: WriteConfiguration,
val bindingProducer: BindingProducer<RootBinding>)
interface ReadContext {
val reader: ValueReader
val objectIdReader: ObjectIdReader
val bindingProducer: BindingProducer<RootBinding>
val beanConstructed: BeanConstructed?
/**
* Each call will reset previously allocated result. For sub readers it is not a problem, because you must use [createSubContext] for this case.
*/
fun allocateByteArrayOutputStream(): BufferExposingByteArrayOutputStream
fun createSubContext(reader: ValueReader): ReadContext
}
class ObjectIdWriter {
private val map: ObjectIntHashMap<Any> = ObjectIntHashMap(TObjectHashingStrategy.IDENTITY)
private var counter = 0
@@ -0,0 +1,37 @@
// Copyright 2000-2019 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.serialization
internal class PolymorphicBinding(private val superClass: Class<*>) : RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
val valueClass = obj.javaClass
val writer = context.writer
if (!context.configuration.allowAnySubTypes) {
throw SerializationException("Polymorphic type without specified allowed sub types is forbidden")
}
writer.addTypeAnnotation(valueClass.name)
context.bindingProducer.getRootBinding(valueClass).serialize(obj, context)
}
override fun deserialize(context: ReadContext): Any {
if (!context.configuration.allowAnySubTypes) {
throw SerializationException("Polymorphic type without specified allowed sub types is forbidden")
}
val reader = context.reader
val beanClass: Class<*>
val typeAnnotationIterator = reader.iterateTypeAnnotations()
if (typeAnnotationIterator.hasNext()) {
val className = typeAnnotationIterator.next()
beanClass = (context.configuration.classLoader ?: javaClass.classLoader).loadClass(className)
if (!superClass.isAssignableFrom(beanClass)) {
throw SerializationException("Class \"$className\" must be assignable to \"${superClass.name}\"")
}
}
else {
throw SerializationException("Class name is not specified")
}
return context.bindingProducer.getRootBinding(beanClass).deserialize(context)
}
}
@@ -13,8 +13,11 @@ data class VersionedFile(val file: Path, val version: Int) {
}
@Throws(IOException::class)
fun <T> readList(itemClass: Class<T>): List<T>? {
@JvmOverloads
fun <T> readList(itemClass: Class<T>, beanConstructed: BeanConstructed? = null): List<T>? {
@Suppress("UNCHECKED_CAST")
return ObjectSerializer.instance.serializer.readVersioned(ArrayList::class.java, file, version, originalType = ParameterizedTypeImpl(ArrayList::class.java, itemClass)) as List<T>?
return ObjectSerializer.instance.serializer.readVersioned(ArrayList::class.java, file, version,
originalType = ParameterizedTypeImpl(ArrayList::class.java, itemClass),
configuration = ReadConfiguration(beanConstructed = beanConstructed)) as List<T>?
}
}
+34
View File
@@ -0,0 +1,34 @@
// Copyright 2000-2019 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.serialization
import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream
data class ReadConfiguration(val allowAnySubTypes: Boolean = false,
val classLoader: ClassLoader? = null,
val beanConstructed: BeanConstructed? = null)
data class WriteConfiguration(val binary: Boolean = true,
val filter: SerializationFilter? = null,
val orderMapEntriesByKeys: Boolean = false,
val allowAnySubTypes: Boolean = false)
data class WriteContext(val writer: ValueWriter,
val filter: SerializationFilter,
val objectIdWriter: ObjectIdWriter?,
val configuration: WriteConfiguration,
val bindingProducer: BindingProducer<RootBinding>)
interface ReadContext {
val reader: ValueReader
val objectIdReader: ObjectIdReader
val bindingProducer: BindingProducer<RootBinding>
val configuration: ReadConfiguration
/**
* Each call will reset previously allocated result. For sub readers it is not a problem, because you must use [createSubContext] for this case.
*/
fun allocateByteArrayOutputStream(): BufferExposingByteArrayOutputStream
fun createSubContext(reader: ValueReader): ReadContext
}
@@ -0,0 +1,179 @@
// Copyright 2000-2019 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.serialization
private fun resolved(binding: NestedBinding): NestedBindingFactory = { binding }
internal fun registerPrimitiveBindings(classToRootBindingFactory: MutableMap<Class<*>, RootBindingFactory>, classToNestedBindingFactory: MutableMap<Class<*>, NestedBindingFactory>) {
classToRootBindingFactory.put(java.lang.String::class.java) { StringBinding() }
val numberAsObjectBinding = NumberAsObjectBinding()
classToRootBindingFactory.put(java.lang.Integer::class.java) { numberAsObjectBinding }
classToRootBindingFactory.put(java.lang.Long::class.java) { numberAsObjectBinding }
classToRootBindingFactory.put(java.lang.Short::class.java) { numberAsObjectBinding }
// java.lang.Float cannot be cast to java.lang.Double
classToRootBindingFactory.put(java.lang.Float::class.java) { FloatAsObjectBinding() }
classToRootBindingFactory.put(java.lang.Double::class.java) { DoubleAsObjectBinding() }
classToRootBindingFactory.put(java.lang.Boolean::class.java) { BooleanAsObjectBinding() }
classToNestedBindingFactory.put(java.lang.Short.TYPE, resolved(ShortBinding()))
classToNestedBindingFactory.put(Integer.TYPE, resolved(IntBinding()))
classToNestedBindingFactory.put(java.lang.Long.TYPE, resolved(LongBinding()))
classToNestedBindingFactory.put(java.lang.Float.TYPE, resolved(FloatBinding()))
classToNestedBindingFactory.put(java.lang.Double.TYPE, resolved(DoubleBinding()))
classToNestedBindingFactory.put(java.lang.Boolean.TYPE, resolved(BooleanBinding()))
val char: NestedBindingFactory = { throw UnsupportedOperationException("char is not supported") }
classToNestedBindingFactory.put(Character.TYPE, char)
classToNestedBindingFactory.put(Character::class.java, char)
val byte: NestedBindingFactory = { throw UnsupportedOperationException("byte is not supported") }
classToNestedBindingFactory.put(java.lang.Byte.TYPE, byte)
classToNestedBindingFactory.put(java.lang.Byte::class.java, byte)
}
private class FloatAsObjectBinding : RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeFloat((obj as Float).toDouble())
}
override fun deserialize(context: ReadContext) = context.reader.doubleValue().toFloat()
}
private class DoubleAsObjectBinding : RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeFloat(obj as Double)
}
override fun deserialize(context: ReadContext) = context.reader.doubleValue()
}
internal class NumberAsObjectBinding : RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeInt((obj as Number).toLong())
}
override fun deserialize(context: ReadContext) = context.reader.intValue()
}
private class BooleanAsObjectBinding : RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeBool(obj as Boolean)
}
override fun deserialize(context: ReadContext) = context.reader.booleanValue()
}
private class BooleanBinding : NestedBinding, RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeBool(obj as Boolean)
}
override fun deserialize(context: ReadContext) = context.reader.booleanValue()
override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
val writer = context.writer
writer.setFieldName(property.name)
writer.writeBool(property.readBoolean(hostObject))
}
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setBoolean(hostObject, context.reader.booleanValue())
}
}
private open class IntBinding : NestedBinding, RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeInt(obj as Long)
}
override fun deserialize(context: ReadContext) = context.reader.intValue()
override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
val writer = context.writer
writer.setFieldName(property.name)
writer.writeInt(property.readInt(hostObject).toLong())
}
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setInt(hostObject, context.reader.intValue())
}
}
private class ShortBinding : IntBinding() {
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setShort(hostObject, context.reader.intValue().toShort())
}
}
private class LongBinding : NestedBinding, RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeInt(obj as Long)
}
override fun deserialize(context: ReadContext) = context.reader.longValue()
override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
val writer = context.writer
writer.setFieldName(property.name)
writer.writeInt(property.readLong(hostObject))
}
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setLong(hostObject, context.reader.longValue())
}
}
private class FloatBinding : NestedBinding, RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeFloat(obj as Double)
}
override fun deserialize(context: ReadContext) = context.reader.doubleValue()
override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
val writer = context.writer
writer.setFieldName(property.name)
writer.writeFloat(property.readFloat(hostObject).toDouble())
}
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setFloat(hostObject, context.reader.doubleValue().toFloat())
}
}
private class DoubleBinding : NestedBinding, RootBinding {
override fun serialize(obj: Any, context: WriteContext) {
context.writer.writeFloat(obj as Double)
}
override fun deserialize(context: ReadContext) = context.reader.doubleValue()
override fun serialize(hostObject: Any, property: MutableAccessor, context: WriteContext) {
val writer = context.writer
writer.setFieldName(property.name)
writer.writeFloat(property.readDouble(hostObject))
}
override fun deserialize(hostObject: Any, property: MutableAccessor, context: ReadContext) {
property.setDouble(hostObject, context.reader.doubleValue())
}
}
private class StringBinding : RootBinding {
override fun deserialize(context: ReadContext): Any {
return context.reader.stringValue()
}
override fun serialize(obj: Any, context: WriteContext) {
val s = obj as String
if (s.length < 64) {
context.writer.writeSymbol(s)
}
else {
context.writer.writeString(s)
}
}
}
@@ -0,0 +1,7 @@
{
'@id':0,
shape:'com.intellij.serialization.Circle'::{
'@id':1,
name:null
}
}
@@ -0,0 +1,10 @@
{
'@id':0,
shape:[
first,
'com.intellij.serialization.Circle'::{
'@id':1,
name:null
}
]
}
@@ -78,7 +78,7 @@ class ListTest {
assertThat(file.file.readChars().trim()).isEqualTo("""
{
version:42,
formatVersion:0,
formatVersion:1,
data:[
foo,
bar
@@ -3,6 +3,7 @@ package com.intellij.serialization
import com.intellij.openapi.util.SystemInfoRt
import com.intellij.testFramework.assertions.Assertions.assertThat
import gnu.trove.THashMap
import org.junit.Assume.assumeTrue
import org.junit.Rule
import org.junit.Test
@@ -16,7 +17,9 @@ class ObjectSerializerTest {
@JvmField
val testName = TestName()
private fun test(bean: Any) = test(bean, testName)
private fun <T : Any> test(bean: T, writeConfiguration: WriteConfiguration? = null): T {
return test(bean, testName, writeConfiguration)
}
@Test
fun `same bean binding regardless of type parameters`() {
@@ -137,6 +140,30 @@ class ObjectSerializerTest {
bean.shape = Circle()
test(bean)
}
@Test
fun `interface type for map value - allowSubTypes`() {
class TestInterfaceBean {
@JvmField
val shape: MutableMap<String, Shape> = THashMap()
}
val bean = TestInterfaceBean()
bean.shape.put("first", Circle())
test(bean, WriteConfiguration(allowAnySubTypes = true, binary = false))
}
@Test
fun `interface type for field - allowSubTypes`() {
class TestInterfaceBean {
@JvmField
var shape: Shape? = null
}
val bean = TestInterfaceBean()
bean.shape = Circle()
test(bean, WriteConfiguration(allowAnySubTypes = true, binary = false))
}
}
private interface Shape
@@ -34,7 +34,7 @@ internal fun <T : Any> test(bean: T, testName: TestName, _writeConfiguration: Wr
val out = BufferExposingByteArrayOutputStream(8 * 1024)
// just to test binary
objectSerializer.write(bean, out, WriteConfiguration(binary = true))
objectSerializer.write(bean, out, WriteConfiguration(binary = true, allowAnySubTypes = _writeConfiguration?.allowAnySubTypes ?: false))
assertThat(out.size() > 0)
out.reset()
@@ -44,7 +44,7 @@ internal fun <T : Any> test(bean: T, testName: TestName, _writeConfiguration: Wr
val ionText = out.toString()
out.reset()
val deserializedBean = objectSerializer.read(bean.javaClass, ionText)
val deserializedBean = objectSerializer.read(bean.javaClass, ionText, configuration = ReadConfiguration(allowAnySubTypes = writeConfiguration.allowAnySubTypes))
objectSerializer.write(deserializedBean, out, writeConfiguration)
assertThat(out.toString()).isEqualTo(ionText)
@@ -1,18 +1,4 @@
/*
* 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-2019 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 org.jetbrains.plugins.gradle.model;
import org.jetbrains.annotations.NotNull;
@@ -27,130 +13,130 @@ public class DefaultExternalSourceDirectorySet implements ExternalSourceDirector
private static final long serialVersionUID = 1L;
@NotNull
private String myName;
private String name;
@NotNull
private Set<File> mySrcDirs;
private File myOutputDir;
private final List<File> myGradleOutputDirs;
private final FilePatternSet myPatterns;
private Set<File> srcDirs;
private File outputDir;
private final List<File> gradleOutputDirs;
private final FilePatternSet patterns;
@NotNull
private List<ExternalFilter> myFilters;
private List<ExternalFilter> filters;
private boolean myInheritedCompilerOutput;
private boolean inheritedCompilerOutput;
public DefaultExternalSourceDirectorySet() {
mySrcDirs = new HashSet<File>();
myFilters = new ArrayList<ExternalFilter>();
myGradleOutputDirs = new ArrayList<File>();
myPatterns = new FilePatternSetImpl(new LinkedHashSet<String>(), new LinkedHashSet<String>());
srcDirs = new HashSet<File>();
filters = new ArrayList<ExternalFilter>();
gradleOutputDirs = new ArrayList<File>();
patterns = new FilePatternSetImpl(new LinkedHashSet<String>(), new LinkedHashSet<String>());
}
public DefaultExternalSourceDirectorySet(ExternalSourceDirectorySet sourceDirectorySet) {
this();
myName = sourceDirectorySet.getName();
mySrcDirs = new HashSet<File>(sourceDirectorySet.getSrcDirs());
myOutputDir = sourceDirectorySet.getOutputDir();
myGradleOutputDirs.addAll(sourceDirectorySet.getGradleOutputDirs());
name = sourceDirectorySet.getName();
srcDirs = new HashSet<File>(sourceDirectorySet.getSrcDirs());
outputDir = sourceDirectorySet.getOutputDir();
gradleOutputDirs.addAll(sourceDirectorySet.getGradleOutputDirs());
myPatterns.getIncludes().addAll(sourceDirectorySet.getPatterns().getIncludes());
myPatterns.getExcludes().addAll(sourceDirectorySet.getPatterns().getExcludes());
patterns.getIncludes().addAll(sourceDirectorySet.getPatterns().getIncludes());
patterns.getExcludes().addAll(sourceDirectorySet.getPatterns().getExcludes());
for (ExternalFilter filter : sourceDirectorySet.getFilters()) {
myFilters.add(new DefaultExternalFilter(filter));
filters.add(new DefaultExternalFilter(filter));
}
myInheritedCompilerOutput = sourceDirectorySet.isCompilerOutputPathInherited();
inheritedCompilerOutput = sourceDirectorySet.isCompilerOutputPathInherited();
}
@NotNull
@Override
public String getName() {
return myName;
return name;
}
public void setName(@NotNull String name) {
myName = name;
this.name = name;
}
@NotNull
@Override
public Set<File> getSrcDirs() {
return mySrcDirs;
return srcDirs;
}
public void setSrcDirs(@NotNull Set<File> srcDirs) {
mySrcDirs = srcDirs;
this.srcDirs = srcDirs;
}
@NotNull
@Override
public File getOutputDir() {
return myOutputDir;
return outputDir;
}
public void setOutputDir(@NotNull File outputDir) {
myOutputDir = outputDir;
this.outputDir = outputDir;
}
@NotNull
@Override
public File getGradleOutputDir() {
assert myGradleOutputDirs.size() > 0;
return myGradleOutputDirs.get(0);
assert gradleOutputDirs.size() > 0;
return gradleOutputDirs.get(0);
}
@NotNull
@Override
public Collection<File> getGradleOutputDirs() {
return myGradleOutputDirs;
return gradleOutputDirs;
}
public void addGradleOutputDir(@NotNull File outputDir) {
myGradleOutputDirs.add(outputDir);
gradleOutputDirs.add(outputDir);
}
@Override
public boolean isCompilerOutputPathInherited() {
return myInheritedCompilerOutput;
return inheritedCompilerOutput;
}
@NotNull
@Override
public Set<String> getExcludes() {
return myPatterns.getExcludes();
return patterns.getExcludes();
}
public void setExcludes(Set<String> excludes) {
myPatterns.getExcludes().clear();
myPatterns.getExcludes().addAll(excludes);
patterns.getExcludes().clear();
patterns.getExcludes().addAll(excludes);
}
@NotNull
@Override
public Set<String> getIncludes() {
return myPatterns.getIncludes();
return patterns.getIncludes();
}
public void setIncludes(Set<String> includes) {
myPatterns.getIncludes().clear();
myPatterns.getIncludes().addAll(includes);
patterns.getIncludes().clear();
patterns.getIncludes().addAll(includes);
}
@NotNull
@Override
public FilePatternSet getPatterns() {
return myPatterns;
return patterns;
}
public void setInheritedCompilerOutput(boolean inheritedCompilerOutput) {
myInheritedCompilerOutput = inheritedCompilerOutput;
this.inheritedCompilerOutput = inheritedCompilerOutput;
}
@NotNull
@Override
public List<ExternalFilter> getFilters() {
return myFilters;
return filters;
}
public void setFilters(@NotNull List<ExternalFilter> filters) {
myFilters = filters;
this.filters = filters;
}
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2016 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-2019 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 org.jetbrains.plugins.gradle.model;
import org.jetbrains.annotations.NotNull;
@@ -23,20 +9,29 @@ import org.jetbrains.annotations.Nullable;
*/
public class DefaultGradleConfiguration implements GradleConfiguration {
private static final long serialVersionUID = 1L;
private final String myName;
private final String myDescription;
private final boolean myVisible;
private final boolean myScriptClasspathConfiguration;
private final String name;
private final String description;
private final boolean visible;
private final boolean scriptClasspathConfiguration;
public DefaultGradleConfiguration(String name, String description, boolean visible) {
this(name, description, visible, false);
}
@SuppressWarnings("unused")
private DefaultGradleConfiguration() {
name = "";
description = "";
visible = false;
scriptClasspathConfiguration = false;
}
public DefaultGradleConfiguration(@NotNull String name, @Nullable String description, boolean visible, boolean scriptClasspathConfiguration) {
myName = name;
myDescription = description;
myVisible = visible;
myScriptClasspathConfiguration = scriptClasspathConfiguration;
this.name = name;
this.description = description;
this.visible = visible;
this.scriptClasspathConfiguration = scriptClasspathConfiguration;
}
public DefaultGradleConfiguration(GradleConfiguration configuration) {
@@ -47,22 +42,22 @@ public class DefaultGradleConfiguration implements GradleConfiguration {
@NotNull
@Override
public String getName() {
return myName;
return name;
}
@Nullable
@Override
public String getDescription() {
return myDescription;
return description;
}
@Override
public boolean isVisible() {
return myVisible;
return visible;
}
@Override
public boolean isScriptClasspathConfiguration() {
return myScriptClasspathConfiguration;
return scriptClasspathConfiguration;
}
}
@@ -14,6 +14,11 @@ public class DefaultGradleConvention extends DefaultGradleProperty implements Gr
super(name, typeFqn, null);
}
@SuppressWarnings("unused")
private DefaultGradleConvention() {
super();
}
public DefaultGradleConvention(GradleConvention convention) {
this(convention.getName(), convention.getTypeFqn());
}
@@ -14,6 +14,11 @@ public class DefaultGradleExtension extends DefaultGradleProperty implements Gra
super(name, typeFqn, null);
}
@SuppressWarnings("unused")
private DefaultGradleExtension() {
super();
}
public DefaultGradleExtension(GradleExtension extension) {
this(extension.getName(), extension.getTypeFqn());
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2016 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-2019 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 org.jetbrains.plugins.gradle.model;
import org.jetbrains.annotations.NotNull;
@@ -24,18 +10,24 @@ import java.io.Serializable;
* @author Vladislav.Soroka
*/
public class DefaultGradleProperty implements GradleProperty {
private static final long serialVersionUID = 1L;
@NotNull
private final String myName;
private final String name;
@NotNull
private final String myRootTypeFqn;
private final String rootTypeFqn;
@Nullable
private final Serializable myValue;
private final Serializable value;
public DefaultGradleProperty(@NotNull String name, @Nullable String typeFqn, @Nullable Serializable value) {
myName = name;
myRootTypeFqn = typeFqn == null ? "Object" : typeFqn;
myValue = value;
this.name = name;
rootTypeFqn = typeFqn == null ? "Object" : typeFqn;
this.value = value;
}
@SuppressWarnings("unused")
protected DefaultGradleProperty() {
this.name = "";
rootTypeFqn = "Object";
this.value = null;
}
public DefaultGradleProperty(GradleProperty property) {
@@ -45,18 +37,18 @@ public class DefaultGradleProperty implements GradleProperty {
@NotNull
@Override
public String getName() {
return myName;
return name;
}
@NotNull
@Override
public String getTypeFqn() {
return myRootTypeFqn;
return rootTypeFqn;
}
@Nullable
@Override
public Serializable getValue() {
return myValue;
return value;
}
}
@@ -1,6 +1,7 @@
// 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.
// Copyright 2000-2019 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 org.jetbrains.plugins.gradle.model;
import java.util.HashSet;
import java.util.Set;
/**
@@ -15,6 +16,12 @@ public class FilePatternSetImpl implements FilePatternSet {
this.excludes = excludes;
}
@SuppressWarnings("unused")
private FilePatternSetImpl() {
includes = new HashSet<String>();
excludes = new HashSet<String>();
}
@Override
public Set<String> getIncludes() {
return includes;