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