Limit max line size of generated JS code

This commit is contained in:
Alexey Andreev 2018-12-21 14:28:30 +03:00
parent 96f77b2f08
commit 4ffe74296d
5 changed files with 66 additions and 39 deletions

View File

@ -74,9 +74,9 @@ public class ClassLoaderNativeGenerator implements Injector {
for (int i = 0; i < dataBytes.length; ++i) {
dataChars[i] = (char) dataBytes[i];
}
writer.append("\"").append(RenderingUtil.escapeString(resource)).append("\"");
RenderingUtil.writeString(writer, resource);
writer.ws().append(':').ws();
writer.append("\"").append(new String(dataChars)).append("\"");
RenderingUtil.writeString(writer, new String(dataChars));
}
}

View File

@ -183,7 +183,7 @@ public class Renderer implements RenderingManager {
if (i > 0) {
writer.append(',').ws();
}
writer.append('"').append(RenderingUtil.escapeString(context.getStringPool().get(i))).append('"');
RenderingUtil.writeString(writer, context.getStringPool().get(i));
}
writer.append("]);").newLine();
stringPoolSize = writer.getOffset() - start;

View File

@ -15,12 +15,14 @@
*/
package org.teavm.backend.javascript.rendering;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.teavm.ast.ConstantExpr;
import org.teavm.ast.Expr;
import org.teavm.backend.javascript.codegen.SourceWriter;
public final class RenderingUtil {
public static final Set<String> KEYWORDS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("break", "case",
@ -43,6 +45,59 @@ public final class RenderingUtil {
return sb.toString();
}
public static void writeString(SourceWriter writer, String s) throws IOException {
if (s.isEmpty()) {
writer.append("\"\"");
return;
}
for (int i = 0; i < s.length(); i += 512) {
int next = Math.min(i + 512, s.length());
if (i > 0) {
writer.newLine().append("+").ws();
}
writer.append('"');
for (int j = i; j < next; ++j) {
char c = s.charAt(j);
switch (c) {
case '\r':
writer.append("\\r");
break;
case '\n':
writer.append("\\n");
break;
case '\t':
writer.append("\\t");
break;
case '\'':
writer.append("\\'");
break;
case '\"':
writer.append("\\\"");
break;
case '\\':
writer.append("\\\\");
break;
default:
if (c < ' ') {
writer.append("\\u00").append(Character.forDigit(c / 16, 16))
.append(Character.forDigit(c % 16, 16));
} else if (Character.isLowSurrogate(c) || Character.isHighSurrogate(c)
|| !Character.isDefined(c)) {
writer.append("\\u")
.append(Character.forDigit(c / 0x1000, 0x10))
.append(Character.forDigit((c / 0x100) % 0x10, 0x10))
.append(Character.forDigit((c / 0x10) % 0x10, 0x10))
.append(Character.forDigit(c % 0x10, 0x10));
} else {
writer.append(c);
}
break;
}
}
writer.append('"');
}
}
public static String escapeString(String str) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); ++i) {

View File

@ -19,6 +19,7 @@ import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.teavm.backend.javascript.codegen.SourceWriter;
import org.teavm.backend.javascript.rendering.RenderingUtil;
import org.teavm.platform.metadata.Resource;
import org.teavm.platform.metadata.ResourceMap;
@ -49,8 +50,8 @@ class BuildTimeResourceMap<T extends Resource> implements ResourceMap<T>, Resour
writer.append(",").ws();
}
first = false;
ResourceWriterHelper.writeString(writer, entry.getKey());
writer.ws().append(':').ws();
RenderingUtil.writeString(writer, entry.getKey());
writer.append(':').ws();
ResourceWriterHelper.write(writer, entry.getValue());
}
writer.append('}').tokenBoundary();
@ -58,6 +59,6 @@ class BuildTimeResourceMap<T extends Resource> implements ResourceMap<T>, Resour
@Override
public String[] keys() {
return data.keySet().toArray(new String[data.size()]);
return data.keySet().toArray(new String[0]);
}
}

View File

@ -17,6 +17,7 @@ package org.teavm.platform.plugin;
import java.io.IOException;
import org.teavm.backend.javascript.codegen.SourceWriter;
import org.teavm.backend.javascript.rendering.RenderingUtil;
final class ResourceWriterHelper {
private ResourceWriterHelper() {
@ -33,7 +34,7 @@ final class ResourceWriterHelper {
} else if (resource instanceof Boolean) {
writer.append(resource == Boolean.TRUE ? "true" : "false");
} else if (resource instanceof String) {
writeString(writer, (String) resource);
RenderingUtil.writeString(writer, (String) resource);
} else {
throw new RuntimeException("Error compiling resources. Value of illegal type found: "
+ resource.getClass());
@ -43,12 +44,12 @@ final class ResourceWriterHelper {
public static void writeIdentifier(SourceWriter writer, String id) throws IOException {
if (id.isEmpty() || !isIdentifierStart(id.charAt(0))) {
writeString(writer, id);
RenderingUtil.writeString(writer, id);
return;
}
for (int i = 1; i < id.length(); ++i) {
if (isIdentifierPart(id.charAt(i))) {
writeString(writer, id);
RenderingUtil.writeString(writer, id);
return;
}
}
@ -68,34 +69,4 @@ final class ResourceWriterHelper {
}
return c >= '0' && c <= '9';
}
public static void writeString(SourceWriter writer, String s) throws IOException {
writer.append('"');
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
switch (c) {
case '\0':
writer.append("\\0");
break;
case '\n':
writer.append("\\n");
break;
case '\r':
writer.append("\\r");
break;
case '\t':
writer.append("\\t");
break;
default:
if (c < 32) {
writer.append("\\u00").append(Character.forDigit(c / 16, 16))
.append(Character.forDigit(c % 16, 16));
} else {
writer.append(c);
}
break;
}
}
writer.append('"');
}
}