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.writer.ClassWriter 20 import com.google.common.annotations.VisibleForTesting 21 import com.squareup.javapoet.CodeBlock 22 23 /** 24 * Defines a code generation scope where we can provide temporary variables, global variables etc 25 */ 26 class CodeGenScope(val writer: ClassWriter) { 27 private var tmpVarIndices = mutableMapOf<String, Int>() 28 private var builder: CodeBlock.Builder? = null 29 companion object { 30 const val TMP_VAR_DEFAULT_PREFIX = "_tmp" 31 const val CLASS_PROPERTY_PREFIX = "__" 32 @VisibleForTesting _tmpVarnull33 fun _tmpVar(index: Int) = _tmpVar(TMP_VAR_DEFAULT_PREFIX, index) 34 fun _tmpVar(prefix: String, index: Int) = "$prefix${if (index == 0) "" else "_$index"}" 35 } 36 37 fun builder(): CodeBlock.Builder { 38 if (builder == null) { 39 builder = CodeBlock.builder() 40 } 41 return builder!! 42 } 43 getTmpVarnull44 fun getTmpVar(): String { 45 return getTmpVar(TMP_VAR_DEFAULT_PREFIX) 46 } 47 getTmpVarnull48 fun getTmpVar(prefix: String): String { 49 if (!prefix.startsWith("_")) { 50 throw IllegalArgumentException("tmp variable prefixes should start with _") 51 } 52 if (prefix.startsWith(CLASS_PROPERTY_PREFIX)) { 53 throw IllegalArgumentException("cannot use $CLASS_PROPERTY_PREFIX for tmp variables") 54 } 55 val index = tmpVarIndices.getOrElse(prefix) { 0 } 56 val result = _tmpVar(prefix, index) 57 tmpVarIndices.put(prefix, index + 1) 58 return result 59 } 60 generatenull61 fun generate() = builder().build().toString() 62 63 /** 64 * copies all variable indices but excludes generated code. 65 */ 66 fun fork(): CodeGenScope { 67 val forked = CodeGenScope(writer) 68 forked.tmpVarIndices.putAll(tmpVarIndices) 69 return forked 70 } 71 } 72