KCode.kt revision 5d454e5f2397a3b160f081ce123b4ca7ff0fc356
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 16d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarimport java.util.BitSet 17d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 18d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarclass KCode (private val s : String? = null){ 19d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 20d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private var sameLine = false 21d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 22895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar private val lineSeparator = System.getProperty("line.separator") 23895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar 24d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar class Appendix(val glue : String, val code : KCode) 25d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 26d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private val nodes = arrayListOf<Any>() 27d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 28fda1703c88eb22e9f166d957d6bda2cd8d645b8fYigit Boyar companion object { 29d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private val cachedIndentations = BitSet() 30d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private val indentCache = arrayListOf<String>() 31d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun indent(n: Int): String { 32d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (cachedIndentations.get(n)) { 33d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return indentCache.get(n) 34d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 35d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val s = (0..n-1).fold(""){prev, next -> "${prev} "} 36d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar cachedIndentations.set(n, true ) 37d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar while (indentCache.size() <= n) { 38d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar indentCache.add(""); 39d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 40d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar indentCache.set(n, s) 41d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return s 42d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 43d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 44d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 45d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun isNull(kcode : KCode?) = kcode == null || (kcode.nodes.isEmpty() && (kcode.s == null || kcode.s.trim() == "")) 46d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 47d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun tab(vararg codes : KCode?) : KCode { 48d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar codes.forEach { tab(it) } 49d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 50d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 51d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 52d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun tab(codes : Collection<KCode?> ) : KCode { 53d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar codes.forEach { tab(it) } 54d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 55d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 56d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 57d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun tab(s : String?, init : (KCode.() -> Unit)? = null) : KCode { 58d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val c = KCode(s) 59d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (init != null) { 60d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.init() 61d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 62d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return tab(c) 63d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 64d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 65d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar private fun tab(c : KCode?) : KCode { 665d454e5f2397a3b160f081ce123b4ca7ff0fc356Yigit Boyar if (c == null || isNull(c)) { 67d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 68d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 69d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nodes.add(c) 70d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 71d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 72d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 73d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun nls(vararg codes : KCode?) : KCode { 74d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar codes.forEach { nl(it) } 75d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 76d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 77d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 78d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun nls(codes : Collection<KCode?>) : KCode { 79d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar codes.forEach { nl(it) } 80d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 81d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 82d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 83d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun nl(c : KCode?) : KCode { 845d454e5f2397a3b160f081ce123b4ca7ff0fc356Yigit Boyar if (c == null || isNull(c)) { 85d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 86d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 87d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nodes.add(c) 88d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c!!.sameLine = true 89d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 90d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 91d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 92d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun nl(s : String?, init : (KCode.() -> Unit)? = null) : KCode { 93d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val c = KCode(s) 94d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (init != null) { 95d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.init() 96d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 97d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return nl(c) 98d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 99d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 100d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun apps(glue : String = "", vararg codes : KCode?) : KCode { 101d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar codes.forEach { app(glue, it)} 102d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 103d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 104d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 105d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun apps(glue : String = "", codes : Collection<KCode?>) : KCode { 106d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar codes.forEach { app(glue, it)} 107d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 108d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 109d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 110d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun app(glue : String = "", c : KCode?) : KCode { 111d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (isNull(c)) { 112d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 113d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 114d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nodes.add(Appendix(glue, c!!)) 115d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return this 116d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 117d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 118d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun app(s : String) : KCode { 119d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val c = KCode(s) 120d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return app("", c) 121d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 122d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 123d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun app(glue : String = "", s : String?, init : (KCode.() -> Unit)? = null) : KCode { 124d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val c = KCode(s) 125d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (init != null) { 126d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.init() 127d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 128d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return app(glue, c) 129d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 130d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 131d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 132d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun toS(n : Int, sb : StringBuilder) { 133d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (s != null) { 134d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar sb.append(s) 135d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 136d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val newlineFirstNode = s != null || (nodes.isNotEmpty() && nodes.first() is Appendix) 137d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar var addedChild = false 138d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar nodes.forEach { when(it) { 139d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is Appendix -> { 140d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar sb.append(it.glue) 141d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.code.toS(n, sb) 142d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 143d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar is KCode -> { 144d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val childTab = n + (if(it.sameLine) 0 else 1) 145d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (addedChild || newlineFirstNode) { 146895b618d9c6e3deb56465d0759cda57f50c46214Yigit Boyar sb.append(lineSeparator) 147d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar sb.append("${indent(childTab)}") 148d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 149d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar it.toS(childTab, sb) 150d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar addedChild = true 151d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 152d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } } 153d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 154d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 155d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 156d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar fun generate() : String { 157d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val sb = StringBuilder() 158d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar toS(0, sb) 159d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return sb.toString() 160d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 161d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar} 162d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar 163d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyarfun kcode(s : String?, init : (KCode.() -> Unit)? = null) : KCode { 164d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar val c = KCode(s) 165d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar if (init != null) { 166d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar c.init() 167d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar } 168d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar return c 169d7af42b29ddf22f0068f7496c5ac6f4f34b543b6Yigit Boyar}