diff --git a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java index 6630b8362..72f45cefc 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -44,6 +44,7 @@ public class Decompiler { private RangeTree.Node parentNode; private FiniteExecutor executor; private Map generators = new HashMap<>(); + private Set methodsToPass = new HashSet<>(); public Decompiler(ClassHolderSource classSource, ClassLoader classLoader, FiniteExecutor executor) { this.classSource = classSource; @@ -96,6 +97,10 @@ public class Decompiler { generators.put(method, generator); } + public void addMethodToPass(MethodReference method) { + methodsToPass.add(method); + } + private void orderClasses(String className, Set visited, List order) { if (!visited.add(className)) { return; @@ -125,7 +130,8 @@ public class Decompiler { if (method.getModifiers().contains(ElementModifier.ABSTRACT)) { continue; } - if (method.getAnnotations().get(InjectedBy.class.getName()) != null) { + if (method.getAnnotations().get(InjectedBy.class.getName()) != null || + methodsToPass.contains(method)) { continue; } MethodNode methodNode = decompile(method); @@ -140,8 +146,8 @@ public class Decompiler { } public MethodNode decompile(MethodHolder method) { - return method.getModifiers().contains(ElementModifier.NATIVE) ? - decompileNative(method) : decompileRegular(method); + return method.getModifiers().contains(ElementModifier.NATIVE) ? decompileNative(method) : + decompileRegular(method); } public NativeMethodNode decompileNative(MethodHolder method) { diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index dbb2986b8..1006a503b 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -53,6 +53,10 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext } } + public void addInjector(MethodReference method, Injector injector) { + injectorMap.put(method, new InjectorHolder(injector)); + } + public Renderer(SourceWriter writer, ListableClassHolderSource classSource, ClassLoader classLoader) { this.naming = writer.getNaming(); this.writer = writer; diff --git a/teavm-core/src/main/java/org/teavm/model/MethodDescriptor.java b/teavm-core/src/main/java/org/teavm/model/MethodDescriptor.java index 4bcc64a4b..aeba3a45e 100644 --- a/teavm-core/src/main/java/org/teavm/model/MethodDescriptor.java +++ b/teavm-core/src/main/java/org/teavm/model/MethodDescriptor.java @@ -34,6 +34,17 @@ public class MethodDescriptor { this.signature = Arrays.copyOf(signature, signature.length); } + public MethodDescriptor(String name, Class... signature) { + if (signature.length < 1) { + throw new IllegalArgumentException("Signature must be at least 1 element length"); + } + this.name = name; + this.signature = new ValueType[signature.length]; + for (int i = 0; i < signature.length; ++i) { + this.signature[i] = ValueType.parse(signature[i]); + } + } + public String getName() { return name; } diff --git a/teavm-core/src/main/java/org/teavm/model/MethodReference.java b/teavm-core/src/main/java/org/teavm/model/MethodReference.java index 3f5ad5da4..38979ac56 100644 --- a/teavm-core/src/main/java/org/teavm/model/MethodReference.java +++ b/teavm-core/src/main/java/org/teavm/model/MethodReference.java @@ -55,6 +55,10 @@ public class MethodReference { this(className, new MethodDescriptor(name, signature)); } + public MethodReference(Class cls, String name, Class... signature) { + this(cls.getName(), new MethodDescriptor(name, signature)); + } + public String getClassName() { return className; } diff --git a/teavm-core/src/main/java/org/teavm/model/ValueType.java b/teavm-core/src/main/java/org/teavm/model/ValueType.java index 86d0b9a13..b4f7795ab 100644 --- a/teavm-core/src/main/java/org/teavm/model/ValueType.java +++ b/teavm-core/src/main/java/org/teavm/model/ValueType.java @@ -16,7 +16,9 @@ package org.teavm.model; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** @@ -25,6 +27,7 @@ import java.util.List; */ public abstract class ValueType { volatile String reprCache; + private static final Map, ValueType> primitiveMap = new HashMap<>(); private ValueType() { } @@ -166,6 +169,19 @@ public abstract class ValueType { public static final Null NULL = new Null(); + + static { + primitiveMap.put(boolean.class, BOOLEAN); + primitiveMap.put(char.class, CHARACTER); + primitiveMap.put(byte.class, BYTE); + primitiveMap.put(short.class, SHORT); + primitiveMap.put(int.class, INTEGER); + primitiveMap.put(long.class, LONG); + primitiveMap.put(float.class, FLOAT); + primitiveMap.put(double.class, DOUBLE); + primitiveMap.put(void.class, VOID); + } + public static ValueType object(String cls) { return new Object(cls); } @@ -267,6 +283,16 @@ public abstract class ValueType { } } + public static ValueType parse(Class cls) { + if (cls.isPrimitive()) { + return primitiveMap.get(cls); + } else if (cls.getComponentType() != null) { + return ValueType.arrayOf(ValueType.parse(cls.getComponentType())); + } else { + return ValueType.object(cls.getName()); + } + } + @Override public int hashCode() { return toString().hashCode(); diff --git a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java index 66cc8ee43..8eba7ff75 100644 --- a/teavm-core/src/main/java/org/teavm/vm/TeaVM.java +++ b/teavm-core/src/main/java/org/teavm/vm/TeaVM.java @@ -20,9 +20,12 @@ import java.util.*; import org.teavm.codegen.*; import org.teavm.common.FiniteExecutor; import org.teavm.dependency.*; -import org.teavm.javascript.*; +import org.teavm.javascript.Decompiler; +import org.teavm.javascript.Renderer; +import org.teavm.javascript.RenderingException; import org.teavm.javascript.ast.ClassNode; import org.teavm.javascript.ni.Generator; +import org.teavm.javascript.ni.Injector; import org.teavm.model.*; import org.teavm.model.util.ListingBuilder; import org.teavm.model.util.ProgramUtils; @@ -73,6 +76,7 @@ public class TeaVM implements TeaVMHost { private Map entryPoints = new HashMap<>(); private Map exportedClasses = new HashMap<>(); private Map methodGenerators = new HashMap<>(); + private Map methodInjectors = new HashMap<>(); private List rendererListeners = new ArrayList<>(); private Properties properties = new Properties(); @@ -98,6 +102,11 @@ public class TeaVM implements TeaVMHost { methodGenerators.put(methodRef, generator); } + @Override + public void add(MethodReference methodRef, Injector injector) { + methodInjectors.put(methodRef, injector); + } + @Override public void add(RendererListener listener) { rendererListeners.add(listener); @@ -315,6 +324,9 @@ public class TeaVM implements TeaVMHost { for (Map.Entry entry : methodGenerators.entrySet()) { decompiler.addGenerator(entry.getKey(), entry.getValue()); } + for (MethodReference injectedMethod : methodInjectors.keySet()) { + decompiler.addMethodToPass(injectedMethod); + } List clsNodes = decompiler.decompile(classSet.getClassNames()); // Render @@ -324,6 +336,9 @@ public class TeaVM implements TeaVMHost { builder.setMinified(minifying); SourceWriter sourceWriter = builder.build(writer); Renderer renderer = new Renderer(sourceWriter, classSet, classLoader); + for (Map.Entry entry : methodInjectors.entrySet()) { + renderer.addInjector(entry.getKey(), entry.getValue()); + } try { for (RendererListener listener : rendererListeners) { listener.begin(renderer, target); diff --git a/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java b/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java index fc0f2cfbc..2acbda0af 100644 --- a/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java +++ b/teavm-core/src/main/java/org/teavm/vm/spi/TeaVMHost.java @@ -18,6 +18,7 @@ package org.teavm.vm.spi; import java.util.Properties; import org.teavm.dependency.DependencyListener; import org.teavm.javascript.ni.Generator; +import org.teavm.javascript.ni.Injector; import org.teavm.model.ClassHolderTransformer; import org.teavm.model.MethodReference; import org.teavm.vm.TeaVM; @@ -36,6 +37,8 @@ public interface TeaVMHost { void add(MethodReference methodRef, Generator generator); + void add(MethodReference methodRef, Injector injector); + void add(RendererListener listener); /** diff --git a/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java b/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java index 7b50dfe88..3524b52d9 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java +++ b/teavm-platform/src/main/java/org/teavm/platform/metadata/Resource.java @@ -15,10 +15,7 @@ */ package org.teavm.platform.metadata; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +import java.lang.annotation.*; /** *

Marks a valid resource interface. Resource interface is an interface, that has get* and set* methods, @@ -33,5 +30,7 @@ import java.lang.annotation.Target; */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) +@Inherited +@Documented public @interface Resource { } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java index 6589f4c8b..ad16bfc25 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformPlugin.java @@ -26,5 +26,8 @@ public class PlatformPlugin implements TeaVMPlugin { @Override public void install(TeaVMHost host) { host.add(new MetadataProviderTransformer()); + host.add(new ResourceTransformer()); + host.add(new ResourceAccessorTransformer(host)); + host.add(new ResourceAccessorDependencyListener()); } } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessor.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessor.java new file mode 100644 index 000000000..e91ca89c2 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessor.java @@ -0,0 +1,86 @@ +/* + * Copyright 2014 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; + +/** + * + * @author Alexey Andreev + */ +final class ResourceAccessor { + public static native Object get(Object obj, String propertyName); + + public static native void put(Object obj, String propertyName, Object elem); + + public static native Object get(Object obj, int index); + + public static native Object add(Object obj, Object elem); + + public static native boolean has(Object obj, String key); + + public static native boolean size(Object obj); + + public static native int castToInt(Object obj); + + public static native Integer castToIntWrapper(Object obj); + + public static native short castToShort(Object obj); + + public static native Short castToShortWrapper(Object obj); + + public static native byte castToByte(Object obj); + + public static native Byte castToByteWrapper(Object obj); + + public static native boolean castToBoolean(Object obj); + + public static native Boolean castToBooleanWrapper(Object obj); + + public static native float castToFloat(Object obj); + + public static native Float castToFloatWrapper(Object obj); + + public static native double castToDouble(Object obj); + + public static native Double castToDoubleWrapper(Object obj); + + public static native String castToString(Object obj); + + public static native Object castFromInt(int value); + + public static native Object castFromIntWrapper(Integer value); + + public static native Object castFromShort(short value); + + public static native Object castFromShortWrapper(Short value); + + public static native Object castFromByte(byte value); + + public static native Object castFromByteWrapper(Byte value); + + public static native Object castFromBoolean(boolean value); + + public static native Object castFromBooleanWrapper(Boolean value); + + public static native Object castFromFloat(float value); + + public static native Object castFromFloatWrapper(Float value); + + public static native Object castFromDouble(double value); + + public static native Object castFromDoubleWrapper(Double value); + + public static native Object castFromString(String value); +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessorDependencyListener.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessorDependencyListener.java new file mode 100644 index 000000000..98345dbd1 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessorDependencyListener.java @@ -0,0 +1,95 @@ +/* + * Copyright 2014 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 org.teavm.dependency.DependencyAgent; +import org.teavm.dependency.DependencyListener; +import org.teavm.dependency.FieldDependency; +import org.teavm.dependency.MethodDependency; +import org.teavm.model.MethodReference; + +/** + * + * @author Alexey Andreev + */ +class ResourceAccessorDependencyListener implements DependencyListener { + @Override + public void started(DependencyAgent agent) { + } + + @Override + public void classAchieved(DependencyAgent agent, String className) { + } + + @Override + public void methodAchieved(DependencyAgent agent, MethodDependency method) { + switch (method.getReference().getName()) { + case "castToIntWrapper": + castToWrapper(agent, method, Integer.class, int.class); + break; + case "castToShortWrapper": + castToWrapper(agent, method, Short.class, short.class); + break; + case "castToByteWrapper": + castToWrapper(agent, method, Byte.class, byte.class); + break; + case "castToBooleanWrapper": + castToWrapper(agent, method, Boolean.class, boolean.class); + break; + case "castToFloatWrapper": + castToWrapper(agent, method, Float.class, float.class); + break; + case "castToDoubleWrapper": + castToWrapper(agent, method, Double.class, double.class); + break; + case "castFromIntegerWrapper": + castFromWrapper(agent, method, Integer.class, int.class); + break; + case "castFromShortWrapper": + castFromWrapper(agent, method, Short.class, short.class); + break; + case "castFromByteWrapper": + castFromWrapper(agent, method, Byte.class, byte.class); + break; + case "castFromBooleanWrapper": + castFromWrapper(agent, method, Boolean.class, boolean.class); + break; + case "castFromFloatWrapper": + castFromWrapper(agent, method, Float.class, float.class); + break; + case "castFromDoubleWrapper": + castFromWrapper(agent, method, Double.class, double.class); + break; + case "castToString": + method.getResult().propagate("java.lang.String"); + break; + } + } + + private void castToWrapper(DependencyAgent agent, MethodDependency method, Class wrapper, Class primitive) { + method.getResult().propagate(wrapper.getName()); + agent.linkMethod(new MethodReference(wrapper, "valueOf", primitive, wrapper), method.getStack()).use(); + } + + private void castFromWrapper(DependencyAgent agent, MethodDependency method, Class wrapper, Class primitive) { + String primitiveName = primitive.getName(); + agent.linkMethod(new MethodReference(wrapper, primitiveName + "Value", primitive), method.getStack()).use(); + } + + @Override + public void fieldAchieved(DependencyAgent agent, FieldDependency field) { + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessorGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessorGenerator.java new file mode 100644 index 000000000..5e8d7542d --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessorGenerator.java @@ -0,0 +1,193 @@ +/* + * Copyright 2014 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.javascript.ast.ConstantExpr; +import org.teavm.javascript.ast.Expr; +import org.teavm.javascript.ni.Injector; +import org.teavm.javascript.ni.InjectorContext; +import org.teavm.model.MethodReference; +import org.teavm.model.ValueType; + +/** + * + * @author Alexey Andreev + */ +class ResourceAccessorGenerator implements Injector { + @Override + public void generate(InjectorContext context, MethodReference methodRef) throws IOException { + switch (methodRef.getName()) { + case "get": + if (methodRef.getDescriptor().parameterType(1) == ValueType.INTEGER) { + context.writeExpr(context.getArgument(1)); + context.getWriter().append('['); + context.writeExpr(context.getArgument(2)); + context.getWriter().append(']'); + } else { + context.writeExpr(context.getArgument(1)); + writePropertyAccessor(context, context.getArgument(2)); + } + break; + case "put": + context.getWriter().append('('); + if (methodRef.getDescriptor().parameterType(1) == ValueType.INTEGER) { + context.writeExpr(context.getArgument(1)); + context.getWriter().append('['); + context.writeExpr(context.getArgument(2)); + } else { + context.writeExpr(context.getArgument(1)); + writePropertyAccessor(context, context.getArgument(2)); + } + context.getWriter().append(']').ws().append('=').ws(); + context.writeExpr(context.getArgument(3)); + context.getWriter().append(')'); + break; + case "add": + context.writeExpr(context.getArgument(1)); + context.getWriter().append(".push("); + context.writeExpr(context.getArgument(2)); + context.getWriter().append(')'); + break; + case "has": + context.writeExpr(context.getArgument(1)); + context.getWriter().append(".hasOwnProperty("); + writeStringExpr(context, context.getArgument(2)); + context.getWriter().append(')'); + break; + case "size": + context.writeExpr(context.getArgument(1)); + context.getWriter().append(".length"); + break; + case "castToInt": + case "castToShort": + case "castToByte": + case "castToBoolean": + case "castToFloat": + case "castToDouble": + case "castFromInt": + case "castFromShort": + case "castFromByte": + case "castFromBoolean": + case "castFromFloat": + case "castFromDouble": + context.writeExpr(context.getArgument(1)); + break; + case "castToIntWrapper": + castToWrapper(context, Integer.class, int.class); + break; + case "castToShortWrapper": + castToWrapper(context, Short.class, short.class); + break; + case "castToByteWrapper": + castToWrapper(context, Byte.class, byte.class); + break; + case "castToBooleanWrapper": + castToWrapper(context, Boolean.class, boolean.class); + break; + case "castToFloatWrapper": + castToWrapper(context, Float.class, float.class); + break; + case "castToDoubleWrapper": + castToWrapper(context, Double.class, double.class); + break; + case "castFromIntWrapper": + castFromWrapper(context, Integer.class, int.class); + break; + case "castFromShortWrapper": + castFromWrapper(context, Short.class, short.class); + break; + case "castFromByteWrapper": + castFromWrapper(context, Byte.class, byte.class); + break; + case "castFromBooleanWrapper": + castFromWrapper(context, Boolean.class, boolean.class); + break; + case "castFromFloatWrapper": + castFromWrapper(context, Float.class, float.class); + break; + case "castFromDoubleWrapper": + castFromWrapper(context, Double.class, double.class); + break; + case "castToString": + context.getWriter().append("$rt_str("); + context.writeExpr(context.getArgument(1)); + context.getWriter().append(")"); + break; + case "castFromString": + context.getWriter().append("$rt_ustr("); + context.writeExpr(context.getArgument(1)); + context.getWriter().append(")"); + break; + } + } + + private void castToWrapper(InjectorContext context, Class wrapper, Class primitive) throws IOException { + context.getWriter().appendMethodBody(new MethodReference(wrapper, "valueOf", primitive, wrapper)).append('('); + context.writeExpr(context.getArgument(1)); + context.getWriter().append(')'); + } + + private void castFromWrapper(InjectorContext context, Class wrapper, Class primitive) throws IOException { + String primitiveName = primitive.getName(); + context.getWriter().appendMethodBody(new MethodReference(wrapper, primitiveName + "Value", primitive)) + .append('('); + context.writeExpr(context.getArgument(1)); + context.getWriter().append(')'); + } + + private void writePropertyAccessor(InjectorContext context, Expr property) throws IOException { + if (property instanceof ConstantExpr) { + String str = (String)((ConstantExpr)property).getValue(); + if (str.isEmpty()) { + context.getWriter().append("[\"\"]"); + return; + } + if (isValidIndentifier(str)) { + context.getWriter().append(".").append(str); + return; + } + } + context.getWriter().append("[$rt_ustr("); + context.writeExpr(property); + context.getWriter().append(")]"); + } + + private void writeStringExpr(InjectorContext context, Expr expr) throws IOException { + if (expr instanceof ConstantExpr) { + String str = (String)((ConstantExpr)expr).getValue(); + context.getWriter().append('"'); + context.writeEscaped(str); + context.getWriter().append('"'); + return; + } + context.getWriter().append("$rt_ustr("); + context.writeExpr(expr); + context.getWriter().append(")"); + } + + private boolean isValidIndentifier(String str) { + if (!Character.isJavaIdentifierStart(str.charAt(0))) { + return false; + } + for (int i = 1; i < str.length(); ++i) { + if (!Character.isJavaIdentifierPart(str.charAt(i))) { + return false; + } + } + return true; + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessorTransformer.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessorTransformer.java new file mode 100644 index 000000000..bb0ae0c26 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceAccessorTransformer.java @@ -0,0 +1,44 @@ +/* + * Copyright 2014 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 org.teavm.model.ClassHolder; +import org.teavm.model.ClassHolderTransformer; +import org.teavm.model.ClassReaderSource; +import org.teavm.model.MethodHolder; +import org.teavm.vm.spi.TeaVMHost; + +/** + * + * @author Alexey Andreev + */ +class ResourceAccessorTransformer implements ClassHolderTransformer { + private TeaVMHost vm; + + public ResourceAccessorTransformer(TeaVMHost vm) { + this.vm = vm; + } + + @Override + public void transformClass(ClassHolder cls, ClassReaderSource innerSource) { + ResourceAccessorGenerator generator = new ResourceAccessorGenerator(); + if (cls.getName().equals(ResourceAccessor.class)) { + for (MethodHolder method : cls.getMethods()) { + vm.add(method.getReference(), generator); + } + } + } +} diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceTransformer.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceTransformer.java new file mode 100644 index 000000000..cbb343123 --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/ResourceTransformer.java @@ -0,0 +1,30 @@ +/* + * Copyright 2014 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 org.teavm.model.ClassHolder; +import org.teavm.model.ClassHolderTransformer; +import org.teavm.model.ClassReaderSource; + +/** + * + * @author Alexey Andreev + */ +class ResourceTransformer implements ClassHolderTransformer { + @Override + public void transformClass(ClassHolder cls, ClassReaderSource innerSource) { + } +}