1d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar/* 2d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Copyright (C) 2015 The Android Open Source Project 3d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 4d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * you may not use this file except in compliance with the License. 5d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * You may obtain a copy of the License at 6d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 7d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * Unless required by applicable law or agreed to in writing, software 8d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 9d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * See the License for the specific language governing permissions and 11d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar * limitations under the License. 12d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar */ 13d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 14fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding.tool.writer 15d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 164ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Guptaimport android.databinding.tool.util.StringUtils 17d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.BitSet 18d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 19d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass KCode (private val s : String? = null){ 20d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 21d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private var sameLine = false 22d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 234ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Gupta private val lineSeparator = StringUtils.LINE_SEPARATOR 24895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar 25d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar class Appendix(val glue : String, val code : KCode) 26d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 27d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private val nodes = arrayListOf<Any>() 28d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 29fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar companion object { 30d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private val cachedIndentations = BitSet() 31d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private val indentCache = arrayListOf<String>() 32d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun indent(n: Int): String { 33d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (cachedIndentations.get(n)) { 34af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar return indentCache[n] 35d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 36af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar val s = (0..n-1).fold(""){prev, next -> "$prev "} 37d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cachedIndentations.set(n, true ) 3859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar while (indentCache.size <= n) { 39d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar indentCache.add(""); 40d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 41af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar indentCache[n] = s 42d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return s 43d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 44d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 45d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 46d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun isNull(kcode : KCode?) = kcode == null || (kcode.nodes.isEmpty() && (kcode.s == null || kcode.s.trim() == "")) 47d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 48d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun tab(vararg codes : KCode?) : KCode { 49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar codes.forEach { tab(it) } 50d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 51d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 52d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun tab(codes : Collection<KCode?> ) : KCode { 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar codes.forEach { tab(it) } 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 5859229481aec5a284d322a2ca80dff836485feb0cYigit Boyar infix fun tab(s : String?, init : (KCode.() -> Unit)? = null) : KCode { 59d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val c = KCode(s) 60d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (init != null) { 61d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.init() 62d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 63d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return tab(c) 64d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 65d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 66d3f2b9229472c9dae9bf4ae8b3e2d653b5653b01George Mount fun tab(c : KCode?) : KCode { 675d454e5f2397a3b160f081ce123b4ca7ff0fc356Yigit Boyar if (c == null || isNull(c)) { 68d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 70d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nodes.add(c) 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 72d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 73d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 7439113ca579a3d4e1c24e204f102e6dc9b26125afTor Norbye infix fun nl(c : KCode?) : KCode { 755d454e5f2397a3b160f081ce123b4ca7ff0fc356Yigit Boyar if (c == null || isNull(c)) { 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 77d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 78d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nodes.add(c) 79af146d6a8c0efcf5682d14047c06866a5548f78fYigit Boyar c.sameLine = true 80d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 81d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 82d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 8339113ca579a3d4e1c24e204f102e6dc9b26125afTor Norbye infix fun nl(s : String?, init : (KCode.() -> Unit)? = null) : KCode { 84d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val c = KCode(s) 85d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (init != null) { 86d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.init() 87d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 88d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return nl(c) 89d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 90d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun app(glue : String = "", c : KCode?) : KCode { 92d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (isNull(c)) { 93d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 94d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 95d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nodes.add(Appendix(glue, c!!)) 96d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 97d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 98d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 9959229481aec5a284d322a2ca80dff836485feb0cYigit Boyar infix fun app(s : String) : KCode { 100d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val c = KCode(s) 101d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return app("", c) 102d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 103d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 104d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun app(glue : String = "", s : String?, init : (KCode.() -> Unit)? = null) : KCode { 105d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val c = KCode(s) 106d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (init != null) { 107d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.init() 108d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 109d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return app(glue, c) 110d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 111d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 112d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 113d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun toS(n : Int, sb : StringBuilder) { 114d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (s != null) { 115d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar sb.append(s) 116d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 117d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val newlineFirstNode = s != null || (nodes.isNotEmpty() && nodes.first() is Appendix) 118d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var addedChild = false 119d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nodes.forEach { when(it) { 120d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is Appendix -> { 121d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar sb.append(it.glue) 122d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.code.toS(n, sb) 123d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 124d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is KCode -> { 125d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val childTab = n + (if(it.sameLine) 0 else 1) 126d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (addedChild || newlineFirstNode) { 127895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar sb.append(lineSeparator) 128d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar sb.append("${indent(childTab)}") 129d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 130d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.toS(childTab, sb) 131d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar addedChild = true 132d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 133d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } } 134d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 135d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 136d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 137d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun generate() : String { 138d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val sb = StringBuilder() 139d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar toS(0, sb) 140d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return sb.toString() 141d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 142d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 143d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 144d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun kcode(s : String?, init : (KCode.() -> Unit)? = null) : KCode { 145d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val c = KCode(s) 146d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (init != null) { 147d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.init() 148d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 149d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return c 1504ba16229a40e9758db86d4fb1df5119fdcb8aa2aDeepanshu Gupta} 151