1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * http://www.apache.org/licenses/LICENSE-2.0 7 * Unless required by applicable law or agreed to in writing, software 8 * distributed under the License is distributed on an "AS IS" BASIS, 9 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 * See the License for the specific language governing permissions and 11 * limitations under the License. 12 */ 13 14package android.databinding.tool.ext 15 16import android.databinding.tool.expr.VersionProvider 17import kotlin.properties.ReadOnlyProperty 18import kotlin.properties.Delegates 19import android.databinding.tool.ext.joinToCamelCase 20import android.databinding.tool.ext.joinToCamelCaseAsVar 21import android.databinding.tool.reflection.ModelAnalyzer 22import android.databinding.tool.reflection.ModelClass 23import android.databinding.tool.reflection.ModelAnalyzer 24 25private class LazyExt<K, T>(private val initializer: (k : K) -> T) : ReadOnlyProperty<K, T> { 26 private val mapping = hashMapOf<K, T>() 27 override fun get(thisRef: K, desc: PropertyMetadata): T { 28 val t = mapping.get(thisRef) 29 if (t != null) { 30 return t 31 } 32 val result = initializer(thisRef) 33 mapping.put(thisRef, result) 34 return result 35 } 36} 37 38private class VersionedLazyExt<K, T>(private val initializer: (k : K) -> T) : ReadOnlyProperty<K, T> { 39 private val mapping = hashMapOf<K, VersionedResult<T>>() 40 override fun get(thisRef: K, desc: PropertyMetadata): T { 41 val t = mapping.get(thisRef) 42 val version = if(thisRef is VersionProvider) thisRef.getVersion() else 1 43 if (t != null && version == t.version) { 44 return t.result 45 } 46 val result = initializer(thisRef) 47 mapping.put(thisRef, VersionedResult(version, result)) 48 return result 49 } 50} 51 52data class VersionedResult<T>(val version : Int, val result : T) 53 54fun Delegates.lazy<K, T>(initializer: (k : K) -> T): ReadOnlyProperty<K, T> = LazyExt(initializer) 55fun Delegates.versionedLazy<K, T>(initializer: (k : K) -> T): ReadOnlyProperty<K, T> = VersionedLazyExt(initializer) 56 57public fun Class<*>.toJavaCode() : String { 58 val name = getName(); 59 if (name.startsWith('[')) { 60 val numArray = name.lastIndexOf('[') + 1; 61 val componentType : String; 62 when (name.charAt(numArray)) { 63 'Z' -> componentType = "boolean" 64 'B' -> componentType = "byte" 65 'C' -> componentType = "char" 66 'L' -> componentType = name.substring(numArray + 1, name.length() - 1).replace('$', '.'); 67 'D' -> componentType = "double" 68 'F' -> componentType = "float" 69 'I' -> componentType = "int" 70 'J' -> componentType = "long" 71 'S' -> componentType = "short" 72 else -> componentType = name.substring(numArray) 73 } 74 val arrayComp = name.substring(0, numArray).replace("[", "[]"); 75 return componentType + arrayComp; 76 } else { 77 return name.replace("$", ".") 78 } 79} 80 81public fun String.androidId() : String = this.splitBy("/")[1] 82 83public fun String.toCamelCase() : String { 84 val split = this.splitBy("_") 85 if (split.size() == 0) return "" 86 if (split.size() == 1) return split[0].capitalize() 87 return split.joinToCamelCase() 88} 89 90public fun String.toCamelCaseAsVar() : String { 91 val split = this.splitBy("_") 92 if (split.size() == 0) return "" 93 if (split.size() == 1) return split[0] 94 return split.joinToCamelCaseAsVar() 95} 96 97public fun String.br() : String = 98 "BR.${if (this == "") "_all" else this}" 99