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) { for (int i = 0; i < dataBytes.length; ++i) {
dataChars[i] = (char) dataBytes[i]; dataChars[i] = (char) dataBytes[i];
} }
writer.append("\"").append(RenderingUtil.escapeString(resource)).append("\""); RenderingUtil.writeString(writer, resource);
writer.ws().append(':').ws(); 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) { if (i > 0) {
writer.append(',').ws(); writer.append(',').ws();
} }
writer.append('"').append(RenderingUtil.escapeString(context.getStringPool().get(i))).append('"'); RenderingUtil.writeString(writer, context.getStringPool().get(i));
} }
writer.append("]);").newLine(); writer.append("]);").newLine();
stringPoolSize = writer.getOffset() - start; stringPoolSize = writer.getOffset() - start;

View File

@ -15,12 +15,14 @@
*/ */
package org.teavm.backend.javascript.rendering; package org.teavm.backend.javascript.rendering;
import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.teavm.ast.ConstantExpr; import org.teavm.ast.ConstantExpr;
import org.teavm.ast.Expr; import org.teavm.ast.Expr;
import org.teavm.backend.javascript.codegen.SourceWriter;
public final class RenderingUtil { public final class RenderingUtil {
public static final Set<String> KEYWORDS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("break", "case", 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(); 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) { public static String escapeString(String str) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); ++i) { 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.HashMap;
import java.util.Map; import java.util.Map;
import org.teavm.backend.javascript.codegen.SourceWriter; 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.Resource;
import org.teavm.platform.metadata.ResourceMap; import org.teavm.platform.metadata.ResourceMap;
@ -49,8 +50,8 @@ class BuildTimeResourceMap<T extends Resource> implements ResourceMap<T>, Resour
writer.append(",").ws(); writer.append(",").ws();
} }
first = false; first = false;
ResourceWriterHelper.writeString(writer, entry.getKey()); RenderingUtil.writeString(writer, entry.getKey());
writer.ws().append(':').ws(); writer.append(':').ws();
ResourceWriterHelper.write(writer, entry.getValue()); ResourceWriterHelper.write(writer, entry.getValue());
} }
writer.append('}').tokenBoundary(); writer.append('}').tokenBoundary();
@ -58,6 +59,6 @@ class BuildTimeResourceMap<T extends Resource> implements ResourceMap<T>, Resour
@Override @Override
public String[] keys() { 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 java.io.IOException;
import org.teavm.backend.javascript.codegen.SourceWriter; import org.teavm.backend.javascript.codegen.SourceWriter;
import org.teavm.backend.javascript.rendering.RenderingUtil;
final class ResourceWriterHelper { final class ResourceWriterHelper {
private ResourceWriterHelper() { private ResourceWriterHelper() {
@ -33,7 +34,7 @@ final class ResourceWriterHelper {
} else if (resource instanceof Boolean) { } else if (resource instanceof Boolean) {
writer.append(resource == Boolean.TRUE ? "true" : "false"); writer.append(resource == Boolean.TRUE ? "true" : "false");
} else if (resource instanceof String) { } else if (resource instanceof String) {
writeString(writer, (String) resource); RenderingUtil.writeString(writer, (String) resource);
} else { } else {
throw new RuntimeException("Error compiling resources. Value of illegal type found: " throw new RuntimeException("Error compiling resources. Value of illegal type found: "
+ resource.getClass()); + resource.getClass());
@ -43,12 +44,12 @@ final class ResourceWriterHelper {
public static void writeIdentifier(SourceWriter writer, String id) throws IOException { public static void writeIdentifier(SourceWriter writer, String id) throws IOException {
if (id.isEmpty() || !isIdentifierStart(id.charAt(0))) { if (id.isEmpty() || !isIdentifierStart(id.charAt(0))) {
writeString(writer, id); RenderingUtil.writeString(writer, id);
return; return;
} }
for (int i = 1; i < id.length(); ++i) { for (int i = 1; i < id.length(); ++i) {
if (isIdentifierPart(id.charAt(i))) { if (isIdentifierPart(id.charAt(i))) {
writeString(writer, id); RenderingUtil.writeString(writer, id);
return; return;
} }
} }
@ -68,34 +69,4 @@ final class ResourceWriterHelper {
} }
return c >= '0' && c <= '9'; 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('"');
}
} }