@@ -2,103 +2,80 @@ package org.projectfluent.syntax.serializer
2
2
3
3
import org.projectfluent.syntax.ast.* // ktlint-disable no-wildcard-imports
4
4
5
- private fun indent (content : CharSequence ): String {
6
- return content.split(" \n " ).joinToString(" \n " )
7
- }
5
+ private fun indent (content : CharSequence ) = content.split(" \n " ).joinToString(" \n " )
8
6
9
- private fun includesLine (elem : PatternElement ): Boolean {
10
- return elem is TextElement && elem.value.contains(" \n " )
11
- }
7
+ private fun PatternElement.includesLine () = this is TextElement && value.contains(" \n " )
12
8
13
- private fun isSelectExpr (elem : PatternElement ): Boolean {
14
- return elem is Placeable &&
15
- elem.expression is SelectExpression
16
- }
9
+ private fun PatternElement.isSelectExpr () = this is Placeable && expression is SelectExpression
17
10
18
11
/* *
19
12
* Serialize Fluent nodes to `CharSequence`.
20
13
*
21
14
* @property withJunk serialize Junk entries or not.
22
15
*/
23
- class FluentSerializer (var withJunk : Boolean = false ) {
16
+ class FluentSerializer (private val withJunk : Boolean = false ) {
24
17
/* *
25
18
* Serialize a Resource.
26
19
*/
27
- fun serialize (resource : Resource ): CharSequence {
28
- val builder = StringBuilder ()
29
-
30
- entries@ for (entry in resource.body) {
31
- val serialized = when (entry) {
32
- is Entry -> serializeEntry(entry)
33
- is Whitespace -> entry.content
34
- is Junk -> {
35
- if (this .withJunk) {
36
- entry.content
37
- } else {
38
- continue @entries
39
- }
20
+ fun serialize (resource : Resource ): CharSequence =
21
+ resource.body
22
+ .mapNotNull {
23
+ when (it) {
24
+ is Entry -> serializeEntry(it)
25
+ is Whitespace -> it.content
26
+ is Junk -> it.content.takeIf { this .withJunk }
27
+ else -> throw SerializeError (" Unknown top-level entry type" )
40
28
}
41
- else -> throw SerializeError (" Unknown top-level entry type" )
42
29
}
43
- builder.append(serialized)
44
- }
45
-
46
- return builder
47
- }
30
+ .joinToString(" " )
48
31
49
32
/* *
50
33
* Serialize Message, Term, Whitespace, and Junk.
51
34
*/
52
- fun serialize (entry : TopLevel ): CharSequence {
35
+ fun serialize (entry : TopLevel ): CharSequence =
53
36
when (entry) {
54
- is Entry -> return serializeEntry(entry)
55
- is Whitespace -> return entry.content
56
- is Junk -> return entry.content
37
+ is Entry -> serializeEntry(entry)
38
+ is Whitespace -> entry.content
39
+ is Junk -> entry.content
40
+ else -> throw SerializeError (" Unknown top-level type: $entry " )
57
41
}
58
- throw SerializeError (" Unknown top-level type: $entry " )
59
- }
60
42
61
43
/* *
62
44
* Serialize an Expression.
63
45
*
64
46
* This is useful to get a string representation of a simple Placeable.
65
47
*/
66
- fun serialize (expr : Expression ): CharSequence {
67
- return serializeExpression(expr)
68
- }
48
+ fun serialize (expr : Expression ): CharSequence = serializeExpression(expr)
69
49
70
50
/* *
71
51
* Serialize a VariantKey.
72
52
*
73
53
* Useful when displaying the options of a SelectExpression.
74
54
*/
75
- fun serialize (key : VariantKey ): CharSequence {
76
- return serializeVariantKey(key)
77
- }
55
+ fun serialize (key : VariantKey ): CharSequence = serializeVariantKey(key)
78
56
79
- private fun serializeEntry (entry : Entry ): CharSequence {
57
+ private fun serializeEntry (entry : Entry ) =
80
58
when (entry) {
81
- is Message -> return serializeMessage(entry)
82
- is Term -> return serializeTerm(entry)
83
- is Comment -> return serializeComment(entry, " #" )
84
- is GroupComment -> return serializeComment(entry, " ##" )
85
- is ResourceComment -> return serializeComment(entry, " ###" )
86
- }
87
- throw SerializeError (" Unknown entry type: $entry " )
88
- }
89
-
90
- private fun serializeComment (comment : BaseComment , prefix : String = "#"): CharSequence {
91
- val builder = StringBuilder ()
92
- val lines = comment.content.split(" \n " )
93
- for (line in lines) {
94
- if (line.isNotEmpty()) {
95
- builder.append(" $prefix $line " , " \n " )
96
- } else {
97
- builder.append(prefix, " \n " )
98
- }
99
- }
100
- return builder
101
- }
59
+ is Message -> serializeMessage(entry)
60
+ is Term -> serializeTerm(entry)
61
+ is Comment -> serializeComment(entry, " #" )
62
+ is GroupComment -> serializeComment(entry, " ##" )
63
+ is ResourceComment -> serializeComment(entry, " ###" )
64
+ else -> throw SerializeError (" Unknown entry type: $entry " )
65
+ }
66
+
67
+ private fun serializeComment (comment : BaseComment , prefix : CharSequence = "#") =
68
+ comment.content.split(" \n " )
69
+ .joinToString(
70
+ " " ,
71
+ transform = {
72
+ if (it.isNotEmpty()) {
73
+ " $prefix $it \n "
74
+ } else {
75
+ " $prefix \n "
76
+ }
77
+ }
78
+ )
102
79
103
80
private fun serializeMessage (message : Message ): CharSequence {
104
81
val builder = StringBuilder ()
@@ -145,44 +122,39 @@ class FluentSerializer(var withJunk: Boolean = false) {
145
122
}
146
123
147
124
private fun serializePattern (pattern : Pattern ): CharSequence {
148
- val startOnLine =
149
- pattern.elements.any(::isSelectExpr) ||
150
- pattern.elements.any(::includesLine)
125
+ val startOnLine = pattern.elements.any { it.isSelectExpr() || it.includesLine() }
151
126
val elements = pattern.elements.map(::serializeElement)
152
127
val content = indent(elements.joinToString(" " ))
153
128
154
- if (startOnLine) {
155
- return " \n $content "
129
+ return if (startOnLine) {
130
+ " \n $content "
131
+ } else {
132
+ " $content "
156
133
}
157
-
158
- return " $content "
159
134
}
160
135
161
- private fun serializeElement (element : PatternElement ): CharSequence {
136
+ private fun serializeElement (element : PatternElement ) =
162
137
when (element) {
163
- is TextElement -> return element.value
164
- is Placeable -> return serializePlaceable(element)
138
+ is TextElement -> element.value
139
+ is Placeable -> serializePlaceable(element)
140
+ else -> throw SerializeError (" Unknown element type: $element " )
165
141
}
166
- throw SerializeError (" Unknown element type: $element " )
167
- }
168
142
169
- private fun serializePlaceable (placeable : Placeable ): CharSequence {
170
- val expr = placeable.expression
171
- when (expr) {
172
- is Placeable -> return " {${serializePlaceable(expr)} }"
143
+ private fun serializePlaceable (placeable : Placeable ): CharSequence =
144
+ when (val expr = placeable.expression) {
145
+ is Placeable -> " {${serializePlaceable(expr)} }"
173
146
// Special-case select expression to control the whitespace around the
174
147
// opening and the closing brace.
175
- is SelectExpression -> return " { ${serializeExpression(expr)} }"
176
- is Expression -> return " { ${serializeExpression(expr)} }"
148
+ is SelectExpression -> " { ${serializeExpression(expr)} }"
149
+ is Expression -> " { ${serializeExpression(expr)} }"
150
+ else -> throw SerializeError (" Unknown placeable type" )
177
151
}
178
- throw SerializeError (" Unknown placeable type" )
179
- }
180
152
181
153
private fun serializeExpression (expr : Expression ): CharSequence {
182
- when (expr) {
183
- is StringLiteral -> return " \" ${expr.value} \" "
184
- is NumberLiteral -> return expr.value
185
- is VariableReference -> return " $${expr.id.name} "
154
+ return when (expr) {
155
+ is StringLiteral -> " \" ${expr.value} \" "
156
+ is NumberLiteral -> expr.value
157
+ is VariableReference -> " $${expr.id.name} "
186
158
is TermReference -> {
187
159
val builder = StringBuilder ()
188
160
builder.append(" -" , expr.id.name)
@@ -192,68 +164,61 @@ class FluentSerializer(var withJunk: Boolean = false) {
192
164
expr.arguments?.let {
193
165
builder.append(serializeCallArguments(it))
194
166
}
195
- return builder
167
+ builder
196
168
}
197
169
is MessageReference -> {
198
170
val builder = StringBuilder ()
199
171
builder.append(expr.id.name)
200
172
expr.attribute?.let {
201
173
builder.append(" ." , it.name)
202
174
}
203
- return builder
175
+ builder
204
176
}
205
- is FunctionReference ->
206
- return " ${expr.id.name}${serializeCallArguments(expr.arguments)} "
177
+ is FunctionReference -> " ${expr.id.name}${serializeCallArguments(expr.arguments)} "
207
178
is SelectExpression -> {
208
179
val builder = StringBuilder ()
209
- val selector = serializeExpression(expr.selector)
210
- builder.append(selector, " ->" )
211
- for (variant in expr.variants) {
212
- builder.append(serializeVariant(variant))
213
- }
180
+ builder.append(serializeExpression(expr.selector), " ->" )
181
+ expr.variants.forEach { builder.append(serializeVariant(it)) }
214
182
builder.append(" \n " )
215
- return builder
216
183
}
184
+ else -> throw SerializeError (" Unknown expression type: $expr " )
217
185
}
218
- throw SerializeError (" Unknown expression type: $expr " )
219
186
}
220
187
221
188
private fun serializeVariant (variant : Variant ): CharSequence {
222
189
val key = serializeVariantKey(variant.key)
223
190
val value = indent(serializePattern(variant.value))
224
191
225
- if (variant.default) {
226
- return " \n *[$key ]$value "
192
+ return if (variant.default) {
193
+ " \n *[$key ]$value "
194
+ } else {
195
+ " \n [$key ]$value "
227
196
}
228
-
229
- return " \n [$key ]$value "
230
197
}
231
198
232
199
private fun serializeCallArguments (expr : CallArguments ): CharSequence {
233
200
val positional = expr.positional.joinToString(" , " , transform = ::serializeExpression)
234
201
val named = expr.named.joinToString(" , " , transform = ::serializeNamedArgument)
235
- if (expr.positional.size > 0 && expr.named.size > 0 ) {
236
- return " ($positional , $named )"
237
- }
238
- if (expr.positional.size > 0 ) {
239
- return " ($positional )"
240
- }
241
- if (expr.named.size > 0 ) {
242
- return " ($named )"
202
+ val hasPositional = expr.positional.size > 0
203
+ val hasNamed = expr.named.size > 0
204
+
205
+ return if (hasPositional && hasNamed) {
206
+ " ($positional , $named )"
207
+ } else if (hasPositional) {
208
+ " ($positional )"
209
+ } else if (hasNamed) {
210
+ " ($named )"
211
+ } else {
212
+ " ()"
243
213
}
244
- return " ()"
245
214
}
246
215
247
- private fun serializeNamedArgument (arg : NamedArgument ): CharSequence {
248
- val value = serializeExpression(arg.value)
249
- return " ${arg.name.name} : $value "
250
- }
216
+ private fun serializeNamedArgument (arg : NamedArgument ) = " ${arg.name.name} : ${serializeExpression(arg.value)} "
251
217
252
- private fun serializeVariantKey (key : VariantKey ): CharSequence {
218
+ private fun serializeVariantKey (key : VariantKey ) =
253
219
when (key) {
254
- is Identifier -> return key.name
255
- is NumberLiteral -> return key.value
220
+ is Identifier -> key.name
221
+ is NumberLiteral -> key.value
222
+ else -> throw SerializeError (" Unknown variant key type: $key " )
256
223
}
257
- throw SerializeError (" Unknown variant key type: $key " )
258
- }
259
224
}
0 commit comments