Skip to content

Commit

Permalink
Added FormatLanguage annotation to JSON (#2234)
Browse files Browse the repository at this point in the history
Resolves #2166

Co-authored-by: Leonid Startsev <sandwwraith@gmail.com>
  • Loading branch information
shanshin and sandwwraith authored May 10, 2023
1 parent 40eb277 commit 5a8795a
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 2 deletions.
14 changes: 12 additions & 2 deletions formats/json/commonMain/src/kotlinx/serialization/json/Json.kt
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,23 @@ public sealed class Json(
}
}

/**
* Decodes and deserializes the given JSON [string] to the value of type [T] using deserializer
* retrieved from the reified type parameter.
*
* @throws SerializationException in case of any decoding-specific error
* @throws IllegalArgumentException if the decoded input is not a valid instance of [T]
*/
public inline fun <reified T> decodeFromString(@FormatLanguage("json", "", "") string: String): T =
decodeFromString(serializersModule.serializer(), string)

/**
* Deserializes the given JSON [string] into a value of type [T] using the given [deserializer].
*
* @throws [SerializationException] if the given JSON string is not a valid JSON input for the type [T]
* @throws [IllegalArgumentException] if the decoded input cannot be represented as a valid instance of type [T]
*/
public final override fun <T> decodeFromString(deserializer: DeserializationStrategy<T>, string: String): T {
public final override fun <T> decodeFromString(deserializer: DeserializationStrategy<T>, @FormatLanguage("json", "", "") string: String): T {
val lexer = StringJsonLexer(string)
val input = StreamingJsonDecoder(this, WriteMode.OBJ, lexer, deserializer.descriptor, null)
val result = input.decodeSerializableValue(deserializer)
Expand Down Expand Up @@ -122,7 +132,7 @@ public sealed class Json(
*
* @throws [SerializationException] if the given string is not a valid JSON
*/
public fun parseToJsonElement(string: String): JsonElement {
public fun parseToJsonElement(@FormatLanguage("json", "", "") string: String): JsonElement {
return decodeFromString(JsonElementSerializer, string)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package kotlinx.serialization.json.internal;

import kotlinx.serialization.InternalSerializationApi

/**
* Multiplatform analogue of `org.intellij.lang.annotations.Language` annotation.
*
* An alias is used instead of class, because the actual class in the JVM will conflict with the class from the stdlib -
* we want to avoid the situation with different classes having the same fully-qualified name.
* [see](https://github.com/JetBrains/java-annotations/issues/34)
*
* Specifies that an element of the program represents a string that is a source code on a specified language.
* Code editors may use this annotation to enable syntax highlighting, code completion and other features
* inside the literals that assigned to the annotated variables, passed as arguments to the annotated parameters,
* or returned from the annotated methods.
* <p>
* This annotation also could be used as a meta-annotation, to define derived annotations for convenience.
* E.g. the following annotation could be defined to annotate the strings that represent Java methods:
*
* <pre>
* &#64;Language(value = "JAVA", prefix = "class X{", suffix = "}")
* &#64;interface JavaMethod {}
* </pre>
* <p>
* Note that using the derived annotation as meta-annotation is not supported.
* Meta-annotation works only one level deep.
*/

@InternalSerializationApi
@Retention(AnnotationRetention.BINARY)
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.FIELD,
AnnotationTarget.VALUE_PARAMETER,
AnnotationTarget.LOCAL_VARIABLE,
AnnotationTarget.ANNOTATION_CLASS
)
public expect annotation class FormatLanguage(
public val value: String,
// default parameters are not used due to https://youtrack.jetbrains.com/issue/KT-25946/
public val prefix: String,
public val suffix: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.serialization.json.internal;

import kotlinx.serialization.InternalSerializationApi

@InternalSerializationApi
public actual typealias FormatLanguage = org.intellij.lang.annotations.Language
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

@file:Suppress("PackageDirectoryMismatch")

package org.intellij.lang.annotations

import kotlinx.serialization.InternalSerializationApi

/**
* JS implementation of JVM-only `org.intellij.lang.annotations.Language` class, adds syntax support by IDE.
*
* This class is missing from the Kotlin/JS targets, so it needs to be distributed along with the serialization runtime.
*
* Copy-paste from [https://github.com/JetBrains/java-annotations](https://github.com/JetBrains/java-annotations).
*
* @see [kotlinx.serialization.json.internal.FormatLanguage]
*/
@InternalSerializationApi
@Retention(AnnotationRetention.BINARY)
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.FIELD,
AnnotationTarget.VALUE_PARAMETER,
AnnotationTarget.LOCAL_VARIABLE,
AnnotationTarget.ANNOTATION_CLASS,
)
public annotation class Language(
val value: String,
val prefix: String = "",
val suffix: String = "",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.serialization.json.internal;

import kotlinx.serialization.InternalSerializationApi

@InternalSerializationApi
public actual typealias FormatLanguage = org.intellij.lang.annotations.Language
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

package kotlinx.serialization.json.internal;

import kotlinx.serialization.InternalSerializationApi

@InternalSerializationApi
public actual typealias FormatLanguage = org.intellij.lang.annotations.Language
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
*/

@file:Suppress("PackageDirectoryMismatch")

package org.intellij.lang.annotations

import kotlinx.serialization.InternalSerializationApi

/**
* Native implementation of JVM-only `org.intellij.lang.annotations.Language` class, adds syntax support by IDE.
*
* This class is missing from the Kotlin/Native targets, so it needs to be distributed along with the serialization runtime.
*
* Copy-paste from [https://github.com/JetBrains/java-annotations](https://github.com/JetBrains/java-annotations).
*
* @see [kotlinx.serialization.json.internal.FormatLanguage]
*/
@InternalSerializationApi
@Retention(AnnotationRetention.BINARY)
@Target(
AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY_GETTER,
AnnotationTarget.PROPERTY_SETTER,
AnnotationTarget.FIELD,
AnnotationTarget.VALUE_PARAMETER,
AnnotationTarget.LOCAL_VARIABLE,
AnnotationTarget.ANNOTATION_CLASS,
)
public annotation class Language(
val value: String,
val prefix: String = "",
val suffix: String = "",
)

0 comments on commit 5a8795a

Please sign in to comment.