mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
javascript: refactor renderer
This commit is contained in:
parent
7cd72f0e96
commit
ed7e8ff7f4
|
@ -8,6 +8,7 @@ import java.util.HashSet;
|
|||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.teavm.backend.javascript.rendering.RenderingUtil;
|
||||
import org.teavm.classlib.ResourceSupplier;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
import org.teavm.backend.javascript.rendering.Renderer;
|
||||
|
@ -54,7 +55,7 @@ public class ClassLoaderNativeGenerator implements Injector {
|
|||
first = false;
|
||||
writer.newLine();
|
||||
String data = Base64.getEncoder().encodeToString(IOUtils.toByteArray(input));
|
||||
writer.append("\"").append(Renderer.escapeString(resource)).append("\"");
|
||||
writer.append("\"").append(RenderingUtil.escapeString(resource)).append("\"");
|
||||
writer.ws().append(':').ws();
|
||||
writer.append("\"").append(data).append("\"");
|
||||
}
|
||||
|
|
|
@ -37,11 +37,13 @@ import org.teavm.backend.javascript.codegen.MinifyingAliasProvider;
|
|||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriterBuilder;
|
||||
import org.teavm.backend.javascript.rendering.Renderer;
|
||||
import org.teavm.backend.javascript.rendering.RenderingContext;
|
||||
import org.teavm.backend.javascript.spi.GeneratedBy;
|
||||
import org.teavm.backend.javascript.spi.Generator;
|
||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||
import org.teavm.backend.javascript.spi.Injector;
|
||||
import org.teavm.debugging.information.DebugInformationEmitter;
|
||||
import org.teavm.debugging.information.DummyDebugInformationEmitter;
|
||||
import org.teavm.debugging.information.SourceLocation;
|
||||
import org.teavm.dependency.DependencyChecker;
|
||||
import org.teavm.dependency.DependencyListener;
|
||||
|
@ -225,8 +227,14 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
|||
builder.setMinified(minifying);
|
||||
SourceWriter sourceWriter = builder.build(writer);
|
||||
|
||||
Renderer renderer = new Renderer(sourceWriter, classes, controller.getClassLoader(), controller.getServices(),
|
||||
asyncMethods, asyncFamilyMethods, controller.getDiagnostics());
|
||||
DebugInformationEmitter debugEmitterToUse = debugEmitter;
|
||||
if (debugEmitterToUse == null) {
|
||||
debugEmitterToUse = new DummyDebugInformationEmitter();
|
||||
}
|
||||
RenderingContext renderingContext = new RenderingContext(debugEmitterToUse, classes,
|
||||
controller.getClassLoader(), controller.getServices(), controller.getProperties(), naming);
|
||||
Renderer renderer = new Renderer(sourceWriter, asyncMethods, asyncFamilyMethods,
|
||||
controller.getDiagnostics(), renderingContext);
|
||||
renderer.setProperties(controller.getProperties());
|
||||
renderer.setMinifying(minifying);
|
||||
if (debugEmitter != null) {
|
||||
|
@ -245,7 +253,7 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
|
|||
}
|
||||
renderer.getDebugEmitter().setLocationProvider(sourceWriter);
|
||||
for (Map.Entry<MethodReference, Injector> entry : methodInjectors.entrySet()) {
|
||||
renderer.addInjector(entry.getKey(), entry.getValue());
|
||||
renderingContext.addInjector(entry.getKey(), entry.getValue());
|
||||
}
|
||||
try {
|
||||
for (RendererListener listener : rendererListeners) {
|
||||
|
|
|
@ -56,10 +56,16 @@ public class DefaultAliasProvider implements AliasProvider {
|
|||
@Override
|
||||
public String getMethodAlias(MethodDescriptor method) {
|
||||
String alias = method.getName();
|
||||
if (alias.equals("<init>")) {
|
||||
alias = "$init";
|
||||
} else if (alias.equals("<clinit>")) {
|
||||
alias = "$clinit";
|
||||
switch (alias) {
|
||||
case "<init>":
|
||||
alias = "$_init_";
|
||||
break;
|
||||
case "<clinit>":
|
||||
alias = "$_clinit_";
|
||||
break;
|
||||
default:
|
||||
alias = "$" + alias;
|
||||
break;
|
||||
}
|
||||
return makeUnique(knownVirtualAliases, alias);
|
||||
}
|
||||
|
@ -67,10 +73,13 @@ public class DefaultAliasProvider implements AliasProvider {
|
|||
@Override
|
||||
public String getStaticMethodAlias(MethodReference method) {
|
||||
String alias = method.getDescriptor().getName();
|
||||
if (alias.equals("<init>")) {
|
||||
alias = "$init";
|
||||
} else if (alias.equals("<clinit>")) {
|
||||
alias = "$clinit";
|
||||
switch (alias) {
|
||||
case "<init>":
|
||||
alias = "_init_";
|
||||
break;
|
||||
case "<clinit>":
|
||||
alias = "_clinit_";
|
||||
break;
|
||||
}
|
||||
|
||||
return makeUnique(knownAliases, getClassAlias(method.getClassName()) + "_" + alias);
|
||||
|
@ -78,7 +87,7 @@ public class DefaultAliasProvider implements AliasProvider {
|
|||
|
||||
@Override
|
||||
public String getFieldAlias(FieldReference field) {
|
||||
return makeUnique(knownVirtualAliases, field.getFieldName());
|
||||
return makeUnique(knownVirtualAliases, "$" + field.getFieldName());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,22 +15,269 @@
|
|||
*/
|
||||
package org.teavm.backend.javascript.rendering;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Deque;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import org.teavm.backend.javascript.codegen.NamingStrategy;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
||||
import org.teavm.backend.javascript.spi.Injector;
|
||||
import org.teavm.common.ServiceRepository;
|
||||
import org.teavm.debugging.information.DebugInformationEmitter;
|
||||
import org.teavm.model.AnnotationReader;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.ListableClassReaderSource;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.TextLocation;
|
||||
import org.teavm.model.ValueType;
|
||||
|
||||
public interface RenderingContext extends ServiceRepository {
|
||||
NamingStrategy getNaming();
|
||||
public class RenderingContext {
|
||||
private final DebugInformationEmitter debugEmitter;
|
||||
private ListableClassReaderSource classSource;
|
||||
private ClassLoader classLoader;
|
||||
private ServiceRepository services;
|
||||
private Properties properties;
|
||||
private NamingStrategy naming;
|
||||
private final Deque<LocationStackEntry> locationStack = new ArrayDeque<>();
|
||||
private final Map<String, Integer> stringPoolMap = new HashMap<>();
|
||||
private final List<String> stringPool = new ArrayList<>();
|
||||
private final List<String> readonlyStringPool = Collections.unmodifiableList(stringPool);
|
||||
private final Map<MethodReference, InjectorHolder> injectorMap = new HashMap<>();
|
||||
private boolean minifying;
|
||||
|
||||
SourceWriter getWriter();
|
||||
public RenderingContext(DebugInformationEmitter debugEmitter, ListableClassReaderSource classSource,
|
||||
ClassLoader classLoader, ServiceRepository services, Properties properties,
|
||||
NamingStrategy naming) {
|
||||
this.debugEmitter = debugEmitter;
|
||||
this.classSource = classSource;
|
||||
this.classLoader = classLoader;
|
||||
this.services = services;
|
||||
this.properties = properties;
|
||||
this.naming = naming;
|
||||
}
|
||||
|
||||
boolean isMinifying();
|
||||
public ListableClassReaderSource getClassSource() {
|
||||
return classSource;
|
||||
}
|
||||
|
||||
ListableClassReaderSource getClassSource();
|
||||
public ClassLoader getClassLoader() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
ClassLoader getClassLoader();
|
||||
public ServiceRepository getServices() {
|
||||
return services;
|
||||
}
|
||||
|
||||
Properties getProperties();
|
||||
public Properties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public NamingStrategy getNaming() {
|
||||
return naming;
|
||||
}
|
||||
|
||||
public void setMinifying(boolean minifying) {
|
||||
this.minifying = minifying;
|
||||
}
|
||||
|
||||
public DebugInformationEmitter getDebugEmitter() {
|
||||
return debugEmitter;
|
||||
}
|
||||
|
||||
public void pushLocation(TextLocation location) {
|
||||
LocationStackEntry prevEntry = locationStack.peek();
|
||||
if (location != null) {
|
||||
if (prevEntry == null || !location.equals(prevEntry.location)) {
|
||||
debugEmitter.emitLocation(location.getFileName(), location.getLine());
|
||||
}
|
||||
} else {
|
||||
if (prevEntry != null) {
|
||||
debugEmitter.emitLocation(null, -1);
|
||||
}
|
||||
}
|
||||
locationStack.push(new LocationStackEntry(location));
|
||||
}
|
||||
|
||||
public void popLocation() {
|
||||
LocationStackEntry prevEntry = locationStack.pop();
|
||||
LocationStackEntry entry = locationStack.peek();
|
||||
if (entry != null) {
|
||||
if (!entry.location.equals(prevEntry.location)) {
|
||||
debugEmitter.emitLocation(entry.location.getFileName(), entry.location.getLine());
|
||||
}
|
||||
} else {
|
||||
debugEmitter.emitLocation(null, -1);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isMinifying() {
|
||||
return minifying;
|
||||
}
|
||||
|
||||
public int lookupString(String string) {
|
||||
return stringPoolMap.computeIfAbsent(string, key -> {
|
||||
stringPool.add(key);
|
||||
return stringPool.size() - 1;
|
||||
});
|
||||
}
|
||||
|
||||
public List<String> getStringPool() {
|
||||
return readonlyStringPool;
|
||||
}
|
||||
|
||||
public String constantToString(Object cst) {
|
||||
if (cst == null) {
|
||||
return "null";
|
||||
}
|
||||
if (cst instanceof ValueType) {
|
||||
ValueType type = (ValueType) cst;
|
||||
return naming.getNameForFunction("$rt_cls") + "(" + typeToClsString(type) + ")";
|
||||
} else if (cst instanceof String) {
|
||||
String string = (String) cst;
|
||||
int index = lookupString(string);
|
||||
return "$rt_s(" + index + ")";
|
||||
} else if (cst instanceof Long) {
|
||||
long value = (Long) cst;
|
||||
if (value == 0) {
|
||||
return "Long_ZERO";
|
||||
} else if ((int) value == value) {
|
||||
return "Long_fromInt(" + value + ")";
|
||||
} else {
|
||||
return "new Long(" + (value & 0xFFFFFFFFL) + ", " + (value >>> 32) + ")";
|
||||
}
|
||||
} else if (cst instanceof Character) {
|
||||
return Integer.toString((Character) cst);
|
||||
} else {
|
||||
return cst.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public String typeToClsString(ValueType type) {
|
||||
int arrayCount = 0;
|
||||
while (type instanceof ValueType.Array) {
|
||||
arrayCount++;
|
||||
type = ((ValueType.Array) type).getItemType();
|
||||
}
|
||||
String value;
|
||||
if (type instanceof ValueType.Object) {
|
||||
ValueType.Object objType = (ValueType.Object) type;
|
||||
value = naming.getNameFor(objType.getClassName());
|
||||
} else if (type instanceof ValueType.Void) {
|
||||
value = "$rt_voidcls()";
|
||||
} else if (type instanceof ValueType.Primitive) {
|
||||
ValueType.Primitive primitiveType = (ValueType.Primitive) type;
|
||||
switch (primitiveType.getKind()) {
|
||||
case BOOLEAN:
|
||||
value = "$rt_booleancls()";
|
||||
break;
|
||||
case CHARACTER:
|
||||
value = "$rt_charcls()";
|
||||
break;
|
||||
case BYTE:
|
||||
value = "$rt_bytecls()";
|
||||
break;
|
||||
case SHORT:
|
||||
value = "$rt_shortcls()";
|
||||
break;
|
||||
case INTEGER:
|
||||
value = "$rt_intcls()";
|
||||
break;
|
||||
case LONG:
|
||||
value = "$rt_longcls()";
|
||||
break;
|
||||
case FLOAT:
|
||||
value = "$rt_floatcls()";
|
||||
break;
|
||||
case DOUBLE:
|
||||
value = "$rt_doublecls()";
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("The type is not renderable");
|
||||
}
|
||||
} else {
|
||||
throw new IllegalArgumentException("The type is not renderable");
|
||||
}
|
||||
|
||||
for (int i = 0; i < arrayCount; ++i) {
|
||||
value = "$rt_arraycls(" + value + ")";
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public String pointerName() {
|
||||
return minifying ? "$p" : "$ptr";
|
||||
}
|
||||
|
||||
public String mainLoopName() {
|
||||
return minifying ? "$m" : "$main";
|
||||
}
|
||||
|
||||
public String tempVarName() {
|
||||
return minifying ? "$z" : "$tmp";
|
||||
}
|
||||
|
||||
public String threadName() {
|
||||
return minifying ? "$T" : "$thread";
|
||||
}
|
||||
|
||||
private static class LocationStackEntry {
|
||||
final TextLocation location;
|
||||
|
||||
LocationStackEntry(TextLocation location) {
|
||||
this.location = location;
|
||||
}
|
||||
}
|
||||
|
||||
public void addInjector(MethodReference method, Injector injector) {
|
||||
injectorMap.put(method, new InjectorHolder(injector));
|
||||
}
|
||||
|
||||
public Injector getInjector(MethodReference ref) {
|
||||
InjectorHolder holder = injectorMap.get(ref);
|
||||
if (holder == null) {
|
||||
holder = new InjectorHolder(null);
|
||||
ClassReader cls = classSource.get(ref.getClassName());
|
||||
if (cls != null) {
|
||||
MethodReader method = cls.getMethod(ref.getDescriptor());
|
||||
if (method != null) {
|
||||
AnnotationReader injectedByAnnot = method.getAnnotations().get(InjectedBy.class.getName());
|
||||
if (injectedByAnnot != null) {
|
||||
ValueType type = injectedByAnnot.getValue("value").getJavaClass();
|
||||
holder = new InjectorHolder(instantiateInjector(((ValueType.Object) type).getClassName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
injectorMap.put(ref, holder);
|
||||
}
|
||||
return holder.injector;
|
||||
}
|
||||
|
||||
private Injector instantiateInjector(String type) {
|
||||
try {
|
||||
Class<? extends Injector> cls = Class.forName(type, true, classLoader).asSubclass(Injector.class);
|
||||
Constructor<? extends Injector> cons = cls.getConstructor();
|
||||
return cons.newInstance();
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException("Illegal injector: " + type, e);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new RuntimeException("Default constructor was not found in the " + type + " injector", e);
|
||||
} catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {
|
||||
throw new RuntimeException("Error instantiating injector " + type, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class InjectorHolder {
|
||||
public final Injector injector;
|
||||
|
||||
private InjectorHolder(Injector injector) {
|
||||
this.injector = injector;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2016 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.backend.javascript.rendering;
|
||||
|
||||
import java.util.Properties;
|
||||
import org.teavm.backend.javascript.codegen.NamingStrategy;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
import org.teavm.common.ServiceRepository;
|
||||
import org.teavm.model.ListableClassReaderSource;
|
||||
|
||||
public interface RenderingManager extends ServiceRepository {
|
||||
NamingStrategy getNaming();
|
||||
|
||||
SourceWriter getWriter();
|
||||
|
||||
boolean isMinifying();
|
||||
|
||||
ListableClassReaderSource getClassSource();
|
||||
|
||||
ClassLoader getClassLoader();
|
||||
|
||||
Properties getProperties();
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 2016 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.backend.javascript.rendering;
|
||||
|
||||
public final class RenderingUtil {
|
||||
public static final String variableNames = "abcdefghijkmnopqrstuvwxyz";
|
||||
public static final String variablePartNames = "abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
private RenderingUtil() {
|
||||
}
|
||||
|
||||
public static String escapeName(String name) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < name.length(); ++i) {
|
||||
char c = name.charAt(i);
|
||||
sb.append(Character.isJavaIdentifierPart(c) ? c : '_');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String escapeString(String str) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < str.length(); ++i) {
|
||||
char c = str.charAt(i);
|
||||
switch (c) {
|
||||
case '\r':
|
||||
sb.append("\\r");
|
||||
break;
|
||||
case '\n':
|
||||
sb.append("\\n");
|
||||
break;
|
||||
case '\t':
|
||||
sb.append("\\t");
|
||||
break;
|
||||
case '\'':
|
||||
sb.append("\\'");
|
||||
break;
|
||||
case '\"':
|
||||
sb.append("\\\"");
|
||||
break;
|
||||
case '\\':
|
||||
sb.append("\\\\");
|
||||
break;
|
||||
default:
|
||||
if (c < ' ') {
|
||||
sb.append("\\u00").append(Character.forDigit(c / 16, 16))
|
||||
.append(Character.forDigit(c % 16, 16));
|
||||
} else if (Character.isLowSurrogate(c) || Character.isHighSurrogate(c)) {
|
||||
sb.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 {
|
||||
sb.append(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String indexToId(int index) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
do {
|
||||
sb.append(variablePartNames.charAt(index % variablePartNames.length()));
|
||||
index /= variablePartNames.length();
|
||||
} while (index > 0);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -20,11 +20,8 @@ import org.teavm.common.ServiceRepository;
|
|||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.model.ListableClassReaderSource;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface GeneratorContext extends ServiceRepository {
|
||||
String getParameterName(int index);
|
||||
|
||||
|
@ -41,4 +38,6 @@ public interface GeneratorContext extends ServiceRepository {
|
|||
boolean isAsyncFamily(MethodReference method);
|
||||
|
||||
Diagnostics getDiagnostics();
|
||||
|
||||
String typeToClassString(ValueType type);
|
||||
}
|
||||
|
|
|
@ -16,16 +16,12 @@
|
|||
package org.teavm.vm.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.teavm.backend.javascript.rendering.RenderingContext;
|
||||
import org.teavm.backend.javascript.rendering.RenderingManager;
|
||||
import org.teavm.vm.BuildTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public abstract class AbstractRendererListener implements RendererListener {
|
||||
@Override
|
||||
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
|
||||
public void begin(RenderingManager manager, BuildTarget buildTarget) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
package org.teavm.vm.spi;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.teavm.backend.javascript.rendering.RenderingContext;
|
||||
import org.teavm.backend.javascript.rendering.RenderingManager;
|
||||
import org.teavm.vm.BuildTarget;
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,7 @@ import org.teavm.vm.BuildTarget;
|
|||
* @author Alexey Andreev
|
||||
*/
|
||||
public interface RendererListener {
|
||||
void begin(RenderingContext context, BuildTarget buildTarget) throws IOException;
|
||||
void begin(RenderingManager context, BuildTarget buildTarget) throws IOException;
|
||||
|
||||
void complete() throws IOException;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,17 @@ import java.util.List;
|
|||
import net.java.html.js.JavaScriptBody;
|
||||
import org.teavm.backend.javascript.codegen.NamingStrategy;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
import org.teavm.backend.javascript.rendering.Renderer;
|
||||
import org.teavm.backend.javascript.spi.Generator;
|
||||
import org.teavm.backend.javascript.spi.GeneratorContext;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.model.AnnotationReader;
|
||||
import org.teavm.model.AnnotationValue;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
import org.teavm.model.ElementModifier;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
|
||||
public class JavaScriptBodyGenerator implements Generator {
|
||||
@Override
|
||||
|
@ -35,7 +42,8 @@ public class JavaScriptBodyGenerator implements Generator {
|
|||
List<AnnotationValue> args = annot.getValue("args").getList();
|
||||
AnnotationValue javacall = annot.getValue("javacall");
|
||||
if (javacall != null && javacall.getBoolean()) {
|
||||
GeneratorJsCallback callbackGen = new GeneratorJsCallback(context.getClassSource(), writer.getNaming());
|
||||
GeneratorJsCallback callbackGen = new GeneratorJsCallback(context, context.getClassSource(),
|
||||
writer.getNaming());
|
||||
body = callbackGen.parse(body);
|
||||
}
|
||||
writer.append("var result = (function(");
|
||||
|
@ -55,7 +63,7 @@ public class JavaScriptBodyGenerator implements Generator {
|
|||
}
|
||||
writer.append(");").softNewLine();
|
||||
writer.append("return ");
|
||||
unwrapValue(writer, method.getResultType(), "result");
|
||||
unwrapValue(context, writer, method.getResultType(), "result");
|
||||
writer.append(";").softNewLine();
|
||||
}
|
||||
|
||||
|
@ -64,16 +72,19 @@ public class JavaScriptBodyGenerator implements Generator {
|
|||
writer.append("(").append(param).append(")");
|
||||
}
|
||||
|
||||
private void unwrapValue(SourceWriter writer, ValueType type, String param) throws IOException {
|
||||
private void unwrapValue(GeneratorContext context, SourceWriter writer, ValueType type, String param)
|
||||
throws IOException {
|
||||
writer.appendMethodBody(JavaScriptConvGenerator.fromJsMethod);
|
||||
writer.append("(").append(param).append(",").ws().append(Renderer.typeToClsString(writer.getNaming(), type))
|
||||
writer.append("(").append(param).append(",").ws().append(context.typeToClassString(type))
|
||||
.append(")");
|
||||
}
|
||||
|
||||
private static class GeneratorJsCallback extends JsCallback {
|
||||
private GeneratorContext context;
|
||||
private ClassReaderSource classSource;
|
||||
private NamingStrategy naming;
|
||||
public GeneratorJsCallback(ClassReaderSource classSource, NamingStrategy naming) {
|
||||
public GeneratorJsCallback(GeneratorContext context, ClassReaderSource classSource, NamingStrategy naming) {
|
||||
this.context = context;
|
||||
this.classSource = classSource;
|
||||
this.naming = naming;
|
||||
}
|
||||
|
@ -105,7 +116,7 @@ public class JavaScriptBodyGenerator implements Generator {
|
|||
ValueType paramType = simplifyParamType(reader.parameterType(i));
|
||||
sb.append(naming.getFullNameFor(JavaScriptConvGenerator.fromJsMethod)).append("(p").append(i)
|
||||
.append(", ")
|
||||
.append(Renderer.typeToClsString(naming, paramType)).append(")");
|
||||
.append(context.typeToClassString(paramType)).append(")");
|
||||
}
|
||||
sb.append(")); })(");
|
||||
if (ident != null) {
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.io.InputStream;
|
|||
import java.io.StringWriter;
|
||||
import net.java.html.js.JavaScriptResource;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.teavm.backend.javascript.rendering.RenderingContext;
|
||||
import org.teavm.backend.javascript.rendering.RenderingManager;
|
||||
import org.teavm.model.AnnotationReader;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.vm.BuildTarget;
|
||||
|
@ -29,10 +29,10 @@ import org.teavm.vm.spi.AbstractRendererListener;
|
|||
|
||||
public class JavaScriptResourceInterceptor extends AbstractRendererListener {
|
||||
@Override
|
||||
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
|
||||
public void begin(RenderingManager manager, BuildTarget buildTarget) throws IOException {
|
||||
boolean hasOneResource = false;
|
||||
for (String className : context.getClassSource().getClassNames()) {
|
||||
ClassReader cls = context.getClassSource().get(className);
|
||||
for (String className : manager.getClassSource().getClassNames()) {
|
||||
ClassReader cls = manager.getClassSource().get(className);
|
||||
AnnotationReader annot = cls.getAnnotations().get(JavaScriptResource.class.getName());
|
||||
if (annot == null) {
|
||||
continue;
|
||||
|
@ -40,7 +40,7 @@ public class JavaScriptResourceInterceptor extends AbstractRendererListener {
|
|||
String path = annot.getValue("value").getString();
|
||||
String packageName = className.substring(0, className.lastIndexOf('.'));
|
||||
String resourceName = packageName.replace('.', '/') + "/" + path;
|
||||
try (InputStream input = context.getClassLoader().getResourceAsStream(resourceName)) {
|
||||
try (InputStream input = manager.getClassLoader().getResourceAsStream(resourceName)) {
|
||||
if (input == null) {
|
||||
throw new RenderingException("Error processing JavaScriptResource annotation on class "
|
||||
+ className + ". Resource not found: " + resourceName);
|
||||
|
@ -48,13 +48,13 @@ public class JavaScriptResourceInterceptor extends AbstractRendererListener {
|
|||
StringWriter writer = new StringWriter();
|
||||
IOUtils.copy(input, writer);
|
||||
writer.close();
|
||||
context.getWriter().append("// Resource " + path + " included by " + className).newLine();
|
||||
context.getWriter().append(writer.toString()).newLine().newLine();
|
||||
manager.getWriter().append("// Resource " + path + " included by " + className).newLine();
|
||||
manager.getWriter().append(writer.toString()).newLine().newLine();
|
||||
}
|
||||
hasOneResource = true;
|
||||
}
|
||||
if (hasOneResource) {
|
||||
context.getWriter().append("// TeaVM generated classes").newLine();
|
||||
manager.getWriter().append("// TeaVM generated classes").newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import java.util.HashSet;
|
|||
import java.util.Set;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
import org.teavm.backend.javascript.rendering.RenderingContext;
|
||||
import org.teavm.backend.javascript.rendering.RenderingManager;
|
||||
import org.teavm.vm.BuildTarget;
|
||||
import org.teavm.vm.spi.AbstractRendererListener;
|
||||
|
||||
|
@ -34,16 +34,16 @@ import org.teavm.vm.spi.AbstractRendererListener;
|
|||
public class ResourcesInterceptor extends AbstractRendererListener {
|
||||
private final Set<String> processed = new HashSet<>();
|
||||
@Override
|
||||
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
|
||||
public void begin(RenderingManager manager, BuildTarget buildTarget) throws IOException {
|
||||
boolean hasOneResource = false;
|
||||
for (String className : context.getClassSource().getClassNames()) {
|
||||
for (String className : manager.getClassSource().getClassNames()) {
|
||||
final int lastDot = className.lastIndexOf('.');
|
||||
if (lastDot == -1) {
|
||||
continue;
|
||||
}
|
||||
String packageName = className.substring(0, lastDot);
|
||||
String resourceName = packageName.replace('.', '/') + "/" + "jvm.txt";
|
||||
try (InputStream input = context.getClassLoader().getResourceAsStream(resourceName)) {
|
||||
try (InputStream input = manager.getClassLoader().getResourceAsStream(resourceName)) {
|
||||
if (input == null || !processed.add(resourceName)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public class ResourcesInterceptor extends AbstractRendererListener {
|
|||
IOUtils.copy(input, arr);
|
||||
String base64 = Base64.getEncoder().encodeToString(arr.toByteArray());
|
||||
input.close();
|
||||
final SourceWriter w = context.getWriter();
|
||||
final SourceWriter w = manager.getWriter();
|
||||
w.append("// Resource " + resourceName + " included by " + className).newLine();
|
||||
w.append("if (!window.teaVMResources) window.teaVMResources = {};").newLine();
|
||||
w.append("window.teaVMResources['" + resourceName + "'] = '");
|
||||
|
@ -60,7 +60,7 @@ public class ResourcesInterceptor extends AbstractRendererListener {
|
|||
hasOneResource = true;
|
||||
}
|
||||
if (hasOneResource) {
|
||||
context.getWriter().append("// TeaVM generated classes").newLine();
|
||||
manager.getWriter().append("// TeaVM generated classes").newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ package org.teavm.jso.impl;
|
|||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
import org.teavm.backend.javascript.rendering.RenderingContext;
|
||||
import org.teavm.backend.javascript.rendering.RenderingManager;
|
||||
import org.teavm.jso.impl.JSDependencyListener.ExposedClass;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.ClassReaderSource;
|
||||
|
@ -41,7 +41,7 @@ class JSAliasRenderer implements RendererListener {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
|
||||
public void begin(RenderingManager context, BuildTarget buildTarget) throws IOException {
|
||||
writer = context.getWriter();
|
||||
classSource = context.getClassSource();
|
||||
}
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
*/
|
||||
package org.teavm.jso.impl;
|
||||
|
||||
import static org.teavm.backend.javascript.rendering.RenderingUtil.escapeString;
|
||||
import java.io.IOException;
|
||||
import org.teavm.ast.ConstantExpr;
|
||||
import org.teavm.ast.Expr;
|
||||
import org.teavm.ast.InvocationExpr;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
import org.teavm.backend.javascript.rendering.Precedence;
|
||||
import org.teavm.backend.javascript.rendering.Renderer;
|
||||
import org.teavm.backend.javascript.spi.Generator;
|
||||
import org.teavm.backend.javascript.spi.GeneratorContext;
|
||||
import org.teavm.backend.javascript.spi.Injector;
|
||||
|
@ -122,7 +122,7 @@ public class JSNativeGenerator implements Injector, DependencyPlugin, Generator
|
|||
if (context.getArgument(0) instanceof ConstantExpr) {
|
||||
ConstantExpr constant = (ConstantExpr) context.getArgument(0);
|
||||
if (constant.getValue() instanceof String) {
|
||||
writer.append('"').append(Renderer.escapeString((String) constant.getValue())).append('"');
|
||||
writer.append('"').append(escapeString((String) constant.getValue())).append('"');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,10 +20,16 @@ import java.lang.reflect.Constructor;
|
|||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Map;
|
||||
import org.teavm.backend.javascript.codegen.SourceWriter;
|
||||
import org.teavm.backend.javascript.rendering.Renderer;
|
||||
import org.teavm.backend.javascript.rendering.RenderingUtil;
|
||||
import org.teavm.backend.javascript.spi.Generator;
|
||||
import org.teavm.backend.javascript.spi.GeneratorContext;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.model.AnnotationReader;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.ElementModifier;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.ValueType;
|
||||
import org.teavm.platform.metadata.ClassScopedMetadataGenerator;
|
||||
import org.teavm.platform.metadata.ClassScopedMetadataProvider;
|
||||
import org.teavm.platform.metadata.Resource;
|
||||
|
@ -80,7 +86,7 @@ public class ClassScopedMetadataProviderNativeGenerator implements Generator {
|
|||
context.getClassLoader(), context.getProperties(), context);
|
||||
|
||||
Map<String, Resource> resourceMap = generator.generateMetadata(metadataContext, methodRef);
|
||||
writer.append("var p").ws().append("=").ws().append("\"" + Renderer.escapeString("$$res_"
|
||||
writer.append("var p").ws().append("=").ws().append("\"" + RenderingUtil.escapeString("$$res_"
|
||||
+ writer.getNaming().getFullNameFor(methodRef)) + "\"").append(";").softNewLine();
|
||||
for (Map.Entry<String, Resource> entry : resourceMap.entrySet()) {
|
||||
writer.appendClass(entry.getKey()).append("[p]").ws().append("=").ws();
|
||||
|
|
|
@ -34,7 +34,7 @@ import java.util.Properties;
|
|||
import java.util.Set;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.teavm.backend.javascript.JavaScriptTarget;
|
||||
import org.teavm.backend.javascript.rendering.RenderingContext;
|
||||
import org.teavm.backend.javascript.rendering.RenderingManager;
|
||||
import org.teavm.backend.wasm.WasmTarget;
|
||||
import org.teavm.cache.DiskCachedClassHolderSource;
|
||||
import org.teavm.cache.DiskProgramCache;
|
||||
|
@ -525,11 +525,11 @@ public class TeaVMTool implements BaseTeaVMTool {
|
|||
|
||||
private AbstractRendererListener runtimeInjector = new AbstractRendererListener() {
|
||||
@Override
|
||||
public void begin(RenderingContext context, BuildTarget buildTarget) throws IOException {
|
||||
public void begin(RenderingManager manager, BuildTarget buildTarget) throws IOException {
|
||||
StringWriter writer = new StringWriter();
|
||||
resourceToWriter("org/teavm/backend/javascript/runtime.js", writer);
|
||||
writer.close();
|
||||
context.getWriter().append(writer.toString()).newLine();
|
||||
manager.getWriter().append(writer.toString()).newLine();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user