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