mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Start eliminating JavaScript generators in classlib in favour of calling
Platform and JSO
This commit is contained in:
parent
3b1d6851a4
commit
d93fa6cf41
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.classlib.impl;
|
||||||
|
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.platform.metadata.MetadataGenerator;
|
||||||
|
import org.teavm.platform.metadata.MetadataGeneratorContext;
|
||||||
|
import org.teavm.platform.metadata.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public class DeclaringClassMetadataGenerator implements MetadataGenerator {
|
||||||
|
@Override
|
||||||
|
public Resource generateMetadata(MetadataGeneratorContext context, MethodReference method) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -31,7 +31,6 @@ public class JCLPlugin implements TeaVMPlugin {
|
||||||
host.add(new EnumDependencySupport());
|
host.add(new EnumDependencySupport());
|
||||||
host.add(new EnumTransformer());
|
host.add(new EnumTransformer());
|
||||||
host.add(new ClassLookupDependencySupport());
|
host.add(new ClassLookupDependencySupport());
|
||||||
host.add(new NewInstanceDependencySupport());
|
|
||||||
host.add(new ObjectEnrichRenderer());
|
host.add(new ObjectEnrichRenderer());
|
||||||
ServiceLoaderSupport serviceLoaderSupp = new ServiceLoaderSupport(host.getClassLoader());
|
ServiceLoaderSupport serviceLoaderSupp = new ServiceLoaderSupport(host.getClassLoader());
|
||||||
host.add(serviceLoaderSupp);
|
host.add(serviceLoaderSupp);
|
||||||
|
|
|
@ -35,75 +35,18 @@ public class ClassNativeGenerator implements Generator, Injector, DependencyPlug
|
||||||
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef)
|
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
switch (methodRef.getName()) {
|
switch (methodRef.getName()) {
|
||||||
case "getComponentType0":
|
|
||||||
generateGetComponentType(context, writer);
|
|
||||||
break;
|
|
||||||
case "getSuperclass":
|
|
||||||
generateGetSuperclass(context, writer);
|
|
||||||
break;
|
|
||||||
case "forNameImpl":
|
case "forNameImpl":
|
||||||
generateForName(context, writer);
|
generateForName(context, writer);
|
||||||
break;
|
break;
|
||||||
case "newInstance":
|
|
||||||
generateNewInstance(context, writer);
|
|
||||||
break;
|
|
||||||
case "getDeclaringClass":
|
case "getDeclaringClass":
|
||||||
generateGetDeclaringClass(context, writer);
|
generateGetDeclaringClass(context, writer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateGetComponentType(GeneratorContext context, SourceWriter writer) throws IOException {
|
|
||||||
String thisArg = context.getParameterName(0);
|
|
||||||
writer.append("var item = " + thisArg + ".$data.$meta.item;").softNewLine();
|
|
||||||
writer.append("return item != null ? $rt_cls(item) : null;").softNewLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateGetSuperclass(GeneratorContext context, SourceWriter writer) throws IOException {
|
|
||||||
String thisArg = context.getParameterName(0);
|
|
||||||
writer.append("var superclass = " + thisArg + ".$data.$meta.superclass;").softNewLine();
|
|
||||||
writer.append("return superclass ? $rt_cls(superclass) : null;").softNewLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(InjectorContext context, MethodReference methodRef) throws IOException {
|
public void generate(InjectorContext context, MethodReference methodRef) throws IOException {
|
||||||
switch (methodRef.getName()) {
|
switch (methodRef.getName()) {
|
||||||
case "isInstance":
|
|
||||||
generateIsInstance(context);
|
|
||||||
break;
|
|
||||||
case "isAssignableFrom":
|
|
||||||
generateIsAssignableFrom(context);
|
|
||||||
break;
|
|
||||||
case "voidClass":
|
|
||||||
context.getWriter().append("$rt_cls($rt_voidcls())");
|
|
||||||
break;
|
|
||||||
case "booleanClass":
|
|
||||||
context.getWriter().append("$rt_cls($rt_booleancls())");
|
|
||||||
break;
|
|
||||||
case "charClass":
|
|
||||||
context.getWriter().append("$rt_cls($rt_charcls())");
|
|
||||||
break;
|
|
||||||
case "byteClass":
|
|
||||||
context.getWriter().append("$rt_cls($rt_bytecls())");
|
|
||||||
break;
|
|
||||||
case "shortClass":
|
|
||||||
context.getWriter().append("$rt_cls($rt_shortcls())");
|
|
||||||
break;
|
|
||||||
case "intClass":
|
|
||||||
context.getWriter().append("$rt_cls($rt_intcls())");
|
|
||||||
break;
|
|
||||||
case "longClass":
|
|
||||||
context.getWriter().append("$rt_cls($rt_longcls())");
|
|
||||||
break;
|
|
||||||
case "floatClass":
|
|
||||||
context.getWriter().append("$rt_cls($rt_floatcls())");
|
|
||||||
break;
|
|
||||||
case "doubleClass":
|
|
||||||
context.getWriter().append("$rt_cls($rt_doublecls())");
|
|
||||||
break;
|
|
||||||
case "wrapClass":
|
|
||||||
context.writeExpr(context.getArgument(0));
|
|
||||||
break;
|
|
||||||
case "getEnumConstantsImpl":
|
case "getEnumConstantsImpl":
|
||||||
context.writeExpr(context.getArgument(0));
|
context.writeExpr(context.getArgument(0));
|
||||||
context.getWriter().append(".$data.values()");
|
context.getWriter().append(".$data.values()");
|
||||||
|
@ -111,24 +54,6 @@ public class ClassNativeGenerator implements Generator, Injector, DependencyPlug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateIsAssignableFrom(InjectorContext context) throws IOException {
|
|
||||||
SourceWriter writer = context.getWriter();
|
|
||||||
writer.append("$rt_isAssignable(");
|
|
||||||
context.writeExpr(context.getArgument(1));
|
|
||||||
writer.append(".$data,").ws();
|
|
||||||
context.writeExpr(context.getArgument(0));
|
|
||||||
writer.append(".$data)");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateIsInstance(InjectorContext context) throws IOException {
|
|
||||||
SourceWriter writer = context.getWriter();
|
|
||||||
writer.append("$rt_isInstance(");
|
|
||||||
context.writeExpr(context.getArgument(1));
|
|
||||||
writer.append(",").ws();
|
|
||||||
context.writeExpr(context.getArgument(0));
|
|
||||||
writer.append(".$data)");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateForName(GeneratorContext context, SourceWriter writer) throws IOException {
|
private void generateForName(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||||
String param = context.getParameterName(1);
|
String param = context.getParameterName(1);
|
||||||
writer.append("switch ($rt_ustr(" + param + ")) {").softNewLine().indent();
|
writer.append("switch ($rt_ustr(" + param + ")) {").softNewLine().indent();
|
||||||
|
@ -140,32 +65,6 @@ public class ClassNativeGenerator implements Generator, Injector, DependencyPlug
|
||||||
writer.outdent().append("}").softNewLine();
|
writer.outdent().append("}").softNewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateNewInstance(GeneratorContext context, SourceWriter writer) throws IOException {
|
|
||||||
String self = context.getParameterName(0);
|
|
||||||
writer.append("if (!").appendClass("java.lang.Class").append(".$$constructors$$) {").indent().softNewLine();
|
|
||||||
writer.appendClass("java.lang.Class").append(".$$constructors$$ = true;").softNewLine();
|
|
||||||
for (String clsName : context.getClassSource().getClassNames()) {
|
|
||||||
ClassReader cls = context.getClassSource().get(clsName);
|
|
||||||
MethodReader method = cls.getMethod(new MethodDescriptor("<init>", ValueType.VOID));
|
|
||||||
if (method != null) {
|
|
||||||
writer.appendClass(clsName).append(".$$constructor$$ = ").appendMethodBody(method.getReference())
|
|
||||||
.append(";").softNewLine();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
writer.outdent().append("}").softNewLine();
|
|
||||||
writer.append("var cls = " + self + ".$data;").softNewLine();
|
|
||||||
writer.append("var ctor = cls.$$constructor$$;").softNewLine();
|
|
||||||
writer.append("if (!ctor) {").indent().softNewLine();
|
|
||||||
writer.append("var ex = new ").appendClass(InstantiationException.class.getName()).append("();").softNewLine();
|
|
||||||
writer.appendMethodBody(new MethodReference(InstantiationException.class.getName(), new MethodDescriptor(
|
|
||||||
"<init>", ValueType.VOID))).append("(ex);").softNewLine();
|
|
||||||
writer.append("$rt_throw(ex);").softNewLine();
|
|
||||||
writer.outdent().append("}").softNewLine();
|
|
||||||
writer.append("var instance = new cls();").softNewLine();
|
|
||||||
writer.append("ctor(instance);").softNewLine();
|
|
||||||
writer.append("return instance;").softNewLine();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void generateGetDeclaringClass(GeneratorContext context, SourceWriter writer) throws IOException {
|
private void generateGetDeclaringClass(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||||
String self = context.getParameterName(0);
|
String self = context.getParameterName(0);
|
||||||
writer.append("if (!").appendClass("java.lang.Class").append(".$$owners$$) {").indent().softNewLine();
|
writer.append("if (!").appendClass("java.lang.Class").append(".$$owners$$) {").indent().softNewLine();
|
||||||
|
@ -188,25 +87,10 @@ public class ClassNativeGenerator implements Generator, Injector, DependencyPlug
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(DependencyAgent agent, MethodDependency graph, CallLocation location) {
|
public void methodAchieved(DependencyAgent agent, MethodDependency graph, CallLocation location) {
|
||||||
switch (graph.getReference().getName()) {
|
switch (graph.getReference().getName()) {
|
||||||
case "voidClass":
|
|
||||||
case "booleanClass":
|
|
||||||
case "byteClass":
|
|
||||||
case "shortClass":
|
|
||||||
case "charClass":
|
|
||||||
case "intClass":
|
|
||||||
case "longClass":
|
|
||||||
case "floatClass":
|
|
||||||
case "doubleClass":
|
|
||||||
case "wrapClass":
|
|
||||||
case "getSuperclass":
|
|
||||||
case "getComponentType0":
|
|
||||||
case "forNameImpl":
|
case "forNameImpl":
|
||||||
case "getDeclaringClass":
|
case "getDeclaringClass":
|
||||||
graph.getResult().propagate(agent.getType("java.lang.Class"));
|
graph.getResult().propagate(agent.getType("java.lang.Class"));
|
||||||
break;
|
break;
|
||||||
case "getName":
|
|
||||||
graph.getResult().propagate(agent.getType("java.lang.String"));
|
|
||||||
break;
|
|
||||||
case "newInstance":
|
case "newInstance":
|
||||||
agent.linkMethod(new MethodReference(InstantiationException.class, "<init>", void.class),
|
agent.linkMethod(new MethodReference(InstantiationException.class, "<init>", void.class),
|
||||||
location).use();
|
location).use();
|
||||||
|
|
|
@ -15,9 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.classlib.java.lang;
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
import org.teavm.dependency.PluggableDependency;
|
import org.teavm.classlib.impl.DeclaringClassMetadataGenerator;
|
||||||
import org.teavm.javascript.spi.GeneratedBy;
|
|
||||||
import org.teavm.javascript.spi.InjectedBy;
|
import org.teavm.javascript.spi.InjectedBy;
|
||||||
|
import org.teavm.platform.Platform;
|
||||||
|
import org.teavm.platform.PlatformClass;
|
||||||
|
import org.teavm.platform.metadata.MetadataProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -25,102 +27,122 @@ import org.teavm.javascript.spi.InjectedBy;
|
||||||
*/
|
*/
|
||||||
public class TClass<T> extends TObject {
|
public class TClass<T> extends TObject {
|
||||||
TString name;
|
TString name;
|
||||||
TString binaryName;
|
|
||||||
boolean primitive;
|
|
||||||
boolean array;
|
|
||||||
boolean isEnum;
|
|
||||||
private TClass<?> componentType;
|
private TClass<?> componentType;
|
||||||
private boolean componentTypeDirty = true;
|
private boolean componentTypeDirty = true;
|
||||||
|
private PlatformClass platformClass;
|
||||||
|
|
||||||
static TClass<?> createNew() {
|
private TClass(PlatformClass platformClass) {
|
||||||
return new TClass<>();
|
this.platformClass = platformClass;
|
||||||
|
platformClass.setJavaClass(Platform.getPlatformObject(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
static TClass<?> getClass(PlatformClass cls) {
|
||||||
public native boolean isInstance(TObject obj);
|
if (cls == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
TClass<?> result = (TClass<?>)(Object)Platform.asJavaClass(cls.getJavaClass());
|
||||||
|
if (result == null) {
|
||||||
|
result = new TClass<>(cls);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
PlatformClass getPlatformClass() {
|
||||||
public native boolean isAssignableFrom(TClass<?> obj);
|
return platformClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInstance(TObject obj) {
|
||||||
|
return Platform.isInstance(Platform.getPlatformObject(obj), platformClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAssignableFrom(TClass<?> obj) {
|
||||||
|
return Platform.isAssignable(obj.getPlatformClass(), platformClass);
|
||||||
|
}
|
||||||
|
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
|
||||||
public TString getName() {
|
public TString getName() {
|
||||||
|
if (name == null) {
|
||||||
|
name = TString.wrap(platformClass.getMetadata().getName());
|
||||||
|
}
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPrimitive() {
|
public boolean isPrimitive() {
|
||||||
return primitive;
|
return platformClass.getMetadata().isPrimitive();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isArray() {
|
public boolean isArray() {
|
||||||
return array;
|
return platformClass.getMetadata().isArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEnum() {
|
public boolean isEnum() {
|
||||||
return isEnum;
|
return platformClass.getMetadata().isEnum();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TClass<?> getComponentType() {
|
public TClass<?> getComponentType() {
|
||||||
if (componentTypeDirty) {
|
if (componentTypeDirty) {
|
||||||
componentType = getComponentType0();
|
PlatformClass arrayItem = platformClass.getMetadata().getArrayItem();
|
||||||
|
componentType = arrayItem != null ? getClass(arrayItem) : null;
|
||||||
componentTypeDirty = false;
|
componentTypeDirty = false;
|
||||||
}
|
}
|
||||||
return componentType;
|
return componentType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GeneratedBy(ClassNativeGenerator.class)
|
@SuppressWarnings("unchecked")
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
static TClass<TVoid> voidClass() {
|
||||||
private native TClass<?> getComponentType0();
|
return (TClass<TVoid>)getClass(Platform.getPrimitives().getVoidClass());
|
||||||
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
@SuppressWarnings("unchecked")
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
static TClass<TBoolean> booleanClass() {
|
||||||
static native TClass<TVoid> voidClass();
|
return (TClass<TBoolean>)getClass(Platform.getPrimitives().getBooleanClass());
|
||||||
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
@SuppressWarnings("unchecked")
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
static TClass<TCharacter> charClass() {
|
||||||
static native TClass<TBoolean> booleanClass();
|
return (TClass<TCharacter>)getClass(Platform.getPrimitives().getCharClass());
|
||||||
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
@SuppressWarnings("unchecked")
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
static TClass<TByte> byteClass() {
|
||||||
static native TClass<TCharacter> charClass();
|
return (TClass<TByte>)getClass(Platform.getPrimitives().getByteClass());
|
||||||
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
@SuppressWarnings("unchecked")
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
static TClass<TShort> shortClass() {
|
||||||
static native TClass<TByte> byteClass();
|
return (TClass<TShort>)getClass(Platform.getPrimitives().getShortClass());
|
||||||
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
@SuppressWarnings("unchecked")
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
static TClass<TInteger> intClass() {
|
||||||
static native TClass<TShort> shortClass();
|
return (TClass<TInteger>)getClass(Platform.getPrimitives().getIntClass());
|
||||||
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
@SuppressWarnings("unchecked")
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
static TClass<TLong> longClass() {
|
||||||
static native TClass<TInteger> intClass();
|
return (TClass<TLong>)getClass(Platform.getPrimitives().getLongClass());
|
||||||
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
@SuppressWarnings("unchecked")
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
static TClass<TFloat> floatClass() {
|
||||||
static native TClass<TLong> longClass();
|
return (TClass<TFloat>)getClass(Platform.getPrimitives().getFloatClass());
|
||||||
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
@SuppressWarnings("unchecked")
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
static TClass<TDouble> doubleClass() {
|
||||||
static native TClass<TFloat> floatClass();
|
return (TClass<TDouble>)getClass(Platform.getPrimitives().getDoubleClass());
|
||||||
|
}
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
|
||||||
static native TClass<TDouble> doubleClass();
|
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
|
||||||
public static native <S extends TObject> TClass<S> wrapClass(Class<S> cls);
|
|
||||||
|
|
||||||
public boolean desiredAssertionStatus() {
|
public boolean desiredAssertionStatus() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GeneratedBy(ClassNativeGenerator.class)
|
@SuppressWarnings("unchecked")
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
public TClass<? super T> getSuperclass() {
|
||||||
public native TClass<? super T> getSuperclass();
|
return (TClass<? super T>)getClass(platformClass.getMetadata().getSuperclass());
|
||||||
|
}
|
||||||
|
|
||||||
public T[] getEnumConstants() {
|
public T[] getEnumConstants() {
|
||||||
return isEnum ? getEnumConstantsImpl() : null;
|
return isEnum() ? getEnumConstantsImpl() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@InjectedBy(ClassNativeGenerator.class)
|
@InjectedBy(ClassNativeGenerator.class)
|
||||||
|
@ -128,10 +150,9 @@ public class TClass<T> extends TObject {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public T cast(TObject obj) {
|
public T cast(TObject obj) {
|
||||||
if (obj != null && !isAssignableFrom(TClass.wrapClass(obj.getClass()))) {
|
if (obj != null && !isAssignableFrom((TClass<?>)(Object)obj.getClass())) {
|
||||||
throw new TClassCastException(TString.wrap(new TStringBuilder()
|
throw new TClassCastException(TString.wrap(obj.getClass().getName() +
|
||||||
.append(TClass.wrapClass(obj.getClass()).getName())
|
" is not subtype of " + name));
|
||||||
.append(TString.wrap(" is not subtype of ")).append(name).toString()));
|
|
||||||
}
|
}
|
||||||
return (T)obj;
|
return (T)obj;
|
||||||
}
|
}
|
||||||
|
@ -140,30 +161,25 @@ public class TClass<T> extends TObject {
|
||||||
return TClassLoader.getSystemClassLoader();
|
return TClassLoader.getSystemClassLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GeneratedBy(ClassNativeGenerator.class)
|
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
|
||||||
private static native TClass<?> forNameImpl(TString name);
|
|
||||||
|
|
||||||
public static TClass<?> forName(TString name) throws TClassNotFoundException {
|
public static TClass<?> forName(TString name) throws TClassNotFoundException {
|
||||||
TClass<?> result = forNameImpl(name);
|
PlatformClass cls = Platform.lookupClass(name.toString());
|
||||||
if (result == null) {
|
if (cls == null) {
|
||||||
throw new TClassNotFoundException();
|
throw new TClassNotFoundException();
|
||||||
}
|
}
|
||||||
return result;
|
return getClass(cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public static TClass<?> forName(TString name, boolean initialize, TClassLoader loader)
|
public static TClass<?> forName(TString name, boolean initialize, TClassLoader loader)
|
||||||
throws TClassNotFoundException {
|
throws TClassNotFoundException {
|
||||||
return forName(name);
|
return forName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GeneratedBy(ClassNativeGenerator.class)
|
public T newInstance() throws TInstantiationException, TIllegalAccessException {
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
return Platform.newInstance(platformClass);
|
||||||
public native T newInstance() throws TInstantiationException, TIllegalAccessException;
|
}
|
||||||
|
|
||||||
@GeneratedBy(ClassNativeGenerator.class)
|
@MetadataProvider(DeclaringClassMetadataGenerator.class)
|
||||||
@PluggableDependency(ClassNativeGenerator.class)
|
|
||||||
public native TClass<?> getDeclaringClass();
|
public native TClass<?> getDeclaringClass();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -61,7 +61,7 @@ public abstract class TEnum<E extends TEnum<E>> extends TObject implements TComp
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public final TClass<E> getDeclaringClass() {
|
public final TClass<E> getDeclaringClass() {
|
||||||
return (TClass<E>)TClass.wrapClass(getClass());
|
return (TClass<E>)(Object)getClass();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -103,6 +103,10 @@ public class SourceWriter implements Appendable, LocationProvider {
|
||||||
return append(naming.getNameFor(cls));
|
return append(naming.getNameFor(cls));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SourceWriter appendClass(Class<?> cls) throws NamingException, IOException {
|
||||||
|
return append(naming.getNameFor(cls.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
public SourceWriter appendField(FieldReference field) throws NamingException, IOException {
|
public SourceWriter appendField(FieldReference field) throws NamingException, IOException {
|
||||||
return append(naming.getNameFor(field));
|
return append(naming.getNameFor(field));
|
||||||
}
|
}
|
||||||
|
@ -113,7 +117,12 @@ public class SourceWriter implements Appendable, LocationProvider {
|
||||||
|
|
||||||
public SourceWriter appendMethod(String className, String name, ValueType... params)
|
public SourceWriter appendMethod(String className, String name, ValueType... params)
|
||||||
throws NamingException, IOException {
|
throws NamingException, IOException {
|
||||||
return append(naming.getNameFor(new MethodReference(className, new MethodDescriptor(name, params))));
|
return append(naming.getNameFor(new MethodReference(className, name, params)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SourceWriter appendMethod(Class<?> cls, String name, Class<?>... params)
|
||||||
|
throws NamingException, IOException {
|
||||||
|
return append(naming.getNameFor(new MethodReference(cls, name, params)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceWriter appendMethodBody(MethodReference method) throws NamingException, IOException {
|
public SourceWriter appendMethodBody(MethodReference method) throws NamingException, IOException {
|
||||||
|
@ -125,6 +134,11 @@ public class SourceWriter implements Appendable, LocationProvider {
|
||||||
return append(naming.getFullNameFor(new MethodReference(className, new MethodDescriptor(name, params))));
|
return append(naming.getFullNameFor(new MethodReference(className, new MethodDescriptor(name, params))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SourceWriter appendMethodBody(Class<?> cls, String name, Class<?>... params)
|
||||||
|
throws NamingException, IOException {
|
||||||
|
return append(naming.getFullNameFor(new MethodReference(cls, name, params)));
|
||||||
|
}
|
||||||
|
|
||||||
private void appendIndent() throws IOException {
|
private void appendIndent() throws IOException {
|
||||||
if (minified) {
|
if (minified) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -102,7 +102,7 @@ public final class JS {
|
||||||
public static native JSObject wrap(short num);
|
public static native JSObject wrap(short num);
|
||||||
|
|
||||||
@InjectedBy(JSNativeGenerator.class)
|
@InjectedBy(JSNativeGenerator.class)
|
||||||
public static native JSObject pass(Object obj);
|
public static native JSObject marshall(Object obj);
|
||||||
|
|
||||||
public static <T extends JSObject> JSArray<T> wrap(T[] array) {
|
public static <T extends JSObject> JSArray<T> wrap(T[] array) {
|
||||||
JSArray<T> result = createArray(array.length);
|
JSArray<T> result = createArray(array.length);
|
||||||
|
|
|
@ -35,6 +35,16 @@
|
||||||
<artifactId>teavm-core</artifactId>
|
<artifactId>teavm-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.teavm</groupId>
|
||||||
|
<artifactId>teavm-jso</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.teavm</groupId>
|
||||||
|
<artifactId>teavm-dom</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform;
|
||||||
|
|
||||||
|
import org.teavm.dependency.PluggableDependency;
|
||||||
|
import org.teavm.javascript.spi.GeneratedBy;
|
||||||
|
import org.teavm.javascript.spi.InjectedBy;
|
||||||
|
import org.teavm.jso.JS;
|
||||||
|
import org.teavm.platform.metadata.ClassResource;
|
||||||
|
import org.teavm.platform.plugin.PlatformGenerator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public final class Platform {
|
||||||
|
private Platform() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PlatformObject getPlatformObject(Object obj) {
|
||||||
|
return (PlatformObject)JS.marshall(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isInstance(PlatformObject obj, PlatformClass cls) {
|
||||||
|
return obj != null && !JS.isUndefined(obj.getPlatformClass().getMetadata()) &&
|
||||||
|
isAssignable(obj.getPlatformClass(), cls);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAssignable(PlatformClass from, PlatformClass to) {
|
||||||
|
if (from == to) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
PlatformSequence<PlatformClass> supertypes = from.getMetadata().getSupertypes();
|
||||||
|
for (int i = 0; i < supertypes.getLength(); ++i) {
|
||||||
|
if (isAssignable(supertypes.get(i), to)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@InjectedBy(PlatformGenerator.class)
|
||||||
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
|
public static native Class<?> asJavaClass(PlatformObject obj);
|
||||||
|
|
||||||
|
public static PlatformPrimitives getPrimitives() {
|
||||||
|
return (PlatformPrimitives)JS.getGlobal();
|
||||||
|
}
|
||||||
|
|
||||||
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
|
public static native <T> T newInstance(PlatformClass cls);
|
||||||
|
|
||||||
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
|
public static native PlatformClass lookupClass(String name);
|
||||||
|
|
||||||
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
|
public static native void initClass(PlatformClass cls);
|
||||||
|
|
||||||
|
@GeneratedBy(PlatformGenerator.class)
|
||||||
|
@PluggableDependency(PlatformGenerator.class)
|
||||||
|
public static native PlatformClass classFromResource(ClassResource resource);
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform;
|
||||||
|
|
||||||
|
import org.teavm.jso.JSObject;
|
||||||
|
import org.teavm.jso.JSProperty;
|
||||||
|
import org.teavm.platform.metadata.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public interface PlatformClass extends JSObject, Resource {
|
||||||
|
@JSProperty("$meta")
|
||||||
|
PlatformClassMetadata getMetadata();
|
||||||
|
|
||||||
|
@JSProperty("classObject")
|
||||||
|
void setJavaClass(PlatformObject obj);
|
||||||
|
|
||||||
|
@JSProperty("classObject")
|
||||||
|
PlatformObject getJavaClass();
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform;
|
||||||
|
|
||||||
|
import org.teavm.jso.JSObject;
|
||||||
|
import org.teavm.jso.JSProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public interface PlatformClassMetadata extends JSObject {
|
||||||
|
@JSProperty("item")
|
||||||
|
PlatformClass getArrayItem();
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
PlatformSequence<PlatformClass> getSupertypes();
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
PlatformClass getSuperclass();
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
boolean isPrimitive();
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
boolean isArray();
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
boolean isEnum();
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform;
|
||||||
|
|
||||||
|
import org.teavm.jso.JSObject;
|
||||||
|
import org.teavm.jso.JSProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public interface PlatformObject extends JSObject {
|
||||||
|
@JSProperty("constructor")
|
||||||
|
PlatformClass getPlatformClass();
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform;
|
||||||
|
|
||||||
|
import org.teavm.jso.JSObject;
|
||||||
|
import org.teavm.jso.JSProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public interface PlatformPrimitives extends JSObject {
|
||||||
|
@JSProperty("$rt_voidcls")
|
||||||
|
PlatformClass getVoidClass();
|
||||||
|
|
||||||
|
@JSProperty("$rt_booleancls")
|
||||||
|
PlatformClass getBooleanClass();
|
||||||
|
|
||||||
|
@JSProperty("$rt_bytecls")
|
||||||
|
PlatformClass getByteClass();
|
||||||
|
|
||||||
|
@JSProperty("$rt_shortcls")
|
||||||
|
PlatformClass getShortClass();
|
||||||
|
|
||||||
|
@JSProperty("$rt_charcls")
|
||||||
|
PlatformClass getCharClass();
|
||||||
|
|
||||||
|
@JSProperty("$rt_intcls")
|
||||||
|
PlatformClass getIntClass();
|
||||||
|
|
||||||
|
@JSProperty("$rt_longcls")
|
||||||
|
PlatformClass getLongClass();
|
||||||
|
|
||||||
|
@JSProperty("$rt_floatcls")
|
||||||
|
PlatformClass getFloatClass();
|
||||||
|
|
||||||
|
@JSProperty("$rt_doublecls")
|
||||||
|
PlatformClass getDoubleClass();
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform;
|
||||||
|
|
||||||
|
import org.teavm.jso.JSIndexer;
|
||||||
|
import org.teavm.jso.JSObject;
|
||||||
|
import org.teavm.jso.JSProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public interface PlatformSequence<T> extends JSObject {
|
||||||
|
@JSProperty
|
||||||
|
int getLength();
|
||||||
|
|
||||||
|
@JSIndexer
|
||||||
|
T get(int index);
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform.metadata;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public interface ClassResource extends Resource {
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ package org.teavm.platform.metadata;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
import org.teavm.model.ListableClassReaderSource;
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
|
import org.teavm.platform.Platform;
|
||||||
import org.teavm.vm.TeaVM;
|
import org.teavm.vm.TeaVM;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,6 +49,12 @@ public interface MetadataGeneratorContext extends ServiceRepository {
|
||||||
*/
|
*/
|
||||||
<T extends Resource> T createResource(Class<T> resourceType);
|
<T extends Resource> T createResource(Class<T> resourceType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new resource that represents class literal. Client code then may use
|
||||||
|
* {@link Platform#classFromResource(ClassResource)} to get actual class.
|
||||||
|
*/
|
||||||
|
ClassResource createClassResource(String className);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new resource array.
|
* Creates a new resource array.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform.plugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.teavm.codegen.SourceWriter;
|
||||||
|
import org.teavm.platform.metadata.ClassResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
class BuildTimeClassResource implements ClassResource, ResourceWriter {
|
||||||
|
private String className;
|
||||||
|
|
||||||
|
public BuildTimeClassResource(String className) {
|
||||||
|
this.className = className;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClassName() {
|
||||||
|
return className;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(SourceWriter writer) throws IOException {
|
||||||
|
writer.appendClass(className);
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,10 +19,7 @@ import java.lang.reflect.Proxy;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import org.teavm.common.ServiceRepository;
|
import org.teavm.common.ServiceRepository;
|
||||||
import org.teavm.model.ListableClassReaderSource;
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
import org.teavm.platform.metadata.MetadataGeneratorContext;
|
import org.teavm.platform.metadata.*;
|
||||||
import org.teavm.platform.metadata.Resource;
|
|
||||||
import org.teavm.platform.metadata.ResourceArray;
|
|
||||||
import org.teavm.platform.metadata.ResourceMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -70,6 +67,11 @@ class DefaultMetadataGeneratorContext implements MetadataGeneratorContext {
|
||||||
return new BuildTimeResourceArray<>();
|
return new BuildTimeResourceArray<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ClassResource createClassResource(String className) {
|
||||||
|
return new BuildTimeClassResource(className);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T extends Resource> ResourceMap<T> createResourceMap() {
|
public <T extends Resource> ResourceMap<T> createResourceMap() {
|
||||||
return new BuildTimeResourceMap<>();
|
return new BuildTimeResourceMap<>();
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.classlib.impl;
|
package org.teavm.platform.plugin;
|
||||||
|
|
||||||
import org.teavm.dependency.*;
|
import org.teavm.dependency.*;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
|
import org.teavm.platform.Platform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -39,7 +40,7 @@ public class NewInstanceDependencySupport implements DependencyListener {
|
||||||
if (cls.hasModifier(ElementModifier.ABSTRACT) || cls.hasModifier(ElementModifier.INTERFACE)) {
|
if (cls.hasModifier(ElementModifier.ABSTRACT) || cls.hasModifier(ElementModifier.INTERFACE)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
MethodReader method = cls.getMethod(new MethodDescriptor("<init>", ValueType.VOID));
|
MethodReader method = cls.getMethod(new MethodDescriptor("<init>", void.class));
|
||||||
if (method != null) {
|
if (method != null) {
|
||||||
allClassesNode.propagate(agent.getType(className));
|
allClassesNode.propagate(agent.getType(className));
|
||||||
}
|
}
|
||||||
|
@ -48,7 +49,7 @@ public class NewInstanceDependencySupport implements DependencyListener {
|
||||||
@Override
|
@Override
|
||||||
public void methodAchieved(final DependencyAgent agent, MethodDependency method, final CallLocation location) {
|
public void methodAchieved(final DependencyAgent agent, MethodDependency method, final CallLocation location) {
|
||||||
MethodReader reader = method.getMethod();
|
MethodReader reader = method.getMethod();
|
||||||
if (reader.getOwnerName().equals("java.lang.Class") && reader.getName().equals("newInstance")) {
|
if (reader.getOwnerName().equals(Platform.class.getName()) && reader.getName().equals("newInstance")) {
|
||||||
allClassesNode.connect(method.getResult());
|
allClassesNode.connect(method.getResult());
|
||||||
method.getResult().addConsumer(new DependencyConsumer() {
|
method.getResult().addConsumer(new DependencyConsumer() {
|
||||||
@Override public void consume(DependencyAgentType type) {
|
@Override public void consume(DependencyAgentType type) {
|
||||||
|
@ -59,8 +60,10 @@ public class NewInstanceDependencySupport implements DependencyListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachConstructor(DependencyAgent checker, String type, CallLocation location) {
|
private void attachConstructor(DependencyAgent checker, String type, CallLocation location) {
|
||||||
MethodReference ref = new MethodReference(type, new MethodDescriptor("<init>", ValueType.VOID));
|
MethodReference ref = new MethodReference(type, "<init>", ValueType.VOID);
|
||||||
checker.linkMethod(ref, location).use();
|
MethodDependency methodDep = checker.linkMethod(ref, location);
|
||||||
|
methodDep.getVariable(0).propagate(checker.getType(type));
|
||||||
|
methodDep.use();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 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.platform.plugin;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import org.teavm.codegen.SourceWriter;
|
||||||
|
import org.teavm.dependency.DependencyAgent;
|
||||||
|
import org.teavm.dependency.DependencyPlugin;
|
||||||
|
import org.teavm.dependency.MethodDependency;
|
||||||
|
import org.teavm.javascript.spi.Generator;
|
||||||
|
import org.teavm.javascript.spi.GeneratorContext;
|
||||||
|
import org.teavm.javascript.spi.Injector;
|
||||||
|
import org.teavm.javascript.spi.InjectorContext;
|
||||||
|
import org.teavm.model.*;
|
||||||
|
import org.teavm.platform.Platform;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
|
*/
|
||||||
|
public class PlatformGenerator implements Generator, Injector, DependencyPlugin {
|
||||||
|
@Override
|
||||||
|
public void methodAchieved(DependencyAgent agent, MethodDependency method, CallLocation location) {
|
||||||
|
switch (method.getReference().getName()) {
|
||||||
|
case "asJavaClass":
|
||||||
|
method.getResult().propagate(agent.getType("java.lang.Class"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(InjectorContext context, MethodReference methodRef) throws IOException {
|
||||||
|
switch (methodRef.getName()) {
|
||||||
|
case "asJavaClass":
|
||||||
|
context.writeExpr(context.getArgument(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
|
||||||
|
switch (methodRef.getName()) {
|
||||||
|
case "newInstance":
|
||||||
|
generateNewInstance(context, writer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateNewInstance(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||||
|
String self = context.getParameterName(0);
|
||||||
|
writer.append("if").ws().append("(!").appendClass(Platform.class).append(".$$constructors$$)").ws()
|
||||||
|
.append("{").indent().softNewLine();
|
||||||
|
writer.appendClass(Platform.class).append(".$$constructors$$").ws().append("=").append("true;").softNewLine();
|
||||||
|
for (String clsName : context.getClassSource().getClassNames()) {
|
||||||
|
ClassReader cls = context.getClassSource().get(clsName);
|
||||||
|
MethodReader method = cls.getMethod(new MethodDescriptor("<init>", void.class));
|
||||||
|
if (method != null) {
|
||||||
|
writer.appendClass(clsName).append(".$$constructor$$").ws().append("=").ws()
|
||||||
|
.appendMethodBody(method.getReference()).append(";").softNewLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.outdent().append("}").softNewLine();
|
||||||
|
writer.append("var cls = " + self + ".$data;").softNewLine();
|
||||||
|
writer.append("var ctor = cls.$$constructor$$;").softNewLine();
|
||||||
|
writer.append("if (!ctor) {").indent().softNewLine();
|
||||||
|
writer.append("var ex = new ").appendClass(InstantiationException.class.getName()).append("();").softNewLine();
|
||||||
|
writer.appendMethodBody(new MethodReference(InstantiationException.class, "<init>", void.class))
|
||||||
|
.append("(ex);").softNewLine();
|
||||||
|
writer.append("$rt_throw(ex);").softNewLine();
|
||||||
|
writer.outdent().append("}").softNewLine();
|
||||||
|
writer.append("var instance = new cls();").softNewLine();
|
||||||
|
writer.append("ctor(instance);").softNewLine();
|
||||||
|
writer.append("return instance;").softNewLine();
|
||||||
|
}
|
||||||
|
}
|
|
@ -30,5 +30,6 @@ public class PlatformPlugin implements TeaVMPlugin {
|
||||||
host.add(new ResourceAccessorTransformer(host));
|
host.add(new ResourceAccessorTransformer(host));
|
||||||
host.add(new ResourceAccessorDependencyListener());
|
host.add(new ResourceAccessorDependencyListener());
|
||||||
host.add(new AsyncMethodProcessor());
|
host.add(new AsyncMethodProcessor());
|
||||||
|
host.add(new NewInstanceDependencySupport());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user