XCodeBlock.kt
/*
* Copyright 2022 The Android Open Source Project
*
* 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.
*/
package androidx.room.compiler.codegen
import androidx.room.compiler.codegen.java.JavaCodeBlock
import androidx.room.compiler.codegen.kotlin.KotlinCodeBlock
interface XCodeBlock : TargetLanguage {
interface Builder : TargetLanguage {
fun add(code: XCodeBlock): Builder
fun add(format: String, vararg args: Any?): Builder
fun addStatement(format: String, vararg args: Any?): Builder
fun addLocalVariable(
name: String,
typeName: XTypeName,
isMutable: Boolean = false,
assignExpr: XCodeBlock? = null
): Builder
fun beginControlFlow(controlFlow: String, vararg args: Any?): Builder
fun nextControlFlow(controlFlow: String, vararg args: Any?): Builder
fun endControlFlow(): Builder
fun build(): XCodeBlock
companion object {
fun Builder.apply(
javaCodeBuilder: com.squareup.javapoet.CodeBlock.Builder.() -> Unit,
kotlinCodeBuilder: com.squareup.kotlinpoet.CodeBlock.Builder.() -> Unit,
): Builder = apply {
when (language) {
CodeLanguage.JAVA -> {
check(this is JavaCodeBlock.Builder)
this.actual.javaCodeBuilder()
}
CodeLanguage.KOTLIN -> {
check(this is KotlinCodeBlock.Builder)
this.actual.kotlinCodeBuilder()
}
}
}
}
}
companion object {
fun builder(language: CodeLanguage): Builder {
return when (language) {
CodeLanguage.JAVA -> JavaCodeBlock.Builder()
CodeLanguage.KOTLIN -> KotlinCodeBlock.Builder()
}
}
fun of(language: CodeLanguage, format: String, vararg args: Any?): XCodeBlock {
return builder(language).add(format, *args).build()
}
/**
* Convenience code block of a new instantiation expression.
*
* Shouldn't contain parenthesis.
*/
fun ofNewInstance(
language: CodeLanguage,
typeName: XTypeName,
argsFormat: String = "",
vararg args: Any?
): XCodeBlock {
return builder(language).apply {
val newKeyword = when (language) {
CodeLanguage.JAVA -> "new "
CodeLanguage.KOTLIN -> ""
}
add("$newKeyword%T($argsFormat)", typeName, *args)
}.build()
}
/**
* Convenience code block of an unsafe cast expression.
*/
fun ofCast(
language: CodeLanguage,
typeName: XTypeName,
expressionBlock: XCodeBlock
): XCodeBlock {
return builder(language).apply {
when (language) {
CodeLanguage.JAVA -> {
add("(%T) (%L)", typeName, expressionBlock)
}
CodeLanguage.KOTLIN -> {
add("(%L) as %T", expressionBlock, typeName)
}
}
}.build()
}
}
}