Skip to content

Instantly share code, notes, and snippets.

View bnorm's full-sized avatar
🐢

Brian Norman bnorm

🐢
View GitHub Profile
@bnorm
bnorm / strings.kt
Created December 20, 2017 20:33
Turns a Kotlin Data class toString() into formatted JSON-like output
fun Any?.toIndentString(): String {
val notFancy = toString()
return buildString(notFancy.length) {
var indent = 0
fun StringBuilder.line() {
appendln()
repeat(2 * indent) { append(' ') }
}
@bnorm
bnorm / Singleton.java
Created August 23, 2015 13:51
Allows collecting into 1 and only 1 object from a stream. Supports a few different finishing object types.
import java.util.Objects;
import java.util.Optional;
import java.util.StringJoiner;
import java.util.stream.Collector;
import java.util.stream.Collectors;
public class Singleton<T> {
private T value;
private volatile int count;
@bnorm
bnorm / ByteBuffers.java
Last active June 28, 2022 03:50
Okio Source/Sink for ByteBuffers
import java.io.IOException;
import java.nio.ByteBuffer;
import okio.Buffer;
import okio.BufferedSink;
import okio.BufferedSource;
import okio.Okio;
import okio.Sink;
import okio.Source;
import okio.Timeout;
@bnorm
bnorm / xref.kt
Last active November 29, 2020 08:41
One to many relationship via property delegation - Inspiration: https://github.com/jcornaz/xref
object OneToMany {
private class One<O, M, C : MutableCollection<M>>(initial: O?, private val rightProperty: KMutableProperty1<O, C>) : ReadWriteProperty<M, O?> {
var one: O? = initial
override fun getValue(thisRef: M, property: KProperty<*>): O? = one
override fun setValue(thisRef: M, property: KProperty<*>, value: O?) {
when {
value != null -> add(value, thisRef)
tasks.named("compileKotlin") { dependsOn("syncSource") }
tasks.register<Sync>("syncSource") {
from(project(":kotlin-ir-plugin").sourceSets.main.get().allSource)
into("src/main/kotlin")
filter {
// Replace shadowed imports from plugin module
when (it) {
"import org.jetbrains.kotlin.com.intellij.mock.MockProject" -> "import com.intellij.mock.MockProject"
else -> it
}
class IrPluginTest {
@Test
fun `IR plugin success`() {
val result = compile(
sourceFile = SourceFile.kotlin(
"main.kt", """
fun main() {
println(debug())
}
fun debug() = "Hello, World!"
class TemplateIrGenerationExtension(
private val messageCollector: MessageCollector,
private val string: String,
private val file: String
) : IrGenerationExtension {
override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
messageCollector.report(CompilerMessageSeverity.INFO, "Argument 'string' = $string")
messageCollector.report(CompilerMessageSeverity.INFO, "Argument 'file' = $file")
}
}
@AutoService(ComponentRegistrar::class)
class TemplateComponentRegistrar(
private val defaultString: String,
private val defaultFile: String,
) : ComponentRegistrar {
@Suppress("unused") // Used by service loader
constructor() : this(
defaultString = "Hello, World!",
defaultFile = "file.txt"
@AutoService(CommandLineProcessor::class)
class TemplateCommandLineProcessor : CommandLineProcessor {
companion object {
private const val OPTION_STRING = "string"
private const val OPTION_FILE = "file"
val ARG_STRING = CompilerConfigurationKey<String>(OPTION_STRING)
val ARG_FILE = CompilerConfigurationKey<String>(OPTION_FILE)
}
@bnorm
bnorm / TemplateGradlePlugin.kt
Created November 21, 2020 18:50
Writing Your Second Kotlin Compiler Plugin - Part 1
class TemplateGradlePlugin : KotlinCompilerPluginSupportPlugin {
override fun apply(target: Project): Unit = with(target) {
extensions.create("template", TemplateGradleExtension::class.java)
}
override fun isApplicable(kotlinCompilation: KotlinCompilation<*>): Boolean = true
override fun getCompilerPluginId(): String = BuildConfig.KOTLIN_PLUGIN_ID
override fun getPluginArtifact(): SubpluginArtifact = SubpluginArtifact(