1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.room.solver 18 19 import androidx.room.compiler.codegen.XCodeBlock 20 import androidx.room.writer.TypeWriter 21 22 /** 23 * Defines a code generation scope where we can provide temporary variables, global variables etc 24 */ 25 class CodeGenScope(val writer: TypeWriter) { 26 val language = writer.context.codeLanguage 27 val javaLambdaSyntaxAvailable = writer.context.javaLambdaSyntaxAvailable <lambda>null28 val builder by lazy { XCodeBlock.builder() } 29 private val tmpVarIndices = mutableMapOf<String, Int>() 30 31 companion object { 32 const val TMP_VAR_DEFAULT_PREFIX = "_tmp" 33 const val CLASS_PROPERTY_PREFIX = "__" 34 getTmpVarStringnull35 internal fun getTmpVarString(index: Int) = getTmpVarString(TMP_VAR_DEFAULT_PREFIX, index) 36 37 private fun getTmpVarString(prefix: String, index: Int) = 38 "$prefix${if (index == 0) "" else "_$index"}" 39 } 40 41 fun getTmpVar(): String { 42 return getTmpVar(TMP_VAR_DEFAULT_PREFIX) 43 } 44 getTmpVarnull45 fun getTmpVar(prefix: String): String { 46 require(prefix.startsWith("_")) { "Tmp variable prefixes should start with '_'." } 47 require(!prefix.startsWith(CLASS_PROPERTY_PREFIX)) { 48 "Cannot use '$CLASS_PROPERTY_PREFIX' for tmp variables." 49 } 50 val index = tmpVarIndices.getOrElse(prefix) { 0 } 51 val result = getTmpVarString(prefix, index) 52 tmpVarIndices[prefix] = index + 1 53 return result 54 } 55 generatenull56 fun generate(): XCodeBlock = builder.build() 57 58 /** Copies all variable indices but excludes generated code. */ 59 fun fork(): CodeGenScope { 60 val forked = CodeGenScope(writer) 61 forked.tmpVarIndices.putAll(tmpVarIndices) 62 return forked 63 } 64 } 65