Skip to content

Commit 032f62f

Browse files
committed
Split escapeJS in linker and js-envs.
And specialize them to the particular needs of each subproject: * `java.lang.StringBuilder` versus `java.io.Writer` instead of the generic `java.lang.Appendable`. * With or without tracking of how many characters are written out. Also review and specialize the one in `ir`.
1 parent 4026e50 commit 032f62f

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Scala.js (https://www.scala-js.org/)
3+
*
4+
* Copyright EPFL.
5+
*
6+
* Licensed under Apache License 2.0
7+
* (https://www.apache.org/licenses/LICENSE-2.0).
8+
*
9+
* See the NOTICE file distributed with this work for
10+
* additional information regarding copyright ownership.
11+
*/
12+
13+
package org.scalajs.jsenv
14+
15+
object JSUtils {
16+
17+
def escapeJS(str: String): String = {
18+
// scalastyle:off return
19+
val end = str.length
20+
var i = 0
21+
while (i != end) {
22+
val c = str.charAt(i)
23+
if (c >= 32 && c <= 126 && c != '\\' && c != '"')
24+
i += 1
25+
else
26+
return createEscapeJSString(str)
27+
}
28+
str
29+
// scalastyle:on return
30+
}
31+
32+
private def createEscapeJSString(str: String): String = {
33+
val sb = new java.lang.StringBuilder(2 * str.length)
34+
printEscapeJS(str, sb)
35+
sb.toString
36+
}
37+
38+
/* !!! BEGIN CODE VERY SIMILAR TO ir/.../Utils.scala and
39+
* linker/.../javascript/Utils.scala
40+
*/
41+
42+
private final val EscapeJSChars = "\\b\\t\\n\\v\\f\\r\\\"\\\\"
43+
44+
private def printEscapeJS(str: String, out: java.lang.StringBuilder): Unit = {
45+
/* Note that Java and JavaScript happen to use the same encoding for
46+
* Unicode, namely UTF-16, which means that 1 char from Java always equals
47+
* 1 char in JavaScript. */
48+
val end = str.length()
49+
var i = 0
50+
/* Loop prints all consecutive ASCII printable characters starting
51+
* from current i and one non ASCII printable character (if it exists).
52+
* The new i is set at the end of the appended characters.
53+
*/
54+
while (i != end) {
55+
val start = i
56+
var c: Int = str.charAt(i)
57+
// Find all consecutive ASCII printable characters from `start`
58+
while (i != end && c >= 32 && c <= 126 && c != 34 && c != 92) {
59+
i += 1
60+
if (i != end)
61+
c = str.charAt(i)
62+
}
63+
// Print ASCII printable characters from `start`
64+
if (start != i) {
65+
out.append(str, start, i)
66+
}
67+
68+
// Print next non ASCII printable character
69+
if (i != end) {
70+
def escapeJSEncoded(c: Int): Unit = {
71+
if (7 < c && c < 14) {
72+
val i = 2 * (c - 8)
73+
out.append(EscapeJSChars, i, i + 2)
74+
} else if (c == 34) {
75+
out.append(EscapeJSChars, 12, 14)
76+
} else if (c == 92) {
77+
out.append(EscapeJSChars, 14, 16)
78+
} else {
79+
out.append("\\u%04x".format(c))
80+
}
81+
}
82+
escapeJSEncoded(c)
83+
i += 1
84+
}
85+
}
86+
}
87+
88+
/* !!! END CODE VERY SIMILAR TO ir/.../Utils.scala and
89+
* linker/.../javascript/Utils.scala
90+
*/
91+
92+
}

nodejs-env/src/main/scala/org/scalajs/jsenv/nodejs/NodeJSEnv.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import scala.annotation.tailrec
1818
import scala.collection.JavaConverters._
1919

2020
import org.scalajs.jsenv._
21+
import org.scalajs.jsenv.JSUtils.escapeJS
2122

2223
import org.scalajs.io._
23-
import org.scalajs.io.JSUtils.escapeJS
2424
import org.scalajs.logging._
2525

2626
import java.io._

0 commit comments

Comments
 (0)